媒体
上传素材
把一张图 / 一段视频变成本站可用的媒体 URL。发布用的媒体必须存在本站对象存储上(外链会过期),所以先用它拿到 mediaUrl,再填进新建 / 修改的 media[].dataUrl。mode=upload 回一条五分钟有效的直传地址,你自己按返回的 Content-Type 发 PUT(字节不经过本站服务器:图片 8MB、视频 500MB);mode=transload 由本站代抓你给的外链再转存,只收图片与封面,上限 8MB。只产出 URL,不会改动任何内容。
POST
/api/v1/mediaposts:write写档限流Idempotency-Key 可选
鉴权与护栏
- 请求头
Authorization: Bearer <长期凭证>,凭证在设置页「接入外部系统 → 长期凭证」签发,见 鉴权与权限。 - 凭证需带 scope
posts:write;签发者在工作区里的角色也要允许该动作。 - 限流:写档,每分钟 10 次(按凭证计),超出回 429 并带
Retry-After。 - 幂等:带
Idempotency-Key就按它去重,不带也能调。
请求体(application/json)
modeenum: upload · transload必填upload = 拿直传地址自己 PUT;transload = 让本站代抓外链转存。
kindenum: image · cover · video必填image 正文配图 · cover 封面 · video 视频。
contentTypestring可选upload 档必填:image/jpeg | png | webp 或 video/mp4 | webm | quicktime。
bytesinteger可选upload 档必填:文件字节数,超上限直接拒。
urlstring (http/https)可选transload 档必填:要转存的外链(只支持图片 / 封面)。
clientRequestIdstring可选幂等键(8–128 chars of [A-Za-z0-9_.:-]);推荐放在 Idempotency-Key 请求头,头与 body 都给时以头为准。
调用规则
- 直传地址只活 5 分钟,拿到就传;过期重新申请即可。
- 视频一律走 upload 档;transload 只收图片与封面。
响应
成功返回 HTTP 201,信封为 { data, meta };右侧(窄屏在本页末尾)给出了各状态码的示例。所有错误都是 { error: { code, message, params }, meta },按机器码处理而不是按 message 匹配,码表见 错误码。
| 状态码 | 可能的错误码 |
|---|---|
| 400 | invalid_input |
| 401 | unauthenticated |
| 402 | plan_limit |
| 403 | forbidden / workspace_not_found |
| 404 | not_found |
| 409 | no_account / needs_reauth / replay |
| 429 | rate_limited |
| 500 | internal |
| 502 | platform_error |
| 503 | external_writes_off |
示例
请求
curl -X POST "https://popkit.loxily.com/api/v1/media" \
-H "Authorization: Bearer popkit_it_••••••••" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: acme-2026-09-21-001" \
-d '{
"mode": "upload",
"kind": "video",
"contentType": "video/mp4",
"bytes": 48213000
}'响应
upload 档
{
"data": {
"mode": "upload",
"kind": "video",
"mediaUrl": "https://storage.googleapis.com/socialhub-media/ws_01J7…/media/01J8ZN….mp4",
"uploadUrl": "https://storage.googleapis.com/socialhub-media/…?X-Goog-Signature=…",
"contentType": "video/mp4",
"expiresInSec": 300,
"next": "PUT the file bytes to uploadUrl with Content-Type: video/mp4 within 300s, then pass mediaUrl in media[].dataUrl."
},
"meta": {
"requestId": "6a1d0c9e-2b7f-4e3a-8c5d-1f0e9b8a7c73"
}
}