API ドキュメント

ベース URL:https://apicafe.ai/api/v1

生成には時間がかかるため、API は非同期です。ジョブを送信するとタスク ID がすぐに返り、結果はポーリングで取得します。動画と画像のエンドポイントは同じ使い方です。

クイックスタート

1. ダッシュボードの API キー ページでキーを作成します。 キーは一度しか表示されないため、安全に保管してください。

2. ジョブを送信:

curl -X POST https://apicafe.ai/api/v1/videos \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2.5",
    "prompt": "A red paper boat drifts across a calm pond at sunrise",
    "duration": 5,
    "resolution": "720p"
  }'

202 Accepted とともにタスクが返ります:

{
  "id": "0b1f9c0e-6c7a-4d52-9d0e-2f6a1d8b7c11",
  "object": "video.task",
  "model": "seedance-2.5",
  "status": "processing",
  "video_url": null,
  "error": null,
  "credits_charged": 263,
  "created_at": "2026-11-09T08:30:00.000Z",
  "completed_at": null
}

3. 完了するまでポーリング:

curl https://apicafe.ai/api/v1/videos/0b1f9c0e-6c7a-4d52-9d0e-2f6a1d8b7c11 \
  -H "Authorization: Bearer sk-..."

status が succeeded になると、video_url に完成した動画の URL が入ります。

認証

すべてのリクエストの Authorization ヘッダーにキーを付けてください:

Authorization: Bearer sk-...

キーをクライアント側のコードに含めないでください。無効化したキーは即座に使えなくなります。

キーの作成時に制限を付けられます:クレジット上限(累計利用上限)、有効期限、モデルの許可リスト、IP の許可リスト(単一アドレスまたは 203.0.113.0/24 のような IPv4 範囲)。アプリやチームメンバーにキーを渡すときに、影響範囲を限定するために使えます。

動画を作成

POST /videos

フィールド型必須説明
modelstringはい動画モデル ID(例:seedance-2.5)。モデル一覧を参照。
promptstringはい生成する内容。1〜4000 文字。
durationintegerいいえ長さ(秒)。モデルごとに受け付ける範囲や値が異なります。省略時はモデルの既定値。
resolutionstringいいえ例:720p。省略時はモデルの既定値。
aspect_ratiostringいいえ例:16:9。省略時はモデルの既定値。
audiobooleanいいえ音声を生成するか。対応モデル(Veo 3.1 など)のみで、料金が変わります。
negative_promptstringいいえ避けたい内容。最大 2000 文字。
image_urlsstring 配列いいえ参考画像の公開 URL(モデルの上限まで)。1 枚のみ対応のモデルでは開始フレームとして使われます。

ジョブに必要なクレジットは送信時に確保されます。正確な金額は credits_charged で返されます。

画像を作成

POST /images

フィールド型必須説明
modelstringはい画像モデル ID(例:nano-banana-2)。
promptstringはい生成する内容。1〜4000 文字。
resolutionstringいいえ例:1K、2K。省略時はモデルの既定値。
aspect_ratiostringいいえ例:1:1、16:9。省略時はモデルの既定値。
image_urlsstring 配列いいえ編集対象または参考にする画像の公開 URL(モデルの上限まで)。
curl -X POST https://apicafe.ai/api/v1/images \
  -H "Authorization: Bearer sk-..." \
  -H "Content-Type: application/json" \
  -d '{"model": "nano-banana-2", "prompt": "A red apple on a white table, photorealistic"}'

一部の画像モデルは即座に結果を返します。返されたタスクがすでに succeeded になっていることがあるので、必ず status を確認してください。

OpenAI 互換の画像エンドポイント

すでに OpenAI の画像 API を使っていますか?クライアントのベース URL を下記に向けて API キーを使うだけで、他は変更不要です。

POST /images/generations

from openai import OpenAI

client = OpenAI(base_url="https://apicafe.ai/api/v1", api_key="sk-...")

result = client.images.generate(
    model="nano-banana-2",
    prompt="A red apple on a white table, photorealistic",
    size="1024x1024",
)
print(result.data[0].url)
フィールド説明
modelモデル一覧の画像モデル ID。
prompt必須。
size任意。モデルが対応する最も近いアスペクト比と解像度に変換されます(1024x1024 は最小ティアの正方形、1792x1024 は 2K の横長など)。省略または auto でモデルの既定値。
n1 のみ対応。
response_formaturl のみ対応。

画像の生成完了まで待機し(最大約 50 秒)、{"created": ..., "data": [{"url": "..."}], "id": "...", "credits_charged": ...} を返します。待機時間を超えた場合は、メッセージにタスク ID を含む 504 generation_timeout が返るので、GET /images/{id} で取得してください。クレジットは確保されたままで、失敗した場合は自動で返金されます。

GET /videos/{id} と GET /images/{id}

同じタスクオブジェクトを返します。取得できるのは自分のタスクのみで、動画のタスク ID は画像エンドポイントでは解決されません(逆も同様)。

フィールド説明
idタスク ID。
objectvideo.task または image.task。
model使用したモデル。
statusprocessing、succeeded、failed のいずれか。
video_url動画タスクのみ。完成した動画の URL。succeeded になるまでは null。
image_url画像タスクのみ。完成した画像の URL。succeeded になるまでは null。
errorstatus が failed のときの簡単な理由。それ以外は null。
credits_chargedこのジョブ用に確保されたクレジット。失敗時は自動で返金されます。
created_atタスクの作成日時(ISO 8601)。
completed_atタスクの完了日時。未完了は null。

完成したファイルは当社のストレージにコピーされます。長期的に必要なものは、ご自身でダウンロードして保管してください。

モデル一覧

GET /models(認証不要)。?type=video または ?type=image で絞り込めます。

利用可能なモデルのエンドポイント、制限、pricing の一覧(解像度ごとの credits_per_unit。音声で料金が変わるモデルは音声あり・なしも)を返します。unit は 1 つの価格が何に対するものかを示します:動画の 1 秒(second)または画像 1 枚(image)。この一覧が常に最新です。

料金とクレジット

レート制限

API キーごとに 10 秒あたり 20 リクエストまでです。超過すると Retry-After ヘッダー付きの 429 rate_limited が返ります。ポーリングも制限に含まれるため、短い間隔で連続して呼ばず、数秒おきに行ってください。

エラー

エラーは共通の形式で返ります:

{
  "error": {
    "code": "insufficient_credits",
    "message": "This request costs 263 credits. Top up your balance and retry."
  }
}
HTTPコード意味
400invalid_json本文が正しい JSON ではありません。
400invalid_requestフィールドが不足、型が正しくない、またはモデルが対応していません。
400invalid_durationduration がモデルの受け付ける範囲外です。
400invalid_resolutionモデルが resolution に対応していません。
400invalid_aspect_ratioモデルが aspect_ratio に対応していません。
400content_policyプロンプトがコンテンツポリシーにより拒否されました。課金は発生しません。
400too_many_images参考画像の数がモデルの上限を超えています。
401missing_api_keyAuthorization ヘッダーがありません。
401invalid_api_keyキーが存在しないか、無効化されています。
401api_key_expiredキーの有効期限が切れています。
402insufficient_credits残高がこのジョブに足りません。
402key_limit_exceededキー自体のクレジット上限を超えてしまいます。
403account_suspendedアカウントが停止されています。
403ip_not_allowedこのキーは別の IP アドレスに制限されています。
403model_not_allowedこのキーはこのモデルの利用を許可されていません。
404model_not_foundモデルが存在しない、提供終了、または別のメディア種別です。
404task_not_foundタスクが存在しません。
429rate_limitedリクエストが多すぎます。
502upstream_error生成サービスが利用できませんでした。課金は発生しません。
500internal_error当社側で問題が発生しました。再試行してください。

サンプル

Python

import time
import requests

API = "https://apicafe.ai/api/v1"
HEADERS = {"Authorization": "Bearer sk-..."}

task = requests.post(
    f"{API}/videos",
    headers=HEADERS,
    json={"model": "seedance-2.5", "prompt": "A red paper boat on a pond"},
).json()

while task["status"] == "processing":
    time.sleep(5)
    task = requests.get(f"{API}/videos/{task['id']}", headers=HEADERS).json()

print(task["status"], task.get("video_url") or task["error"])

JavaScript

const API = "https://apicafe.ai/api/v1";
const headers = {
  Authorization: "Bearer sk-...",
  "Content-Type": "application/json",
};

let task = await (
  await fetch(`${API}/images`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      model: "nano-banana-2",
      prompt: "A red apple on a white table",
    }),
  })
).json();

while (task.status === "processing") {
  await new Promise((resolve) => setTimeout(resolve, 3000));
  task = await (await fetch(`${API}/images/${task.id}`, { headers })).json();
}

console.log(task.status, task.image_url ?? task.error);