Place outbound calls (API)
Trigger an AI-driven outbound call from your own code — survey, follow-up, or confirmation flows.
Outbound calling lets you hand a destination number and an agent configuration to ThunderPhone and have the AI place the call on your behalf. Typical use cases:
- Appointment confirmations
- Survey callbacks
- "Second-try" follow-ups after a missed call
- Dispatch-style notifications
Prerequisites
- Bring a VoIP number
Outbound calling requires you to own the
from_numberthrough a VoIP connection. Demo numbers are inbound-only. See Bring your own numbers. - Create an agent
An outbound-flavoured prompt tends to start with the agent identifying itself and its purpose — "Hi, this is Acme calling to confirm your appointment for tomorrow at 3pm…" Set
outbound_speak_ordertoagent_first(the default). - Keep a positive balance
Outbound calls return
402 Payment Requiredif balance is ≤$0.00. Top up viaPOST /v1/billing/top-upor enable auto-reload.
Place a call with a saved agent
The simplest path — reference an agent by id:
curl -X POST https://api.thunderphone.com/v1/call \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from_number": "+15551234567",
"to_number": "+14155550199",
"agent_id": 12
}'Response:
{ "call_id": 987654321, "status": "initiated" }Place a call with inline config
If you want a one-off prompt that isn't worth saving as an agent,
pass config instead. The shape matches the response schema of the
call.incoming webhook:
curl -X POST https://api.thunderphone.com/v1/call \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from_number": "+15551234567",
"to_number": "+14155550199",
"config": {
"prompt": "You are confirming Jane Doe appointment for 3pm tomorrow…",
"voice": "john",
"product": "spark"
}
}'Follow the call
In parallel, subscribe to the
telephony.complete webhook —
the fastest way to know a call finished. If you can't accept inbound
webhooks, poll GET /v1/calls/{call_id} every couple of seconds; the
record includes end_reason, duration_seconds, and the recording
URL once the call ends.
Failure modes worth handling
| Error | Fix |
|---|---|
402 Payment Required | Top up the balance or enable auto-reload |
403 outbound blocked (demo number) | Bring a VoIP number instead |
403 outbound blocked (unverified VoIP) | Run POST /v1/phone-numbers/{id}/verify-voip |
404 from_number is not registered to this organization | Confirm the from_number matches a phone number you own |
502 Bad Gateway | Transient SIP / LiveKit failure; safe to retry |
Controlling hold time
Outbound calls that run long because the callee is slow to respond
(IVR trees, queues) can be capped with max_hold_seconds:
{
"from_number": "+15551234567",
"to_number": "+14155550199",
"agent_id": 12,
"max_hold_seconds": 120
}The agent hangs up if no human audio has been received in the last N seconds. Default is 900 (15 minutes).