Developer docs: Authentication
Authentication
Every request carries an API key in the X-API-Key header. Keys belong to your organization, carry explicit scopes and can be limited to one agent.
Create a key
- Sign in as an owner or admin and open Settings → API keys.
- Choose Create key, give it the name of the system that will use it (for example “CRM sync”), and pick its scopes.
- Optionally bind it to one agent and set an expiry date.
- Copy the key. It starts with
bck_and is shown only once; we store only a hash of it. If you lose it, revoke it and create a new one.
Send the key
X-API-Key: bck_0000000000000000000000000000000000000000000000000Check a key with the account endpoint, which every key may call:
curl "https://bookifycall.com/api/v1/external/me" \
-H "X-API-Key: $BOOKIFYCALL_API_KEY"It returns your organization, plan, the key's scopes and your rate limit (reference).
When authentication fails
| Status | Code | Meaning |
|---|---|---|
| 401 | APIKEY_002 | Header missing, or the key is unknown, expired or revoked. |
| 403 | APIKEY_003 | The key lacks a scope this endpoint needs. error.details.required and error.details.granted say which. |
| 403 | PLAN_001 | Your plan does not include API access (Enterprise). |
| 403 | AUTH_006 | An agent-bound key asked for another agent, or for an organization-wide resource. |
{
"success": false,
"message": "API key is missing a required scope",
"error": {
"code": "APIKEY_003",
"message": "API key is missing a required scope",
"details": {
"required": [
"recordings:read"
],
"granted": [
"calls:read"
]
}
},
"meta": {
"timestamp": "2026-10-16T12:00:00.000Z",
"path": "/api/v1/external/calls-history/…/recording"
}
}Scopes
A key can do only what its scopes allow. A key created without choosing scopes is read-only: calls:read, leads:read, appointments:read, agents:read, numbers:read, webhooks:read, compliance:read. Write scopes never include their read counterpart, and recordings:read is separate from calls:read because audio is more sensitive than metadata.
| Scope | Endpoints |
|---|---|
calls:read | |
recordings:read | |
calls:write | |
scheduled_calls:write | |
leads:read | |
appointments:read | |
agents:read | |
agents:write | |
numbers:read | |
numbers:write | |
compliance:read | |
webhooks:read | |
webhooks:write |
Agent-bound keys
Bind a key to one agent when a system should only ever see that agent, for example one location:
- Reads return only that agent's calls, recordings, leads from its calls, appointments, scheduled calls and numbers. Records with no agent (leads you entered by hand) stay visible.
- Another agent's record answers 404, exactly like a record that does not exist.
- Outbound calls use the bound agent by default. Webhook subscriptions, compliance status and creating agents are organization-wide, so a bound key gets
403 AUTH_006there.
Rotate a key
- Create a new key with the same scopes.
- Deploy it to your system and confirm requests succeed (
GET /me). - Revoke the old key in Settings → API keys. Revocation applies to the very next request.
Keys can carry an expiry date (up to five years ahead); an expired key answers 401 APIKEY_002. Settings shows when each key was last used and flags keys whose creator has left the team.