Flash docs

Troubleshooting

Diagnose 401/403/400/413/415/429/5xx, context rejections, wrong transports, interrupted streams, and how to write a useful support request.

Work from the status code, then the response message and your account state. The status narrows the category; it does not by itself identify the exact cause. The API's own errors are JSON — {"error": {"message", "type", "param", "code"}} — but edge infrastructure (a proxy or load balancer) can return its own HTML error page; treat non-JSON bodies as an infrastructure signal.

No access at all

"I don't have Flash." Access is authorized-customer only. Confirm you were onboarded into this environment, and that your key came from the same environment's portal (dev keys never work against production and vice versa). The portal API keys page is where keys live.

401 — authentication required

The request never established a recognized identity. Causes, in order of likelihood:

  1. No Authorization header, or not in Bearer <key> form (e.g. API-Key, or a stray prefix).
  2. The key is unknown to this environment (wrong environment, mistyped, or reissued).
  3. Shell quoting ate the variable. Check it safely, without printing the value: test -n "$TERALOR_API_KEY" && echo set || echo missing. Do not debug with curl -v against an authenticated request — verbose output dumps the Authorization header and exposes the secret.

Recognized-but-unusable keys (revoked, expired) and account/entitlement refusals return 403, not 401. A 401 is never fixed by retrying with the same credential; re-establish the credential.

403 — the key authenticated but can't authorize

The key was recognized but something refuses admission: the key is revoked or expired, the account is not active, a reconciliation hold is open, or no synchronized authority (active legacy grant or paid- through subscription period) covers the request time. Check Portal → Billing and Limits and billing. Unlike a 401, the credential itself was understood — the state around it is what needs to change. After a portal change, allow the state to synchronize; if a refusal persists, file a support request with the metadata below.

400 — your request, precisely

The message names the violation. Common ones and the fix:

  • request contains unsupported fields — remove fields outside the allowed set. SDK defaults (e.g. n, temperature, top_p, response_format, seed) are rejected, not silently ignored.
  • model is not offered — send the exact id discovery lists (Flash); other names fail.
  • max_tokens is outside the configured bound / max_tokens leaves no input room — re-run discovery and re-budget output vs input room (Use Flash well).
  • reasoning_effort is not allowed / think is not allowed — use only advertised values.
  • tools are not available — the current catalog advertises no tool support; drop tools/tool_choice.
  • request body must be valid JSON / must be a JSON object — check quoting/escaping in your shell.

413 / 415 — before parsing even happens

413: the body exceeds the configured byte limit — shrink the payload (excerpt instead of whole files). 415: the Content-Type media type is not application/json (a charset parameter is fine, e.g. application/json; charset=utf-8).

404 — wrong transport, not a temporary failure

The supported inference endpoints are GET /v1/models and POST /v1/chat/completions (API reference). A 404 almost always means the client is speaking a different dialect: SDK responses/beta.messages/embeddings paths, a doubled /v1/v1, or a base URL that already includes /chat/completions. Fix the transport; retrying a 404 forever is not backoff.

429 — slow down, honor the headers

retry-after (when present) and x-ratelimit-* are forwarded by the platform. Reduce in-flight requests, spread bursts, and never treat local throttling as a reservation against your whole account (Limits and billing).

502 / 503 — the platform side

  • 502: upstream/provider failure or an internal fault. A 502 or a broken stream can mean dispatch is uncertain — the request may or may not have run. Do not blindly duplicate-retry: reconcile first (check for partial output or side effects in your harness), then resubmit at most once after a delay as an explicit bounded decision. Persistent 502s are a support case with request metadata.
  • 503: the model is configured but currently unhealthy. Discovery omits unhealthy models, so re-run GET /v1/models to confirm, then wait/retry.

Interrupted streams and uncertain replay

If a streaming response stops mid-flight (connection reset, timeout, client kill), the request's fate is unknown, not failed: it may have been billed for partial work. Do not blindly replay it into a loop. Mark the task uncertain, preserve the partial output as incomplete, and resubmit only as an explicit, bounded decision — ideally after confirming through your harness that the dispatch is finished/cancelled. Idempotent-looking replays of large generations double spend.

Writing a useful support request

Include the safe metadata; exclude everything secret:

  • Include: timestamp (with timezone), HTTP status, the error.message/type text (if the body was JSON), request id if your client captured one, the route and model id, approximate request size, client/tool name and version, and what you expected.
  • Never include: the API key (or any fragment of it), prompt or completion content, session cookies, or internal identifiers you shouldn't be pasting.

A ticket with 403, a timestamp, and "plan upgraded 20 minutes ago, still refusing" is actionable in one reply; a ticket with a pasted key is a second incident.

On this page