API keys
API keys are created and managed in the RelationsAI platform, under Settings → API Keys; the API itself cannot create, rotate or revoke keys. This page covers key types, scopes, expiry, rotation, revocation and how to store keys safely.
Console only Key management happens in the console only.
Who can manage keys
Workspace owners and admins can create, rotate and revoke keys. Other members cannot see the key list; they ask an admin for a key. A key belongs to the workspace it was created in and to the member who created it (see Keys follow their creator's role).
Key types
| Property | Test key | Live key |
|---|---|---|
| Prefix | rai_test_ | rai_live_ |
| Mode | Test mode, "livemode": false | Live mode, "livemode": true |
| Calls | Simulated: never dials anyone | Real calls to real people |
| Charges | Never | Charged to the workspace balance |
| Data | Test-mode objects only | Live objects only |
| Expiry | 30, 90, 180 or 365 days, or never | 30, 90, 180 or 365 days; always expires |
| Browser use | Allowed from browser-based tools | Refused |
A live key sent from browser code is refused with live_key_not_allowed_in_browser. A key is the prefix followed by 40 letters and digits. Build and test with a test key; create a live key only for the system that will place real calls.
Get an API key
You create keys in the RelationsAI platform. You need to be an owner or admin of the workspace.
Sign in to the platform
Go to voice.relationsai.com and sign in to the workspace the key is for.
Create the key
Select Create API key, then:
- Name the key after the system that will use it, for example
CRM sync, so you know what breaks if you revoke it. Names are 1 to 64 characters. - Choose the Environment: Test to build and try things for free, Live for real calls.
- Choose the Permissions (scopes). Read scopes are ticked by default; write scopes, such as Place calls (
calls:write), must be added. Scopes your own role cannot grant are shown as unavailable. - Choose when it Expires.
- Select Create API key.
- Name the key after the system that will use it, for example
Copy and store the key
The full key is shown once. Copy it, store it on your server (see Storing keys safely) and confirm that you have stored it. Then send it in the
Authorizationheader:Authorization: Bearer <token>.
If the tab says the API is not yet enabled for your workspace, keys cannot be created yet: email support@relationsai.com to join the preview. The same keys also appear on the API & Developers page, next to webhooks.
After that, the console shows only the key's prefix and last four characters, with its name, environment, permissions, status, who created it and when, its expiry, when and from which address it was last used, and how many requests and errors it had in the last 24 hours.
Check a new key with GET/workspace: api_key in the response shows its id, name, environment, effective scopes and expiry.
Scopes
Grant only what an integration needs. Each operation needs one scope, shown in the API reference for that operation. A request without it fails with insufficient_scope.
| Scope | Allows | Default |
|---|---|---|
workspace:read | Read the workspace, the current key and its limits. | Every key |
agents:read | List and retrieve agents and check their readiness. | Yes |
numbers:read | List and retrieve phone numbers. | Yes |
calls:read | List and retrieve calls, with status, outcome, timing and cost. | Yes |
calls:write | Place outbound calls. Live calls are charged to the workspace. | No |
transcripts:read | Read call transcripts, verbatim. | Yes |
recordings:read | Get short-lived links to call recordings. | Yes |
analysis:read | Read call summaries, extracted fields and goal outcome. | Yes |
campaigns:read | List and retrieve campaigns and their recipients. | Yes |
campaigns:write | Create and edit campaigns, add recipients, and start, pause, resume and stop them. Live campaigns are charged. | No |
contacts:read | List and retrieve contacts, including consent and custom fields. | Yes |
contacts:write | Create, update and delete contacts and record consent. | No |
dnc:read | List and look up do-not-call entries. | Yes |
dnc:write | Add numbers to and remove numbers from the do-not-call list. Removals are audited. | No |
webhooks:read | List and retrieve webhook endpoints and their deliveries. | Yes |
webhooks:write | Create, update, delete and test webhook endpoints, rotate their secrets and retry deliveries. | No |
Some typical sets:
| Integration | Scopes |
|---|---|
| Reporting or BI export | calls:read, transcripts:read, analysis:read, campaigns:read |
| CRM that triggers calls and stores results | agents:read, calls:read, calls:write, transcripts:read, recordings:read, analysis:read |
| Contact and consent sync | contacts:read, contacts:write, dnc:read, dnc:write |
| Campaign scheduler | agents:read, campaigns:read, campaigns:write, contacts:read |
No key can change workspace settings, compliance settings, members, billing, integrations or other keys: those stay in the console.
Keys follow their creator's role
A key's effective scopes are the scopes it was created with, limited to what the member who created it is allowed to do right now. This is checked on every request, so a change takes effect immediately:
- The creator's role is reduced. The key loses the scopes the new role cannot grant. An operation that needs one of them fails with
insufficient_permissions(an operation that needs a scope the key never had still fails withinsufficient_scope).GET /v1/workspaceshows the effective scopes. - The creator leaves the workspace or is blocked. Every request with the key fails with
insufficient_permissions.
Plan for this: when someone who created production keys changes role or leaves, have an admin create replacement keys from an account that will stay, deploy them, then revoke the old ones.
Expiry and rotation
Every live key expires after 30, 90, 180 or 365 days; a test key can also be set to never expire. After the expiry, requests fail with api_key_expired. Rotate before the date: expires_at from GET /v1/workspace tells your monitoring when.
Rotating a key in the console creates a replacement with the same name, scopes and environment, shown once like a new key. You choose how long the old key keeps working:
| Grace period | Use when |
|---|---|
| Immediately | The old key may have leaked. |
| 1 hour | One service, deployed quickly. |
| 24 hours | Several services, or a slower release process. |
| 7 days | Many systems, or teams that deploy weekly. |
During the grace period both keys work and the old one shows as Expiring; afterwards the old key answers api_key_expired. A good rotation:
- Rotate the key in the console with a grace period long enough for your deploy.
- Put the new secret in your secret manager and deploy it everywhere the old key is used.
- Check that requests succeed with the new key (
GET /v1/workspaceshows the newapi_key.id), and that the old key's Last used time in the console stops moving. - Let the grace period run out, or revoke the old key.
The replacement key belongs to the admin who rotates it, so it follows that person's role from then on.
Revoking a key
Revoke a key in the console as soon as it may have leaked or is no longer needed. Revocation is immediate and cannot be undone: the next request with the key fails with api_key_revoked, and recording links the key obtained stop working too. If the key was in use, rotate first (with Immediately if it leaked) so the replacement is ready.
Older keys
Keys that start with sk_live_ were issued before API v1. They predate scopes and test mode, and they keep working where they worked before, but API v1 refuses them with legacy_api_key_not_supported. The console lists them as legacy keys and offers Create a scoped key instead. They cannot be rotated; create a scoped key, move to it, then revoke the old one.
Storing keys safely
- Keep keys in a secret manager or in environment variables set by your deployment, read at runtime. The examples in these docs show
<token>where your key goes. - Never put a key in source control, client-side code, mobile apps, logs, error reports, analytics, URLs, or support emails. Log the key's id (
key_...) or the request id instead. - Use a separate key per system and per environment, so you can rotate or revoke one without touching the others.
- If a key is exposed, rotate it with Immediately, then check its recent use in the console.
More in Security practices.