API keys
A key is how your code proves who it is: Authorization: Bearer lel_live_.... Every key belongs to the organization, never to a person, and carries a list of scopes (what it may do).
The examples use this client:
Code
Rules that always apply
- No key can create, change, rotate or revoke keys. Keys are managed only from the dashboard, with the session of a person. A key that could mint keys would be the most valuable one to steal, so a person with a login always stands behind that power.
- The secret is shown once, when the key is created or rotated. Lelemon stores only a hash, so a lost secret cannot be recovered: rotate or replace the key.
Choose the scopes
Each scope is written resource:action, such as agents:write or cases:read. GET /v2/scopes lists all of them and the scope catalog says what each one allows. GET /v2/me returns the scopes of the key you are using.
Give a key the scopes of the job and nothing else:
| Job | Scopes |
|---|---|
| A server that only reads conversations | cases:read, contacts:read |
| A chat in your app | contacts:write, cases:read, cases:write, cases:converse |
| A script that configures agents | agents:read, agents:write, pipelines:write, knowledge:write |
| A webhook consumer | webhooks:read, webhooks:write |
Two groups cost money or send your data outside Lelemon, so they are separate scopes: cases:converse writes as the contact, which runs the agent and spends model tokens; actions:write and webhooks:write decide where conversation data goes.
Manage keys in the dashboard
Create, rotate and revoke keys under Settings, Integrations. Rotation issues a new key with the same name, scopes and expiry window, and lets the old secret keep working for a grace period (24 hours by default) so you can deploy without downtime. Revoking stops a key on the next request, even inside that grace period. A revoked key answers 401 api_key_invalid.
If a secret leaked: revoke it first and rotate afterwards. Rotating leaves the old secret working for the grace period.
Allowed sites
A key with actions:write decides where your agents send data, so it must name the sites it may call. A key takes between 1 and 10 addresses, each a valid http or https origin. An action whose URL is on another site answers 403 action_origin_not_allowed.
Keys for subaccounts
A platform acts on a subaccount with its own key and the Lelemon-Subaccount: sub_... header. When your customer needs direct access, issue a key that sees only that subaccount with POST /v2/subaccounts/{id}/api-keys. Its scopes cannot go beyond yours and never include subaccounts:*. It takes expiresInDays (30, 90 or 365) and ignores Idempotency-Key, so the secret is never stored.
More on subaccounts in Run Lelemon for your customers.
Errors you will meet
| Error | Cause |
|---|---|
401 api_key_invalid | The key is missing, wrong or revoked |
403 scope_missing | The key lacks the scope of the route; detail names it |
403 action_origin_not_allowed | An action calls a site that is not in allowedActionOrigins |
400 invalid_request | An unknown scope, or actions:write without allowed sites |
All codes are in the error catalog.
Good practice
- One key per system and per environment, named after it. A leaked key then costs one rotation, not a migration.
- Keep keys on your server. Anyone can read a key shipped in a browser or a mobile app.
- Give each key the scopes of its job, and an expiry when it is for a person or a contractor.
- Rotate on a schedule with a short grace period, and check the last use in the dashboard to confirm the old key went quiet before it expires.
- Never log the secret. The
prefixis enough to find a key.
What's next
- Authentication and scopes for the header and the model.
- Run Lelemon for your customers for subaccounts.