Skip to content
VoxaDocs
Navigation
Open console →

Account

Authentication

Your code authenticates to Voxa with an API key, and this page covers keys, roles and permissions, rate limits, time zones and errors: the conventions every endpoint follows.

API conventions

Base URLhttps://voxa.abhinavyadav.in/api/v1
FormatJSON in and out (Content-Type: application/json)
AuthenticationAn API key in X-API-Key or Authorization: Bearer
Time zone?timezone= or X-Timezone; India time by default
MoneyIntegers in paise: 50000 is ₹500.00
Phone numbersE.164, for example +919812345678
Ids32-character hex strings (webhook ids have a prefix: we_, whd_, evt_)

Versioning

The public API is versioned in the path: every endpoint is served under /api/v1. Build integrations on /api/v1 only. The console uses unversioned /api/... paths that can change with it; /api/v1 stays stable.

The full list of endpoints is in the API reference.

API keys

Create a key in the console under API keys. You need the owner, admin or developer role.

  • A key looks like vx_... and is shown once. Voxa stores only a hash of it.
  • A key belongs to one workspace. It never needs the X-Workspace-ID header.
  • A key can do what a developer can, and also read the balance and billing (see the table below).
  • Revoking a key (in the console, or DELETE /api/v1/keys/{id}) stops it at once.

Send the key in either header:

curl https://voxa.abhinavyadav.in/api/v1/agents -H "X-API-Key: $VOXA_API_KEY"

curl https://voxa.abhinavyadav.in/api/v1/agents -H "Authorization: Bearer $VOXA_API_KEY"

Keys can also be managed through the API: GET /api/v1/keys lists them (name, prefix, who created it, when it was last used), POST /api/v1/keys with {"name": "..."} creates one and returns key once.

Keep keys on your server. Anyone with a key can place calls that spend your credits.

Apps connected through the MCP server’s OAuth flow use access tokens that start with vxo_, sent as Authorization: Bearer. See MCP server.

Roles and permissions

Every member of a workspace has one role. Each role is a fixed set of permissions, and each endpoint asks for one permission.

PermissionWhat it allowsViewerDeveloperAdminOwnerAPI key
agents.viewRead agents, versions, numbers, catalogs, limitsYesYesYesYesYes
calls.viewRead calls, timelines, recordingsYesYesYesYesYes
logs.viewRead the workspace’s logsYesYesYesYesYes
members.viewRead the member listYesYesYesYesYes
agents.editCreate, change, duplicate, delete and restore agents; test toolsYesYesYesYes
calls.placePlace, cancel and end calls; browser callsYesYesYesYes
keys.manageAPI keys and webhooksYesYesYesYes
billing.viewBalance, ledger, plan, invoicesYesYesYes
audit.viewThe audit logYesYes
numbers.manageConnect phone numbers to agentsYesYes
members.manageInvite and remove members; ask for higher limitsYesYes
billing.manageTop up creditsYes
kyc.manageBusiness details (KYC)Yes

A request without the permission gets 403 with your role cannot do this (<permission>).

Workspace status

A new workspace starts in onboarding: it submits its business details and waits for approval. Until the workspace is active, most endpoints return:

{"detail": "workspace not active", "code": "workspace_inactive"}

with status 403. Billing, limits and onboarding endpoints work before activation.

Rate limits

Each API key may make a set number of requests per minute: 120 by default (the platform sets it). The window is a fixed calendar minute. Keyed responses carry:

HeaderMeaning
X-RateLimit-LimitRequests allowed per minute.
X-RateLimit-RemainingRequests left in this minute.
X-RateLimit-ResetUnix time (seconds) when the current window ends.

Over the limit, you get 429 with {"detail": "rate limit exceeded; slow down"} and a Retry-After header in seconds. Wait that long and try again.

Time zones

Every /api/v1 endpoint returns timestamps in one time zone. Choose it per request with the timezone query parameter or the X-Timezone header, using an IANA name. The default is Asia/Kolkata.

curl "https://voxa.abhinavyadav.in/api/v1/calls/$CALL_ID?timezone=UTC" -H "X-API-Key: $VOXA_API_KEY"
curl https://voxa.abhinavyadav.in/api/v1/calls/$CALL_ID -H "X-API-Key: $VOXA_API_KEY" -H "X-Timezone: Europe/London"
  • Fields named at, date or timestamp, or ending in _at (created_at, ended_at…), come back as ISO 8601 with the zone’s offset: 2026-10-01T15:30:00+05:30.
  • The zone used is echoed in the X-Timezone response header.
  • An unknown zone returns 400 with {"detail": "unknown timezone 'Mars/Base': use an IANA name such as Asia/Kolkata or UTC"}.
  • Webhook payloads are always in UTC.
  • When sending times, include an offset or use UTC.

Errors

Errors are JSON with a detail field:

{"detail": "agent not found"}
StatusMeaning
400The request can’t be carried out as asked, for example no caller number, or an unknown time zone.
401No key, or the key is invalid or revoked: sign in required.
402Out of credits.
403Your role lacks the permission, or the workspace isn’t active ("code": "workspace_inactive").
404Not found, or not in your workspace.
409Conflicts with the current state, for example a plan limit, or a number used by another workspace.
422Validation failed. detail lists each problem with its field.
429Rate limited.
502A provider (Plivo, Cartesia) didn’t answer. Try again.
500Server error. The body has request_id: quote it when you contact support.

A 422 from validation looks like this:

{
  "detail": [
    {"type": "less_than_equal", "loc": ["body", "call", "max_duration_seconds"], "msg": "Input should be less than or equal to 3600", "input": 7200}
  ]
}

Every response has an X-Request-ID header. It also identifies the request in your workspace’s logs in the console.

Esc