Agent Number

Place an outbound call

Dial a number. Open the audio WebSocket. Hang up by closing it.

Place the call

curl -X POST https://agentnumber.really.com/voice/dial \
  -H "authorization: Bearer <token>" \
  -H "content-type: application/json" \
  -d '{"phone_number": "+15555550123", "to": "+15555550199"}'
# → 200
# {"call_id": "call_...", "stream_url": "wss://agentnumber.really.com/voice/stream/call_...", "direction": "outbound", "caller": "+15555550199", "phone_number": "+15555550123"}

phone_number is the bearer-owned number you're calling FROM. to is the destination.

Open the stream WebSocket

Use any WS client. The bearer goes in the Authorization header on the upgrade request. Audio is binary frames, 16 kHz mono PCM in both directions. Voice quality + cellular bridging is handled server-side.

Hang up

Close the stream WebSocket. The server detects the close and tears down the carrier leg.

Common errors

StatusErrorMeaning
400invalid_requestBody missing phone_number or to
401missing/invalid bearer tokenBearer missing or invalid
403not_ownerBearer doesn't own phone_number
404phone_number_not_foundphone_number not on an active subscription
409phone_busyNumber already on a call (single-active-call constraint)
409subscription_not_boundSubscription has no slot binding
502mac_unreachable / mac_dial_failedHardware adapter returned non-2xx or was unreachable

Receiving incoming calls

Open /voice/presence/<phone> and keep the WebSocket open. The server pushes JSON text frames for three event types over the call lifecycle: {event: "ringing", call_id, caller, stream_url} on incoming, {event: "answered", call_id} when picked up, and {event: "ended", call_id, missed} on hangup.

Where to go next