curl --request POST \
--url 'https://api.apimart.ai/v1/uploads/images?retention_days=3' \
--header 'Authorization: Bearer <token>' \
--form 'file=@/path/to/reference.png'
import requests
with open("reference.png", "rb") as file:
response = requests.post(
"https://api.apimart.ai/v1/uploads/images?retention_days=3",
headers={"Authorization": "Bearer <token>"},
files={"file": file}
)
response.raise_for_status()
result = response.json()
print(result["url"])
const input = document.querySelector('input[type="file"]');
const file = input?.files?.[0];
if (!file) throw new Error("Select a file first");
const formData = new FormData();
formData.append("file", file, file.name);
const response = await fetch("https://api.apimart.ai/v1/uploads/images?retention_days=3", {
method: "POST",
headers: { Authorization: "Bearer <token>" },
body: formData
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.error?.message ?? `HTTP ${response.status}`);
}
console.log(result.url);
{
"url": "https://cdn.example/uploads/reference.png",
"filename": "reference.png",
"content_type": "image/png",
"file_type": "image",
"bytes": 235680,
"created_at": 1793836800,
"retention_days": 3,
"expires_at": 1794182400
}
{
"error": {
"message": "insufficient balance: uploading files requires a positive account balance, please top up",
"type": "insufficient_user_quota"
}
}
{
"error": {
"message": "image file exceeds maximum 31457280 bytes (30MB)",
"type": "invalid_request_error"
}
}
上传管理
上传图片
上传 JPEG、PNG、GIF 或 WebP 图片,获取可用于生成接口的公网 URL,默认单文件上限 30MB。
POST
/
v1
/
uploads
/
images
curl --request POST \
--url 'https://api.apimart.ai/v1/uploads/images?retention_days=3' \
--header 'Authorization: Bearer <token>' \
--form 'file=@/path/to/reference.png'
import requests
with open("reference.png", "rb") as file:
response = requests.post(
"https://api.apimart.ai/v1/uploads/images?retention_days=3",
headers={"Authorization": "Bearer <token>"},
files={"file": file}
)
response.raise_for_status()
result = response.json()
print(result["url"])
const input = document.querySelector('input[type="file"]');
const file = input?.files?.[0];
if (!file) throw new Error("Select a file first");
const formData = new FormData();
formData.append("file", file, file.name);
const response = await fetch("https://api.apimart.ai/v1/uploads/images?retention_days=3", {
method: "POST",
headers: { Authorization: "Bearer <token>" },
body: formData
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.error?.message ?? `HTTP ${response.status}`);
}
console.log(result.url);
{
"url": "https://cdn.example/uploads/reference.png",
"filename": "reference.png",
"content_type": "image/png",
"file_type": "image",
"bytes": 235680,
"created_at": 1793836800,
"retention_days": 3,
"expires_at": 1794182400
}
{
"error": {
"message": "insufficient balance: uploading files requires a positive account balance, please top up",
"type": "insufficient_user_quota"
}
}
{
"error": {
"message": "image file exceeds maximum 31457280 bytes (30MB)",
"type": "invalid_request_error"
}
}
上传参考素材,成功后直接返回公网 URL,无需轮询。支持 3、7、15、30 天保存档位;3 天档在账户免费额度内免费,超额或选择长存档时需开启付费上传。实际免费额度与可用档位请查看控制台。
文档 Playground 不支持文件上传,请使用下方 cURL、Python 或 JavaScript 示例。JavaScript 示例需要页面中有已选择文件的
<input type="file">。curl --request POST \
--url 'https://api.apimart.ai/v1/uploads/images?retention_days=3' \
--header 'Authorization: Bearer <token>' \
--form 'file=@/path/to/reference.png'
import requests
with open("reference.png", "rb") as file:
response = requests.post(
"https://api.apimart.ai/v1/uploads/images?retention_days=3",
headers={"Authorization": "Bearer <token>"},
files={"file": file}
)
response.raise_for_status()
result = response.json()
print(result["url"])
const input = document.querySelector('input[type="file"]');
const file = input?.files?.[0];
if (!file) throw new Error("Select a file first");
const formData = new FormData();
formData.append("file", file, file.name);
const response = await fetch("https://api.apimart.ai/v1/uploads/images?retention_days=3", {
method: "POST",
headers: { Authorization: "Bearer <token>" },
body: formData
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.error?.message ?? `HTTP ${response.status}`);
}
console.log(result.url);
{
"url": "https://cdn.example/uploads/reference.png",
"filename": "reference.png",
"content_type": "image/png",
"file_type": "image",
"bytes": 235680,
"created_at": 1793836800,
"retention_days": 3,
"expires_at": 1794182400
}
{
"error": {
"message": "insufficient balance: uploading files requires a positive account balance, please top up",
"type": "insufficient_user_quota"
}
}
{
"error": {
"message": "image file exceeds maximum 31457280 bytes (30MB)",
"type": "invalid_request_error"
}
}
认证
string
必填
使用有效、未禁用、未过期的 APIMart API Key,格式为
Bearer <token>,且账号未被封禁。账户余额必须大于 0。付费上传还需账户余额及 API Key 剩余额度足以支付本次上传费用;免费额度与 Key 的消费额度是两种不同的限制。可在 API Key 管理页面 获取 Key。请求参数
integer
可选,支持
3、7、15、30,单位为天。显式传入时覆盖账户默认档;省略时采用控制台当前生效的默认保存时长,不一定是 3 天。仅接受 URL 查询参数,表单中的同名字段不生效。可用档位以控制台为准。file
必填
通过
multipart/form-data 的 file 字段传入一个带文件名的文件。不要使用 JSON、base64 字符串或文件 URL 代替文件部分。其他表单字段会被忽略;同一请求传入多个 file 时只处理第一个。支持格式: JPEG (.jpg, .jpeg), PNG (.png), GIF (.gif), WebP (.webp)默认单文件上限: 30MB。单文件上限可调整,以实际服务配置和超限错误提示为准。--form、Python files 或 JavaScript FormData 时,由客户端自动生成包含 boundary 的 Content-Type,不要手动设置该请求头。
文件校验
文件类型按实际内容识别,不依赖扩展名或客户端声明的 MIME 类型。文件内容必须与上传接口匹配;改扩展名不能转换格式,类型不匹配会返回 HTTP400。
图片必须可完整解码,总像素不超过 40MP,任一边不超过 32768 像素;GIF 最多 500 帧。
| 格式 | 识别后的 MIME 类型 |
|---|---|
| JPEG (.jpg, .jpeg) | image/jpeg |
| PNG (.png) | image/png |
| GIF (.gif) | image/gif |
| WebP (.webp) | image/webp |
保存时长与付费设置
| 保存档位 | 收费规则 | 免费额度 |
|---|---|---|
| 3 天 | 免费额度内免费;超额后需开启付费上传并确认该档价格,按文件实际大小收费。 | 使用账户共享免费额度。 |
| 7 / 15 / 30 天 | 每个文件均按所选档位收费,与剩余免费额度无关。 | 不占用免费额度。 |
默认保存时长设为 7、15 或 30 天后,不传
retention_days 的上传也会逐个收费,即使仍有免费额度。指定 retention_days=3 可让本次上传使用 3 天档规则;上方请求示例均显式指定了 3 天。curl --request POST \
--url 'https://api.apimart.ai/v1/uploads/images?retention_days=7' \
--header 'Authorization: Bearer <token>' \
--form 'file=@/path/to/reference.png'
成功响应
HTTP200 返回文件信息,url 位于 JSON 顶层,没有 data 包装,也不返回生成任务 ID。
响应示例仅展示文件信息,省略可选的 quota 和 overage;实际返回条件见下方字段说明。
string
文件公网 URL。将其填入目标生成接口对应的参考素材参数;该模型仍有独立的格式、大小、数量、时长等限制,上传成功不代表一定符合模型要求。
string
原始文件名。
string
服务端按文件内容识别的 MIME 类型,不是客户端声明的值。
string
文件类别,本接口返回
image。integer
实际文件大小,单位为字节。
integer
上传时间,Unix 时间戳,单位为秒。
integer
本次实际采用的保存档位,单位为天,值为
3、7、15 或 30。integer
文件过期时间,Unix 时间戳,单位为秒。请使用该值判断 URL 的有效期。
object
仅收费上传返回:3 天档超额上传,或 7 / 15 / 30 天档上传。
charged 表示是否已扣费;bytes 为计费文件字节数;cost_usd 为本次费用(美元);price_per_gb_usd 为该档每 GB 单价;retention_days 为计费档位。免费上传不返回此对象。object
可选的账户共享免费额度信息。3 天档返回,长存档不占免费名额,因此不返回此对象;不限额或统计暂不可用时见下方说明。
| 字段 | 说明 |
|---|---|
quota.limit | 当前账户在统计窗口内的免费文件额度,以实际返回或控制台显示为准,并非开启付费后的上传总上限。 |
quota.used | 窗口内已统计的 3 天档上传数量,包含本次成功上传。 |
quota.remaining | 当前剩余免费名额。 |
quota.window_hours | 统计窗口小时数,默认 72。 |
quota.reset_at | 最早一批记录移出统计窗口的时间,Unix 秒。届时释放部分名额,不代表全部额度同时重置。 |
共享额度与请求限速
图片、视频和音频接口共享同一账户的免费额度,多个 API Key 不叠加额度。窗口按整点滚动,默认统计最近约 71–72 小时的 3 天档成功上传。长存档不占免费名额;格式错误、超出大小或存储失败的上传不占名额。额度上限以控制台或quota.limit 实际返回为准。
3 天档的普通受限响应提供 X-Upload-Quota-Limit、X-Upload-Quota-Remaining、X-Upload-Quota-Reset,分别对应 limit、remaining、reset_at;Reset 为 Unix 秒。不限额账户返回 quota: {"unlimited": true},不带上述三个额度响应头。
统计暂不可用时,成功响应可能省略 quota;长存档也不返回 quota。不要将字段缺失当作 0 或不限额,也不要因此重复上传。
3 天档免费额度耗尽后,已开启付费上传且该档价格已确认时可继续付费上传;否则按下方 429 规则处理。另有每个 Key 每 60 秒 1000 次请求的限速,对应 rate_limit_error,与免费文件额度独立。
错误处理
错误对象位于 JSON 顶层的error 中。结合 HTTP 状态码、error.type / error.code 以及顶层 overage 的字段判断,避免只匹配可能随语言变化的 error.message。错误中的 overage 与成功响应中的计费对象不同,可包含 available、enabled、needs_reconfirm、retention_days、price_per_gb_usd、可选的 settings_url 和 reason。开启或重新确认价格均可前往控制台。
| HTTP | 字段 / 判断依据 | 原因与处理 |
|---|---|---|
| 400 | invalid_request_error | 缺少文件、不是 multipart、空文件、类型不匹配、格式不支持或内容损坏;修正文件或接口路径后重试。 |
| 400 | retention_days | 保存天数无效或所选档位未开放;检查查询参数,并在控制台查看可用档位。 |
| 401 / 403 | — | Key 无效、已禁用或账号被封禁;检查认证和账号状态。 |
| 402 | insufficient_user_quota | 账户余额不大于 0,或 Key 已过期;补充余额或更换有效 Key。免费上传也需满足准入条件。 |
| 402 | overage.reason = overage_not_enabled | 选了长存档但未开启付费上传;前往控制台开启并确认价格。 |
| 402 | overage.reason = needs_reconfirm | 长存档价格未确认或上调后未重新确认;确认当前价格后重试。 |
| 402 | overage.reason = insufficient_balance | 账户余额不足以支付本次上传;充值后重试。 |
| 402 | overage.reason = insufficient_key_quota | API Key 设置了消费上限且剩余额度不足;调整 Key 额度后重试。 |
| 413 | invalid_request_error | 超过该类型的单文件大小上限;压缩或缩小文件,以错误信息中的当前限制为准。 |
| 429 | rate_limit_error | Key 请求过于频繁;降低请求频率并退避重试。 |
| 429 | overage.enabled = false | 3 天档免费额度用完且未开启付费上传;前往控制台开启并确认价格,或按 Retry-After 等待免费名额释放。 |
| 429 | overage.needs_reconfirm = true | 3 天档价格待确认;前往控制台重新确认后重试。 |
| 429 | error.type = rate_limit_exceeded | 免费额度已用完;若没有 overage,按 error.message 处理,可能是付费上传暂不可用。如选择等待免费名额,按 Retry-After 指定秒数重试。 |
| 500 | server_error | 文件写入存储失败;稍后重试。 |
| 503 | Retry-After | 暂时无法计费或获取账户额度信息;按响应头指定秒数重试,本次失败不扣费。 |
URL 使用与文件保存
保存时长与免费额度的 72 小时统计窗口是两个概念。文件按所选档位过期,实际到期时间以expires_at 为准;过期后 URL 返回 404。请保留原始文件,不要假定 URL 永久有效。
对于大量文件上传场景,建议优先使用自有对象存储(OSS)。如调用的模型支持公网文件 URL,可直接使用自有存储链接作为输入,减少重复上传及存储成本。