Call Flows
A Call Flow is the JSON your server returns when Teler asks what to do
on a call. Teler POSTs a request to your flow URL with call metadata; you
respond with a flow describing one action: stream, play, or hangup.
Mental model
Section titled “Mental model”For incoming calls Teler hits the Incoming Call URL on the Voice App.
For outgoing calls Teler hits the flow_url you passed to calls.create().
What Teler sends
Section titled “What Teler sends”Teler’s request to your flow endpoint:
POST /flowContent-Type: application/json{ "call_id": "<uuid>", "account_id": "<uuid>", "from_number": "+91XXXXXXXXXX", "to_number": "+91XXXXXXXXXX", "direction": "inbound"}| Field | Type | Description |
|---|---|---|
call_id | UUID | Unique ID for this call. Use it to correlate with webhooks. |
account_id | UUID | Your Teler account. |
from_number | string (E.164) | Calling party. |
to_number | string (E.164) | Called party. |
direction | enum | "inbound" or "outbound". |
Your endpoint must respond within 5 seconds with 200 OK and a Call Flow body.
The request shape above is the same on both webhook versions
(2025-08-01 and 2026-06-01). It is the response below whose
available actions depend on the version.
Actions
Section titled “Actions”A Call Flow body is a single JSON object with an action field. Teler
executes exactly one action per flow request. Availability by webhook
version:
| Action | 2025-08-01 | 2026-06-01 |
|---|---|---|
stream | Yes | Yes |
play | Yes | Yes |
hangup | Yes | Yes |
dial | No | Yes |
say | — | — |
say is defined in the flow schema but is not yet implemented at
runtime; returning it currently fails the call. See
API versioning to change the pin on your Voice
App or SIP Trunk.
The flow endpoint accepts a single JSON object (one action). Arrays of actions are rejected.
stream
Section titled “stream”Open a bidirectional WebSocket carrying real-time call audio.
| Field | Type | Required | Default | Constraints |
|---|---|---|---|---|
action | string | yes | none | Must be "stream". |
ws_url | string | yes | none | Secure WebSocket URL (wss://). |
chunk_size | integer | no | 400 | Audio chunk size in milliseconds. Range: 20 to 2000, and must be divisible by 20. |
sample_rate | enum | no | "8k" | "8k" or "16k". |
{ "action": "stream", "ws_url": "wss://yourdomain.com/media-stream", "chunk_size": 1000, "sample_rate": "16k"}See Media Streaming for the WebSocket protocol Teler uses on this connection.
Play an audio file into the call, then end.
| Field | Type | Required | Constraints |
|---|---|---|---|
action | string | yes | Must be "play". |
media_url | string | yes | Publicly reachable HTTPS URL serving an MP3 or WAV file. |
{ "action": "play", "media_url": "https://example.com/media-file.mp3"}hangup
Section titled “hangup”End the call immediately.
| Field | Type | Required | Constraints |
|---|---|---|---|
action | string | yes | Must be "hangup". |
{ "action": "hangup"}Originate an outbound leg and bridge it into the current call. Available
only on webhook version 2026-06-01. Full schema and examples:
dial.
{ "action": "dial", "to": "+14155550123"}Response requirements
Section titled “Response requirements”| Constraint | Value |
|---|---|
| Status code | 200 OK |
| Content-Type | application/json |
| Response time | ≤ 5 seconds |
| Body | Single JSON object with one action |
If your endpoint times out, returns a non-2xx, or returns invalid JSON, the
call ends and a call.failed webhook is delivered.