Authenticate with an API key
How a request says who it is — the API key, the one project the key acts in, and the scopes that say what it may do.
3 min read
Every request to the API carries an API key. The key says which project the request acts in and what it may do there.
The key
Send the key in the Authorization header, after the word Bearer.
Authorization: Bearer sl_live_…A key starts with sl_live_. A key issued before the prefix became sl_live_ starts with sg_live_ and keeps working. You see it once, when it is issued or rotated, because Slen stores only a hash of it. Keys are issued on the keys page — Manage API keys walks through it.
Keep the key where your server keeps its secrets. Do not put it into code that runs in a browser or on a customer's device.
The examples of this reference read the key from the SLEN_API_KEY environment variable.
curl https://api.slen.ai/api/v1/models \
-H "Authorization: Bearer $SLEN_API_KEY"{
"data": [
{
"model_code": "gpt-4o-mini",
"provider": "openai",
"model_price_id": "1108",
"input_price_per_million": "0.15000000",
"output_price_per_million": "0.60000000",
"cached_input_price_per_million": "0.07500000",
"max_output_tokens": 16384,
"currency": "USD",
"effective_from": "2026-01-01T00:00:00+00:00",
"effective_to": null
}
]
}The two probes, /health and /ready, are the only paths that take no key.
What a key reaches
A key belongs to one project of one organization, and it acts in that project only.
What the key creates is created in its project. A list answers with the rows of its project.
A row of another project, or of another organization, answers
404— exactly as a row that does not exist.What an organization shares between its projects can be read with the key and cannot be changed with it. An attempt answers
403with the codeproject_access_restricted.
A service that works with two projects needs two keys.
Scopes
A key carries one or more scopes. Every operation that takes a key requires one scope, and the page of a resource names it for each operation.
| Scope | Also grants |
|---|---|
read | — |
gateway:write | read |
management:read | customers:read |
management:write | management:read, flows:write, customers:read, customers:write |
flows:write | management:read, customers:read |
customers:read | — |
customers:write | customers:read |
| Scope | What it is for |
|---|---|
read | Read what the project did — operations, executions, authorizations, the ledger, analytics, the model catalogue |
gateway:write | Send requests that may spend — run a flow |
management:read | Read the configuration — flows, provider connections and pools, customers and their credits |
management:write | Change the configuration and the budgets, top up and adjust customers' credits, approve or reject what waits for a decision |
flows:write | Create, edit and publish flows |
customers:read | Read your customers, their credit accounts and statements, and the credit prices |
customers:write | Create, top up, charge, adjust, block and delete your customers, and change the settings of their accounts |
Some scopes include others, and the first table lists everything each one includes. management:write includes management:read, flows:write, customers:write and customers:read. It does not include read, so a key that carries management:write alone cannot call an operation that requires read.
Give a key the scopes its service needs and no more. A service that only sends requests needs gateway:write. An application that also keeps its customers — adds them, tops them up, charges and blocks them — needs gateway:write and customers:write, and changes nothing else with them.
When a request is refused
401with the codeinvalid_api_key— the request has no key, the key does not exist, or it was revoked. A rotated key answers the same to its old secret.403with the codeinsufficient_scope— the key is valid and does not carry the scope the operation requires.error.messagenames the missing scope.403with the codeproject_access_restricted— the key tried to change something that belongs to the whole organization.
The envelope of an error is described in Overview, and every code in Error codes.
Built from openapi b070e1f, sdk contract 6a2e0e0, php 4089db3, node 0fa87be