Hotline APIBeta

A small, safe HTTP API for one account's call flow — the same operations the AI assistant uses. It can read the hotline, create extensions, wire menu keys and routes, set what prompts say, and undo any batch of its own changes. It cannot touch phone numbers, billing, contacts, users, or other accounts, and it never deletes anything it did not create.

Base URL: https://<your-app>/api/v1/hotline
Auth: Authorization: Bearer hl_… (create tokens under Account Settings → Hotline API).
Rate limit: 120 requests / minute per token. All bodies and responses are JSON.

Concepts

Endpoints

Method Path Purpose
GET /describe?depth=6 The hotline as a tree from its entry (phone number / test pin): root menu, keys, routes; plus unreachable extensions.
GET /types Catalog of extension types, their prompts, settings and routes.
GET /extensions?type=ivr List extensions (optionally one type).
GET /extensions/{type}/{id} One extension: prompts, settings, keys (menus), routes, how callers reach it.
POST /extensions Create: {type, name, settings?, prompts?, voice?}.
PATCH /extensions/{type}/{id} Rename and/or update settings: {name?, settings?}.
PUT /extensions/{type}/{id}/prompts/{slot} Set a prompt: {text, voice?} — text may be words or an audio URL; empty clears.
PUT /extensions/{type}/{id}/routes/{slot} Set a named route: {target_type, target_id} (nulls clear it).
POST /menus Create a menu with keys in one call: {name, greeting?, keys?: {"1": {type, id}}, voice?}.
PUT /menus/{menu}/keys/{key} Point a key: {target_type, target_id}.
DELETE /menus/{menu}/keys/{key} Clear a key.
GET /change-sets Recent batches.
GET /change-sets/{id} One batch with its changes.
POST /change-sets/{id}/undo Revert the batch.
GET /libraries, /labels Helpers for record.recordable_id and label actions.

Every write response carries change_set: {id, audio_pending}. Errors are {error: "…"} with 401 (token), 404 (not found), 422 (refused, with a human-readable reason).

Settings per type

Type Settings
ivr active
library listening_order (asc/desc), active
record recordable_id (library), conformation (ask to confirm), save_on_hangup, max_length, min_length, active
transferToNumber number (digits with country code, required), caller_id, call_timeout
dial caller_id
validation type (pin / contacts / all_contacts / labels), pin (required for pin), active
exam passing_score, allow_retakes, keep_all_attempts, announce_score, active
conference pin, moderator_pin, max_members
bookmark type (single / multiple)
addToLabel / removeFromLabel label_id (required)
twiml url (required), method, active

Prompt slots: ivr.greeting, play.audio, record.before|after|confirmation, library.intro|menu, exam.intro|score_intro|correct|incorrect|closed|already_taken, validation.pin_prompt|pin_retry|pin_failed|identify_prompt|personal_pin_prompt|identify_failed, addToLabel.message, removeFromLabel.message. Voices: alloy, echo (default), fable, onyx, nova, shimmer.

Example — build a small hotline

TOKEN=hl_…
H="Authorization: Bearer $TOKEN"
API=https://hotlines.example.com/api/v1/hotline

# 1. A recording and a message box
curl -s -X POST $API/extensions -H "$H" -H 'Content-Type: application/json' \
  -d '{"type":"play","name":"Office hours","prompts":{"audio":"We are open Sunday to Thursday, nine to five."}}'
# → data.id = 41, change_set.id = 7

curl -s -X POST $API/extensions -H "$H" -H 'Content-Type: application/json' \
  -d '{"type":"record","name":"Leave a message","settings":{"conformation":true},"change_set_id":7}'
# → data.id = 154

# 2. A menu pointing at them (same batch)
curl -s -X POST $API/menus -H "$H" -H 'Content-Type: application/json' \
  -d '{"name":"Front desk","greeting":"Welcome. Press 1 for office hours, 2 to leave a message.","keys":{"1":{"type":"play","id":41},"2":{"type":"record","id":154}},"change_set_id":7}'

# 3. Look at it — or undo the whole batch
curl -s $API/describe -H "$H"
curl -s -X POST $API/change-sets/7/undo -H "$H"

Notes for integrators and the assistant