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 輪詢,回應格式與上方 DONE/FAILED 相同,只是
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>"
查詢參數:
| 參數 | 預設值 | 說明 |
|---|---|---|
limit | 50 | 最大 1000。 |
hydrate | true | false 只會回傳 [{ 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)。 |
| 429 | guest_quota_exceeded | 您已達到匿名每 IP 或全域每日請求次數上限。 |
| 429 | guest_cost_exceeded | 您已達到匿名每 IP 或全域每日費用上限(成本較高的工具會更快耗盡這個額度)。 |
| 202 | — | 成功 — { ticket_id, status: "QUEUED" }。請以與其他呼叫相同的方式輪詢結果。 |
注意: 在這條路徑上,您的 inputs 在呼叫被接受之前不會依照工具的 schema 進行檢查 — 缺少
必填欄位或值無效並不會讓您拿到 400。而是這次執行本身會失敗,您會在輪詢結果時看到這個結果。當您
取得 API 金鑰之後,請改用下方的已認證路徑,它會在事前就進行驗證。
使用 API 金鑰或 session token 呼叫
可呼叫您有權限使用的所有工具。
| 狀態碼 | 錯誤代碼 | 意義 |
|---|---|---|
| 401 | — | 憑證缺漏、無效或已過期。 |
| 403 | app_disabled | 您的應用程式已被停用。 |
| 403 | org_suspended | 您的組織已被停權。 |
| 403 | org_pending_deletion | 您的組織已排定刪除。 |
| 403 | — | 此工具不在您憑證的允許 pipeline 清單中。 |
| 403 | origin_not_allowed | 您的 Application 設定了 allowed_origins,而請求的 Origin header 與清單中任何一項都不完全相符。只有在您(或您的組織管理員)在 Console 中主動啟用此設定時才會生效 — 從未設定過此項目的 app 不受影響。 |
| 400 | — | 您的 inputs 不符合該工具的要求(缺少必填欄位、值無效,或輸入總量過大)。與匿名路徑不同,這條路徑會事前進行驗證。 |
| 429 | rate_limited | 您送出請求的速度超過每分鐘限制 — 這是每個 org 固定的一分鐘時間窗,而非滑動視窗。因為是固定視窗而非滑動視窗,在分鐘邊界上的爆量請求可能會短暫超過名目上限最多約 2 倍(例如 12:00:59 一波、緊接著 12:01:00 又一波);請採取退避重試,而不要假設有一個精確的上限值。 |
| 429 | quota_exceeded | 您已達到每月請求配額上限。 |
| 429 | daily_cost_exceeded | 您已達到每日費用上限 — 這是速度型限制,與下方餘額用盡的情況不同。 |
| 402 | insufficient_credits | 您組織的 credit 餘額不足以支付這次呼叫。請儲值後再重試。注意:單純的 x-api-key 完全沒有 org wallet,所以在 wallet 模式計費下,即使有餘額,可計費呼叫仍會回傳這個錯誤 — 請改用 session JWT(見 選擇您的認證模式)。 |
| 202 | — | 成功 — { ticket_id, status: "QUEUED" }。請輪詢結果。 |
若想更深入了解憑證運作方式,以及 401/403/429 認證判斷邏輯,請參見 選擇您的認證 模式。每個工具的輸入、有效值與輸出格式,請參見 工具參考手冊。