Skip to content
Salyro
Operate

Errors

The families a failure falls into, which of them are worth retrying, and which need something changed before the next attempt.

A gateway that returns failures you cannot tell apart forces every client to write the same blind retry loop. This page describes the failures a Public API consumer can receive, grouped by what you should do about them — which is the only grouping that helps while you are writing the code around a call.

Everything here concerns requests made to the Public API with a Salyro key. Failures from the dashboard or from signing in are a separate matter and are not covered.

The four families

FamilyWhat happenedRetry?
AuthenticationThe key was missing, wrong, revoked, or is another gateway'sNo — fix the key
Rate limit exceededThe key's request rate was exceededYes — wait, then retry
Normalised provider errorThe provider rejected or failed the requestDepends on what the provider reported
Unsupported parameterA parameter the provider does not support was sentNo — change the request

Authentication

The key was not accepted. In practice this is one of four things: it was not sent, it was mistyped, it has been revoked, or it belongs to a different gateway than the one being addressed.

Retrying does not help — an unaccepted key is not accepted on the second attempt either. Revocation in particular is immediate and final, so a key that stopped working after being revoked has to be replaced rather than restored. See API keys.

Rate limit exceeded

Each Salyro API key carries a limit on how quickly it may make requests, and exceeding it causes requests to be rejected until the rate falls back within it. Salyro returns this as a 429.

This is the one family where retrying is the correct response. Wait and try again, backing off rather than retrying immediately — an immediate retry is more traffic against the limit you have just exceeded.

Note what this failure is not: it is a limit on request rate, not on spend. Budgets are not enforced, so no request is ever rejected for cost reasons.

Normalised provider error

The provider itself rejected or failed the request — an invalid request by its rules, a model it would not serve, an outage or an overload on its side.

Salyro normalises these into a consistent shape, so that a failure from Anthropic and a failure from OpenAI reach your code the same way rather than in two provider-specific formats. Without that, the promise of one interface breaks the moment something goes wrong.

Whether to retry depends on what the provider reported: a transient failure on their side is worth another attempt, and a rejection of the request as written is not. The request log records the provider, the model and the status for each request, which is where you establish which of the two it was — see Logs & conversations.

A parameter the provider does not support

You sent a parameter that the target provider does not support. It comes back as an explicit error.

That is a deliberate decision and it is worth stating plainly, because the alternative is common and much worse: silently dropping the unsupported parameter and answering successfully. A caller that asks for structured output and receives a cheerful 200 full of prose has no way to discover what went wrong, and the failure surfaces later, somewhere else, as a parsing error.

Salyro does not drop parameters. If the provider will not honour something you sent, you are told so, and the fix is to change the request or to send it to a model that supports it.

The shape of a failure

Every failure carries the same body, and reading it in the right order is what turns a failure into an action:

JSON
{
  "error": {
    "message": "Incorrect API key provided.",
    "type": "authentication_error",
    "code": "invalid_api_key",
    "param": null
  }
}

type is the family, code is the stable identifier for the specific condition and the thing to branch on, and param names the offending field when the failure is about one field. message is written for a person: read it, log it, and do not write logic against it.

The Public API reference sets out the statuses each family arrives with, and Debug a failed request is the ordered path from a failure to its cause.

Where to look

Every failed request appears in the gateway's request log with its status, provider, model and timing, so a failure reported by your code can be matched to the request that produced it. Records are written asynchronously, so a failure from a few seconds ago may take a moment to appear.