MediaAsync 外部接入文档
MediaAsync 是异步媒体生成服务。调用方通过公开 model 提交图片、视频或图片工具任务,服务立即返回任务 id,后台 Worker 完成 Provider 调用、轮询、产物上传后,再通过查询接口返回最终产物 URL。
快速开始
默认本地服务地址:
https://media.kitt.tools
所有业务 API 都需要 Bearer token。API token 由服务管理员在 Admin 中创建,形如 sk_...。
Authorization: Bearer sk_...
sk_... 只用于访问 MediaAsync,不是上游 Provider key。创建任务默认使用调用方自带 Provider key 的 BYOK/OpenAI-compatible 路由:
X-MediaAsync-Provider-Key: upstream-provider-key
X-MediaAsync-Provider-Base-URL: https://api.example.com/v1
X-MediaAsync-Provider-Base-URL 可省略,省略时使用服务端 [byok].base_url。调用方传入的 base URL 必须是公网 HTTP(S) 地址;localhost、私网 IP、Docker/container 主机名、单标签主机名、.local、.internal 等内网目标都会被拒绝。
最小图片生成请求:
curl -sS https://media.kitt.tools/v1/images/generations \
-H "Authorization: Bearer sk_..." \
-H "X-MediaAsync-Provider-Key: upstream-provider-key" \
-H "X-MediaAsync-Provider-Base-URL: https://api.example.com/v1" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "a small ceramic teapot on a walnut table",
"size": "1024x1024",
"output_format": "png"
}'
创建成功会返回异步任务:
{
"id": "0f0d4e89-...",
"object": "image.generation",
"status": "queued"
}
随后轮询任务:
curl -sS https://media.kitt.tools/v1/images/0f0d4e89-... \
-H "Authorization: Bearer sk_..."
接入流程
- 调用
GET /v1/models/catalog获取可用模型、能力和价格信息。 - 选择路由:默认 BYOK/OpenAI-compatible 需要传上游 Provider key;托管渠道需要传
X-MediaAsync-Route: managed。 - 选择支持目标能力的公开
model,不要传内部format或渠道 ID。 - 调用对应的创建接口,拿到任务
id。 - 使用单任务查询或批量查询轮询状态。
- 当
status为succeeded时,从data[].url获取产物。 - 当
status为failed或canceled时,根据业务需要重试或结束。
公共页面
| 页面 | 说明 |
|---|---|
/usage.html | 本文档的 HTML 渲染版 |
/usage.md | 本文档的 Markdown 原文 |
/docs | Swagger UI |
/api-docs/openapi.json | OpenAPI JSON |
/playground.html | 浏览器调试页面 |
/dashboard.html | 浏览器监控页面 |
/playground.html 和 /dashboard.html 是公开页面外壳,页面内实际调用业务 API 时仍需要 sk_... token。
认证
所有创建、查询、取消、重试、批量查询、模型目录和 quote 接口都使用:
Authorization: Bearer sk_...
缺失或无效 token 返回:
{
"error": {
"message": "missing or invalid API key"
}
}
Bearer token 只能访问同一个 API key 创建的任务。不同 key 创建的任务在查询、取消、重试和批量查询中不可见。
上游路由
创建任务有两套上游路由:
| 路由 | 请求头 | Provider key 来源 | 说明 |
|---|---|---|---|
| BYOK/OpenAI-compatible | 不传 X-MediaAsync-Route,或传 X-MediaAsync-Route: byok | 调用方请求头 X-MediaAsync-Provider-Key | 默认路由。适合调用方把价格、充值和额度放在自己的上游 Provider 账户里,MediaAsync 只负责异步任务和产物托管 |
| Managed | X-MediaAsync-Route: managed | MediaAsync Admin 托管渠道 | 适合使用服务方自有渠道、包月权益或更高成功率路由 |
BYOK 路由目前只支持 OpenAI-compatible 图片生成和图片编辑,即 /v1/images/generations 和 /v1/images/edits。请求必须包含:
X-MediaAsync-Provider-Key: upstream-provider-key
如果服务端没有配置 [byok].base_url,请求还必须包含:
X-MediaAsync-Provider-Base-URL: https://api.example.com/v1
托管渠道请求不要传 X-MediaAsync-Provider-Key 或 X-MediaAsync-Provider-Base-URL,否则会返回 400。Provider-compatible 入口、视频、图片工具和非 OpenAI-compatible 能力必须使用:
X-MediaAsync-Route: managed
模型目录
简化模型列表
GET /v1/models
curl -sS https://media.kitt.tools/v1/models \
-H "Authorization: Bearer sk_..."
响应:
{
"object": "list",
"data": [
{
"id": "gpt-image-2",
"object": "model",
"created": 1778470000,
"owned_by": "openai"
}
]
}
完整模型目录
GET /v1/models/catalog
curl -sS https://media.kitt.tools/v1/models/catalog \
-H "Authorization: Bearer sk_..."
响应重点字段:
{
"object": "list",
"data": [
{
"id": "gpt-image-2",
"object": "model",
"owned_by": "openai",
"display_name": "GPT Image 2",
"task_type": "image.generate",
"task_types": ["image.generate", "image.edit"],
"capabilities": { "image": true, "provider": "openai" },
"channels": [
{
"channel_id": "openai-main",
"provider_format": "openai",
"provider_model": "gpt-image-2",
"enabled": true
}
],
"pricing_profiles": [
{
"id": "default-gpt-image-2-image-generate",
"version": 1,
"channel_id": null,
"task_type": "image.generate",
"currency": "usd",
"rules": [{ "type": "per_image", "micro_usd_per_image": 40000 }],
"enabled": true
}
]
}
]
}
调用方只需要传公开 model。模型绑定、真实 Provider、Provider model、渠道优先级和重试策略由 MediaAsync 内部决定。
通用响应
创建任务响应
{
"id": "task-id",
"object": "image.generation",
"status": "queued"
}
object 随任务类型变化,常见值包括:
| 任务 | object |
|---|---|
| 图片生成 | image.generation |
| 图片编辑 | image.edit |
| 图片放大 | image.upscale |
| 区域擦除 | image.erase_region |
| 去背景 | image.remove_background |
| 矢量化 | image.vectorize |
| 视频生成 | video |
查询任务响应
轮询接口返回的是任务当前快照。处理中时 data 通常为空数组;成功后 data 是产物数组;失败或取消时 data 通常为空,错误信息在 error。
处理中示例:
{
"id": "task-id",
"object": "image.generation",
"status": "running",
"stage": "provider_processing",
"progress": 40,
"model": "gpt-image-2",
"task_type": "image.generate",
"data": [],
"error": null,
"created_at": 1778470000,
"updated_at": 1778470010,
"completed_at": null
}
成功示例:
{
"id": "task-id",
"object": "image.edit",
"status": "succeeded",
"stage": "succeeded",
"progress": 100,
"model": "gpt-image-2",
"task_type": "image.edit",
"data": [
{
"id": "artifact-id",
"object": "image",
"url": "https://cdn.example.com/result.png",
"content_type": "image/png",
"size_bytes": 123456
}
],
"error": null,
"created_at": 1778470000,
"updated_at": 1778470030,
"completed_at": 1778470030
}
失败示例:
{
"id": "task-id",
"object": "image.generation",
"status": "failed",
"stage": "failed",
"progress": 100,
"model": "gpt-image-2",
"task_type": "image.generate",
"data": [],
"error": {
"message": "provider error: upstream request failed"
},
"created_at": 1778470000,
"updated_at": 1778470030,
"completed_at": 1778470030
}
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | MediaAsync 任务 ID,创建接口返回的同一个值 |
object | string | 响应对象类型,图片任务如 image.generation、image.edit,视频任务为 video |
status | string | 任务总状态 |
stage | string | 当前处理阶段 |
progress | number | 0 到 100 的进度估计;不同 Provider 粒度可能不同 |
model | string/null | 调用方提交的公开模型 ID |
task_type | string | 任务类型,如 image.generate、image.edit、video.generate |
data | array | 产物数组。任务未完成、失败或取消时通常为空 |
error | object/null | 失败原因。成功和处理中为 null |
created_at | number | Unix timestamp,秒 |
updated_at | number | Unix timestamp,秒 |
completed_at | number/null | 完成、失败或取消时间;未结束时为 null |
data 数组里的每一项是一个 artifact:
| 字段 | 类型 | 说明 |
|---|---|---|
id | string | 产物 ID |
object | string | 产物媒体类型。常见为 image、video、audio |
url | string | 可访问的产物 URL。调用方应保存或转存这个 URL |
content_type | string | MIME 类型,如 image/png、image/webp、image/svg+xml、video/mp4 |
size_bytes | number | 产物文件大小,单位 bytes |
常见 data 形态:
图片任务成功:
"data": [
{
"id": "artifact-image-1",
"object": "image",
"url": "https://cdn.example.com/tasks/task-id/image/artifact.png",
"content_type": "image/png",
"size_bytes": 345678
}
]
多图任务成功:
"data": [
{
"id": "artifact-image-1",
"object": "image",
"url": "https://cdn.example.com/tasks/task-id/image/1.png",
"content_type": "image/png",
"size_bytes": 345678
},
{
"id": "artifact-image-2",
"object": "image",
"url": "https://cdn.example.com/tasks/task-id/image/2.png",
"content_type": "image/png",
"size_bytes": 331024
}
]
视频任务成功:
"data": [
{
"id": "artifact-video-1",
"object": "video",
"url": "https://cdn.example.com/tasks/task-id/video/result.mp4",
"content_type": "video/mp4",
"size_bytes": 8923441
}
]
矢量化任务成功时通常返回 SVG:
"data": [
{
"id": "artifact-svg-1",
"object": "image",
"url": "https://cdn.example.com/tasks/task-id/image/result.svg",
"content_type": "image/svg+xml",
"size_bytes": 48210
}
]
调用方判断产物类型时优先看 content_type。例如 content_type 为 video/mp4 时按视频处理,为 image/svg+xml 时按 SVG 文本/矢量图处理。
status 取值:
| status | 含义 |
|---|---|
queued | 已入队,等待后台处理 |
running | 正在提交、轮询或上传 |
succeeded | 已完成,data 中包含产物 |
failed | 失败,error 中包含失败信息 |
canceled | 已取消 |
stage 取值:
| stage | 含义 |
|---|---|
queued | 等待处理 |
channel_selecting | 正在选择可用渠道 |
provider_submitting | 正在提交 Provider |
provider_processing | Provider 处理中 |
artifact_uploading | 正在上传产物 |
succeeded | 已成功 |
failed | 已失败 |
canceled | 已取消 |
图片生成
POST /v1/images/generations
Content-Type: application/json
默认 BYOK 路由需要传 X-MediaAsync-Provider-Key,也可传 X-MediaAsync-Provider-Base-URL 覆盖默认上游。BYOK 只支持这个图片生成接口和 /v1/images/edits。要改用 Admin 托管渠道,在请求头加 X-MediaAsync-Route: managed,且不要传 Provider key 相关请求头。
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
model | 是 | string | 公开模型 ID |
prompt | 是 | string | 图片提示词 |
size | 否 | string | 如 auto、1024x1024、1536x1024、1024x1536 |
n | 否 | number | 图片数量,默认 1 |
quality | 否 | string | 如 auto、high、medium、low |
background | 否 | string | 如 auto、opaque 或 Provider 支持值 |
output_format | 否 | string | png、jpeg、webp 等 |
output_compression | 否 | number | 有损格式压缩比例 |
response_format | 否 | string | Provider 支持时可传 url 或 b64_json |
user | 否 | string | 上游调用方关联 ID |
示例:
curl -sS https://media.kitt.tools/v1/images/generations \
-H "Authorization: Bearer sk_..." \
-H "X-MediaAsync-Provider-Key: upstream-provider-key" \
-H "X-MediaAsync-Provider-Base-URL: https://api.example.com/v1" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "a clean product photo of a tiny ceramic teapot",
"size": "1024x1024",
"output_format": "png"
}'
图片编辑
POST /v1/images/edits
图片编辑支持 JSON 和 multipart form-data。
默认 BYOK 路由需要传 X-MediaAsync-Provider-Key,也可传 X-MediaAsync-Provider-Base-URL 覆盖默认上游。BYOK 只支持这个图片编辑接口和 /v1/images/generations。要改用 Admin 托管渠道,在请求头加 X-MediaAsync-Route: managed。
JSON 请求
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
model | 是 | string | 公开模型 ID,模型能力需包含 image.edit |
prompt | 是 | string | 编辑指令 |
image | 否 | image reference | 单张输入图;image 和 images 至少传一个 |
images | 否 | image reference[] | 多张输入图 |
mask | 否 | image reference | 可选 mask 图 |
size | 否 | string | 输出尺寸 |
n | 否 | number | 输出图片数量 |
quality | 否 | string | 质量档位 |
background | 否 | string | 背景策略 |
input_fidelity | 否 | string | 输入保真策略 |
output_format | 否 | string | png、jpeg、webp 等 |
response_format | 否 | string | Provider 支持时可传 url 或 b64_json |
user | 否 | string | 上游调用方关联 ID |
JSON 示例:
curl -sS https://media.kitt.tools/v1/images/edits \
-H "Authorization: Bearer sk_..." \
-H "X-MediaAsync-Provider-Key: upstream-provider-key" \
-H "X-MediaAsync-Provider-Base-URL: https://api.example.com/v1" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "turn the sketch into a clean watercolor illustration",
"image": {
"filename": "source.png",
"mime_type": "image/png",
"data": "<base64-without-data-url-prefix>"
},
"size": "1024x1024",
"output_format": "png"
}'
Multipart 请求
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
model | 是 | text | 公开模型 ID |
prompt | 是 | text | 编辑指令 |
image | 是 | file | 输入图片,多图可重复传多个 image 字段 |
image[] | 否 | file | 多图兼容写法 |
mask | 否 | file | mask 图片 |
size / n / quality / background / output_format | 否 | text | 同 JSON |
Multipart 示例:
curl -sS https://media.kitt.tools/v1/images/edits \
-H "Authorization: Bearer sk_..." \
-H "X-MediaAsync-Provider-Key: upstream-provider-key" \
-H "X-MediaAsync-Provider-Base-URL: https://api.example.com/v1" \
-F "model=gpt-image-2" \
-F "prompt=turn the sketch into a clean watercolor illustration" \
-F "[email protected];type=image/png" \
-F "size=1024x1024" \
-F "output_format=png"
图片工具
这些接口使用 JSON。image 和 mask 字段使用下方“媒体输入引用格式”。
图片工具目前使用 Admin 托管渠道,请传 X-MediaAsync-Route: managed。
| 接口 | 任务类型 | 必填字段 | 可选字段 |
|---|---|---|---|
POST /v1/images/upscale | image.upscale | model, image | mode, response_format, user |
POST /v1/images/erase-region | image.erase_region | model, image, mask | prompt, response_format, user |
POST /v1/images/remove-background | image.remove_background | model, image | response_format, user |
POST /v1/images/vectorize | image.vectorize | model, image | svg_compression, limit_num_shapes, max_num_shapes, response_format, user |
示例:
curl -sS https://media.kitt.tools/v1/images/upscale \
-H "Authorization: Bearer sk_..." \
-H "X-MediaAsync-Route: managed" \
-H "Content-Type: application/json" \
-d '{
"model": "recraft-crisp-upscale",
"image": { "url": "https://example.com/source.png" },
"mode": "crisp"
}'
视频生成
POST /v1/videos
Content-Type: application/json
视频生成目前使用 Admin 托管渠道,请传 X-MediaAsync-Route: managed。
| 字段 | 必填 | 类型 | 说明 |
|---|---|---|---|
model | 是 | string | 公开视频模型 ID |
prompt | 是 | string | 视频提示词 |
input_reference | 否 | image/video reference | 首帧、参考图或参考视频,取决于模型和渠道 |
seconds | 否 | string | 时长,例如 "6" |
size | 否 | string | 分辨率或尺寸,例如 1280x720 |
quality | 否 | string | Provider 支持的质量档位 |
user | 否 | string | 上游调用方关联 ID |
示例:
curl -sS https://media.kitt.tools/v1/videos \
-H "Authorization: Bearer sk_..." \
-H "X-MediaAsync-Route: managed" \
-H "Content-Type: application/json" \
-d '{
"model": "google-veo-3.1-generate-preview",
"prompt": "a cinematic product shot of a ceramic teapot",
"seconds": "6",
"size": "1280x720"
}'
查询、批量查询、取消和重试
图片任务查询:
curl -sS https://media.kitt.tools/v1/images/task-id \
-H "Authorization: Bearer sk_..."
视频任务查询:
curl -sS https://media.kitt.tools/v1/videos/task-id \
-H "Authorization: Bearer sk_..."
批量查询:
curl -sS https://media.kitt.tools/v1/media/batch \
-H "Authorization: Bearer sk_..." \
-H "Content-Type: application/json" \
-d '{ "ids": ["task-id-1", "task-id-2"] }'
批量响应:
{
"object": "list",
"data": [
{
"id": "task-id-1",
"object": "image.edit",
"status": "running",
"stage": "provider_processing",
"progress": 40,
"model": "gpt-image-2",
"task_type": "image.edit",
"data": [],
"error": null,
"created_at": 1778470000,
"updated_at": 1778470010,
"completed_at": null
}
],
"missing": ["task-id-2"]
}
/v1/media/batch 的 data 数组与单任务查询响应结构一致,只是一次返回多个任务快照。missing 表示这些 ID 对当前 API key 不可见,可能是任务不存在,也可能是由其他 API key 创建。批量查询不会因为部分 ID 缺失而整体失败。
取消:
curl -sS -X POST https://media.kitt.tools/v1/images/task-id/cancel \
-H "Authorization: Bearer sk_..."
重试:
curl -sS -X POST https://media.kitt.tools/v1/images/task-id/retry \
-H "Authorization: Bearer sk_..."
视频任务使用 /v1/videos/{video_id}/cancel 和 /v1/videos/{video_id}/retry。
cancel 只允许 queued 或 running 任务;retry 只允许 failed 或 canceled 任务。
媒体输入引用格式
图片编辑、参考图、参考视频和图片工具输入通常支持以下格式。
URL 字符串:
"https://example.com/source.png"
URL 对象:
{ "url": "https://example.com/source.png" }
Data URL:
"data:image/png;base64,iVBORw0KGgo..."
Base64 对象:
{
"filename": "source.png",
"mime_type": "image/png",
"data": "iVBORw0KGgo..."
}
data 字段传纯 base64,不需要 data:image/png;base64, 前缀。
内部文件引用:
{
"kind": "mediaasync_file",
"file_id": "file_..."
}
普通第三方最常用的是 HTTP URL、data URL、base64 对象,或图片编辑 multipart 文件上传。
Quote 估价
POST /internal/quote
Content-Type: application/json
请求:
{
"model": "gpt-image-2",
"task_type": "image.generate",
"channel_id": null,
"input": {
"prompt": "a small ceramic teapot",
"n": 1,
"quality": "high"
}
}
响应:
{
"quote_id": "qt_...",
"quote_version": 1,
"currency": "usd",
"estimated_cost_usd": "0.040000",
"max_cost_usd": "0.040000",
"expires_at": "2026-05-11T03:40:00Z",
"pricing_snapshot": {
"model": "gpt-image-2",
"task_type": "image.generate",
"channel_policy": "auto",
"pricing_profile": "default-gpt-image-2-image-generate"
}
}
Quote 是估价能力,不代表 MediaAsync 内部完成扣费。余额冻结、扣款、退款通常由上游网关或业务系统负责。
Provider-compatible API
Provider-compatible 入口用于降低已有调用方迁移成本。请求体更接近供应商原生格式,但不会绕过 MediaAsync 的模型目录、渠道调度、重试、轮询、上传和 artifact 状态机。
| Provider | 接口 |
|---|---|
| Google/Gemini | POST /google/v1beta/models/{model}:generateContent |
| Google/Veo | POST /google/v1beta/models/{model}:predictLongRunning |
| MiniMax 图片 | POST /minimax/v1/image_generation |
| MiniMax 视频 | POST /minimax/v1/video_generation |
| MiniMax 音频 | POST /minimax/v1/t2a_async_v2 |
| Volcengine 图片 | POST /volcengine/v1/images/generations |
| Volcengine 视频 | POST /volcengine/v1/contents/generations/tasks |
| Volcengine 视频查询 | GET /volcengine/v1/contents/generations/tasks/{task_id} |
| Recraft Crisp Upscale | POST /recraft/v1/images/crispUpscale |
| Recraft Creative Upscale | POST /recraft/v1/images/creativeUpscale |
| Recraft Erase Region | POST /recraft/v1/images/eraseRegion |
| Recraft Remove Background | POST /recraft/v1/images/removeBackground |
| Recraft Vectorize | POST /recraft/v1/images/vectorize |
这些入口仍要求 Authorization: Bearer sk_...。创建成功返回 MediaAsync 任务 { id, object, status },最终结果仍通过 MediaAsync 查询接口轮询。
错误和状态码
错误响应:
{
"error": {
"message": "bad request: model gpt-image-2 not found"
}
}
常见 HTTP 状态:
| 状态码 | 含义 |
|---|---|
400 | 参数错误或请求体格式错误 |
401 | API key 缺失或无效 |
404 | 任务不存在或当前 API key 不可见 |
502 | Provider 或存储调用失败 |
503 | Redis 或队列不可用 |
重要约定
- 调用方只传公开
model,不要传内部format、物理渠道 ID 或持久化字段。Provider key 只在默认 BYOK 创建请求中通过X-MediaAsync-Provider-Key传入;Managed 路由不要传 Provider key。 - 创建接口是异步接口,创建成功不代表生成完成。
- 最终产物 URL 来自
data[].url,可能是本地/files/*URL,也可能是 R2/CDN URL。 - Provider-compatible 入口的响应仍是 MediaAsync 异步任务响应,不保证完全复刻 Provider 原始同步响应。
- MediaAsync 不做终端用户体系、余额扣减或内容审核;这些通常由上游网站、网关和 Provider 策略负责。