Voizematic API Reference

The Voizematic REST API lives at https://voizematic.ai/api/v1, authenticates with a bearer key issued in the panel, and lets your own systems place calls, manage agents and contacts, read transcripts and receive webhook events. It is the same engine the panel uses; anything you can do here is billed per connected minute from the wallet, exactly as a panel call is.

Docs: Getting started · Configuration · Integrations · API reference · MCP connector · Tutorials · FAQ

How do I authenticate?

Open the gear icon → Global Settings → API Keys and create a key. It starts with vz_live_. Send it on every request:

Authorization: Bearer vz_live_…
Content-Type: application/json

Keys act under your account. Rate limit: 1,000 requests per minute per key; a 429 response carries a Retry-After header. Regenerating the key invalidates the old one immediately.

Which endpoints exist?

MethodPathPurpose
GET/api/v1/agentsList your agents: id, name, type, greeting, system_prompt, voice, phone_number, knowledge_base_ids.
POST/api/v1/agentsCreate an agent: name and system_prompt required; optional greeting, type (outbound/inbound) and voice (professional_male, professional_female, hindi_male). Returns the agent with its numeric id.
PUT/api/v1/agents/:agentIdUpdate an agent's name, system_prompt, greeting, voice or booking_url (see below; null removes it).
POST/api/v1/callsPlace an outbound call now: to_number (E.164), agent_id, optional knowledge_base_id, optional context (≤ 2,000 characters of details for this one call, e.g. cart contents or an order number).
GET/api/v1/callsYour calls, newest first; limit (1–500, default 100) and offset query parameters.
GET/api/v1/calls/:callIdOne call (by the call_id from POST /calls or a call_sid): status, duration, summary, transcript, recording URL.
GET/api/v1/calls/:callId/transcriptThe transcript as text and as speaker turns, with the summary and recording URL.
GET/api/v1/contactsList your contacts.
POST/api/v1/contactsAdd one contact: name and phone (E.164) required; optional email, tags and custom_fields.
POST/api/v1/contacts/bulkAdd up to 1,000 contacts in one request; invalid rows are reported in errors.
GET/api/v1/phone-numbers/availableSearch numbers you can buy: country (ISO code, e.g. IN, US) required; optional type (fixed/mobile for India; local/mobile/toll-free elsewhere), capabilities (e.g. voice,sms), area_code (US) and limit (≤ 50). Each result has its setup_fee_usd and monthly_fee_usd; Indian (+91) numbers also carry setup_fee_inr (₹299) and monthly_fee_inr (₹199), the amounts actually charged.
POST/api/v1/phone-numbersBuy a number from your wallet: phone_number (E.164, from the search) and optional agent_id to assign it straight away. Same price and rules as the dashboard — Indian numbers need approved KYC first (403 compliance_required), and a low wallet returns 400.
GET/api/v1/phone-numbersEvery number on your account: id, phone_number, country, capabilities, status, monthly_fee_usd, next_renewal_at and the agents using it.
GET/api/v1/phone-numbers/:idOne number, by its id or the E.164 number.
PUT / DELETE/api/v1/phone-numbers/:id/agentAssign ({"agent_id": 42}) or unassign an agent. A number takes one outbound and one inbound agent; a second agent of the same type returns 409. DELETE removes every agent from the number, or only ?agent_id=42.
GET / POST/api/v1/webhooksList or register webhook endpoints (also available under Global Settings → API Keys → Webhooks); DELETE /api/v1/webhooks/:id removes one and POST /api/v1/webhooks/:id/test sends a signed test event.

How do I place a call with context?

curl -X POST https://voizematic.ai/api/v1/calls \
  -H "Authorization: Bearer vz_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "to_number": "+919876543210",
    "agent_id": 42,
    "context": "Abandoned cart: 2 × running shoes size 8, ₹4,998. Coupon SAVE10 valid till Friday."
  }'

The call is queued and dialled by the platform's call worker within seconds — except Indian numbers outside 9 AM–9 PM IST, which are held until the window opens (the response then includes deferred_until); the response carries its call_id, which every later webhook event and GET /api/v1/calls/:callId use. The wallet must hold at least $1.00; numbers on your block, opt-out or Do-Not-Call lists, or on a national do-not-call registry, are refused with 403 before anything is queued. The agent receives the context as background for that one call — it is never read out verbatim and is not treated as instructions.

Can the agent book on my own system instead of Google Calendar?

Yes. Set booking_url (HTTPS) on the agent with POST /api/v1/agents or PUT /api/v1/agents/:agentId. The response returns booking_secret once. During a call the agent then POSTs to your URL — signed with X-Voizematic-Signature, an HMAC-SHA256 of the raw body using that secret — and you reply within 8 seconds:

Every request carries agent_id and, when known, call_id, so one URL can serve many businesses. An error, a timeout or a reply without success: true makes the agent tell the caller it could not confirm — it never claims a booking.

What do webhook events look like?

Events: call.created, call.ended, call.failed, call.transcribed and email.requested. email.requested fires when an agent wants to email a caller and your account has no Gmail connected: data has channel (call, whatsapp or telegram), agent_id, call_id, to, subject, body and is_html (plus cc, bcc, attachments), and you send it from your own email system — Voizematic never sends API accounts' email from its own mailbox. With no subscriber the agent gives the caller the details by voice instead. call.failed also fires when a queued call is refused before dialling, with data.reason. Failed deliveries (network error, timeout, 5xx, 408, 429) are retried after 30 s, 2 min and 10 min with the same payload. Each POST carries a JSON body with the event name, timestamp and call data, plus two headers: X-Voizematic-Event (the event name) and X-Voizematic-Signature (an HMAC-SHA256 of the raw body using your webhook secret, so you can verify origin). call.transcribed includes the transcript, summary and recording URL, and every call event carries the call_id returned by POST /api/v1/calls. Endpoints must use HTTPS. Respond with a 2xx status promptly.

Errors

StatusMeaning
401Missing or invalid key.
402Insufficient wallet balance to place the call (the body reports the current balance).
404Agent, call or contact not found under this account.
400Validation failed — to_number (E.164) and numeric agent_id are required; context must be a string (it is truncated to 2,000 characters).
403Call refused before dialling: ACCOUNT_LIMIT (outbound calls off or monthly cap reached), NUMBER_BLOCKED, NUMBER_OPTED_OUT or NUMBER_ON_DNC.
409NO_PHONE_NUMBER — the account has no phone number to call from; get one under Phone Numbers (the free trial line only rings your own phone from the dashboard).
429Rate limit exceeded; wait for the Retry-After seconds.
503The call could not be queued; safe to retry.

Prefer an assistant-driven integration instead of code? See the MCP connector. Code samples in JavaScript and Python are in the panel's API Reference page after sign-in.