Skip to content
VoxaDocs
Navigation
Open console →

Get started

Quickstart

This guide takes you from an empty workspace to a finished phone call with cURL: create an API key, create an agent, place a call, wait for it to end, and read what was said.

Before you start

You need:

  • a Voxa workspace that is active (its business details were approved);
  • credits in the workspace (new workspaces get welcome credits);
  • a phone number assigned to your workspace, for the caller ID of outbound calls. Numbers are listed in the console under Phone numbers. If you have none, ask the Voxa team to assign one.

1. Create an API key

In the console, open API keys and choose Create key. You need the owner, admin or developer role.

The key looks like vx_... and is shown once. Store it in an environment variable:

export VOXA_API_KEY=vx_your_key

Check that it works by reading your balance:

curl https://voxa.abhinavyadav.in/api/v1/billing -H "X-API-Key: $VOXA_API_KEY"
{
  "credits_paise": 50000,
  "price_per_minute_paise": 400,
  "minutes_left": 125.0,
  "low_balance": false,
  "plan_name": "Starter"
}

Amounts are in paise: 50000 is ₹500.00. Authentication covers headers, roles and rate limits.

2. Create an agent

Only name is required; every other setting has a default. This agent greets the caller by name, which it reads from a {customer_name} variable you fill in when you place the call.

curl -X POST https://voxa.abhinavyadav.in/api/v1/agents \
  -H "X-API-Key: $VOXA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Appointment reminder",
    "welcome_message": "Hello {customer_name}, this is City Clinic calling about your appointment tomorrow.",
    "system_prompt": "You work at City Clinic. Confirm whether {customer_name} can come to their appointment tomorrow at {slot}. If not, ask which day suits them.",
    "voice": {"language": "en"},
    "call": {"max_duration_seconds": 300},
    "analytics": {"summarize": true, "extraction_prompt": "confirmed: true if the caller will come, false if not\nnew_day: the day they asked for instead, if any"}
  }'

The response is the full agent, with every default filled in, its id, its version and the variables its text uses:

{
  "id": "1b81a241c0e44f5c9d1f0e2a7c3b9d10",
  "name": "Appointment reminder",
  "version": 1,
  "variables": ["customer_name", "slot"],
  "llm": {"provider": "gemini", "model": "gemini-3.5-flash-lite", "temperature": 0.4, "max_tokens": 300},
  "voice": {"provider": "cartesia", "model": "sonic-3.6", "voice_id": "", "voice_name": "", "language": "en", "speed": 1.0},
  "transcriber": {"provider": "cartesia", "model": "ink-2", "turn_detection": "balanced", "language": "hi", "endpointing_ms": 300, "keyterms": []},
  "call": {"max_duration_seconds": 300, "hangup_after_silence_seconds": 15, "allow_interruptions": true, "...": "..."},
  "analytics": {"summarize": true, "extraction_prompt": "confirmed: true if ..."},
  "tools": [],
  "webhook_url": "",
  "phone_number": "",
  "status": "active",
  "created_at": "2026-10-01T14:42:44.120000+05:30",
  "updated_at": "2026-10-01T14:42:44.120000+05:30",
  "updated_by": "key:backend"
}

Save the id:

export AGENT_ID=1b81a241c0e44f5c9d1f0e2a7c3b9d10

Want to hear the agent before it calls anyone? Open it in the console and choose Test in browser to talk to it from your browser. See Browser calls.

3. Place a call

to is the number to call. from_number is the caller ID; it must be one of your workspace’s numbers. If the agent has a phone_number, you can leave from_number out. user_data fills the agent’s variables.

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"}
  }'
{"call_id": "00b1d622a8f04f4f8f3a3c2d9e5b7a11", "status": "queued", "position": 1}

Every outbound call goes into your workspace’s queue first. Voxa dials it as soon as a call slot is free and the agent’s calling hours (9:00 to 21:00 in Asia/Kolkata by default) are open. To dial outside those hours while testing, add "ignore_call_window": true.

export CALL_ID=00b1d622a8f04f4f8f3a3c2d9e5b7a11

4. Wait for the call to end

Poll the call until its status is one of completed, failed, no-answer, busy or canceled:

while true; do
  STATUS=$(curl -s https://voxa.abhinavyadav.in/api/v1/calls/$CALL_ID \
    -H "X-API-Key: $VOXA_API_KEY" | python3 -c 'import json,sys; print(json.load(sys.stdin)["status"])')
  echo "$STATUS"
  case "$STATUS" in completed|failed|no-answer|busy|canceled) break ;; esac
  sleep 5
done

You will see queued, then ringing, then in-progress, then a final status. Polling is fine for a first try; in production, use webhooks instead and wait for call.completed.

5. Read the transcript

curl https://voxa.abhinavyadav.in/api/v1/calls/$CALL_ID -H "X-API-Key: $VOXA_API_KEY"
{
  "id": "00b1d622a8f04f4f8f3a3c2d9e5b7a11",
  "agent_id": "1b81a241c0e44f5c9d1f0e2a7c3b9d10",
  "agent_name": "Appointment reminder",
  "channel": "phone",
  "direction": "outbound",
  "from_number": "+918035001234",
  "to_number": "+919812345678",
  "status": "completed",
  "user_data": {"customer_name": "Rohan", "slot": "11 am"},
  "transcript": [
    {"role": "assistant", "text": "Hello Rohan, this is City Clinic calling about your appointment tomorrow.", "at": "2026-10-01T14:44:02.410000+05:30", "interrupted": false},
    {"role": "user", "text": "Yes, I'll be there at eleven.", "at": "2026-10-01T14:44:07.950000+05:30", "interrupted": false},
    {"role": "assistant", "text": "Great, we'll see you tomorrow at 11 am. Goodbye!", "at": "2026-10-01T14:44:09.120000+05:30", "interrupted": false}
  ],
  "duration_seconds": 14.2,
  "hangup_by": "agent",
  "hangup_reason": "agent ended the call",
  "cost_paise": 95,
  "summary": "City Clinic called Rohan to confirm tomorrow's 11 am appointment. Rohan confirmed he will come. The agent said goodbye and ended the call.",
  "extracted": {"confirmed": true, "new_day": null},
  "...": "..."
}

Timestamps come back in India time (+05:30) unless you ask for another zone: add ?timezone=UTC (or any IANA name) to the URL, or send an X-Timezone header.

The summary and extracted fields are filled a few seconds after the call ends, once post-call analytics has run. The call object explains every field.

Two more things you can fetch:

# Every step of the call, with latencies
curl https://voxa.abhinavyadav.in/api/v1/calls/$CALL_ID/events -H "X-API-Key: $VOXA_API_KEY"

# The stereo recording (caller left, agent right)
curl -o call.wav "https://voxa.abhinavyadav.in/api/v1/calls/$CALL_ID/recording" -H "X-API-Key: $VOXA_API_KEY"

Next steps

Esc