Voice delivery & billing
Once a voice batch is submitted, track how each call resolved — by polling the batch or by receiving webhooks — and understand how Zend charges for it. This page covers batch status, status webhooks, billing, and common errors.
Every send returns a batch_id. Use it to check progress, or pass a callback_url to get pushed updates. See Send Voice for the request that starts a batch.
Check batch status
GET/voice/{batch_id}
Retrieve the batch summary and per-recipient results.
curl https://api.tryzend.com/voice/voice_1f6a2b3c-4d5e-6789-abcd-ef0123456789 \
-H "x-api-key: YOUR_API_KEY"
Response
{
"batch": {
"batch_id": "voice_1f6a2b3c-4d5e-6789-abcd-ef0123456789",
"source": "tts",
"text": "Hello, this is a call from Zend. Your verification code is 4821.",
"voice": "female",
"audio_url": "https://storage.googleapis.com/zend-2d42e.firebasestorage.app/voice-audio/tts/66ec54...85.mp3",
"status": "completed",
"counts": {
"total": 1,
"answered": 1,
"no_answer": 0,
"busy": 0,
"failed": 0,
"fallback_sent": 0
},
"unit_cost": 0.35,
"credits_reserved": 0.35,
"error_message": null,
"created_at": "2026-07-19T10:20:00Z"
},
"recipients": [
{
"id": "6884da240f0e633b7b979c00",
"to": "233XXXXXXXXX",
"status": "delivered",
"error_message": null,
"voice_refunded": false,
"fallback_sms_sent": false,
"fallback_message_id": null
}
]
}
Batch statuses
| Status | Description |
|---|---|
pending | Batch accepted, not yet processed |
processing | Calls are being dispatched |
submitted | All calls handed off to the carrier |
completed | All calls resolved (answered, unanswered, or failed) |
failed | The batch could not be processed |
Recipient statuses
| Status | Description |
|---|---|
pending | Not yet dispatched |
processing | Being dispatched |
sent | Call in progress or retrying |
delivered | Call was answered |
failed | Call failed — see error_message: no_answer or busy_or_unreachable |
Status webhooks
If you pass callback_url on the send request, Zend posts a JSON payload to it for every recipient status change:
{
"id": "6884da240f0e633b7b979c00",
"batch_id": "voice_1f6a2b3c-4d5e-6789-abcd-ef0123456789",
"recipient": "233XXXXXXXXX",
"status": "delivered",
"channel": "voice",
"fallback_sms_sent": false,
"timestamp": "2026-07-19T10:20:12Z"
}
| Status | Meaning |
|---|---|
sent | Call submitted to the carrier |
delivered | Call was answered |
not_reached | No answer or busy — the call is refunded, and a fallback SMS is sent if enabled |
Note
Your endpoint should respond with a
2xx status code.How billing works
A flat rate per recipient is reserved when you call /voice/send. Once a call resolves:
- Answered calls are charged the reserved amount.
- Unanswered calls — no answer, busy, or unreachable — are automatically refunded.
- Fallback SMS messages are billed separately at standard SMS rates, and only when one is actually sent.
Common errors
Insufficient credits
{
"statusCode": 400,
"message": "Insufficient credits. Required: 175.00, Available: 42.50",
"error": "Bad Request"
}
Validation error
{
"statusCode": 422,
"message": "Provide exactly one of \"text\" or \"voice_url\"",
"error": "Unprocessable Entity"
}
Related
- Send Voice — authentication and the base voice request.
- Audio & TTS — text-to-speech tips, voice options, and uploading your own audio.