錯誤
Platform API 失敗使用標準 HTTP 狀態碼。幾乎每次失敗都包含一個穩定的
subcode 字串,用戶端應依此進行分支 — 單獨依賴狀態碼會產生歧義
(403 同時涵蓋 scope、產品、origin、IP 與金鑰類型)。
Envelope
大多數錯誤都會傳回 FastAPI 風格的 detail wrapper:
{ "detail": "<subcode>" }
結構化的 429 payload(map_load_quota_exceeded, b2b_overloaded,
org_overloaded, tile_access_restricted)是位於頂層的扁平物件 —
沒有 detail wrapper:
{ "error": "map_load_quota_exceeded", "meter": "map_loads", "limit": 50000, "used": 50000 }
帶 string-detail 的 429(map-load hard stop)仍保留 wrapper:
{ "detail": "map_load_hard_stop" }
某些非 streaming endpoint 會以 HTTP 200 加 error key 的形式回報失敗 —
最典型的是 POST /chat/control/route。如果只根據
status 分支,就會將它們視為成功。請務必讀取 body。
表格
| 狀態 | Subcode | 含義 | 處理方式 |
|---|---|---|---|
| 401 | (no detail) | 金鑰缺少 / 無效 / 已撤銷 / 已過期 | 檢查金鑰值,並確認未被撤銷。Viewer 不需要金鑰。 |
| 401 | publishable_requires_session | publishable key(kld_pk_…)被當作 direct bearer 傳送 | 透過 SDK 使用,由 SDK 將其交換為 session。 |
| 403 | insufficient_scope | 金鑰有效,但缺少 route 所需 scope | 建立 / 重新建立具有正確 scope(ai / maps / design)的金鑰。 |
| 403 | tier_capability_not_allowed | 已儲存 key 曾經擁有該 capability,但組織目前 tier 已不再允許(通常為 Pro→Free downgrade) | 升級方案,或使用目前 tier 允許的產品。 |
| 403 | origin_required | publishable key 在沒有瀏覽器 Origin 的情況下使用(例如伺服器端) | publishable key 僅限瀏覽器使用。 |
| 403 | session_origin_mismatch | 要求 Origin 不在 key 的 allowlist 中 | 更新 key 的 allowed origins(請參閱 取得 API 金鑰)。 |
| 403 | product_not_allowed | key 不允許用於此產品 | 建立允許該產品的 key(或使用不需要金鑰的 viewer)。 |
| 403 | server_key_in_browser | server key(kld_sk_…)從瀏覽器使用 | server key 僅限伺服器端;也會被 CORS 阻擋。 |
| 403 | ip_not_allowed | server key 從 allowlist 外的 IP 使用 | 更新 key 的 IP allowlist,或從允許的位址呼叫。 |
| 403 | publishable_key_required | SDK session exchange 使用了 publishable key 以外的內容 | 在 session-exchange 步驟使用 kld_pk_… key。 |
| 403 | sessions_disabled | 此 deployment 已停用 session 發放 | 聯絡支援 — 這是運行狀態,不是客戶設定。 |
| 403 | sessions_not_configured | session infrastructure 尚未設定 | 聯絡支援。 |
| 422 | (various) | 要求 body 格式錯誤 | 修正 payload(請參閱 Endpoints)。mint 時,unknown_scope / unknown_product 表示未識別值;publishable_live_requires_origins 表示 live publishable key 在沒有 allowed origins 的情況下被 mint。 |
| 429 | (flat) map_load_quota_exceeded | 組織每月 map-loads 配額已用盡 | 升級方案或減少底圖載入。 |
| 429 | map_load_hard_stop | 付費組織超過 map-loads 配額 5× | 此處停止服務;配額以上的 soft band 在達到該點前仍可運作。 |
| 429 | (flat) tile_access_restricted | Tile 要求被拒絕(通常是 origin allowlist 不符)。包含 Retry-After: 3600 | 將頁面 origin 加入 key allowlist;在 header 指定時間後重試。 |
| 429 | (flat) b2b_overloaded | 全域 request-shedding 已啟用 | 降低要求頻率,並加入 jitter 後重試。 |
| 429 | (flat) org_overloaded | 組織層級 shedding | 降低要求頻率並重試。 |
| 429 | limiter_unavailable | rate limiter 暫時無法存取 | 視為暫時性問題並重試。 |
| 429 | rate_limited | 目前要求過多 | 遵循 Retry-After。 |
| 503 | (no detail) | 金鑰服務暫時無法使用 | 暫時性問題 — 稍後重試。 |
金鑰管理
來自 POST/PATCH/DELETE /shared-api/api-keys/* 的失敗(使用 Cognito org-admin
JWT,而不是 platform key):
| 狀態 | Subcode | 含義 |
|---|---|---|
| 403 | free_plan_publishable_only | Free-tier 組織只能建立 publishable key。 |
| 403 | plan_required | 組織沒有可識別的 API plan 記錄。 |
| 403 | tier_capability_not_allowed | PATCH 嘗試將 key 擴展到組織目前 tier admission 之外。 |
| 403 | vendor_scope_requires_acknowledgement | vendor scope 需要每個 key 明確設定 acknowledgement flag。 |
| 409 | key_limit_reached | 組織已達到其方案允許的每組織 key 數量上限。 |
完整的 mint 流程與 PATCH 更新路徑請參閱 取得 API 金鑰。
Streaming 錯誤
在 SSE stream 中,終止性失敗會以 error event 的形式出現,而不是
HTTP status(因為 response 已經以 200 開始):
event: error
data: { "type":"error", "message":"…", "code":"…", "partial_text":"…" }
將 error event 視為該 stream 的結束。stream 中途出現的 quota
event 不是錯誤 — 它只是告訴您還剩多少 budget 的 meter。
用戶端必須忽略未知 event name — 在穩定 contract 內可以不升級版本就
加入新 event。
瀏覽器中的 CORS "blocked"
如果瀏覽器在真實要求中回報 CORS block,則要求 Origin
不在 key allowlist 中 — 這不是 auth failure。請參閱
CORS & allowed origins。