Overview

The Passthru Applet sends call and streaming metadata from Voice Applet flows to your server, especially useful when executing:

  • Voicebot Applet (Bidirectional Streaming)

  • Stream Applet (Unidirectional Streaming)

Passthru sends additional stream-specific parameters as query parameters, enriching standard passthru behaviour.

Refer to the standard passthru documentation here: Working with Passthru Applet

This guide is an extended version with additional parameters for streaming flows.

How It Works

Passthru makes an HTTP GET request to your URL, passing URL-encoded call and stream metadata.

Example:

GET https://yourserver.com/passthru-handler?

CallSid=56b1234567abcdef89abcdef12345678&

flow_id=voicebot-flow-xyz123&

Direction=inbound&

From=+918888000000&

To=+912233344455&

Stream[StreamSID]=6f048d2e897a0d2d4029560f3f541947&

Stream[Status]=completed&

Stream[Duration]=28&

Stream[RecordingUrl]=https://recordings.exotel.com/exotelrecordings/exotelt/6f048d2e897a0d2d4029560f3f541947.mp3&

Stream[StreamUrl]=wss://stream.customer.com/media&

Stream[DisconnectedBy]=bot


Your backend must parse:

  • URL query parameters

  • Nested keys (e.g., Stream[Status])

  • JSON strings


JSON Format (Raw Query String)

Sometimes, all parameters are sent in a single JSON string under the Stream key:

Stream={"StreamSID":"62xxx...",

"RecordingUrl":"https://recordings.exotel.com/...",

"Status":"completed",

"Duration":"28",

"StreamUrl":"ws://10.32.76.120:5007/media",

"DisconnectedBy":"user"}

  • Ensure your backend deserialises this string correctly.

Handling Passthru Responses

Passthru requests can be handled synchronously or asynchronously:

  • Sync: Exotel will immediately pass the call details synchronously during the call flow execution. It is possible only to make a binary decision using Passthru.

    • 200 OK → Option A

    • 302 Found → Option B

    • The person on call will wait until your URL responds.

  • Async: Exotel will asynchronously pass the call details without interrupting the call flow execution. Use this mode when you don’t want to dynamically change flow execution. The user will not experience a delay.


Streaming-Specific Fields (Flat Format)

Parameter

Description

Stream[StreamSID]

Unique streaming session ID

Stream[Status]

Status (completedfailedcancelled)

Stream[Duration]

Stream duration (seconds)

Stream[StreamUrl]

WebSocket URL for streaming

Stream[RecordingUrl]

URL to recording (if enabled)

Stream[DisconnectedBy]

Disconnector (userbotNA)

Stream[DetailedStatus]

Present on failure (e.g., Streaming_call_throttled)

Stream[Error]

Error string (e.g., network failure or WS rejection)

Note: The above fields are added on top of standard passthru parameters.

Throttling Scenario

Concurrency limit breaches trigger:

Stream[Status]=failed

Stream[DetailedStatus]=Streaming_call_throttled


Implement retry or fallback strategies accordingly.

Failure Handling

Below are the most common failure and disconnection scenarios captured in the passthru payload:

Test 1: Call hung up during greeting

Expected: Capture who disconnected and status

{

  "Status": "cancelled",

  "DisconnectedBy": "user"

}

Test 2: Invalid WebSocket URL

Expected: Failure metadata including error, stream URL, and disconnector

{

  "StreamSID": "b68e46bca0fdexxxxx89643f6d81196d",

  "RecordingUrl": "https://recordings.exotel.com/exotelrecordings/exotelt/b68e46bca0fdexxxxx89643f6d81196d.mp3",

  "Status": "failed",

  "Duration": "0",

  "StreamUrl": "ws://xx.x.xx.xxx:50/media",

  "Error": "3009 failed to establish ws conn dial tcp 10.1.76.120:50: connect: connection refused",

  "DisconnectedBy": "NA"

}


Test 3: Call cancelled after delay in streaming setup

Expected: Accurate cancellation reason and disconnection origin


{

  "StreamSID": "6f048d2e897a0dxxxxx9560f3f541947",

  "Status": "cancelled",

  "DisconnectedBy": "user"

}

Test 4: Call disconnected by bot after successful conversation

Expected: Final stream status and session metadata

{

  "StreamSID": "f5dd49d7ac3xxxxx4b491ce948501947",

  "Status": "completed",

  "Duration": "29",

  "StreamUrl": "wss://e33e-54-251-51-3.xxxxx-free.app",

  "DisconnectedBy": "bot"

}

These structured outputs ensure consistent understanding of streaming lifecycle and failure context.

Note: DisconnectedBy values are standardized to: userbotNA.

Passthru logs enriched with detailed Error messages improve debugging and recovery mechanisms.

Active Stream Monitoring API

Monitor active streams:

MUM Region:

curl -X GET 'http://api.in.exotel.com/v1/Accounts/{Tenant ID}/ActiveStreams'


SGP Region:

curl -X GET 'https://api.exotel.com/v1/Accounts/{Tenant ID}/ActiveStreams'

Sample Response:

{

  "status": "success",

  "active_streams": 12,

  "max_allowed_streams": 100,

  "account_sid": "Exotel"

}


Best Practices

  • Position Passthru immediately after Stream or Voicebot Applets.

  • Backend should handle both flat and JSON query formats.

  • Trigger fallback based on Stream[DetailedStatus].

  • Actively monitor concurrency limits.

  • Log StreamSIDRecordingUrl, and detailed errors for debugging and auditing.

  • Clearly interpret and handle disconnect causes (DisconnectedBy).

  • Passthru backend responses must comply with synchronous (HTTP codes) or asynchronous processing models appropriately.


Use Cases

  • Real-time monitoring of stream health

  • Dynamic routing based on real-time stream conditions

  • Enhanced debugging through detailed error reporting

  • Optimised concurrency and call management

  • Graceful error handling and escalation mechanisms


Deployment Strategy

Follow structured rollout:

  1. Dev Environment: Validate passthru logic with mock logs.

  2. QA/Staging: Test real call scenarios thoroughly.

  3. Canary Release (Prod): Roll out feature gradually, monitoring closely.

  4. Full Release: Expand to all users upon successful canary release.

Ensure rollback capabilities via feature flags and previous stable versions.

Summary

The Passthru Applet for Voice Streaming significantly enhances standard passthru functionality by providing extensive stream metadata, failure reasons, and real-time observability. Leverage these capabilities to:

  • Monitor and optimize streaming performance

  • Facilitate precise error handling and debugging

  • Enable intelligent and dynamic routing decisions

Implement these advanced passthru mechanisms to build robust, observable, and scalable voice-streaming integrations with Exotel APIs.