上传源素材
本页内容
准备上传
本地 Agent 先计算文件的完整字节数、实际 MIME 与 SHA-256,再通过 POST /v1/uploads/prepare 或 assets.upload.prepare 提交 name、mime、size、checksum、idempotency_key。文件大小为 1 字节至 64 MiB。checksum 使用 64 位小写十六进制。
同一文件的一次上传始终沿用原 idempotency_key;元信息改变时返回 409 IDEMPOTENCY_CONFLICT。准备结果含 upload_id、十五分钟有效期,以及 upload.url、PUT 方法和所需请求头。X-Upload-Token 只能用于该文件,不是账户 API Key,不能用于读取资源或创建付费任务。不要把上传凭证写入日志或反馈。
上传与登记
使用返回的 URL 和请求头上传原始字节。上传接收不需要额外携带账户密钥;原账号、接入 Key、连接或登录会话失效时会拒绝。上传后状态为 uploaded,尚不能用于报价。
通过 POST /v1/uploads/{upload_id}/complete 或 assets.upload.complete 完成登记。服务端重新读取存储对象并核对大小与 SHA-256,只有 completed 返回的 asset_id 才能放入 input.asset_ids。并发或重复完成返回同一资源;已删除的资源不会因重试而重新创建。
下面的 Node.js 示例需要 JISU_API、JISU_KEY 和 JISU_UPLOAD_IDEMPOTENCY_KEY 环境变量,命令参数依次为本地文件路径和实际 MIME。一次上传中断后使用同一个幂等键重跑。
import { readFile } from "node:fs/promises";
import { basename } from "node:path";
import { createHash } from "node:crypto";
const [file, mime] = process.argv.slice(2);
const { JISU_API, JISU_KEY, JISU_UPLOAD_IDEMPOTENCY_KEY } = process.env;
if (!file || !mime || !JISU_API || !JISU_KEY || !JISU_UPLOAD_IDEMPOTENCY_KEY) {
throw new Error("Missing file, MIME or required environment variables");
}
const bytes = await readFile(file);
const headers = { Authorization: "Bearer " + JISU_KEY, "Content-Type": "application/json" };
async function json(response) {
const body = await response.json();
if (!response.ok) throw new Error(body.error?.code || "UPLOAD_FAILED");
return body;
}
const prepared = await json(await fetch(JISU_API + "/v1/uploads/prepare", {
method: "POST", headers,
body: JSON.stringify({
name: basename(file), mime, size: bytes.length,
checksum: createHash("sha256").update(bytes).digest("hex"),
idempotency_key: JISU_UPLOAD_IDEMPOTENCY_KEY,
}),
}));
if (prepared.status !== "completed") {
await json(await fetch(prepared.upload.url, {
method: "PUT", headers: prepared.upload.headers, body: bytes,
}));
}
const completed = await json(await fetch(
JISU_API + "/v1/uploads/" + prepared.upload_id + "/complete",
{ method: "POST", headers, body: "{}" },
));
console.log(completed.asset_id);
中断与过期
GET /v1/uploads/{upload_id} 和 assets.upload.get 可查询状态,查询接口不返回上传凭证。prepared 表示等待完整文件,uploading 表示正在接收,uploaded 表示待校验登记,completed 表示已登记,expired 表示已过期。
409 UPLOAD_IN_PROGRESS 或 429 UPLOAD_BUSY 时稍后查询原上传,不新建文件。中断可重传完整文件;本版不支持分片或断点续传。SHA-256、大小或真实文件类型不匹配会拒绝,不能仅修改 Content-Type 伪装文件。文本须为 UTF-8,JSON 须可解析。文件签名识别不等于完整媒体解码或安全扫描。
存储内容丢失或损坏时,完成接口返回 UPLOAD_CONTENT_MISMATCH 并恢复 prepared,可在有效期内重传。超过十五分钟使用新幂等键重新准备;Worker 清理未登记的过期对象。每个账号最多八个未完成会话、两个同时上传,平台同时接收上限为四个;单次接收限时六十秒。
直接上传与远程导入
既有 POST /v1/uploads 仍接受原始字节,使用账户 Bearer 凭证、实际 Content-Type 和经过 URL 编码的 X-Filename,校验后直接返回资源 id。这个接口没有准备会话的幂等恢复能力。
POST /v1/uploads/import 或 assets.import 接受 HTTPS url 和 name。平台拒绝内网、非标准端口与超限下载,并校验实际内容类型。
稳定引用
任务通过 input.asset_ids 引用本人已登记资源;GET /v1/assets/{id} 或 assets.get 重新签发下载链接。远程 MCP 无法读取本机路径,原始文件仍由本地 Agent 上传。使用本地域名时,外部供应商无法下载参考素材;真实上游验收等待配置公网可达的资源地址。
预览与下载
资源查询返回 url(预览)、download_url(附件下载)和 download_name(文件名)。链接有效期为一小时,过期后用稳定资源 ID 重新查询;持有链接即可在有效期内读取文件,请勿公开敏感资源的链接。文件支持 HEAD、单段 bytes Range 与 If-Range,便于音视频拖动;不支持的范围返回 416。
控制台可预览并复制 UTF-8 文本和 JSON 结果。预览最多读取 128 KiB,截断时会提示;下载始终读取完整原文件。
删除资源与作品
DELETE /v1/assets/{id} 或 assets.delete 会立即禁止读取和引用该资源,并排队清理存储文件;重复删除同一资源不会重复创建清理任务。存储暂时不可用时 Worker 自动重试,运营资源详情显示清理状态。正在执行的任务引用该素材时返回 409 ASSET_IN_USE。
控制台删除作品会一并删除其输出文件,保留账单、资金记录和任务记录。进行中的作品不能删除,其他任务仍在引用输出文件时也不能删除。克隆音色使用独立的音色删除流程。备份中的历史副本遵循备份保留策略,线上删除不代表历史备份已经清除。
文档