Skip to content
Salyro
Get started

Authentication

How a Public API consumer identifies itself, where the key comes from, and what a rejected request tells you.

Salyro has two ways in, and they have nothing to do with each other. People sign in to the dashboard to configure a gateway. Code authenticates to the Public API with a Salyro API key. This page is about the second one.

Keeping them apart matters because they fail differently, they are held in different places, and one is never a fallback for the other. A dashboard session cannot call the Public API, and an API key cannot open the dashboard.

Two separate systems

DashboardPublic API
Who uses itA person, in a browserYour server-side code
Whereapp.salyro.comapi.salyro.com
CredentialYour email and passwordA Salyro API key
ScopeYour whole accountOne gateway
How it is presentedA session, in the browserAuthorization: Bearer on each request

The two are separated at the front door, by which host and which route a request arrives on, and neither path is tried if the other one fails. A request to the Public API with anything other than a valid Salyro API key is rejected — it is never re-checked as if it might be a person signing in.

The key comes from a gateway

A Salyro API key is issued by a gateway, in the dashboard, under that gateway's API Keys. It authenticates as that gateway and reaches that gateway's provider credentials — nothing else.

This is why there is no gateway id in the URL, no X-Gateway header and no project parameter anywhere in the API. The key already says which gateway it is; adding a second way to say the same thing would create a way for the two to disagree.

The full key is shown once, at the moment it is issued. Salyro keeps a one-way hash of it and cannot show it again — see API keys for the lifecycle around that, including how to replace one without downtime.

Sending the key

A standard bearer token on every request:

HTTP
POST /v1/chat/completions HTTP/1.1
Host: api.salyro.com
Authorization: Bearer sk-sly-...
Content-Type: application/json

Every Salyro key starts with sk-sly-. The marker is there so that a key found in a log, a screenshot or a public repository is identifiable as Salyro's at a glance, which is what makes a leak reportable at all.

In practice you set it once and never write it in a request again:

Shell
export SALYRO_API_KEY="sk-sly-..."

curl https://api.salyro.com/v1/models \
  -H "Authorization: Bearer $SALYRO_API_KEY"

Where to keep it

A Salyro key carries the authority to spend against your provider accounts. Treat it as you would the provider key it stands in for:

  • In an environment variable or a secret store on the server. Not in source control, and not in a configuration file that is committed.
  • Never in browser code, a mobile app, or anything else shipped to a user. A key in a client is a published key, and no amount of obfuscation changes that.
  • One key per environment, so that revoking or rotating one does not disturb the others.

When a key is rejected

An unaccepted key produces 401 with an OpenAI-shaped body:

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

There are only a few ways to arrive here, and all of them are the same kind of problem:

  1. The header was not sent, or not in this form

    The value must be Bearer followed by the key. A bare key with no Bearer prefix, or the key in a different header, is a missing key.

  2. The key is mistyped or truncated

    Usually a copy that lost characters, or a shell that ate part of it. Check that the value starts with sk-sly- and that nothing wrapped it in quotes that ended up inside the string.

  3. The key has been revoked

    Revocation is immediate and final. A key that stopped working after being revoked cannot be restored — issue a new one.

  4. It is the right key for a different gateway

    Keys do not span gateways. A staging key against a production gateway is not a permissions problem to be granted; it is the wrong key.

A provider failure is not an authentication failure

The two credentials in play are easy to confuse when something breaks, so it is worth stating which is which.

Your Salyro key authenticates you to Salyro. Your provider credentials are what the gateway uses to call OpenAI, Anthropic, Gemini or Grok on your behalf. They fail separately and they mean different things:

  • A rejected Salyro key is a 401 from Salyro. Nothing was sent to a provider, and nothing was spent.
  • A provider that rejects the gateway's credential — expired, revoked at the provider, out of quota — is a provider failure. It is reported as one, with the provider's condition normalised into the error body, and it is not a 401.

The distinction is what tells you where to go: the first is fixed in your own configuration, the second in the gateway's provider credentials.

Rotating a key

Because revocation takes effect at once, the order matters when the key is in use: issue the replacement, deploy it, confirm requests are succeeding, and only then revoke the old one. A gateway can hold more than one active key, which is what makes that overlap possible.

The exception is a key you believe is exposed — there the interruption is the cheaper cost. Respond to a leaked API key is that case as a procedure.