Skip to Content

API errors and how to handle them

This page lets you write error handling once and get it right. At the end you will have a copy-pasteable handler that distinguishes a bad key from an empty wallet from a rate limit, and know which failures are worth retrying.

The error envelope

Errors raised by the SynapseX API itself — a bad key, an empty wallet, a missing scope, a malformed body — use the OpenAI-style envelope:

{"error":{"message":"…","type":"…"}}

Not every error body has that shape. When the failure comes from the model gateway behind the API — a refused model id, a rate limit — the gateway’s own response is forwarded to you verbatim, with its original status code and a body shaped {"detail": "…"} instead. Branch your error handling on the HTTP status code, and read error.message when it is present, falling back to detail.

The type values raised by the API itself on /chat/completions and /models are:

typeHTTP statusMeaning
authentication_error401The key is missing, malformed, invalid or expired
insufficient_quota402The workspace has no credits
permission_error403The key lacks the chat:write scope
invalid_request_error400The request body is missing something required
server_error502 / 503SynapseX or an upstream service failed

400 — invalid request

{"error":{"message":"model and messages are required","type":"invalid_request_error"}}

Both model and messages are mandatory. Fix the request body; retrying will not help.

401 — invalid or expired key

Two distinct bodies, both HTTP 401. With no Authorization header, or a header that does not start with Bearer sk-synapsex-:

{"error":{"message":"Missing or invalid API key","type":"authentication_error"}}

With a well-formed but unrecognised or expired key:

{"error":{"message":"Invalid or expired API key","type":"authentication_error"}}

Fix: check that the header includes the literal Bearer prefix and the full sk-synapsex- key, and that the key has not been deleted in the console. A key is shown only once at creation, so if it was lost it must be replaced, not recovered. See Authentication.

402 — insufficient credits

{"error":{"message":"Insufficient credits","type":"insufficient_quota"}}

This is checked as part of authentication, before any model runs — you are not charged for the failed request, and no partial output is produced.

Fix: top up the workspace balance. See Credits and spending. Do not retry a 402 in a loop; nothing about retrying changes the balance.

403 — permission denied

{"error":{"message":"API key does not have chat:write scope","type":"permission_error"}}

Fix: create a key with the default scope set, which includes chat:write.

A 403 can also mean the model you asked for is not available to API keys. In that case the refusal names the model rather than the scope, and it lists the ids that are available. Fix: read those ids out of the error message and use one of them.

Do not fix this by re-reading GET /api/v1/models — that endpoint returns the whole catalog and is not filtered to what your key may call, so the id you were just refused is still in it. See Models.

429 — rate limited

Fix: back off exponentially with jitter and cap the number of retries, so a sustained limit does not become an infinite loop.

Do not build against a Retry-After header on this API — the response your client receives does not carry one. The only SynapseX header this API adds is X-SynapseX-Request-Id, and only on /chat/completions responses that reached the model gateway.

Specific per-key request or token limits are not published either, and you should not build against a number you inferred from observation. Treat 429 as “slow down”, not as a value you can read.

5xx and upstream failures

server_error with 502 or 503 means SynapseX or an upstream model service failed or is unconfigured. These are the only errors worth retrying blindly: retry with exponential backoff, a few times at most.

If the failing response carries an X-SynapseX-Request-Id header, keep it and include it when you report the problem — it identifies the exact request. A 502 or 503 raised by SynapseX before your request reached the model gateway does not carry one.

Python error handling with the SDK

The Python SDK raises a typed exception per status:

from synapsex_platform import ( LLMClient, AuthenticationError, InsufficientCreditsError, PermissionDeniedError, RateLimitError, APIError, ) client = LLMClient() # reads SYNAPSEX_API_KEY try: response = client.chat_completions( model="synapsex-forge-code-14b-v1", messages=[{"role": "user", "content": "Hello!"}], ) print(response["choices"][0]["message"]["content"]) except AuthenticationError: raise SystemExit("Check SYNAPSEX_API_KEY - the key is missing or invalid.") except InsufficientCreditsError: raise SystemExit("Out of credits. Top up the workspace before retrying.") except PermissionDeniedError as exc: raise SystemExit(f"Not permitted: {exc}. Check the key scope and the model id.") except RateLimitError: ... # back off and retry except APIError as exc: # Any other non-success status. exc.status_code and exc.payload are set. raise SystemExit(f"Request failed ({exc.status_code}): {exc}")

AuthenticationError, InsufficientCreditsError, PermissionDeniedError and RateLimitError all subclass APIError, so catch the specific ones first.

The same handling with the stock OpenAI client

If you use the openai package instead, branch on the status code:

import openai try: response = client.chat.completions.create( model="synapsex-forge-code-14b-v1", messages=[{"role": "user", "content": "Hello!"}], ) except openai.APIStatusError as exc: if exc.status_code == 401: raise SystemExit("Invalid SynapseX API key.") if exc.status_code == 402: raise SystemExit("Out of SynapseX credits.") if exc.status_code == 403: raise SystemExit("Missing chat:write scope, or the model is unavailable.") if exc.status_code == 429: ... # back off and retry raise

Troubleshooting table

SymptomMost likely causeAction
401 on every callMissing Bearer prefix, or the key was deletedRe-check the header; create a new key
Worked yesterday, 401 todayKey deleted or rotatedIssue a new key and redeploy
402 immediately, no outputWorkspace balance at or below zeroAdd credits
403 mentioning scopeKey created without chat:writeCreate a new key with the default scope
403 mentioning the modelModel not available to API keysUse one of the ids listed in the error message itself
400 model and messages are requiredBody missing a required fieldSend both model and messages
Parameter appears ignoredThe field is not forwarded by the APISee the supported field list in Chat completions
429 burstsSending too fastBack off exponentially with jitter; there is no Retry-After header to read
Intermittent 502 / 503Upstream failureRetry with backoff; report with X-SynapseX-Request-Id