Skip to content
VoxaDocs
Navigation
Open console →

Calls

Outbound calls

You place an outbound call with one request; Voxa queues it, dials it when a call slot is free and the agent's calling hours are open, and records everything that happens.

Place a call

POST /api/v1/agents/{agent_id}/call needs the calls.place permission.

curl -X POST https://voxa.abhinavyadav.in/api/v1/agents/$AGENT_ID/call \
  -H "X-API-Key: $VOXA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+919812345678",
    "from_number": "+918035001234",
    "user_data": {"customer_name": "Rohan", "slot": "11 am", "order_id": "ORD-5531"},
    "ignore_call_window": false
  }'

201 Created:

{"call_id": "00b1d622a8f04f4f8f3a3c2d9e5b7a11", "status": "queued", "position": 3}

position is the call’s place in your workspace’s queue, counting itself: 1 means no other call is waiting ahead of it.

Request body

FieldTypeDefaultAllowedWhat it does
tostringrequired8 to 15 digits, optional leading +The number to call. Voxa adds the + if you leave it out, so include the country code (919812345678 for India).
from_numberstring""same format, or emptyThe caller ID. Falls back to the agent’s phone_number.
user_dataobject{}any JSON objectFills the agent’s {variables} and is sent to your tools.
ignore_call_windowbooleanfalseDial even outside the agent’s calling hours.

Caller ID

The call is placed from from_number if you send it, otherwise from the agent’s phone_number. If neither is set, you get 400 no caller number: give this agent a Plivo number, or pass from_number.

Use a number assigned to your workspace (see Phone numbers in the console, or GET /api/v1/numbers).

User data

user_data is a free-form JSON object saved on the call. Voxa uses it in three places:

  1. Variables. Each key fills the matching {variable} in the welcome message and prompt. See Variables.
  2. Tools. It is sent to your tools as _call.user_data in every POST tool request. See Tools.
  3. The call record. It comes back as user_data on the call and in webhooks, so you can match the call to your own records.

Keys the agent doesn’t use are kept anyway. Put your own ids (order_id, customer_id) here.

{caller_phone} is filled automatically with to; you don’t need to send it.

What happens next

  1. The call is saved as queued and a call.queued event is sent with its position. If it is outside the calling window, the event message says it is waiting for it.
  2. The worker takes the oldest queued calls while your workspace has free call slots. See The queue.
  3. When a slot is free (and credits and calling hours allow), the call moves to ringing and a call.dequeued event records how long it waited. Then Voxa asks Plivo to dial, and sends call.placed.
  4. When the person answers, the call becomes in-progress and call.started is sent.
  5. If nobody answers, the call ends as no-answer, busy, failed or canceled, with Plivo’s hang-up cause in hangup_reason.

Plivo is told to drop the call 30 seconds after the agent’s max_duration_seconds, as a safety net behind Voxa’s own limit.

Cancel or hang up

POST /api/v1/calls/{id}/hangup cancels a queued call or ends a live one. It needs calls.place.

curl -X POST https://voxa.abhinavyadav.in/api/v1/calls/$CALL_ID/hangup -H "X-API-Key: $VOXA_API_KEY"
{"ended": true}
Call statusResult
queuedcanceled, with hangup_by: "api" and hangup_reason: "canceled from the console". Never dialled, never charged.
ringingThe record is closed as completed, with hangup_by: "api", and is not charged. The phone may keep ringing briefly; if the person answers, Voxa hangs up straight away.
in-progressThe agent stops at once and the call ends as completed, with hangup_by: "api" and hangup_reason: "ended from the console". It is charged for the time it ran.
Already endedNothing changes.

Placing many calls

To call a list of contacts, upload it as a batch: Voxa schedules the calls, retries the people it didn’t reach and gives you the results as a CSV. Or send one request per number. Every call goes into the same queue, so you can send them all at once and Voxa dials them as slots free up, oldest first.

  • Mind the rate limit: 120 requests per minute per key by default.
  • Each request checks your balance; when it reaches ₹0, new requests get 402, and calls still queued fail with out of credits when their turn comes.
  • Queued calls expire after 24 hours.

Errors

StatusdetailFix
400no caller number: ...Pass from_number or give the agent a phone_number.
402out of credits: add credits in BillingTop up in the console.
403workspace not activeYour workspace isn’t active yet (or was suspended).
404agent not foundCheck the agent id.
422Validation errors, or Plivo is not available to this workspaceCheck to and from_number; ask the Voxa team about provider access.

Find your calls

curl "https://voxa.abhinavyadav.in/api/v1/calls?direction=outbound&status=queued,ringing,in-progress" \
  -H "X-API-Key: $VOXA_API_KEY"

See The call object for every filter.

Esc