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
| Family | What happened | Retry? |
|---|---|---|
| Authentication | The key was missing, wrong, revoked, or is another gateway's | No — fix the key |
| Rate limit exceeded | The key's request rate was exceeded | Yes — wait, then retry |
| Normalised provider error | The provider rejected or failed the request | Depends on what the provider reported |
| Unsupported parameter | A parameter the provider does not support was sent | No — 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:
{
"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.
