Products · /v1/calls

A receptionist in an API

Calls in both directions. Inbound rings route by each tenant's business hours — forwarded to the right person or sent to voicemail with a transcript. Outbound, one API call dials your user and their customer and bridges them — and can stream a live transcript of the conversation while it happens.

Voicemailafter hours

0:16

+1 415 413 6287

“Hi, calling about a leaky faucet in the…”

What you get out of the box

Business-hours routing

Open hours forward to real phones; closed hours go to voicemail. Evaluated per tenant, in the tenant's own timezone.

Voicemail with transcripts

voicemail.created delivers the recording and a transcript, ready to render in your product's inbox next to the texts.

Live transcripts, mid-call

Pass transcribe: true and every utterance arrives as a call.transcript webhook while the call is happening — the raw material for agent assist, coaching, and instant call notes.

Click-to-call, bridged

POST /v1/calls rings your user first, then their customer, and bridges the legs — both sides see the tenant's number, never a personal cell.

Keypad in, keypad out

POST a gather and the call speaks your prompt and collects keypresses — “press 1 to confirm tomorrow's appointment” is one request, and call.gather delivers the answer to your webhook. Going the other way, send DTMF on a live call to dial extensions and navigate phone trees; every far-end keypress streams in as call.dtmf.

The browser is a phone

Create a web client per agent seat and add client:wc_… to the ring targets — inbound calls ring inside your web app alongside cell phones; first answer wins and sees the caller's real number. Simultaneous ring and no-answer voicemail included.

Raw audio, streamed live

POST a stream and the call's audio forks to your WebSocket as ~20ms frames — no public server needed, you connect to us. Bidirectional streams play your audio back into the call: the substrate for AI voice agents, custom speech recognition, and real-time coaching.

routing-config.sh
curl -X PATCH https://api.handset.dev/v1/tenants/tnt_01kzv…/routing_config \
  -d timezone="America/Los_Angeles" \
  -d hours[mon][open]="08:00" -d hours[mon][close]="17:00" \
  -d after_hours="voicemail" \
  -d greeting="You've reached Bayview Dental…"

# later, after a missed evening call:
→ webhook: voicemail.created { "duration": 16, "transcript": "Hi, calling about…" }

The API surface

Endpoints

POST/v1/callsStart a click-to-call: dial the agent, then the customer, bridged
GET/v1/callsList calls with status, duration, and routing outcome
GET/v1/calls/{id}Retrieve one call and its event timeline
GET/v1/calls/{id}/transcriptThe live transcript so far — callable mid-call
POST/v1/calls/{id}/gatherAsk a keypad question: TTS prompt, collected digits back as a webhook
POST/v1/calls/{id}/dtmfSend digits on a live call — extensions, PINs, phone trees
POST/v1/calls/{id}/streamsFork live call audio to your WebSocket — bidirectional for voice agents
POST/v1/web_clientsProvision a browser softphone seat for an agent
POST/v1/web_clients/{id}/tokensMint a short-lived browser login token — keys stay server-side
GET/v1/voicemailsList voicemails per tenant
GET/v1/voicemails/{id}Retrieve a voicemail with recording and transcript
GET/v1/recordings/{id}Retrieve call recording metadata and media
PATCH/v1/tenants/{id}/routing_configSet hours, greeting, forwarding, and voicemail behavior

Ship voice & voicemail this sprint.

We're onboarding a small group of vertical SaaS platforms. Tell us what your customers need to say, and to whom.