素材上传与下载
阅读指引:本篇是《开放平台服务端 API 指南》的第 5 部分。接口基础地址、通用约定与各接口请求限制,请先阅读《服务端 API 概览》。
8. 上传与下载应用素材
应用素材属于当前应用私有资源。两个接口都只接受具备 material:manage 的应用级 Bearer Token,不接受用户 Token;调用前应确认应用实际获授该 Scope。
素材标识与隔离上传成功返回的 media_id 是后续引用和下载所需的唯一标识。素材与当前应用绑定,不能跨应用查询或下载。
8.1 支持类型与限制
type |
文件大小 | 格式与处理规则 |
|---|---|---|
file |
5 B~20 MiB | 普通文件;下载时使用规范化后的安全附件文件名。 |
voice |
5 B~2 MiB | 仅 M4A、MP3、WAV,实际音频时长不超过 60 秒;暂不支持 AMR。平台解析文件内容,不接受调用方提交时长。 |
video |
5 B~10 MiB | 仅 MP4;平台解析实际时长和画面尺寸,当前不生成视频首帧。 |
image |
5 B~10 MiB | 仅 JPG/JPEG、PNG;平台校验图片格式和原图尺寸,后续素材下载返回原图。 |
所有大小均指原始文件字节数,不包含 multipart 封装。文件扩展名必须与实际文件格式一致;不能通过修改后缀绕过格式校验。图片及视频画面宽、高均不得超过 20,000 像素,总像素不得超过 100,000,000。
8.2 上传素材
POST /openapi/v1/materials?type={file|voice|video|image}
请求必须使用 multipart/form-data,整个请求最大 20 MiB + 64 KiB,且必须、只能包含一个名为 media、带非空文件名的文件字段;不接受额外表单字段或调用方提交的大小、MD5、时长和宽高。
| 请求项 | 必填 | 类型与规则 |
|---|---|---|
Authorization Header |
是 | Bearer {APP_ACCESS_TOKEN},Token 必须具备 material:manage。 |
type query |
是 | string;只能为 file/voice/video/image,只能出现一次,不能附加其他 query 参数。 |
media form part |
是 | file;必须有非空文件名,整个 multipart 中只能出现这一个 part。 |
curl -X POST "${OPENAPI_BASE_URL}/openapi/v1/materials?type=image" \
-H "Authorization: Bearer ${APP_ACCESS_TOKEN}" \
-F "media=@./example.png"
{
"code": 200,
"message": "ok",
"data": {
"media_id": "media_0123456789abcdef0123456789abcdef",
"type": "image",
"created_at": 1787625600000
}
}
| 响应字段 | JSON 类型 | 含义与单位 |
|---|---|---|
code |
integer | 业务码;成功为 200。 |
message |
string | 简短结果文本;业务判断以 code 为准。 |
data.media_id |
string | 当前应用下的素材不透明标识,可用于发送消息和下载原始素材。 |
data.type |
string | 平台确认的素材类型,与请求 type 一致。 |
data.created_at |
integer | 素材创建时间,Unix 毫秒时间戳。 |
- 只有素材完成处理并进入可用状态后,接口才返回
media_id。 - 响应不包含平台文件标识、缩略图、MD5 或文件服务器 URL。
- 同一应用与来源 IP 的初始上传限流为 10 次/分钟;超限返回 HTTP 429 和
170507。 - 当前不支持断点上传、素材列表和删除接口。
8.3 下载原始素材
GET /openapi/v1/materials/content?media_id={MEDIA_ID}
| 请求项 | 必填 | 规则 |
|---|---|---|
Authorization Header |
是 | Bearer {APP_ACCESS_TOKEN},Token 必须具备 material:manage。 |
media_id query |
是 | string;上传接口返回的素材标识,只能出现一次,不能附加其他 query 参数。 |
Range Header |
否 | 当前不支持;一旦出现即返回 HTTP 416。 |
curl "${OPENAPI_BASE_URL}/openapi/v1/materials/content?media_id=${MEDIA_ID}" \
-H "Authorization: Bearer ${APP_ACCESS_TOKEN}" \
--output ./downloaded-file
成功时响应体直接是上传时的原始文件字节,不使用 JSON 包装。响应包含原始 Content-Type、Content-Length 和安全编码的附件文件名,并设置 Cache-Control: private, no-store 与 X-Content-Type-Options: nosniff。
- 图片下载返回原图,不提供缩略图;视频当前不提供首帧。
media_id必填且只能出现一次;不要附加未文档化的应用或文件标识。- 素材不存在、非正常状态、已删除或属于其他应用时,统一返回 HTTP 404 和
170505,不透露素材是否属于其他应用。 - 当前不支持
Range;携带该请求头返回 HTTP 416。调用方须按完整文件下载。 - 同一应用与来源 IP 的初始下载限流为 60 次/分钟。
8.4 素材接口错误码
| HTTP | code | 含义与处理 |
|---|---|---|
| 400 | 170501 |
type、media_id、multipart、字段或文件名无效。 |
| 400 | 170502 |
扩展名、实际格式、容器、图片解码或尺寸不受支持。 |
| 413 | 170503 |
文件小于 5 B、超过对应类型上限,或整个上传请求超限。 |
| 400 | 170504 |
语音实际时长超过 60 秒。 |
| 404 | 170505 |
当前应用下没有可下载的正常素材。 |
| 429 | 170507 |
素材上传或下载请求过于频繁,退避后重试。 |
| 500 | 170508 |
素材处理失败;不要在紧密循环中重试。 |
| 502 | 170509 |
文件存储暂不可用或完整性校验失败,稍后重试。 |