モデルカタログとスキーマ
認証付きライブカタログから呼び出せるモデルを選び、料金を読み、現在の JSON Schema で要求を作ります。
createTask.model は、認証付き GET /api/v1/models が返す正確な model を使います。input は同じ項目の現在の inputSchema で定義します。呼び出せる ID の唯一の基準は、その時点の応答です。
固定ページから ID をコピーしないでください
公開時点の一覧、シリーズのページ、開発元のカタログは探すための情報です。予定、無効、改名した項目を含む可能性があり、ライブカタログが空でも代わりにはできません。有料処理前に認証付きカタログを取得し、enabled: true と available: true の両方を確認します。
例の MODEL_ID_FROM_CATALOG は実モデルでなく仮の値です。自分のライブカタログの model へ置き換えます。読み取りは無料です。
モデルと検証済み入力を選ぶ
スキーマはモデルごとに違います。安全に実行するには、ライブのモデルと、サーバー検証済みの例を一緒に選びます。
const response = await fetch(
'https://api.spicyapi.ai/api/v1/models?includeSchema=1&includeExamples=1',
{ headers: { Authorization: `Bearer ${process.env.SPICY_API_KEY}` } },
);
const envelope = await response.json();
if (!response.ok || envelope.code !== 200) throw new Error(envelope.msg);
const selected = envelope.data.items.find(
(item) => item.enabled && item.available && item.examples?.length,
);
if (!selected) throw new Error('No callable model with a validated example');
const createTaskBody = {
model: selected.model,
input: selected.examples[0].input,
};各例は、現在のスキーマでサーバーが検証した完全な input で、そのまま送れます。
コードからカタログを取得する
GET /api/v1/models
GET /api/v1/models/{model}curl "https://api.spicyapi.ai/api/v1/models?modality=video" \
-H "Authorization: Bearer $SPICY_API_KEY"一覧にページ分割はなく、フィルターに合い、そのキーから見える全モデルを 1 応答で返します。パラメーターはすべて任意です。
| パラメーター | 意味 |
|---|---|
modality | image、video、audio、text |
provider | 開発元。大文字小文字も含め完全一致。例は ByteDance。項目の provider からコピー |
task | text-to-image、edit(画像編集)、image-to-video、text-to-video、reference-to-video、speech-to-text、video-analyze、video-edit、video-extend、character-animation、chat など。現在の種類は tasks で確認。画像編集の公開 ID は .../edit、tasks 分類は image-to-image で、フィルターは両表記に対応 |
search | ID または表示名の任意位置にある、大文字小文字を区別しない文字列。最大 128 文字 |
includeSchema | true または 1 で各項目の inputSchema を追加 |
includeExamples | true または 1 で現在のスキーマで検証した examples を追加 |
単一モデルの GET /api/v1/models/{model} は、常に inputSchema と examples を含みます。includeSchema と includeExamples は一覧だけに影響します。ID のスラッシュはそのままでよく、HTTP クライアントがパスの値を 1 区間として扱う場合だけ percent-encode します。存在しないか、現在提供していないモデルは 404 です。
一覧の一部を示す例です。
{
"code": 200,
"msg": "success",
"data": {
"total": 1,
"items": [
{
"model": "MODEL_ID_FROM_CATALOG",
"family": "…",
"displayName": "…",
"provider": "…",
"modality": "video",
"tasks": ["image-to-video"],
"async": true,
"enabled": true,
"available": true,
"availability": "available",
"taskTimeoutSeconds": 1200,
"maxOutputDurationSeconds": 10,
"quantityField": "duration_seconds",
"pricing": [
{ "variant": "generate_audio=false;resolution=720p", "unit": "per_second", "price": "0.05", "currency": "USD" },
{ "variant": "generate_audio=true;resolution=720p", "unit": "per_second", "price": "0.08", "currency": "USD" }
],
"startingPrice": { "variant": "generate_audio=false;resolution=720p", "unit": "per_second", "price": "0.05", "currency": "USD" },
"badges": ["audio_output"],
"relatedModels": [],
"version": "v1",
"updatedAt": "2026-09-16T16:47:57Z"
}
]
},
"request_id": "req_01k3m8x9q2z4v7n5p6r8s0t1w2"
}料金は例示です。一覧の inputSchema と examples は、指定した場合だけ出ます。
クライアントが使う項目
| 項目 | 目的 |
|---|---|
model | createTask.model に送る正確な publisher/model/task |
family | 関連するエンドポイントをまとめる安定したシリーズ ID |
displayName | 人向けの名前 |
provider | モデルを作った研究所など開発元 |
modality / tasks | カタログでの媒体分類と実行タスク。modality は閲覧と modality フィルター用で、出力の媒体の保証ではない。speech-to-text は audio に分類して文章を返す。出力の形参照 |
toolkit | ツールの系列。現在は subject-swap のみ。所属なしでは項目自体がないため、キーの存在でなく値を確認。badges と同じ分類情報で、受理、価格、検証には影響しない。人物の置換参照 |
async | true は作成後、ポーリングか Webhook で取得。false は応答内に回答 |
inputSchema | フォームと検証用の JSON Schema 2020-12 |
examples | 現在のスキーマで検証済み入力。一覧では指定時だけ返す |
enabled | 今呼べるか。公開済みで未開放、一時停止は false。送信前に available と合わせて確認 |
available | 今呼べるか。false は料金未設定など、呼び出しが失敗する状態 |
availability | planned、available、preview(項目・出力が変わり得る)、maintenance(一時的な失敗で復帰予定) |
pricing / startingPrice | アカウントの料金。読み方参照 |
quantityField | 課金数量になる入力項目。動画では通常 duration_seconds。空なら呼び出しごとに 1 単位。必ずカタログで読む |
taskTimeoutSeconds | 1 タスクの実行期限。メディアの長さではない |
maxOutputDurationSeconds | duration_seconds の maximum による最長出力。最大値の定義がなければ省略 |
badges | commercial_use、no_watermark など能力・許諾のタグ。未知値は無視 |
relatedModels | 選んだ代替・次の候補。呼べるモデル ID |
version / updatedAt | 後の取得で変わったかの比較用 |
mature と policyTier は説明用ラベルで、要求の受理には関与しません。
料金の読み方
pricing の各項目が 1 つの料金の段階です。
| 項目 | 意味 |
|---|---|
unit | per_image、出力の per_second、per_request、per_1k_tokens |
price | USD の単価を表す 10 進数文字列。アカウント別の料金を反映済み |
variant | 選択する設定。単一料金なら空、1 項目なら 720p などの値、複数なら項目名順の field=value を ; で結合。例は generate_audio=false;resolution=480p |
currency | 常に USD |
regularPrice、offerLabel、offerPercent、offerEndsAt | 特典適用中だけ。適用前の額、名前、割合、終了時点 |
startingPrice は最安の段階で、選んだ設定の価格ではありません。選択する項目は、あれば inputSchema["x-pricing"].variantFields、なければ x-ui.affects_price: true(quantityField を除く)です。省略した項目はスキーマの default として数えます。
- メディア: 基本は
price × quantityで、数量は入力のquantityFieldの値で、quantityFieldが空なら 1 です。ただし一部は追加入力ごとに別料金、多くは参照画像ごとの料金を加えます。端数ではなく請求の実要素です。編集の参照配列を増やすと、unit、quantity、variant、段階のpriceが 1 枚と同じでも額が倍増し得て、上の算術だけでは見える兆候なしに過少評価します。機械で判別する印は、quantityFieldでもx-pricing.variantFieldsにもないx-ui.affects_price: trueです。段階を選ばず額を変えるため、pricingを下限とし、正確な額は見積もりで取得します。 - テキスト(
per_1k_tokens):1 数値では課金を表せません。priceは 1,000 出力トークンの単価だけです。入力とキャッシュ入力は別の通常より安い単価で、実測使用量から課金します。総トークン数へpriceを掛けません。入力、キャッシュ入力、出力の 100 万当たりは、モデルページと公開カタログのprice.perMillionTokensにあります。
ネイティブ API の正確な要求を支払い前に見積もるには、POST /api/v1/jobs/quote を使います。最終額は settled: true の cost と課金で確認します。
カタログのキャッシュ
- 最大 60 秒(
Cache-Control: private, max-age=60)キャッシュできます。料金はアカウント固有なので、非公開のアカウント別キャッシュだけにし、共有・公開 CDN へ置きません。 - その後も、毎タスク取得し直さないでください。カタログは送信と独立した読み取り枠を使います。毎回の取得は読み取り容量を浪費します。レート制限参照。
- 数分ごとなどの定期更新、検証の
400、そのモデルの送信拒否後に更新します。 - 使用した
versionとupdatedAtを残し、後の変更を比較します。 - 固定スキーマを配布せず、ライブに呼べる項目がない場合は固定ページを代わりにしません。
共通スキーマと Playground の規則
inputSchema は JSON Schema 2020-12 です。標準キーワードがサーバー検証を行い、項目の x-ui は表示順、表示方法、見積もり更新の補助だけです。未知の表示拡張は無視し、required、列挙、範囲、条件の代わりにしません。Spicy Schema 契約参照。
自分のモデル別パラメーター表を作る
サイトに固定の表がないのは、モデルと項目が毎週変わり、古い情報が 400 や誤った価格につながるためです。唯一の情報源は、カタログの inputSchema です。Playground も同じ文書を表示し、SDK もそれで検証します。
スキーマを表へ対応させる
| スキーマ内 | 表での表示 |
|---|---|
properties のキー | パラメーター名。全モデルで 1 意味に 1 名前 |
required に含まれるか | 必須か任意か |
anyOf / allOf | 条件付き必須。anyOf は少なくとも 1 つ、allOf の if → then は A を渡すなら B も必要 |
type | 型 |
description | ヘルプ。英語の文をそのまま使え、自分で書く必要はない |
enum | 許可値。x-ui.enum_labels があれば表示ラベルへ変換 |
minimum / maximum | 範囲。x-ui.step は刻み、x-ui.unit は単位(s、px) |
minItems / maxItems | 配列の件数。省くと到達する上限が伝わらない |
items | 配列の 1 項目の形。items.type が object なら完全なオブジェクトで、required、additionalProperties、子の type、description、範囲、default を読み、自由入力でなく入れ子の表にする |
default | 省略時の初期値 |
x-ui.order | 大きい順の並べ替え。properties のキー順では並べない。JSON のキー順は契約外 |
x-ui.primary | 主入力として最上部へ固定 |
x-ui.advanced | 詳細設定へ折り畳める |
x-ui.affects_price | 料金に影響する表示。変更時に再見積もり |
x-ui.widget | 編集フォームの操作欄。13 値は Spicy Schema参照 |
条件は inputSchema のルートに 2 形式だけです。anyOf は各枝の required の少なくとも 1 つ、allOf は if → then で A なら B です。シリーズから推測せず、oneOf、not、dependentSchemas は期待しません。新規は Spicy Schemaの標準名、古いものはライブのスキーマに従います。
取得する
const modelId = 'MODEL_ID_FROM_CATALOG'; // the exact `model` value from GET /api/v1/models
const res = await fetch(`https://api.spicyapi.ai/api/v1/models/${modelId}`, {
headers: { Authorization: `Bearer ${process.env.SPICY_API_KEY}` },
});
const { data } = await res.json();
const schema = data.inputSchema;
const rows = Object.entries(schema.properties)
.sort(([, a], [, b]) => (b['x-ui']?.order ?? 0) - (a['x-ui']?.order ?? 0))
.map(([name, prop]) => ({
name,
required: (schema.required ?? []).includes(name),
type: prop.type,
description: prop.description,
values: prop.enum
? prop.enum.map((v) => prop['x-ui']?.enum_labels?.[v] ?? v)
: prop.minimum !== undefined || prop.maximum !== undefined
? [`${prop.minimum ?? ''}–${prop.maximum ?? ''}${prop['x-ui']?.unit ?? ''}`]
: [],
default: prop.default,
affectsPrice: prop['x-ui']?.affects_price === true,
advanced: prop['x-ui']?.advanced === true,
}));この例は意図的に単一値までで、配列の values は空です。配列は enum や範囲でなく items、minItems、maxItems で内容を示すためです。配布前に拡張します。array だけで形や件数がない行は、読者が具体的に使えません。
単一モデルには examples もあり、各例は現在のスキーマでサーバー検証済みの完全入力です。文書の最小例にも、そのまま送る本文にも使えます。手書きはスキーマ変更で古くなりますが、examples はそうならないため、より安全です。
modelId を変えれば全モデルを扱い、新規追加でも使えます。全カタログの表には、GET /api/v1/models?includeSchema=1 の items を繰り返し、キャッシュに従います。
description より詳しい説明
description はフォーム向けの 1 文です。より説明が必要な項目には、公開カタログに別のメモがあります。
curl "https://api.spicyapi.ai/console/v1/catalog/models/MODEL_ID_FROM_CATALOG?locale=en"単一記録の paramNotes は、項目名をキーにするオブジェクトで、locale により 10 言語で取得できます。何を基準に数えるか、どの設定が遅くなるか、スキーマに合っても満足しにくい入力など、ラベルに収まらない説明です。自分でホストするファイルでは、取得するか、いつ取得し、使えない場合どうなるかを説明する唯一の場所であることが多くあります。
2 つの境界があります。paramNotes はキー不要の公開カタログだけで、認証付き GET /api/v1/models にはないため、別に取得してスキーマの横へキャッシュします。また文章であって規則ではなく、受理を決めるのは inputSchema だけです。

