Authentication
Every request to /api/v1 carries a bearer API key. There is no X-API-Key
header, no OAuth client-credentials flow, and no unauthenticated endpoint.
Authorization: Bearer rk_live_...
Accept: application/jsonCreating a key
Keys are issued from the dashboard, not through the API.
- Select the profile the integration should act on — the profile switcher sits at the top of the dashboard sidebar.
- Open API keys, or go to
/settings/api-keys. - Add an optional label and select Create key.
- Copy the secret.
The secret is shown exactly once
Adeli stores a SHA-256 hash of your key and the first few characters for display. Nothing in the product can recover the plaintext, so if you lose it, delete the key and create another.
Keys look like rk_live_ followed by 43 URL-safe characters. The dashboard
lists them by their prefix, such as rk_live_Ab3dEf9…, so you can tell which
key is which without ever revealing one.
Keys are scoped to one profile
A key is bound to the profile that was selected when it was created, and that binding is permanent. This is the only authorization boundary in the API:
- Reads return only accounts, posts, and messages belonging to that profile.
profileIdis optional on every endpoint that accepts it. Omit it and Adeli uses the key's profile.- Supplying a different
profileIdreturns404 profile_not_found, not403. The API does not confirm whether a profile you cannot reach exists. POST /api/v1/profilesalways returns403 profile_scope_violation. Create profiles in the dashboard, then issue one key per profile.
There are no scopes, roles, or per-endpoint permissions. A key can do everything the API offers, for one profile.
One key per customer
If you serve multiple end customers, give each one its own profile and its own key. A leaked key then exposes one customer rather than all of them, and revoking it does not interrupt anyone else.
Revoking a key
Delete the key from API keys. Revocation is immediate — there is no cache
and no grace period, and the next request with that key returns 401. Deleting
a profile also deletes its keys.
Keep keys on your server
An Adeli key can publish posts and send messages on your customer's behalf. Treat it like a database password.
- Never ship a key in browser JavaScript, a mobile app bundle, or a public repo.
- Never put one in a URL — they end up in logs, proxies, and analytics.
- Call Adeli from your backend and expose only the results to your frontend.
The @adeli/sandbox workspace in the Adeli repository is a working example of
this shape: the browser posts to a small server route, and that route is the only
place the key exists.
Failed authentication
A missing, malformed, or revoked key returns 401 with the standard error
envelope:
{
"error": {
"code": "unauthorized",
"message": "A valid Bearer API key is required"
}
}Check a key quickly with a request that has no side effects:
curl -i "$ADELI_URL/api/v1/profiles" \
-H "Authorization: Bearer $ADELI_API_KEY"See Errors for everything else the API can return.