LatentKit

Error Handling

Structured JSON errors, streaming error events, and support correlation IDs.

Request correlation

Every response should include X-LK-Request-ID. Log it with failures when opening support tickets or tracing logs.

Typed JSON errors

Gateway failures return a structured JSON envelope with stable machine-readable codes:

{
  "error": {
    "code": "INSUFFICIENT_CREDITS",
    "category": "billing",
    "message": "Insufficient credits for Platform Access. Please top up your balance.",
    "request_id": "req_abc123",
    "retryable": false
  }
}
FieldDescription
error.codeStable programmatic code
error.categoryBroad handling category such as upstream, model_output, auth, or billing
error.messageHuman-readable detail
error.request_idCorrelation ID for request logs and support
error.retryableWhether retrying the same request can reasonably succeed

Top-level code, message, and request_id remain for older SDKs. New integrations should use error.code and error.category.

Common codes

HTTPCodeMeaning
401INVALID_API_KEYFix Authorization header
400 / 422VALIDATION_ERRORFix request body
403POLICY_REJECTEDPolicy guardrail or route eligibility rejected input
402INSUFFICIENT_CREDITSCredits or plan limit
429RATE_LIMITEDRetry after the Retry-After header (always present on 429)
413REQUEST_TOO_LARGERequest body exceeds the edge/app limit; reduce payload size
413AUDIO_TOO_LARGEAudio exceeds the audio byte budget; use audio.url or async jobs
409IDEMPOTENCY_KEY_REUSEDSame Idempotency-Key with a different payload
409IDEMPOTENCY_REPLAY_IN_PROGRESSOriginal request still running; retry shortly
503NO_HEALTHY_PROVIDERSee below — check retryable before backing off
200 / 503TOOL_CALL_NOT_PRODUCEDA tool call was required, but the model returned text

NO_HEALTHY_PROVIDER: configuration vs. transient

A 503 NO_HEALTHY_PROVIDER distinguishes two very different situations — branch on error.retryable:

  • retryable: false + suggested_action: "attach_provider_for_capability" — a configuration state: no provider/route is attached for the required capability. No amount of client retrying fixes this; open the routing policy in the console (the error's detail.dashboard_url_path points there) and attach a provider.
  • retryable: true — providers are attached but currently unhealthy; retry with backoff.

Non-JSON responses never reach you

The API host speaks JSON on every response, including infrastructure failures: the edge normalizes any non-JSON error (proxy error pages, origin-down responses) into this same envelope, and an external synthetic monitor asserts it continuously. If you ever observe an HTML error body from ai.latentkit.com, treat it as a platform bug and report it with the X-LK-Request-ID.

Streaming errors

After SSE starts, terminal failures use:

event: error
data: {"error":{"code":"UPSTREAM_ERROR","category":"upstream","message":"...","request_id":"req_abc123","retryable":true},"code":"UPSTREAM_ERROR"}

Client guidance

  1. Read error.category for generic handling and error.code for precise handling
  2. Retry idempotent requests on transient 5xx with backoff
  3. Do not retry 401, 400, or budget errors without changing inputs or billing state

Upgrade-oriented errors

Some plan-limit responses include fields like upgrade_required and upgrade_to for console-native upgrade flows.

See Error reference for the complete taxonomy and retry guidance.

On this page