API reference
Introduction
Build agents, place calls and read results over HTTPS with JSON. Every endpoint page has code samples and a Try it panel that sends real requests with your key.
Base URL and versions
https://voxa.abhinavyadav.in/api/v1Integrations use the versioned API, /api/v1. It is served by the same code as the console's own/api paths, but only /api/v1 is documented and kept backward compatible. Requests and responses are JSON (Content-Type: application/json) except file uploads and downloads. Money is in paise (₹1 = 100 paise). The full spec is at /openapi.json (OpenAPI 3.1).
Authentication
Send an API key with every request, in either header:
curl https://voxa.abhinavyadav.in/api/v1/agents \
--header 'X-API-Key: vx_your_key'X-API-Key: vx_...orAuthorization: Bearer vx_...: a workspace API key. Create one in the console under Settings, API keys, or with Create an API key. A key acts as a developer in its workspace and can also read billing.Authorization: Bearer vxo_...: the access token of an app connected through OAuth (an MCP client). It acts as the user who connected it, limited to what a key may do. See the MCP server guide.Authorization: Bearer <session token>: a signed-in user, from Sign in. AddX-Workspace-IDto pick a workspace (else the first one). Account endpoints, and actions only an owner or admin may take (members, KYC, top-ups), need a session.
Each endpoint page says what it accepts and which permission it needs. Roles and permissions are in Authentication.
Time zones
Every /api/v1 endpoint takes a time zone: the timezone query parameter or the X-Timezone header, an IANA name such as Asia/Kolkata, UTC or America/New_York. The default is Asia/Kolkata. Every timestamp in the JSON response (fields named at, date, timestamp or ending in _at) is returned in that zone as ISO 8601 with its offset, such as 2026-10-01T15:30:00+05:30. The zone used comes back in the X-Timezone response header; an unknown zone is a400.
Errors
Errors use HTTP status codes and a JSON body with a detail message written for people:
{
"detail": "agent not found"
}Validation errors (422) list each problem, with where it is:
{
"detail": [
{
"type": "string_pattern_mismatch",
"loc": [
"body",
"to"
],
"msg": "String should match pattern '^\\+?[0-9]{8,15}$'",
"input": "12"
}
]
}| Status | Meaning |
|---|---|
400 | The request can't be served as sent: an unknown timezone, no workspace chosen (X-Workspace-ID), or a rule such as "a workspace always needs an owner". |
401 | No credentials, or they're wrong, expired or revoked. The response has WWW-Authenticate: Bearer. |
402 | Out of credits (placing a call). |
403 | Your role or key lacks the permission, or the workspace isn't active yet: then the body also has "code": "workspace_inactive". |
404 | No such resource in your workspace. |
409 | Conflicts with the current state: a duplicate, a limit reached, or KYC already submitted. |
413, 415 | An upload is too large, or not a PDF, PNG or JPG. |
422 | The body or a parameter failed validation (see the shape above), or a setting isn't allowed, such as a provider your workspace can't use. |
429 | Too many requests: over the rate limit, or too many failed sign-ins. |
500 | Our fault. The body has request_id; send it to support. |
502 | A provider (voices, phone numbers) didn't answer. Try again shortly. |
Every response has an X-Request-ID header; include it when you report a problem.
Rate limits
Each API key (and each connected OAuth app) may make 120 requests per minute by default, counted in fixed one-minute windows. Every response to a keyed request carries the state of the window:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per minute. |
X-RateLimit-Remaining | Requests left in this window. |
X-RateLimit-Reset | When the window ends, in Unix seconds. |
Over the limit, the answer is 429 with Retry-After (seconds): wait that long and retry. Session tokens aren't rate limited this way, but sign-in allows 5 failed attempts per address in 5 minutes. Placing calls has its own limit, the workspace's concurrent calls: extra calls wait in the queue (see Get call limits).
Pagination
Long lists page with limit and skip and answer {"items": [...], "total": n}, newest first, wheretotal counts everything that matches the filters:
| Endpoint | limit default, max |
|---|---|
| List calls | 50, 200 |
| List deliveries | 50, 200 |
| List credit changes | 50, 200 |
| List audit events | 50, 200 |
| List server logs | 100, 500 |
Other lists return everything as an array (agents, webhooks, keys, members), or a capped recent window: the last 100 payments, 200 invoices, 50 sessions and 50 limit requests, and an agent's kept versions.
import requests
BASE = "https://voxa.abhinavyadav.in/api/v1"
headers = {"X-API-Key": "vx_your_key"}
skip, calls = 0, []
while True:
page = requests.get(f"{BASE}/calls", headers=headers, params={"limit": 200, "skip": skip}).json()
calls += page["items"]
skip += len(page["items"])
if not page["items"] or skip >= page["total"]:
breakTry it in the browser
Paste a key into an endpoint's Try it panel and press Send. The key stays in this browser tab (sessionStorage) and never appears in the code samples. On this site, requests go through doc.voxa.abhinavyadav.in/api/ to the API, so the browser allows them. Requests are real: creating, changing and deleting do just that.
All endpoints
88 endpoints in 10 groups.
Agents
Create, configure, version and duplicate voice agents.
- GET
/api/v1/agentsList agents - POST
/api/v1/agentsCreate an agent - GET
/api/v1/agents/{agent_id}Get an agent - PUT
/api/v1/agents/{agent_id}Update an agent - DELETE
/api/v1/agents/{agent_id}Delete an agent - POST
/api/v1/agents/{agent_id}/duplicateDuplicate an agent - GET
/api/v1/agents/{agent_id}/versionsList versions - GET
/api/v1/agents/{agent_id}/versions/{version}Get a version - POST
/api/v1/agents/{agent_id}/versions/{version}/restoreRestore a version
Calls
Place outbound calls and read every call's record, timeline and recording.
Webhooks
Endpoints that receive call events, their secrets and the delivery log.
- GET
/api/v1/webhooks/eventsList event types - GET
/api/v1/webhooksList endpoints - POST
/api/v1/webhooksCreate an endpoint - PATCH
/api/v1/webhooks/{endpoint_id}Update an endpoint - DELETE
/api/v1/webhooks/{endpoint_id}Delete an endpoint - POST
/api/v1/webhooks/{endpoint_id}/rotate-secretRotate an endpoint's secret - POST
/api/v1/webhooks/{endpoint_id}/testSend a test event - GET
/api/v1/webhooks/default-secretGet the default secret hint - POST
/api/v1/webhooks/default-secret/rotateRotate the default secret - GET
/api/v1/webhooks/deliveriesList deliveries - GET
/api/v1/webhooks/deliveries/{delivery_id}Get a delivery - POST
/api/v1/webhooks/deliveries/{delivery_id}/retryRetry a delivery
Catalog
Models, languages, voices and providers you can configure an agent with.
Phone numbers
Numbers assigned to your workspace and the agent that answers each.
Tools
Try an HTTP tool before an agent uses it on a call.
Workspace
The workspace, its limits, members, invites, API keys and KYC.
- GET
/api/v1/workspaceGet the workspace - PATCH
/api/v1/workspaceRename the workspace - GET
/api/v1/workspace/limitsGet call limits - GET
/api/v1/workspace/limits/requestsList limit requests - POST
/api/v1/workspace/limits/requestsRequest a higher limit - GET
/api/v1/membersList members - PATCH
/api/v1/members/{user_id}Change a member's role - DELETE
/api/v1/members/{user_id}Remove a member - GET
/api/v1/invitesList invites - POST
/api/v1/invitesInvite a member - DELETE
/api/v1/invites/{invite_id}Revoke an invite - GET
/api/v1/keysList API keys - POST
/api/v1/keysCreate an API key - DELETE
/api/v1/keys/{key_id}Revoke an API key - GET
/api/v1/kycGet KYC - PUT
/api/v1/kycSave KYC details - POST
/api/v1/kyc/documentsUpload a KYC document - GET
/api/v1/kyc/documents/{doc_id}Download a KYC document - DELETE
/api/v1/kyc/documents/{doc_id}Delete a KYC document - POST
/api/v1/kyc/submitSubmit KYC - GET
/api/v1/searchSearch - GET
/api/v1/mastersGet settings lists
Billing
Credits, plan, top-ups, the ledger and invoices.
- GET
/api/v1/billingGet the balance - GET
/api/v1/billing/ledgerList credit changes - GET
/api/v1/billing/paymentsList payments - POST
/api/v1/billing/topupStart a top-up - POST
/api/v1/billing/payments/{payment_id}/completeComplete a payment - GET
/api/v1/billing/planGet the plan - GET
/api/v1/billing/packsList credit packs - GET
/api/v1/billing/invoicesList invoices - GET
/api/v1/billing/invoices/{invoice_id}/pdfDownload an invoice
Observability
Dashboard stats, server logs and the audit log.
Account and sign-in
Sign up, sign in and manage your own user account (session tokens only).
- POST
/api/v1/auth/signupSign up - POST
/api/v1/auth/loginSign in - POST
/api/v1/auth/login/2faSign in with a code - GET
/api/v1/auth/meWho am I - POST
/api/v1/auth/logoutSign out - GET
/api/v1/invites/{token}Get an invite - POST
/api/v1/invites/{token}/acceptAccept an invite - GET
/api/v1/accountGet your account - PATCH
/api/v1/accountUpdate your name - DELETE
/api/v1/accountDelete your account - POST
/api/v1/account/emailChange your email - POST
/api/v1/account/passwordChange your password - GET
/api/v1/account/sessionsList your sessions - DELETE
/api/v1/account/sessions/{session_id}Revoke a session - POST
/api/v1/account/sessions/revoke-othersSign out other sessions - POST
/api/v1/account/2fa/setupStart two-step setup - POST
/api/v1/account/2fa/enableTurn on two-step verification - POST
/api/v1/account/2fa/disableTurn off two-step verification