spicyapi文件
主要內容

Agent 與自動化串接

適用於 AI 程式設計 Agent、後端任務與媒體處理管線的正式環境串接手冊。

可複製的參考用戶端

下載儲存庫裡沒有任何第三方相依套件的參考程式碼。兩種實作都涵蓋模型探索、任務建立、失敗任務重試、狀態查詢、所有終態、有上限的等待、冪等鍵與錯誤處理。任務一經受理即不可取消。

這些是文件裡的範例程式,不是已發布的 npm / PyPI 套件;10 分鐘只是本機等待上限,不是正式環境的 SLA。

當 AI 程式設計 Agent 或自動化後端要串接 SpicyAPI 時,從本頁開始。它把 API Reference 整理成一條有邊界、可恢復、可驗收的工作流程:發現契約、驗證模型參數、只建立一次、安全等待、查核完成狀態,並在資源過期前儲存輸出。

API Key 只能留在後端

不要把 SPICY_API_KEY 寫進瀏覽器 JavaScript、行動裝置 App 安裝檔、公開提示詞、程式碼儲存庫或 Agent 對話記錄。使用者介面呼叫你的後端,再由後端呼叫 SpicyAPI。給 Agent 的應該是 SPICY_API_KEY 這樣的金鑰引用,而不是金鑰明文。

機器可讀的發現入口

優先讀取能回答目前問題的最小檔案,既節省上下文,也減少 Agent 使用過期資訊的機會。

入口適用情境
/agent.md簡短的串接規則與預設安全流程
/llms.txt產品、模型與文件的公開索引
/llms-full.txt短索引不夠用時改讀的完整檢索語料
/api/agent面向工具和自動用戶端的結構化 JSON 清單
/openapi.yaml請求與回應結構的權威快照

以 OpenAPI 快照和即時模型目錄為契約。行銷範例只用於說明,不是 Schema 來源。發現檔案可以快取,但在產生程式碼前或參數驗證突然失敗時應重新取得。

官方 npm 整合

SDK、CLI、MCP 與通用 Agent Skill 是四個獨立的 MIT 授權 npm 套件。只安裝目前需要的套件;@spicyapi/skill 採用可移植的 Agent Skills 目錄結構,並非 Codex 專屬。

套件用途
@spicyapi/sdkTypeScript SDK、OpenAPI 型別與 Webhook 簽章驗證工具
@spicyapi/cli獨立的 spicyapi 命令列用戶端
@spicyapi/mcp獨立的 stdio 與本機 HTTP MCP Server
@spicyapi/skill面向相容 Agent 的通用 SpicyAPI Skill
npm install @spicyapi/sdk
npx --yes --package=@spicyapi/cli spicyapi --help
npx --yes --package=@spicyapi/mcp spicyapi-mcp
npx --yes --package=@spicyapi/skill spicyapi-skill install

Skill 預設安裝到 ~/.agents/skills/spicyapi。若某個 Agent 使用自己的 Skills 目錄,請用 --target /準確/目錄/spicyapi 指定;安裝器不會在未給 --force 時覆蓋已有目錄。

在程式設計 Agent 裡使用

MCP 服務在本機以 stdio 方式執行,把模型目錄、報價、建任務、等結果交給 Agent 使用。每一次可計費操作都會停下來要確認,Agent 繞不過去。下面是各用戶端目前建議的串接方式;設定位置與寫法由用戶端自己定義,也會隨版本變化,請以它們的官方文件為準。

Claude Code

claude mcp add spicyapi \
  -e SPICY_API_KEY=$SPICY_API_KEY \
  -- npx --yes --package=@spicyapi/mcp spicyapi-mcp

npx --yes --package=@spicyapi/skill spicyapi-skill install \
  --target ~/.claude/skills/spicyapi

Codex CLI

codex mcp add spicyapi \
  --env SPICY_API_KEY=$SPICY_API_KEY \
  -- npx --yes --package=@spicyapi/mcp spicyapi-mcp

npx --yes --package=@spicyapi/skill spicyapi-skill install \
  --target ~/.codex/skills/spicyapi

這兩條命令都會把目前 shell 裡的 SPICY_API_KEY 寫進該用戶端的本機設定,所以要在已經 export 過金鑰的終端機裡執行。金鑰留在本機,不要提交。

Cursor、Windsurf 與 Gemini CLI

設定檔分別是 ~/.cursor/mcp.json~/.codeium/windsurf/mcp_config.json~/.gemini/settings.json,寫法相同:

{
  "mcpServers": {
    "spicyapi": {
      "command": "npx",
      "args": ["--yes", "--package=@spicyapi/mcp", "spicyapi-mcp"],
      "env": { "SPICY_API_KEY": "YOUR_SERVER_SIDE_KEY" }
    }
  }
}

它們都是儲存庫之外的使用者層級檔案。把 YOUR_SERVER_SIDE_KEY 換成真實金鑰之後,不要把這段設定複製進任何會提交的專案檔案。

VS Code

.vscode/mcp.json 會隨儲存庫一起提交,所以金鑰不能寫在裡面。讓 VS Code 在首次啟動服務時提示輸入,並存進它自己的金鑰儲存:

.vscode/mcp.json
{
  "inputs": [
    {
      "id": "spicyapi-key",
      "type": "promptString",
      "description": "SpicyAPI key",
      "password": true
    }
  ],
  "servers": {
    "spicyapi": {
      "type": "stdio",
      "command": "npx",
      "args": ["--yes", "--package=@spicyapi/mcp", "spicyapi-mcp"],
      "env": { "SPICY_API_KEY": "${input:spicyapi-key}" }
    }
  }
}

設定好之後

直接讓 Agent 做一件真事:

用 SpicyAPI 列出我能呼叫的影像模型,挑一個便宜的生成一張夜景人像,完成後把結果連結給我。

Agent 會讀目錄、取該模型的 Schema、拿到準確報價,並在扣費之前停下來等你確認。裝上 Skill 之後,它還會重複使用同一個冪等鍵、優先讀取已就緒的結果連結,而不是反覆輪詢。

60 秒 TypeScript SDK 路徑

需要 Node.js 22.13 或更高版本。先從官網模型頁的 API 標籤或已認證的即時模型目錄複製準確的模型 ID 和經過 Schema 驗證的輸入;不要把下面的環境變數名當作模型值。

npm install @spicyapi/sdk
export SPICY_API_KEY="從後端金鑰庫注入"
export SPICY_MODEL_ID="從即時目錄複製的模型 ID"
export SPICY_INPUT_JSON='{"prompt":"your prompt"}'
run.ts
import { randomUUID } from "node:crypto";
import { SpicyClient } from "@spicyapi/sdk";

const client = new SpicyClient();
const modelId = process.env.SPICY_MODEL_ID;
if (!modelId) throw new Error("SPICY_MODEL_ID is required");

const model = await client.getModel(modelId);
const input = JSON.parse(process.env.SPICY_INPUT_JSON ?? "{}");

// createTask 會預扣餘額;應在使用者確認後才執行。
const accepted = await client.createTask(
  { model: model.model, input },
  { idempotencyKey: randomUUID() },
);
console.log("accepted", accepted.taskId);

const terminal = await client.waitForTask(accepted.taskId, {
  timeoutMs: 10 * 60_000,
  onUpdate: (task) => console.log(task.state),
});
console.log(JSON.stringify(terminal, null, 2));
npx --yes tsx run.ts

createTaskretryTask 都可能預扣餘額,而且新的已受理任務目前不能取消。自動化工具必須在呼叫前顯示模型、輸入摘要和目錄價格,並取得明確確認;可以先呼叫不扣款的 POST /api/v1/jobs/quote 取得精確報價,受理回應同樣會回傳準確的 estimatedCost。網路重試必須重複使用同一個冪等鍵。

SDK 能力邊界

方法用途
listModels / getModel讀取即時模型、Schema、範例和價格
getBalance讀取 available、held 與 total
createTask / retryTask建立或重試可能計費的任務,支援冪等鍵
getTask / waitForTask查詢一次,或有總時限地等待終態
createUploadUrl / commitUploadedFile完成直傳票據與 spicy:// 提交流程
uploadBytes / uploadFileNode.js 圖片上傳快捷方法
createDownloadUrl為輸出物件簽發短期下載網址

TypeScript 是目前的官方 SDK。Python、Go 與其他語言請使用本頁的 HTTP 契約和 OpenAPI 3.1 產生用戶端;不要把未經發布的第三方封裝稱為官方 SDK。

正式環境工作流程

選擇模型並驗證輸入

先選擇與目標模態相符的模型端點,再根據該端點目前的 Schema 驗證輸入。不要猜欄位名,也不要悄悄丟棄未知欄位。

只建立一次

為一次邏輯生成請求建立一個穩定的 Idempotency-Key,首次請求前持久化,所有重試都重複使用同一個值。絕不能在重試迴圈裡產生新 Key。詳見冪等請求

POST /api/v1/jobs/createTask
Authorization: Bearer $SPICY_API_KEY
Content-Type: application/json
Idempotency-Key: project-42-scene-07-v1

拿到 taskId 後立刻儲存。它是狀態查詢、Webhook 對帳、客服追查和計費核對的穩定身分。重試可能回傳同一個任務,本機不能因此新增第二筆記錄。

有上限地等待

正式環境優先使用帶簽章的 Webhook。必須輪詢時,可從 2 秒開始,間隔乘以約 1.5,最大 15 秒,並設定明確的總時限。succeededfailedcanceledexpired 都是終態;任何程式都不應無限輪詢。

有界輪詢骨架
const deadline = Date.now() + 10 * 60_000;
let delay = 2_000;

while (Date.now() < deadline) {
  await sleep(delay);
  const task = await recordInfo(taskId);
  if (['succeeded', 'failed', 'canceled', 'expired'].includes(task.state)) return task;
  delay = Math.min(Math.round(delay * 1.5), 15_000);
}
throw new Error(`task ${taskId} exceeded the polling deadline`);

本機逾時不等於生成失敗。保留任務 ID,稍後繼續對帳。

驗證簽章後再處理回呼

先在控制台設定 Webhook 簽章金鑰。驗證 X-Webhook-Timestamp 並拒絕過期請求,對原始請求本文計算摘要,再用常數時間比較 HMAC 簽章。用投遞 request_id 去除重複,用 data.taskId 更新任務;快速回傳 2xx,把後續工作放入佇列。完整演算法見 Webhooks

及時儲存輸出

完成的任務會在 output.assets[].url 中回傳可直接使用的結果 URL,無需額外請求下載網址。請在過期前將需要長期保留的檔案複製到自己的儲存。選用的 download-url 介面可根據物件 Key 簽發下載網址,這類已簽章的網址在 20 分鐘後過期。URL 有效期與媒體保留期是不同概念,詳見媒體檔案資料留存

最小持久化記錄

至少儲存以下狀態,程式重啟後才能安全恢復:

{
  "localRequestId": "project-42-scene-07-v1",
  "idempotencyKey": "project-42-scene-07-v1",
  "taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
  "model": "MODEL_ID_FROM_CATALOG",
  "state": "queued",
  "lastCheckedAt": "2026-08-29T12:00:00Z",
  "webhookDeliveryId": null,
  "outputKeys": []
}

MODEL_ID_FROM_CATALOG 表示從已認證即時目錄選出的精確 ID,不是可原樣傳送的值。不要把已簽章的下載 URL 當作長期主鍵,也不要看到 HTTP 200 就判斷生成成功;應讀取 data.state

先用 Mock 驗證編排

根據非同步任務Webhooks錯誤處理裡的信封結構,建立本機契約 Mock。測試案例至少包含:

  • queued → running → succeeded;
  • code: 200data.state: "failed" 的終態失敗;
  • 重複建立回傳相同 taskId
  • 正確簽章、錯誤簽章與重複投遞;
  • 429503、網路逾時和超過輪詢總時限;
  • 下載網址過期後重新簽發。

Mock 只能驗證流程,不能驗證模型品質。發布前仍應使用與正式環境完全相同的模型與輸入結構跑一個小任務。

上線驗收清單

  • 金鑰只存在於後端的金鑰庫,日誌會自動遮蔽金鑰。
  • 串接時讀取模型目前的 Schema,不靠猜測欄位。
  • 一次邏輯請求只有一個持久化的 Idempotency-Key
  • taskId 在後續處理前寫入資料庫,程式重啟後仍可恢復。
  • 輪詢同時具備退避、最大間隔與總時限。
  • Webhook 驗證時間戳記、原始請求本文摘要與 HMAC,並依投遞 ID 去除重複。
  • data.state 判斷終態失敗,而不是 HTTP 狀態或信封 code
  • 在 URL 或保留期過期前複製輸出,以物件 Key 作為穩定引用。
  • 日誌記錄 request_idtaskId、模型和嘗試次數,但不記錄金鑰與完整提示詞。
  • Mock 涵蓋重複建立、重放、逾時、速率限制和媒體過期。

建議的 Agent 交付格式

要求 Agent 一併回傳:最終選擇的模型端點、Schema 版本或取得時間、冪等鍵策略、輪詢總時限、Webhook 簽章驗證方案和已完成的驗收清單。這樣「已串接」才是可複核的結論。

本頁目錄