画像を作るエンドポイントは 2 つあります。
POST /v1/images/generationsは、テキストのプロンプトから画像を生成します。POST /v1/images/editsは、1 枚以上の参照画像を、テキストのプロンプトで編集します。
どちらのエンドポイントも、Authorization: Bearer で送る API キーが必要です。認証を参照してください。本文は JSON です。multipart のアップロードには対応していないため、参照画像は、JSON の中に URL または data URI として入れて送ります。
すべての画像のリクエストは、ジョブとして実行されます。リクエストは、ジョブの完了を待ってレスポンスで画像を返すことも、ジョブをすぐに返して、結果を後で受け取れるようにすることもできます。
画像を生成する
Section titled “画像を生成する”モデルとプロンプトを送ります。例では、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 | 出力解像度。1 枚あたりの価格が決まります。 |
n | integer | いいえ | 1 | 1〜100 | 生成する画像の枚数(1〜100)。価格は 1 枚あたりの価格にこの値を掛けたものです。 |
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 リファレンスに載っています。 - その時間を過ぎてもジョブが実行中のときは、レスポンスは、ジョブと、ジョブを指す
Locationヘッダを持つ202です。生成は続きます。 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 のレスポンスのあとは、2 通りのどちらかで結果を受け取ります。ジョブの説明に従ってジョブをポーリングするか、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 です。
出力ファイル
Section titled “出力ファイル”response_format で、画像の返し方を選びます。
urlが既定です。dataの各項目に、urlとexpires_atが入ります。URL は署名付きです。API キーは不要で、expires_atまで使えます。expires_atは、ジョブが完了してから 7 日後です。それまでは、URL を知っていれば誰でも画像をダウンロードできるため、URL は秘密として扱ってください。expires_atを過ぎるとファイルは削除されるため、必要な画像は保存してください。b64_jsonは、画像を base64 でレスポンス本文に入れます。画像が大きすぎて本文に入れきれないときは、入らない画像がurlの項目として返ります。
data には、届けた画像 1 枚につき 1 項目が入ります。まとめて生成した画像の一部が失敗したときは、data の項目が n より少なくなることがあり、課金されるのは届いた画像の分だけです。
画像を編集する
Section titled “画像を編集する”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 か、data:image/...;base64, の URI です。画像の形式は PNG、JPEG、WebP、GIF です。プロンプトで 1 枚目や 2 枚目の画像を指せるため、順番が意味を持ちます。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 件 |
レスポンスは、生成と同じです。
安全に再試行する
Section titled “安全に再試行する”自分で決めた値の Idempotency-Key ヘッダを送ります。同じキーと同じ内容のリクエストが再び届くと、同じジョブが返り、課金は 1 回だけです。同じキーで内容の違うリクエストを送ると、409 と idempotency_conflict を返します。キーは一定の期間だけ記憶され、その期間は API リファレンスに載っています。
リクエストが受理されると、Sakuranbo AI は、依頼した画像の価格を残高から確保します。ジョブが終わると、届けた画像の分の請求額を計算し、確保した金額の残りを残高に戻します。キャンセルされたジョブ、時間切れになったジョブ、拒否されたジョブは課金されません。失敗したジョブも、通常は課金されず、確保した金額は残高に戻ります。
まれに、リクエストがモデルの提供元に届いたかどうかを、Sakuranbo AI が確認できないことがあります。その場合、ジョブは upstream_error で失敗し、確保した金額は、課金されるかどうかを Sakuranbo AI が確認するまで確保されたままになります。確保されたままのときは、ジョブ ID を添えてサポートにお問い合わせください。
価格は、モデル、resolution、画像の枚数で決まります。モデルカタログと料金のページを参照するか、実行する前に POST /v1/estimate で計算してください。見積 APIを参照してください。
コンテンツポリシー
Section titled “コンテンツポリシー”モデルの提供元が、プロンプト、参照画像、または生成された画像を、その内容を理由に拒否することがあります。その場合、ジョブは 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
です。残高とキーの利用上限を参照してください。すべてのコードは、エラーを参照してください。
価格はすべて USD 表示です。表示価格には当社のマージンを含みます。