大文件上传(视觉理解)
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 使用,上游即可完整理解整个文件。
流程三步:① 创建上传任务拿直传地址 → ② 把文件直传上去 → ③ 完成并取回 gs:// 引用。
单次使用,用完即删:拿到的
gs://引用只能用一次。第一次在 Gemini 请求里引用并成功返回后,该文件会被自动删除。若同一文件要在多轮对话里反复引用,见 第 4 节 的X-Upload-Single-Use说明。文件直传我们的存储,不经过网关:第 ② 步的字节走预签名直传地址,不占用你的 API 额度、也不受请求体大小限制。
有效期:上传地址(第 ①→② 步)默认 1 小时内有效;完成后的
gs://引用若一直不使用,最长保留约 24 小时后自动清理。
1. 创建上传任务:POST /v1/uploads
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
size_bytes |
int | 是 | 文件的精确字节数(会签进上传地址,直传时大小不符会被拒)。 |
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/...(预签名直传地址)...",
"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 |
预签名直传地址,用第 2 步的 PUT 把文件上传到这里。 |
upload_headers |
直传时必须原样带上的请求头(它们已签进地址,不一致会被拒)。 |
upload_expires_at |
直传地址的过期时间(默认 1 小时)。 |
2. 上传文件:PUT 到 upload_url
用上一步返回的 upload_url 和 upload_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_uri 放进 Gemini 原生接口 请求的 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_type 仅支持 video/* image/* audio/* application/pdf。 |
| 400 | complete 时文件未上传 |
先完成第 2 步的 PUT 再调 complete。 |
| 400 | 大小不符 | 直传的字节数与创建时的 size_bytes 不一致。 |
| 404 | 上传任务不存在 / 非本组织 | upload_id 错误或不属于你的组织。 |
| 404 | 功能未开通 | 你的组织所在线路未开通大文件上传,请联系客服。 |
| 409 | 转存进行中 | complete 正在转存,Retry-After 秒后重试即可。 |
| 410 | 引用已失效 | 文件已被引用(单次使用)、已删除或已过期。 |
| 429 | 超出每日配额 | 单组织每日创建的上传任务数达到上限。 |