Voice Alarms
Schedule recurring outbound voice campaigns that dial a list of numbers on a schedule.
Voice Alarms
A Voice Alarm is a scheduled outbound voice campaign — a list of destinations, a from caller ID, an answer_url, and a schedule. TryVox dials each destination at the scheduled time, fetches VoxML from your answer_url to control the call, and tracks per-recipient outcomes.
Use cases: appointment reminders, dispatch alerts, daily check-ins, morning announcements to a fixed call list.
This is a higher-level surface than Make a Call. Use Make a Call for one-off, ad-hoc placements; use Voice Alarms when you have a recurring schedule and a fixed audience.
Endpoints
All endpoints are mounted under /v1/voice/account/{auth_id}/voice-alarms/... and authenticate with HTTP Basic.
| Method | Path | Purpose |
|---|---|---|
POST | /v1/voice/account/{auth_id}/voice-alarms | Create an alarm |
GET | /v1/voice/account/{auth_id}/voice-alarms | List alarms |
GET | /v1/voice/account/{auth_id}/voice-alarms/{id} | Get one |
PUT | /v1/voice/account/{auth_id}/voice-alarms/{id} | Update |
DELETE | /v1/voice/account/{auth_id}/voice-alarms/{id} | Delete |
POST | /v1/voice/account/{auth_id}/voice-alarms/{id}/pause | Pause — skip upcoming runs |
POST | /v1/voice/account/{auth_id}/voice-alarms/{id}/resume | Resume |
Lifecycle
CREATE
│
▼
pending ─── scheduled_at reached ───► active ───► completed (one-shot)
│ │
│ └──────► active again (next interval)
▼
cancelled (DELETE) paused (POST /pause)| Status | Meaning |
|---|---|
pending | Created, waiting for scheduled_at. |
active | Currently dialing. |
paused | Skips the next scheduled run; previously completed runs are kept. |
completed | One-shot alarm finished its single run. |
cancelled | Soft-deleted; no further runs. |
Create an alarm
POST /v1/voice/account/{auth_id}/voice-alarmsRequest body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Human label. |
from | string | yes | Caller ID. Must be a verified caller ID on the account. |
to | string[] | yes | E.164 destination numbers. The whole list is dialed each scheduled run. |
answer_url | string | yes | URL TryVox calls when each leg is answered. Returns VoxML. |
answer_method | string | no | GET or POST. Default: POST. |
status_url | string | no | URL TryVox calls with status updates per leg. |
scheduled_at | string | yes | ISO 8601 UTC time of the first run. |
repeat_interval | string | no | once, daily, weekly, monthly. Default: once. |
country_iso | string[] | no | Two-letter ISO codes for routing decisions. Optional metadata. |
max_retries | integer | no | Retry per-leg on failure (busy / no-answer / carrier failure). Default: 0. |
retry_interval | integer | no | Seconds between retries. Default: 60. |
timeout_seconds | integer | no | Ring timeout per leg. Default: 30. |
notify_emails | string[] | no | Emails to receive a summary after each run. |
Example
curl -X POST https://api.tryvox.io/v1/voice/account/$TRYVOX_AUTH_ID/voice-alarms \
-u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{
"name": "Daily on-call wakeup",
"from": "+919876543210",
"to": ["+14155551234", "+14155556789", "+14155559999"],
"answer_url": "https://your-app.com/voice-alarm/answer",
"scheduled_at": "2026-04-10T05:30:00Z",
"repeat_interval": "daily",
"max_retries": 2,
"retry_interval": 120,
"timeout_seconds": 25,
"notify_emails": ["oncall-leads@example.com"]
}'Response
201 Created:
{
"id": "8f7a4b2e-91c2-4f3d-9a1e-2c4b6d8f0a1c",
"account_id": "TJab12cd34",
"name": "Daily on-call wakeup",
"from": "+919876543210",
"to": ["+14155551234", "+14155556789", "+14155559999"],
"answer_url": "https://your-app.com/voice-alarm/answer",
"answer_method": "POST",
"scheduled_at": "2026-04-10T05:30:00Z",
"repeat_interval": "daily",
"max_retries": 2,
"retry_interval": 120,
"timeout_seconds": 25,
"status": "pending",
"total_calls": 0,
"completed_calls": 0,
"failed_calls": 0,
"next_run_at": "2026-04-10T05:30:00Z",
"notify_emails": ["oncall-leads@example.com"],
"created_at": "2026-04-09T10:30:00Z"
}List alarms
GET /v1/voice/account/{auth_id}/voice-alarmscurl -u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
https://api.tryvox.io/v1/voice/account/$TRYVOX_AUTH_ID/voice-alarmsReturns 200 OK with an array of alarms scoped to this account.
Update an alarm
PUT /v1/voice/account/{auth_id}/voice-alarms/{id}PATCH-style: only fields you submit are applied. Most useful: changing to, rescheduling via scheduled_at, or flipping status to paused / active.
curl -X PUT https://api.tryvox.io/v1/voice/account/$TRYVOX_AUTH_ID/voice-alarms/$ALARM_ID \
-u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{"to": ["+14155551234", "+14155556789"]}'Returns 200 OK with the updated alarm.
Pause / Resume
POST /v1/voice/account/{auth_id}/voice-alarms/{id}/pause
POST /v1/voice/account/{auth_id}/voice-alarms/{id}/resumePause sets status: "paused" and skips upcoming scheduled_at triggers. Resume reverts to pending (or active if a run is overdue and starts immediately).
curl -X POST \
-u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
https://api.tryvox.io/v1/voice/account/$TRYVOX_AUTH_ID/voice-alarms/$ALARM_ID/pause204 No Content.
Delete
DELETE /v1/voice/account/{auth_id}/voice-alarms/{id}204 No Content. The alarm flips to cancelled immediately. In-flight legs from the current run continue; no future runs.
Per-run behaviour
When scheduled_at is reached:
- Status flips from
pendingtoactive. - TryVox places one outbound call per entry in
to, in parallel up to a per-tenant concurrency cap. - Each leg fetches VoxML from
answer_urlwhen answered. Thefromnumber must be a verified caller ID — the alarm fails its run if it isn't (you'll see avalidation_failedentry on the email summary). - Per-leg failures are retried up to
max_retrieswithretry_intervalbetween attempts. - After all legs complete (or exhaust retries), counters update:
total_calls+=len(to)completed_calls+= successful legsfailed_calls+= legs that exhausted retries
- For recurring alarms,
next_run_atis set to the next interval boundary. Foronce, status flips tocompleted.
Errors
| Status | Code | Reason |
|---|---|---|
| 400 | VALIDATION_FAILED | Missing required field, to empty, scheduled_at not parseable |
| 401 | INVALID_CREDENTIALS | Auth ID / Auth Token bad |
| 403 | FORBIDDEN | Auth ID in URL doesn't match the authenticated key, or from isn't a verified caller ID |
| 404 | NOT_FOUND | Alarm doesn't exist on this account |
Notes
- The
fromrequirement is real. A single rejected leg won't pause the alarm, but if every leg has the samefromand it's not verified, the whole run fails. Verify before scheduling. scheduled_atis UTC. Don't pass a local time without offset — it's parsed strictly.- Per-tenant concurrency caps the parallelism within a run. Large
tolists fan out in batches; the run isn't atomic. - No partial-list retries. If a single leg fails after
max_retries, you can't retry just that one — re-run the alarm by updatingscheduled_atto a near-future time, or fall back to Make a Call for the missed numbers. - Email summaries are best-effort, sent through the Notifications email service.