Tone docs
Flows

A BYO media session

What happens on the wire between Tone and your own voice stack, from dial to hang-up.

See Bring your own voice stack for setup and Tone Media Streams for the protocol reference.

The setup, once

#StepWhere
1Declare your sender classificationDashboard
2Store the endpoint credentialDashboard — Developer → Secrets
3PATCH /v1/numbers/{id} with routingMode: "byo_ws" and mediaEndpointAPI

Steps 1 and 2 are dashboard-only and will 403 with an API key, deliberately.

Then, per call

#What happens
1POST /v1/calls without agentId — sending one is a 422
2The compliance gate runs, exactly as it does for an agent call
3The carrier dials
4Tone opens a WebSocket to your mediaEndpoint
5A start frame arrives with the call id, direction, from, to and your customParameters
6media frames flow both ways until someone hangs up
7Tone writes the call record and bills at the BYO rate

Inbound needs no extra work: a BYO number answers inbound the same way.

The endpoint

static names one wss:// URL, used for every call with the call id appended as a query parameter. webhook names an https:// URL fetched per call that answers {"url":"wss://…"} — which is how you route calls to different backends.

🔴 Both must be publicly reachable. Private and link-local addresses are refused when you save the config, and refused again at connect time after DNS resolution — because the first check can be sidestepped by DNS and the second by a config that was never validated.

Three rules that decide whether it sounds right

  • Send small chunks, 20–100ms. One large buffer is a caller waiting.
  • Use mark to know when your audio finished playing. Guessing from byte counts drifts.
  • Hang up by closing the socket. There is no separate hang-up frame.

customParameters merge in three layers, later winning: static number config → per-call variables → identity facts (callId, direction, from, to).

Every refusal reports a completed call

If Tone cannot reach you, the call still ends properly — it is never left hanging in your CDR:

endReason
refused_no_endpointThe number is byo_ws with no mediaEndpoint
refused_endpoint_unreachableYour endpoint did not accept the connection
refused_endpoint_forbiddenIt resolved into private address space, or refused the credential
refused_media_formatThe negotiated audio format is not one we speak
max_durationThe 60-minute ceiling

Each writes a call record with a failed disposition. Watch for these before blaming the carrier.

Two limitations

Campaigns do not run on BYO numbers — refused at launch rather than as thousands of per-call errors.

A negotiated full-stack rate does not apply. BYO bills the telephony-plus-platform subset; see Billing.

Was this page helpful?

On this page