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

StatusDescription
pendingBatch accepted, not yet processed
processingCalls are being dispatched
submittedAll calls handed off to the carrier
completedAll calls resolved (answered, unanswered, or failed)
failedThe batch could not be processed

Recipient statuses

StatusDescription
pendingNot yet dispatched
processingBeing dispatched
sentCall in progress or retrying
deliveredCall was answered
failedCall 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"
}
StatusMeaning
sentCall submitted to the carrier
deliveredCall was answered
not_reachedNo 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"
}
  • Send Voice — authentication and the base voice request.
  • Audio & TTS — text-to-speech tips, voice options, and uploading your own audio.