大容量ファイルアップロード(視覚理解)

POST /v1/uploads · POST /v1/uploads/{id}/complete · GET /v1/uploads/{id} · DELETE /v1/uploads/{id}

Gemini マルチモーダルモデルで大容量ファイルの視覚理解(動画 / 画像 / 音声 / PDF)を行う際、素材が約 15 MB を超えると、base64 のインライン送信(リクエストボディ全体の上限 20 MB)も使えず、公開 https:// URL も上流に先頭の約 15 MB しか読み込まれません(それ以降は静かに破棄され、エラーにもなりません)。本エンドポイントはこれを解決します:大容量ファイルをまず当社ストレージにアップロードして gs:// 参照を取得し、それを Gemini ネイティブインターフェースfile_data.file_uri として使えば、上流がファイル全体を理解できます。

3 ステップ:① アップロードタスクを作成して直接アップロード用 URL を取得 → ② ファイルを直接アップロード → ③ 完了して gs:// 参照を取得。

一度きりの使用、使用後は自動削除:取得した gs:// 参照は一度しか使えません。それを参照した最初の Gemini リクエストが成功して返ると、ファイルは自動的に削除されます。同じファイルを複数ターンで繰り返し参照するには、第 4 節X-Upload-Single-Use の説明をご覧ください。

ファイルは当社ストレージへ直接アップロードされ、ゲートウェイを経由しません:ステップ ② のバイトは署名付きの直接アップロード URL へ送られ、API クォータを消費せず、リクエストボディのサイズ制限も受けません。

有効期限:アップロード URL(ステップ ①→②)はデフォルトで 1 時間有効です。完了後の gs:// 参照は、一度も使われないと約 24 時間後に自動的にクリーンアップされます。

1. アップロードタスクを作成:POST /v1/uploads

フィールド 必須 説明
size_bytes int はい ファイルの正確なバイト数(アップロード URL に署名され、アップロード時にサイズが一致しないと拒否されます)。
mime_type string はい ファイルの MIME タイプ。video/*image/*audio/*application/pdf に対応。
curl https://api.portal.aiin1.ai/v1/uploads \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "size_bytes": 33852748, "mime_type": "video/mp4" }'

レスポンス

{
  "upload_id": "upload_2b9574243b714a13a9fceda4c152f314",
  "upload_url": "https://<account>.r2.cloudflarestorage.com/...(署名付き直接アップロード URL)...",
  "upload_method": "PUT",
  "upload_headers": { "Content-Type": "video/mp4", "Content-Length": "33852748" },
  "upload_expires_at": "2026-07-23T13:10:38+00:00",
  "single_use": true
}
フィールド 説明
upload_id アップロードタスク ID。以降の complete / 照会 / 削除で使用します。
upload_url 署名付き直接アップロード URL。ステップ 2 でここへ PUT します。
upload_headers アップロード時にそのまま付与する必要があるヘッダー(URL に署名済みで、一致しないと拒否されます)。
upload_expires_at アップロード URL の有効期限(デフォルト 1 時間)。

2. ファイルをアップロード:upload_urlPUT

前ステップで返された upload_urlupload_headers を使い、ファイルのバイトを PUT します。このステップはストレージへ直接送信され、API ゲートウェイを経由しません:

curl -X PUT "<前ステップで返された upload_url>" \
  -H "Content-Type: video/mp4" \
  --data-binary @my-video.mp4

アップロード成功時は 200(ボディなし)を返します。Content-Type は作成時の mime_type と一致し、アップロードするバイト数は size_bytes と等しくなければならず、そうでない場合ストレージが拒否します。

3. 完了して参照を取得:POST /v1/uploads/{id}/complete

ファイルを送り終えたら complete を呼びます。ファイルが正しいサイズでアップロードされたことを検証し、上流が読み取れる gs:// 参照へ転送し、転送完了まで同期的に待機(200 MB で通常数秒)した後、以下を返します:

curl -X POST https://api.portal.aiin1.ai/v1/uploads/upload_2b9574243b714a13a9fceda4c152f314/complete \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

レスポンス

{
  "upload_id": "upload_2b9574243b714a13a9fceda4c152f314",
  "file_uri": "gs://.../30367d4d.../upload_2b9574243b714a13a9fceda4c152f314",
  "uri_type": "gcs",
  "size_bytes": 33852748,
  "single_use": true
}
フィールド 説明
file_uri Gemini リクエストの file_data.file_uri に貼り付ける参照(第 4 節を参照)。
uri_type 参照の種別。現在は常に gcs

complete冪等です:ファイルが準備完了なら再度呼んでも同じ file_uri を返し、転送がまだ進行中なら 409 を返します(少し待って再試行してください)。

4. Gemini ネイティブインターフェースで使う

file_uriGemini ネイティブインターフェース リクエストの file_data に入れます(mime_type はファイルと一致させてください):

curl https://api.portal.aiin1.ai/v1beta/models/gemini-3.1-pro-preview:generateContent \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{
      "parts": [
        {"text": "この動画の内容を詳しく説明してください。"},
        {"file_data": {"mime_type": "video/mp4", "file_uri": "gs://.../upload_2b9574243b714a13a9fceda4c152f314"}}
      ]
    }]
  }'

一度きりの使用:上記のリクエストが成功して返るとfile_uri が指すファイルは自動的に削除され、再度参照すると失敗します。

複数ターンでの再利用:同じファイルを複数ターンで繰り返し参照するには、Gemini リクエストにヘッダー X-Upload-Single-Use: off を付けます。これにより参照後すぐには削除されず、有効期限(約 24 時間)の満了時にクリーンアップされます。

5. 照会と削除(任意)

upload_id でステータスを照会:

curl https://api.portal.aiin1.ai/v1/uploads/upload_2b9574243b714a13a9fceda4c152f314 \
  -H "Authorization: Bearer YOUR_API_KEY"
{ "upload_id": "upload_2b9574243b714a13a9fceda4c152f314", "status": "ready", "file_uri": "gs://.../upload_2b9574243b714a13a9fceda4c152f314", "uri_type": "gcs", "size_bytes": 33852748, "mime_type": "video/mp4", "created_at": "2026-07-23T12:10:38+00:00", "ready_at": "2026-07-23T12:11:02+00:00" }

status の値:pending_upload(アップロード待ち)/ copying(転送中)/ ready(使用可能)/ consumed(参照済み)/ deleted / expired / copy_failed

明示的に削除(一度きりの使用では通常不要):

curl -X DELETE https://api.portal.aiin1.ai/v1/uploads/upload_2b9574243b714a13a9fceda4c152f314 \
  -H "Authorization: Bearer YOUR_API_KEY"
{ "upload_id": "upload_2b9574243b714a13a9fceda4c152f314", "deleted": true }

自組織以外の upload_id は一律 404 を返します。

6. よくあるエラー

HTTP 状況 説明
400 size_bytes / mime_type が不正 size_bytes は上限以内の正の整数、mime_typevideo/* image/* audio/* application/pdf のみ対応。
400 complete 時にファイル未アップロード complete を呼ぶ前にステップ 2 の PUT を完了してください。
400 サイズ不一致 アップロードしたバイト数が作成時の size_bytes と異なります。
404 アップロードタスクが存在しない / 自組織のものでない upload_id が誤っているか、あなたの組織に属していません。
404 機能が未開通 あなたの組織のラインで大容量ファイルアップロードが有効化されていません。サポートへお問い合わせください。
409 転送進行中 complete が転送中です。Retry-After 秒後に再試行してください。
410 参照が無効 ファイルは既に参照済み(一度きりの使用)、削除済み、または期限切れです。
429 日次クォータ超過 あなたの組織が作成したアップロードタスクの日次上限に達しました。