Authentication
The Voxy API uses bearer-token authentication. A token is scoped to a single workspace and a set of permissions you choose when minting it. New here? Start with the quickstart.
API keys
API keys are 32+ character secrets prefixed with voxy_sk_live_ (production) or voxy_sk_test_ (sandbox). The full secret is shown exactly once at creation time — store it in your secret manager before closing the dialog.
A key is bound to the workspace where it was created. Presenting a workspace-A key to a workspace-B endpoint returns 403 TENANT_MISMATCH.
Header format
Include the secret on every request as a bearer token:
Authorization: Bearer voxy_sk_live_8x4nT2K9P0bW…Cookies are not a supported auth mechanism for the public API — they are reserved for the first-party web client at voxyhq.com.
Scopes
Each key carries an explicit list of scopes — fine-grained permissions like calls:write, contacts:read, webhooks:write. Requesting a handler the key isn't scoped for returns 403 API_KEY_SCOPE_MISSING.
Pick the minimum scope set the integration needs — privilege creep is the single most common cause of incident blast radius.
| Scope | What it unlocks |
|---|---|
calls:read | List, fetch, and pull recording / report URLs for any call in the workspace. |
calls:write | Originate manual + bridged calls, hang up live calls, trigger re-analysis. |
contacts:read | List contacts and fetch the per-contact detail view (calls, leads, notes). |
contacts:write | Create, update, delete contacts. CSV import lands here too. |
campaigns:read | List campaigns and inspect attempt status per contact. |
campaigns:write | Create / update campaigns, start · pause · cancel · resume · archive, attach contacts. |
agents:read | List agents, fetch agent definitions and the composed-prompt preview. |
agents:write | Create, update, delete agents and edit their action sets. |
leads:read | List and fetch AI-extracted leads from completed calls. |
leads:write | Create, update, delete leads. Stage transitions land here. |
phone_numbers:read | List workspace DIDs, fetch per-number configuration. |
webhooks:read | List webhook subscriptions and inspect delivery history. |
webhooks:write | Create, update, delete webhook subscriptions. Rotate signing secrets. |
usage:read | Read per-key usage counters (request count, daily-quota state). |
# A key scoped 'calls:write' + 'contacts:read' is enough for an
# outbound dialer integration.
curl -H "Authorization: Bearer voxy_sk_live_…" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"agentId":"agt_…","to":"+15551234567","from":"+15557654321"}' \
https://voxyhq.com/v1/workspaces/{id}/calls/originate-manualKey rotation
Rotate keys on a schedule you control. The recommended pattern:
- Mint a new key with the same scope set as the old one.
- Deploy the new key to every consumer; verify traffic is flowing via the per-key last-used timestamp.
- Revoke the old key from Settings → API keys. Revocation is immediate and global — the next request with the old secret returns
401 AUTH_INVALID_CREDENTIALS.
Rotate at least every 90 days, immediately on any suspected leak, and whenever an engineer with key access leaves the team.
Security best practices
- Never commit a key to a git repo, paste it into a chat tool, or log it. Voxy redacts bearer tokens in our request log but your stack might not.
- Use a per-environment key (staging vs production) so a leaked sandbox key can't place real calls.
- Bind the key to the smallest scope set you can.
- Treat a leaked key like a leaked password — revoke immediately, audit the request log for unfamiliar activity.
- Combine with per-key rate limits and a daily quota to cap blast radius if a key is compromised.
- Stream error codes into your observability stack so an unexpected spike in
API_KEY_SCOPE_MISSINGorTENANT_MISMATCHpages on-call.