API keys and scopes
A secret key is an account key or a workspace key. Each one carries a list of scopes. A missing scope returns 403 with code scope_missing. Create and revoke keys with the auth API. Publishable keys are a separate credential: see Publishable keys.
Which key
| Key | Prefix | Reaches |
|---|---|---|
| Account key | rymi_acct_ | Account routes, and any workspace in the account when you send Rymi-Workspace |
| Workspace key | rymi_ws_ | That workspace. Rymi-Workspace naming another workspace returns 403 workspace_forbidden |
| Legacy secret key | rymi_ | Your existing keys. Rymi treats them as account keys with every scope (legacy: true) |
| Publishable key | sb_publishable_ | Starting calls for one agent. No scopes. Never reaches billing, accounts, members, keys, notification settings or the login (403 publishable_forbidden) |
key_prefix on list responses is the first 16 characters. The raw key is the field key on POST /v1/auth/api-keys, and only on that response.
In Studio, account keys are under Account settings → API keys. Workspace keys are under Settings → API keys. A legacy key is labelled Full access (legacy).
An account key needs an account Owner or Admin. A workspace key needs a workspace Admin, or an account Owner or Admin, and it belongs to the workspace the request is acting in. A secret key cannot create an account key. An Editor's create request returns 403 role_forbidden.
Scopes
A scope is resource:read or resource:write. Send them as scopes on create. There is no billing:write.
Workspace scopes
A workspace key can hold these, and an account key can hold them too.
| Scope | Routes it opens |
|---|---|
agents:read, agents:write | /v1/agents, templates, languages, managed SKUs, share links, API tools. GET /v1/billing/estimate needs agents:read |
calls:read, calls:write | /v1/calls, scheduled callbacks, realtime and WebRTC. calls:write starts calls |
campaigns:read, campaigns:write | /v1/campaigns |
contacts:read, contacts:write | /v1/contacts and /v1/dnc |
knowledge:read, knowledge:write | Knowledge sources on an agent |
numbers:read, numbers:write | /v1/numbers and /v1/telephony |
connections:read, connections:write | Providers, connections, connectors, OAuth, tool secrets, voice providers, MCP servers |
compliance:read, compliance:write | /v1/compliance |
webhooks:read, webhooks:write | /v1/webhooks |
workspace_members:read, workspace_members:write | /v1/workspaces/:id/members |
analytics:read | /v1/analytics, /v1/insights, and GET /v1/workspaces/:id/usage |
Account scopes
An account key can hold these. A workspace key that asks for one gets 400 invalid_scope, and the body names that scope.
| Scope | Routes it opens |
|---|---|
workspaces:read, workspaces:write | Creating and updating workspaces, and GET /v1/accounts/:id/workspaces |
account_members:read, account_members:write | /v1/accounts/:id/members |
keys:read, keys:write | /v1/auth/api-keys and /v1/keys |
billing:read | GET routes under /v1/billing. POST /v1/billing/estimate is a price check and needs agents:read |
GET /v1/auth/me, GET /v1/workspaces, GET /v1/accounts, GET /v1/accounts/:id, and GET /v1/keys/self need no scope.
A route with no declared scope is closed to keys. Keys also cannot use POST /v1/auth/regenerate-key, the /v1/auth/me routes other than GET /v1/auth/me (profile, password, export, account deletion), or notification writes (except legacy keys).
Presets
Studio fills the scope checkboxes from three presets. The API takes the scope strings, not the preset id.
| Preset | Id | Scopes |
|---|---|---|
| Start calls only | start-calls | calls:write, agents:read |
| Read-only reporting | read-only-reporting | calls:read, analytics:read, agents:read |
| Full workspace | full-workspace | Every workspace scope listed above |
Billing writes are closed
Secret keys, including legacy rymi_ keys, can no longer call billing writes. Each of these returns 403 scope_missing with required_scope set to null:
POST /v1/billing/checkout/startPOST /v1/billing/mandate/registerPOST /v1/billing/reconcilePUT /v1/billing/auto-rechargePUT /v1/billing/extra-usagePUT /v1/billing/alertsPUT /v1/billing/countryDELETE /v1/billing/payment-methods/:id
Billing reads need billing:read. A legacy key still passes those reads. To add credits, top up in Studio under Account → Billing.
Missing scope
{
"error": "Missing scope",
"code": "scope_missing",
"required_scope": "calls:write"
}required_scope is the scope the route needs. It is null when the route is a billing write, or when the route has no declared scope.
GET /v1/keys/self returns { kind, account_id, workspace_id, scopes, legacy } for the key on the request. Node calls rymi.keys.self(). Python calls rymi.keys.self(). See Node and Python. Over MCP, a connection that uses a secret key calls that route once and lists only the tools whose scope the key holds. A legacy key lists every tool. A billing write from that list still returns scope_missing.
Create one
- Decide account or workspace, and copy a preset or tick scopes.
POST /v1/auth/api-keyswithkind,scopes, and an optionallabel(up to 100 characters).- Store
keyfrom the201. List and revoke responses showkey_prefixonly. - To rotate, create the next key, deploy it, confirm
last_used_atmoves, thenDELETE /v1/auth/api-keys/:id.

