上传与下载
用链接、内嵌或上传的方式发送参考图片、视频和音频,以及下载任务生成的文件。
很多模型需要文件作为输入——要动起来的照片、要续写的片段、声音样本、一首歌。交给模型的方式有四种,拿回结果的方式只有一种。
发送文件的四种方式
| 你手里有 | 这样传 | 适合 |
|---|---|---|
| 一个公开的 HTTPS 链接 | 直接传链接,如 "image_url": "https://…/photo.jpg" | 你已经托管好的文件 |
| 内存里的一张小图 | 传 data URI,如 "image_url": "data:image/png;base64,…" | 快速测试、1 MiB 以内的图片 |
| 一个本地文件 | 先上传,再传 "image_url": "popnow://f/fil_…" | 其他所有情况,包括视频和音频 |
| 素材库里的文件 | 传 "image_url": "popnow://a/ast_…" | 在很多任务里反复使用的文件。见素材库 |
不管哪种方式,文件都放在模型 schema 为它声明的字段里(image_url、image_urls、video_url、audio_url …)。
公开链接
链接必须直接返回文件本身,并且在任务运行期间不用登录就能访问。网盘或社交网络的分享页返回的是网页而不是文件,任务会以 invalid_asset 失败;这种情况请先下载文件再上传。
内嵌图片
图片可以用带 MIME 类型的标准 Base64 data URI 发送:JPEG、PNG、WebP 或 GIF,每张解码后不超过 1 MiB、每边不超过 8,192 像素,每个请求最多 16 张,整个 JSON 请求体不超过 2 MiB。不支持不带前缀的 Base64、SVG,以及内嵌的视频或音频。内嵌图片会作为上传文件存进你的账户,所以任务的 input 里显示的是 popnow:// URI,而不会把原始字节原样返回。
上传文件
上传分三步:申请上传票据、PUT 文件内容、提交确认。
申请票据
FILE=reference.png
CONTENT_TYPE=image/png
BYTES=$(wc -c < "$FILE" | tr -d ' ')
TICKET=$(curl -s -X POST "https://api.popnow.ai/api/v1/common/upload-url" \
-H "Authorization: Bearer $POPNOW_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"contentType\": \"$CONTENT_TYPE\", \"bytes\": $BYTES}")
UPLOAD_URL=$(echo "$TICKET" | jq -r .data.uploadUrl)
FILE_ID=$(echo "$TICKET" | jq -r .data.fileId)响应里有 fileId、uploadUrl、必须原样发送的 headers、expiresAt(大约 20 分钟后)和 maxBytes。这里没有文件名:存储路径一律由服务器决定。
PUT 文件内容
curl -s -o /dev/null -w "%{http_code}\n" -X PUT "$UPLOAD_URL" \
-H "Content-Type: $CONTENT_TYPE" \
-H "Content-Length: $BYTES" \
--data-binary @"$FILE"票据里的每个请求头都要原样发送——它们都参与了签名——并且不要带 Authorization 头。在浏览器里,请省略 Content-Length,发送大小与声明完全一致的 File 或 Blob,浏览器会自动设置它。
提交确认
curl -s -X POST "https://api.popnow.ai/api/v1/files/$FILE_ID/commit" \
-H "Authorization: Bearer $POPNOW_API_KEY"提交时会检查大小、类型和文件签名,并返回可以使用的 URI:
{
"code": 200,
"msg": "success",
"data": {
"fileId": "fil_01k3m8x9q2z4v7n5p6r8s0t1w3",
"status": "ready",
"uri": "popnow://f/fil_01k3m8x9q2z4v7n5p6r8s0t1w3",
"contentType": "image/png",
"bytes": 402118,
"width": 1024,
"height": 1024,
"expiresAt": "2026-10-17T09:12:00Z"
},
"request_id": "req_…"
}把 uri 填进模型的字段,例如 "image_url": "popnow://f/fil_…"。popnow:// URI 只对你自己账户的密钥有效。重复提交是安全的。
上传限制
| 类型 | contentType | 单个文件上限 | 最长时长 |
|---|---|---|---|
| 图片 | image/jpeg、image/png、image/webp、image/gif | 10 MiB | — |
| 视频 | video/mp4、video/webm | 90 MiB | 600 秒 |
| 音频 | audio/mpeg、audio/wav | 90 MiB | 600 秒 |
| LoRA 权重 | application/octet-stream(.safetensors 文件) | 2 GiB | — |
具体模型可能接受得更少,它的 schema 会逐个字段注明。上传的文件是临时的——提交响应里的 expiresAt 告诉你文件何时删除——所以请在创建任务前不久再上传。想反复使用某个文件,就把它存进素材库。
如果提交返回 40003,说明你发送的内容和票据对不上(大小、类型或内容不同)。请申请新票据重新上传。
下载结果
完成的任务会在 output.assets 里列出文件,每个都带一个可以直接用的 url:
curl -L -o result.mp4 "$(curl -s "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
-H "Authorization: Bearer $POPNOW_API_KEY" | jq -r '.data.output.assets[0].url')"- 链接是签名过的,大约 20 分钟内有效(
expiresAt)。不要保存链接;保存taskId,需要时重新读一次任务拿新链接。 - 下载时不要带 API 密钥。链接本身就是授权,拿到链接的人在它过期前都能下载。
- 想在不读整个任务的情况下生成新链接,可以调用
POST /api/v1/common/download-url,请求体{ "taskId": "…" }(可选再加上文件的key)。
文件本身会一直保留到任务的 retention.outputsExpireAt 指定的时间,或者你清除这个任务为止。超出这个时间还需要的文件,请复制到你自己的存储或素材库。

