两个端点用于创建图像:
POST /v1/images/generations根据文本提示词生成图像。POST /v1/images/edits根据文本提示词编辑一张或多张参考图像。
两个端点都需要通过 Authorization: Bearer 发送 API 密钥。详见认证。请求体为 JSON。不支持 multipart 上传,因此参考图像要以 URL 或 data URI 的形式放在 JSON 中发送。
每个图像请求都作为任务运行。请求可以等待任务完成并在响应中返回图像,也可以立即返回任务,让你稍后再取回结果。
生成图像
章节标题“生成图像”发送模型和提示词。示例使用 sakuranbo/cherryimage-1.0-pro。
curl -X POST "https://api.sakuranbo.ai/v1/images/generations" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SAKURANBO_API_KEY" \ -d '{ "model": "sakuranbo/cherryimage-1.0-pro", "prompt": "A matte ceramic coffee mug on a walnut desk, soft morning light, shallow depth of field", "resolution": "2k", "aspect_ratio": "4:3"}'const response = await fetch("https://api.sakuranbo.ai/v1/images/generations", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.SAKURANBO_API_KEY}`, }, body: JSON.stringify({ "model": "sakuranbo/cherryimage-1.0-pro", "prompt": "A matte ceramic coffee mug on a walnut desk, soft morning light, shallow depth of field", "resolution": "2k", "aspect_ratio": "4:3" }),});const data = await response.json();console.log(data);import os
import requests
response = requests.post( "https://api.sakuranbo.ai/v1/images/generations", headers={ "Authorization": f"Bearer {os.environ['SAKURANBO_API_KEY']}", }, json={ "model": "sakuranbo/cherryimage-1.0-pro", "prompt": "A matte ceramic coffee mug on a walnut desk, soft morning light, shallow depth of field", "resolution": "2k", "aspect_ratio": "4:3", },)print(response.json())以下是示例模型的输入参数:
| 名称 | 类型 | 必填 | 默认值 | 约束 | 说明 |
|---|---|---|---|---|---|
prompt | string | 是 | 最多 5,000 个字符 | 要生成的图像或要应用的编辑的文字描述。 | |
images | url[] | 否 | 最多 10 项 | 用于编辑的参考图(1 到 10 张)。在 /v1/images/edits 中为必填。 | |
resolution | enum | 否 | 2k | 可选值:1k, 1.5k, 2k | 输出分辨率,决定每张图片的价格。 |
n | integer | 否 | 1 | 1 至 100 | 要生成的图像数量(1 到 100)。价格为每张图片的价格乘以该值。 |
aspect_ratio | enum | 否 | auto | 可选值:auto, 1:1, 4:3, 3:4, 16:9, 9:16, 3:2, 2:3, 21:9 | 输出图像的宽高比。 |
output_format | enum | 否 | jpeg | 可选值:jpeg, png | 图像文件格式。 |
请求体包含以下字段:
| 名称 | 类型 | 必填 | 默认值 | 约束 |
|---|---|---|---|---|
model | string | 是 | 1 至 128 个字符 | |
prompt | string | 是 | ||
n | number | 否 | ||
resolution | string | 否 | ||
aspect_ratio | string | 否 | ||
output_format | string | 否 | ||
response_format | string | 否 | url | 可选值:url, b64_json |
resolution 决定价格。不在表中的参数或超出范围的值会返回 400 和 invalid_request。error.param 给出参数名称,error.details.allowed、error.details.minimum 或 error.details.maximum 给出有效的取值。
等待结果
章节标题“等待结果”默认情况下,请求会等待图像生成。
- 如果任务在最长等待时间内完成,响应为
200,并包含图像。等待时间见 API 参考。 - 如果超过该时间任务仍在运行,响应为
202,包含任务以及指向它的Location响应头。生成会继续运行。 - 如果你发送
Prefer: respond-async,响应会立即为202,并带有响应头Preference-Applied: respond-async。
curl -X POST "https://api.sakuranbo.ai/v1/images/generations" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SAKURANBO_API_KEY" \ -H "Prefer: respond-async" \ -d '{ "model": "sakuranbo/cherryimage-1.0-pro", "prompt": "A matte ceramic coffee mug on a walnut desk, soft morning light, shallow depth of field", "resolution": "2k", "aspect_ratio": "4:3"}'const response = await fetch("https://api.sakuranbo.ai/v1/images/generations", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.SAKURANBO_API_KEY}`, Prefer: "respond-async", }, body: JSON.stringify({ "model": "sakuranbo/cherryimage-1.0-pro", "prompt": "A matte ceramic coffee mug on a walnut desk, soft morning light, shallow depth of field", "resolution": "2k", "aspect_ratio": "4:3" }),});const data = await response.json();console.log(data);import os
import requests
response = requests.post( "https://api.sakuranbo.ai/v1/images/generations", headers={ "Authorization": f"Bearer {os.environ['SAKURANBO_API_KEY']}", "Prefer": "respond-async", }, json={ "model": "sakuranbo/cherryimage-1.0-pro", "prompt": "A matte ceramic coffee mug on a walnut desk, soft morning light, shallow depth of field", "resolution": "2k", "aspect_ratio": "4:3", },)print(response.json())收到 202 响应后,可以用两种方式取回结果。按任务中的说明轮询任务,或按 Webhook 中的说明接收 job.succeeded、job.failed 或 job.cancelled 事件。
如果任务在请求等待期间失败,响应是错误而不是 202,error.details.job_id 为该任务的 ID。收到 202 响应之后,失败会改为显示在任务的 error 字段中,而读取该任务的请求仍然返回 200。
200 响应包含以下字段:
| 名称 | 类型 |
|---|---|
created | integer |
data | object[] |
usage | object |
cost | object |
job_id | string |
cost 是最终扣费金额。同样的金额也在 X-Usage-Cost-Usd 响应头中。job_id 是生成这些图像的任务的 ID。
输出文件
章节标题“输出文件”通过 response_format 选择图像的返回方式。
url是默认值。data中的每一项都有url和expires_at。该 URL 带有签名,不需要 API 密钥,并且在expires_at之前有效,即任务完成后 7 天。在此之前,任何拿到该 URL 的人都可以下载图像,因此请把 URL 当作机密。expires_at之后文件会被删除,请保存你需要的图像。b64_json把图像以 base64 放在响应体中。如果图像太大无法内联,放不下的图像会以url项返回。
data 中每一张已交付的图像对应一项。如果一批图像中有部分失败,data 的项数可能少于 n,并且你只需为已交付的图像付费。
编辑图像
章节标题“编辑图像”POST /v1/images/edits 接受与生成端点相同的字段,且 images 字段为必填。
curl -X POST "https://api.sakuranbo.ai/v1/images/edits" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $SAKURANBO_API_KEY" \ -d '{ "model": "sakuranbo/cherryimage-1.0-pro", "prompt": "Make the mug dark blue", "images": [ "https://example.com/reference.png" ]}'const response = await fetch("https://api.sakuranbo.ai/v1/images/edits", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.SAKURANBO_API_KEY}`, }, body: JSON.stringify({ "model": "sakuranbo/cherryimage-1.0-pro", "prompt": "Make the mug dark blue", "images": [ "https://example.com/reference.png" ] }),});const data = await response.json();console.log(data);import os
import requests
response = requests.post( "https://api.sakuranbo.ai/v1/images/edits", headers={ "Authorization": f"Bearer {os.environ['SAKURANBO_API_KEY']}", }, json={ "model": "sakuranbo/cherryimage-1.0-pro", "prompt": "Make the mug dark blue", "images": [ "https://example.com/reference.png", ], },)print(response.json())images 是参考图像的列表。每一项是公开的 https URL,或者是 PNG、JPEG、WebP 或 GIF 图像的 data:image/...;base64, URI。顺序很重要,因为提示词可以指代第一张图像或第二张图像。data URI 的大小限制比 URL 更小,因此较大的图像请以公开 URL 发送。
服务器在创建任务之前会获取每个 URL 来进行检查。它不会跟随重定向,并会拒绝包含凭据、IP 地址或内部主机名的 URL。无法使用的图像会返回 400 和 invalid_request。error.param 是 images 加上该项的索引。对于 URL,error.details.reason 会说明问题所在。对于过大的 data URI,error.details.max_bytes 为大小上限。
| 名称 | 类型 | 必填 | 默认值 | 约束 |
|---|---|---|---|---|
model | string | 是 | 1 至 128 个字符 | |
prompt | string | 是 | ||
n | number | 否 | ||
resolution | string | 否 | ||
aspect_ratio | string | 否 | ||
output_format | string | 否 | ||
response_format | string | 否 | url | 可选值:url, b64_json |
images | string[] | 是 | 1 至 10 项 |
响应与生成端点相同。
安全地重试
章节标题“安全地重试”发送 Idempotency-Key 请求头,值由你自己选择。如果之后又收到幂等键相同、内容也相同的请求,你会得到同一个任务,并且只会被扣费一次。相同的幂等键搭配不同的请求会返回 409 和 idempotency_conflict。幂等键只会被记住一段有限的时间,具体时长见 API 参考。
计费
章节标题“计费”请求被接受时,Sakuranbo AI 会从你的余额中预留你所请求的图像的价格。任务结束时,会按已交付的图像计算费用,其余的预留回到你的余额。被取消、已过期或被拒绝的任务不会计费。失败的任务通常也不会计费,其预留会回到你的余额。
在极少数情况下,Sakuranbo AI 无法确认请求是否已到达模型提供方。此时任务会以 upstream_error 失败,其预留金额会保持预留,直到 Sakuranbo AI 确认该请求是否计费。如果它一直保持预留,请联系支持团队并提供任务 ID。
价格取决于模型、resolution 和图像数量。请查看模型目录和定价页面,也可以在运行请求之前用 POST /v1/estimate 计算。详见费用预估 API。
内容政策
章节标题“内容政策”模型提供方可能因内容拒绝提示词、参考图像或生成的图像。此时任务会以 content_policy_violation 失败,不会扣费。正在等待任务的请求会返回 422 和该错误代码,error.details.job_id 为任务的 ID。收到 202 响应之后,该错误代码出现在任务的 error 字段中。
错误
章节标题“错误”| 代码 | HTTP 状态码 | 类型 | 说明 |
|---|---|---|---|
invalid_request | 400 | invalid_request_error | 请求格式有误或取值超出范围。如果有效取值已知,会列在 details.allowed 中。 |
unauthorized | 401 | authentication_error | API 密钥缺失、格式有误、未知、已被吊销或已过期。响应不会说明属于哪一种情况。 |
balance_insufficient | 402 | insufficient_balance | 可用余额低于该请求需要预留的金额。error.details.limit_source 为 balance。 |
key_limit_exceeded | 402 | insufficient_balance | 该请求会使 API 密钥超出其支出上限。error.details.limit_source 为 key,error.details.resets_at 说明计数器何时重新开始。 |
account_suspended | 403 | permission_error | 账户已被停用,图像、视频和对话请求会被拒绝。请联系支持团队。余额、充值、API 密钥和任务仍可使用。 |
model_not_found | 404 | not_found_error | 目录中不存在该模型 ID。对于不是文本模型的模型,对话端点也会返回此代码。 |
idempotency_conflict | 409 | conflict_error | 该 Idempotency-Key 已被用于另一个内容不同的请求。 |
payload_too_large | 413 | invalid_request_error | 请求体超过了允许的大小。error.details.max_bytes 为大小上限。 |
content_policy_violation | 422 | content_policy_error | 模型提供方因内容拒绝了提示词、参考图像或生成的输出。该请求不会计费。 |
rate_limited | 429 | rate_limit_error | 模型提供方正在限制请求。同一地址提交的举报过多时,POST /v1/reports 也会返回该错误代码。请在 Retry-After 响应头给出的时间之后重试。 |
concurrency_limited | 429 | rate_limit_error | 模型提供方繁忙,暂时无法处理该请求。这不是对账户中任务数量的限制。请稍后重试。 |
upstream_error | 502 | upstream_error | 上游提供方返回了错误。 |
upstream_unavailable | 503 | overloaded_error | 上游提供方暂时容量不足,请稍后重试。 |
POST /v1/images/edits 返回相同的错误代码。对于 429 或 503 响应,请等待
Retry-After 响应头给出的秒数再重试。402 响应带有 error.details.limit_source,其值为 balance
或 key。详见余额与 API
密钥限额。完整的错误代码列表请参阅错误。
所有价格均以 USD 计价,标价已包含我们的加价。