Skip to main content

Authentication

The Voka public API uses bearer API keys in the Authorization header.

Authorization: Bearer voka_live_<random>

Key format

PrefixModeWhere to use
voka_live_…LiveReal calls, production wrappers
voka_test_…Test (coming soon)Sandbox / development

The first 12 characters (voka_live_X) are the prefix — safe to display in your own logs and dashboards. The full key is irreversibly hashed at rest; we never store it in cleartext and cannot recover it if you lose it.

Where to mint keys

In the Voka dashboard: Integrations → API Keys → Create new key.

You'll be shown the full key value once. Copy it immediately — we cannot show it again. If you lose it, rotate (creates a new value) or revoke (disables the old value).

Permission scopes

Each key gets a set of named scopes. Routes 403 when a key lacks the required scope. Adding new scopes to an existing key takes effect immediately.

ScopeEndpoints / events it authorizes
read_assistantsGET /api/v1/assistants
read_callsGET /api/v1/calls, GET /api/v1/calls/{id}, GET /api/v1/calls/{id}/transcript
read_analyticsGET /api/v1/outbound-calls/{id}/transcript
outbound_callsPOST /api/v1/outbound-calls
manage_webhooksPOST / GET / DELETE /api/v1/webhook-subscriptions, secret rotation
send_sms (coming soon)POST /api/v1/sms/send

The marketplace integration preset in the dashboard pre-checks read_assistants + read_calls + manage_webhooks — the minimum that a typical Zapier / n8n / Make wrapper needs.

Connection-test endpoint

Every wrapper validates the saved connection by calling:

GET /api/v1/auth/whoami

This requires NO scope (any valid key works). Returns the customer identity + the scopes the key actually has, so the wrapper can branch its UI based on what's enabled.

curl https://voice.vokaai.com/api/v1/auth/whoami \
-H "Authorization: Bearer voka_live_..."
{
"customer_id": "0bf91...",
"customer_name": "Acme Dental",
"mode": "live",
"permissions": { "read_calls": true, "manage_webhooks": true, ... }
}

Failure modes

All auth failures return RFC 9457 problem details with a stable code:

StatusCodeMeaning
401auth.missingNo Authorization header at all
401auth.invalidToken doesn't match the voka_live_… format
401auth.revokedKey was disabled in the dashboard
401auth.expiredKey passed its expires_at
403perm.deniedKey is valid but lacks the scope this endpoint requires

Failed authentication attempts are logged for security monitoring. Repeated failures from a single IP or against a single key prefix may be rate-limited or blocked.

Rotation and revocation

  • Rotate — generates a new value for the same key id; old value invalid after a short grace period (recommended for normal credential hygiene).
  • Revoke — sets the key to inactive immediately; cannot be undone (use this if you suspect compromise).

Both flows are in Integrations → API Keys in the dashboard. Wrapper integrations should detect auth.revoked and prompt the customer to re-authenticate.

Security notes

  • HTTPS only. HTTP requests are rejected.
  • Never put the key in a URL query parameter — it ends up in logs and Referer headers. Always use Authorization: Bearer.
  • Production API traffic is restricted to a defined set of regions. If your wrapper hosts outside North America, contact support to confirm coverage.
  • Outbound calling has per-key daily spend limits and country allowlists configurable in the dashboard, so a leaked key has bounded financial blast radius.