← 開發者指南

Direct API 整合

以純 HTTP 呼叫 API — 不使用 SDK,任何語言皆可。確切的匿名與已認證請求/回應格式,附 curl 範例。

不使用 SDK,任何語言皆可 — 這是直接呼叫 API 的確切 HTTP 合約。如果您使用的是 JavaScript, SDK 已經把這一切(提交、輪詢、錯誤處理)都包好了 — 請見 純網頁整合, 或者如果您還沒選定要看哪一篇指南,請見 選擇您的整合路徑

下方每個範例都已顯示這個環境真實的 API 基礎 URL — 請直接照抄使用,後面不要再加任何路徑片段。

兩個不同的 endpoint,並非同一個 URL 搭配兩種認證模式

這是兩個各自獨立的 HTTP endpoint。它們對同一個工具也會回傳不同的回應格式 — 請先確認您實際 串接的是哪一個。

匿名 — POST /tools/:slug/run + GET /tools/runs/:ticketId

不需要任何憑證。使用工具的 slug。回應欄位在所有工具間都會統一正規化為 result.text(外加 token/延遲的中繼資料),讓公開的 Tool Portal 能用同一個通用的 renderer 顯示任何工具。依 IP 進行速率限制;匿名路徑的錯誤對照表請見下方的 錯誤(特別是 403 那則說明)。

curl -X POST "https://api.quravin.com/tools/translate/run" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": { "text": "Hello", "target_language": "de" }
  }'

回應(202):

{ "ticket_id": "01J...ULID", "status": "QUEUED" }

輪詢:

curl "https://api.quravin.com/tools/runs/01J...ULID"

完成後的回應:

{
  "ticket_id": "01J...ULID",
  "status": "DONE",
  "mode": "pipeline",
  "pipeline_id": "translate-string",
  "result": { "text": "Hallo", "model": "gpt-4o-mini", "latency_ms": 812 },
  "created_at": "2026-07-10T12:00:00.000Z",
  "updated_at": "2026-07-10T12:00:02.000Z"
}

注意是 result.text,不是 result.translation — 匿名路徑一律正規化為 text

已認證 — POST /tickets + GET /tickets/:id

需要 x-api-key: <key>Authorization: Bearer <jwt>(如何取得任一種,請見 選擇您的認證 模式)。使用 pipeline_id,並回傳每個 pipeline 原始、 未經正規化的輸出格式 — 以 translate-string 來說就是 translation,而不是 text。每個工具的 pipeline_id 與真正的輸出欄位,請見 工具參考手冊

使用靜態 API 金鑰:

curl -X POST "https://api.quravin.com/tickets" \
  -H "Content-Type: application/json" \
  -H "x-api-key: <your-api-key>" \
  -d '{
    "mode": "pipeline",
    "pipeline_id": "translate-string",
    "inputs": { "text": "Hello", "target_language": "de" }
  }'

使用 session JWT(透過 POST /auth/token 發行 — 見 選擇您的認證 模式)— body 完全相同,只有 header 不同:

curl -X POST "https://api.quravin.com/tickets" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your-jwt>" \
  -d '{
    "mode": "pipeline",
    "pipeline_id": "translate-string",
    "inputs": { "text": "Hello", "target_language": "de" }
  }'

兩者都會回傳相同的回應(202):

{ "ticket_id": "01J...ULID", "status": "QUEUED" }

輪詢 — 使用 API 金鑰:

curl "https://api.quravin.com/tickets/01J...ULID" \
  -H "x-api-key: <your-api-key>"

輪詢 — 使用 session JWT:

curl "https://api.quravin.com/tickets/01J...ULID" \
  -H "Authorization: Bearer <your-jwt>"

完成後的回應:

{
  "ticket_id": "01J...ULID",
  "status": "DONE",
  "mode": "pipeline",
  "pipeline_id": "translate-string",
  "pipeline_version": "v3",
  "result": { "translation": "Hallo", "applied_terms": [] },
  "created_at": "2026-07-10T12:00:00.000Z",
  "updated_at": "2026-07-10T12:00:02.000Z"
}

若失敗則會是:

{
  "ticket_id": "01J...ULID",
  "status": "FAILED",
  "mode": "pipeline",
  "pipeline_id": "translate-string",
  "error": "Ticket failed: <reason>",
  "created_at": "2026-07-10T12:00:00.000Z",
  "updated_at": "2026-07-10T12:00:02.000Z"
}

取消 ticket — DELETE /tickets/:id

請求取消(透過寫入 cancel.flag)。您只能取消自己憑證所建立的 ticket — 具備 operator 範圍的 API 金鑰可以取消任何 ticket,而 JWT/webtoken 呼叫者只能取消自己的 ticket(否則回傳 403)。

curl -X DELETE "https://api.quravin.com/tickets/01J...ULID" \
  -H "x-api-key: <your-api-key>"

# 或使用 session JWT:
curl -X DELETE "https://api.quravin.com/tickets/01J...ULID" \
  -H "Authorization: Bearer <your-jwt>"

回應:

{ "ticket_id": "01J...ULID", "status": "CANCELED" }

對已取消的 ticket 執行 GET /tickets/:id 輪詢,回應格式與上方 DONEFAILED 相同,只是 status: "CANCELED"

列出您的 ticket — GET /tickets

回傳限定於您自身身分的 ticket — JWT/webtoken 呼叫者永遠只會拿回自己的 ticket;只有 operator 範圍的 API 金鑰可以帶入 ?user= / ?app= 查詢任意使用者/app 的 ticket。

curl "https://api.quravin.com/tickets?limit=20" \
  -H "Authorization: Bearer <your-jwt>"

查詢參數:

參數預設值說明
limit50最大 1000。
hydratetruefalse 只會回傳 [{ ticket_id }] — 成本較低,會跳過抓取每個 ticket 的完整狀態。
user呼叫者自己的 id只有 operator 範圍的 API 金鑰可以帶入其他使用者的 id。
app呼叫者自己的 app只有 operator 範圍的 API 金鑰可以帶入其他 app 的 id。

回應:

{ "tickets": [ { "ticket_id": "01J...ULID", "status": "DONE", "...": "..." } ] }

如果您正從公開的「試用」小工具升級為真正的整合,最重要的一點是:輸出欄位名稱會改變 — 從匿名的 result.text 變成已認證路徑中該 pipeline 專屬的欄位 — 以 translate 來說,就是 result.translation

錯誤

您可能拿到哪些錯誤,取決於您的呼叫方式 — 匿名呼叫與已認證呼叫的驗證方式不同。請勿假設某一種 路徑的錯誤行為也適用於另一種路徑。

匿名呼叫(無 API 金鑰)

可呼叫所有已發布的工具,並依 IP 進行速率限制。

狀態碼錯誤代碼意義
404未知的工具 slug。
403機器人檢查未通過。這條路徑需要能執行 Cloudflare Turnstile 挑戰的真實瀏覽器環境 — 從伺服器、curl 或沒有 Turnstile token 的無頭腳本呼叫一律會回傳 403。伺服器對伺服器的呼叫請改用已認證路徑(API 金鑰或 session JWT)。
429guest_quota_exceeded您已達到匿名每 IP 或全域每日請求次數上限。
429guest_cost_exceeded您已達到匿名每 IP 或全域每日費用上限(成本較高的工具會更快耗盡這個額度)。
202成功 — { ticket_id, status: "QUEUED" }。請以與其他呼叫相同的方式輪詢結果。

注意: 在這條路徑上,您的 inputs 在呼叫被接受之前不會依照工具的 schema 進行檢查 — 缺少 必填欄位或值無效並不會讓您拿到 400。而是這次執行本身會失敗,您會在輪詢結果時看到這個結果。當您 取得 API 金鑰之後,請改用下方的已認證路徑,它會在事前就進行驗證。

使用 API 金鑰或 session token 呼叫

可呼叫您有權限使用的所有工具。

狀態碼錯誤代碼意義
401憑證缺漏、無效或已過期。
403app_disabled您的應用程式已被停用。
403org_suspended您的組織已被停權。
403org_pending_deletion您的組織已排定刪除。
403此工具不在您憑證的允許 pipeline 清單中。
403origin_not_allowed您的 Application 設定了 allowed_origins,而請求的 Origin header 與清單中任何一項都不完全相符。只有在您(或您的組織管理員)在 Console 中主動啟用此設定時才會生效 — 從未設定過此項目的 app 不受影響。
400您的 inputs 不符合該工具的要求(缺少必填欄位、值無效,或輸入總量過大)。與匿名路徑不同,這條路徑事前進行驗證。
429rate_limited您送出請求的速度超過每分鐘限制 — 這是每個 org 固定的一分鐘時間窗,而非滑動視窗。因為是固定視窗而非滑動視窗,在分鐘邊界上的爆量請求可能會短暫超過名目上限最多約 2 倍(例如 12:00:59 一波、緊接著 12:01:00 又一波);請採取退避重試,而不要假設有一個精確的上限值。
429quota_exceeded您已達到每月請求配額上限。
429daily_cost_exceeded您已達到每日費用上限 — 這是速度型限制,與下方餘額用盡的情況不同。
402insufficient_credits您組織的 credit 餘額不足以支付這次呼叫。請儲值後再重試。注意:單純的 x-api-key 完全沒有 org wallet,所以在 wallet 模式計費下,即使有餘額,可計費呼叫仍會回傳這個錯誤 — 請改用 session JWT(見 選擇您的認證模式)。
202成功 — { ticket_id, status: "QUEUED" }。請輪詢結果。

若想更深入了解憑證運作方式,以及 401/403/429 認證判斷邏輯,請參見 選擇您的認證 模式。每個工具的輸入、有效值與輸出格式,請參見 工具參考手冊