見積もりとプロトコル互換
正確な見積もりを確認してから API を実行します。
最新のモデル Schema に従い、model、input、任意の callBackUrl を request.json に保存します。見積もりはタスクや残高の確保を発生させません。利用主体、モデル、同一リクエストに結び付き、有効期間は 5 分です。
curl https://api.spicyapi.ai/api/v1/jobs/quote \
-H "Authorization: Bearer $SPICY_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @request.jsonestimatedCost、maxCharge、quantity は十進文字列、currency は USD です。金額、上限、expiresAt を表示し、ユーザー確認後に同じリクエストへ quoteId と expectedCost を付けて送信します。入力変更、期限切れ、料金変更では新規受理時に 40901 となり、再見積もりと再確認が必要です。
応答が失われたら元の Idempotency-Key で復旧します。新しいキーで別タスクを作らないでください。受理済みリプレイは見積もり期限切れ後も有効です。確定料金は recordInfo の cost と settled で確認し、見積もりやテキスト終了記号だけでは判断しません。
SDK・CLI・MCP
CLI の tasks create は見積もり後に確認します。非対話実行には明示的な --yes が必要です。MCP の spicyapi_task_quote は見積もり専用です。spicyapi_task_create は見積もりを署名済み状態に保存し、プロトコルでユーザーへ確認します。エージェントによる代理確認はできません。
spicyapi tasks quote --model "$SPICY_MODEL" --input-file input.json
spicyapi tasks create --model "$SPICY_MODEL" --input-file input.json \
--idempotency-key "$SPICY_IDEMPOTENCY_KEY" --waitテキスト・動画互換 API
OpenAI 形式のベース URL は https://api.spicyapi.ai/v1 です。Anthropic と Google GenAI の SDK では、ベース URL に https://api.spicyapi.ai を指定します。/v1 や /v1beta は SDK が自動で付け足します。互換 API はすべて同じ API キーを使い、Authorization: Bearer ヘッダーで送ります。Anthropic SDK が使う x-api-key と、Google GenAI SDK が使う x-goog-api-key も受け付けますが、URL に付けた ?key= は受け付けません。最新カタログから chat に対応する正確なモデルを選んでください。ツール呼び出し、画像メッセージ、生成パラメータの対応はモデルの Schema に従います。応答は各プロトコルの形式で、プラットフォームの JSON 外枠は付きません。プロトコルごとのパラメータ対応、ストリームの終わり方、エラーの形式はテキストとストリーミングを参照してください。
| プロトコル | エンドポイント |
|---|---|
| Models | GET /v1/models |
| Chat Completions | POST /v1/chat/completions |
| Responses | POST /v1/responses |
| Messages | POST /v1/messages |
| Gemini generateContent | POST /v1beta/models/{model}:generateContent |
| Gemini streamGenerateContent | POST /v1beta/models/{model}:streamGenerateContent |
| Videos | POST /v1/videos |
| Video status | GET /v1/videos/{videoId} |
| Video content | GET /v1/videos/{videoId}/content |
推論テキストを返す Chat モデルでは、省略可能な文字列 message.reasoning_content が含まれる場合があります。ストリーミングでは delta.reasoning_content です。ツール呼び出し後に会話を続ける際は、最新のモデル Schema が対応していれば、該当する assistant メッセージにこの値をそのまま保持できます。usage.completion_tokens_details.reasoning_tokens は completion_tokens に含まれる内訳なので、重複して加算しないでください。推論テキストや token の内訳を返さないモデルもあります。
Responses は会話全体を input に含めます。previous_response_id は未対応です。Videos は JSON の model、prompt、input_reference、seconds、size を変換します。content は短期署名 URL へ 302 リダイレクトします。全フィールドと状態は OpenAPI を参照してください。
quoteId と expectedCost は jobs/createTask と jobs/stream で使用します。/v1 と /v1beta の互換 API は受理時の料金を適用します。料金上限の確認が必要な場合はネイティブのタスク API を使ってください。
公式 OpenAI クライアントでストリーミング
Chat Completions には公式の openai クライアントを直接使います。@spicyapi/sdk はネイティブタスク、見積もり、アップロードを扱います。openai を別途インストールし、自分のサーバー上で実行してください。現在呼び出せる正確なチャットモデル ID と、操作ごとに保存した冪等キーを使います。
npm install openaiimport OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.SPICY_API_KEY,
baseURL: "https://api.spicyapi.ai/v1",
maxRetries: 0,
});
const signal = AbortSignal.timeout(120_000);
const stream = await client.chat.completions.create({
model: process.env.SPICY_MODEL,
messages: [{ role: "user", content: "Explain a rainbow in one sentence." }],
stream: true,
stream_options: { include_usage: true },
}, {
signal,
headers: { "Idempotency-Key": process.env.SPICY_IDEMPOTENCY_KEY },
});
try {
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta.content ?? "");
if (chunk.usage) process.stderr.write(JSON.stringify(chunk.usage) + "\n");
}
} finally {
stream.controller.abort();
}中断シグナルは接続からストリームの読み取りまで適用されます。中断はローカルの受信を止めるだけで、受理済みタスクのキャンセルや返金を保証しません。非ストリーミングでは stream: false とし、choices[0].message.content を読みます。ツール呼び出しの断片は index ごとに連結し、完全な assistant メッセージを保存してから対応する tool_call_id の結果を追加します。ツールと推論フィールドはモデルの schema が対応する場合にのみ使ってください。
CLI と MCP は現在、ネイティブタスクの送信と追跡に対応しており、チャットのトークン配信は行いません。逐次表示にはこのクライアントを、見積もり確認が必要なら jobs/stream を使います。

