如何上传文件
把图片、视频、音频上传到 Get3W 存储,然后把返回的 download_url 填入任意模型的输入参数。客户端先发一个带鉴权的小请求获取上传凭证,再用短期有效的 URL 把文件直接传到存储,文件字节不经过 API 网关。
接口
POST https://api.get3w.com/v1/media/uploads
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json请求体
json
{
"filename": "image.png",
"size": 1024000,
"content_type": "image/png"
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
filename | string | 是 | 原始文件名,需包含扩展名 |
size | integer | 是 | 文件的精确字节数,最大 200 MB(209,715,200 字节) |
content_type | string | 否 | MIME 类型;省略时按扩展名推断 |
支持的格式:
| 类型 | 扩展名 |
|---|---|
| image | jpg jpeg png gif webp bmp tiff tif |
| video | mp4 webm mov |
| audio | mp3 wav m4a aac flac |
响应
json
{
"type": "image",
"download_url": "https://get3w-media-1252164560.cos.ap-guangzhou.myqcloud.com/tmp/uploads/2026/10/17/3f2a....png",
"filename": "image.png",
"size": 1024000,
"upload": {
"method": "PUT",
"url": "https://...signed...",
"headers": {
"Content-Type": "image/png",
"x-cos-acl": "public-read",
"x-cos-forbid-overwrite": "true"
},
"expires_at": "2026-10-17T02:15:00Z"
}
}| 字段 | 说明 |
|---|---|
type | image、video 或 audio |
download_url | 上传成功后作为模型输入使用的公开 URL |
upload.method | 固定为 PUT |
upload.url | 短期有效的签名上传 URL(15 分钟内有效) |
upload.headers | PUT 时必须原样携带的请求头 |
upload.expires_at | upload.url 失效时间(UTC) |
用返回的 method、URL 和 headers 上传文件的原始字节。PUT 返回任意 2xx 即表示成功,download_url 可立即使用。
示例
bash
FILE="/path/to/image.png"
FILE_SIZE=$(wc -c < "$FILE" | tr -d ' ')
TICKET=$(curl --fail-with-body --silent --show-error \
-X POST "https://api.get3w.com/v1/media/uploads" \
-H "Authorization: Bearer $GET3W_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg filename "$(basename "$FILE")" --argjson size "$FILE_SIZE" \
'{filename: $filename, size: $size}')")
UPLOAD_URL=$(printf '%s' "$TICKET" | jq -r '.upload.url')
UPLOAD_HEADERS=()
while IFS= read -r header; do
UPLOAD_HEADERS+=(-H "$header")
done < <(printf '%s' "$TICKET" | jq -r \
'.upload.headers | to_entries[] | "\(.key): \(.value)"')
curl --fail-with-body --request PUT "$UPLOAD_URL" \
"${UPLOAD_HEADERS[@]}" \
--upload-file "$FILE"
printf '%s' "$TICKET" | jq -r '.download_url'python
import mimetypes
import os
from pathlib import Path
import requests
path = Path("/path/to/image.png")
payload = {"filename": path.name, "size": path.stat().st_size}
content_type = mimetypes.guess_type(path.name)[0]
if content_type:
payload["content_type"] = content_type
ticket_response = requests.post(
"https://api.get3w.com/v1/media/uploads",
headers={"Authorization": f"Bearer {os.environ['GET3W_API_KEY']}"},
json=payload,
timeout=30,
)
ticket_response.raise_for_status()
ticket = ticket_response.json()
with path.open("rb") as file:
upload_response = requests.put(
ticket["upload"]["url"],
headers=ticket["upload"]["headers"],
data=file,
timeout=300,
)
upload_response.raise_for_status()
print(ticket["download_url"])javascript
import { readFile, stat } from 'node:fs/promises';
import { basename } from 'node:path';
const filePath = '/path/to/image.png';
const ticketResponse = await fetch('https://api.get3w.com/v1/media/uploads', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.GET3W_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
filename: basename(filePath),
size: (await stat(filePath)).size,
}),
});
if (!ticketResponse.ok) throw new Error(await ticketResponse.text());
const ticket = await ticketResponse.json();
const uploadResponse = await fetch(ticket.upload.url, {
method: ticket.upload.method,
headers: ticket.upload.headers,
body: await readFile(filePath),
});
if (!uploadResponse.ok) throw new Error(await uploadResponse.text());
console.log(ticket.download_url);错误码
| 状态码 | 说明 |
|---|---|
| 400 | 缺少必填字段或字段类型错误(Invalid parameters)、文件名无效、格式不支持,或 content type 与扩展名不符 |
| 401 | 缺少 API key 或 API key 无效 |
| 413 | 文件超过 200 MB |
| 429 | 超出上传频率限制(每分钟 60 次),请稍后重试 |
向 upload.url 发起 PUT 时,如果凭证已过期、请求头与返回的不一致,或实际上传字节数与声明的 size 不符,会返回 403,此时请重新申请上传凭证。
凭证上传成功后再次使用会返回 409(已存在的对象不会被覆盖),每个文件请单独申请凭证。
注意事项
- upload URL 是临时凭证:不要记录日志、持久化保存或分享给他人
- API key 只发送给
api.get3w.com:PUT请求中不要携带Authorization头 - 把
upload.url当作不透明值:其域名和存储服务商可能变化,务必使用该次返回的完整 URL,不要自行拼接或改写 - 一个凭证对应一个文件:凭证不可复用,已存在的对象不会被覆盖
- 保留期:上传的文件保留 7 天后自动删除,仅用于模型推理输入。详见数据保留政策