SIP Call (Inbound & Outbound) Handling Through APIs, Webhooks and Websockets Like Twilio
Budget: ₹12,500 – ₹37,500 INR
>>Voice Call Flow
End-to-End Workflow Overview
1. Inbound SIP Call reaches the SIP trunk (running on Rocky Linux with Asterisk or
FreeSWITCH). The SIP channels are connected to the Linux server on a SIP port on an IP.
2. Asterisk/FreeSWITCH triggers a primary webhook to our AWS backend server (call
handling logic).
3. If the primary webhook fails (non-2xx HTTP response, timeout, or invalid XML), the
media server calls a fallback webhook URL.
4. The AWS backend responds with Twiml-style XML containing <Connect> and a
WebSocket URL.
5. The media server connects audio to the WebSocket for bi-directional audio streaming.
6. The AWS Server processes audio and sends synthesized responses over the same
WebSocket.
7. When the call ends, the media server sends an end-of-call summary/status webhook to
AWS server including duration, start time, end time, number details etc
>Webhook Communication
---Primary Webhook (Initial Call Event)
Example JSON Payload:
{
"call_sid": "CA1234567890abcdef",
"from": "+919876543210",
"to": "+911234567890",
"direction": "inbound",
"timestamp": "2025-07-16T10:00:00Z",
"sip_headers": {
"X-Call-ID": "abc123xyz"
},
"media_server": "asterisk",
"account_id": "your_internal_account_id"
}
Fallback Webhook (If Primary Fails)
Example JSON Payload:
{
"call_sid": "CA1234567890abcdef",
"reason": "Primary webhook failed",
"fallback_timestamp": "2025-07-16T10:00:03Z"
}
--Response from AWS Server – TwiML with WebSocket
Example XML Response:
<Response>
<Connect>
<Stream url="wss://your-backend.com/stream/server">
<Parameter name="call_sid" value="CA1234567890abcdef"/>
<Parameter name="user_id" value="42"/>
</Stream>
</Connect>
</Response>
--WebSocket Audio Streaming Format
From Media Server to AWS Server
{
"event": "start",
"stream_sid": "MZxxxxxxxxxxxxxx",
"call_sid": "CAxxxxxxxxxxxxxxxxx",
"sample_rate": 8000,
"media_format": "audio/x-mulaw"
}
{
"event": "media",
"media": {
"payload": "base64encoded-audio-chunk=="
}
}
{
}
"event": "stop"
From AWS Server to Media Server
{
"event": "media",
"media": {
"payload": "base64encoded-audio-chunk=="
}
}
>End-of-Call Summary/Status Webhook
Example JSON Payload:
{
"call_sid": "CA1234567890abcdef",
"from": "+919876543210",
"to": "+911234567890",
"start_time": "2025-07-16T10:00:00Z",
"end_time": "2025-07-16T10:01:23Z",
"duration": 83,
"termination_reason": "completed",
"media_server": "asterisk",
"sip_headers": {
"X-Call-ID": "abc123xyz"
}
}
>WebSocket Authentication
Example WebSocket URL (Backend AWS Server):
wss://your-backend.com/stream/server?call_sid=CAxxx&token=JWTxyz
>Final Summary for the Developer
• Media server (Asterisk/FreeSWITCH) will send an HTTP webhook to the AWS backend
when a call arrives.
• The backend returns a Twiml-style XML containing a <Connect> directive with a
WebSocket URL.
• Fallback webhook used if primary fails.
• Asterisk connects to WebSocket for audio streaming.
• Real-time µ-law audio sent and received (base64 in JSON).
• The backend AWS server responds with voice (in the encoded format shared above) via
same WebSocket.
• Call end triggers a summary/status webhook.
• Different API Endpoints are also required for different events like call_termination based on call_sid, call_forwarding based on call_sid, etc.
• An API is required to trigger outbound calls. Our server will send an API request with the details like the from_number, to_number, webhook_url, status_url, parameters etc. Then this API should trigger an outbound call based on the parameters/json passed. It is basically a twilio/plivo/vonage style architecture for call routing and handling.
Note: We have the AWS Server part ready, the Media server part (Asterisk/FreeSwitch) is
left with the webhooks, APIs and websocket connection from the Datacenter server
where the SIP line is terminated, to our AWS backend server.
End-to-End Workflow Overview
1. Inbound SIP Call reaches the SIP trunk (running on Rocky Linux with Asterisk or
FreeSWITCH). The SIP channels are connected to the Linux server on a SIP port on an IP.
2. Asterisk/FreeSWITCH triggers a primary webhook to our AWS backend server (call
handling logic).
3. If the primary webhook fails (non-2xx HTTP response, timeout, or invalid XML), the
media server calls a fallback webhook URL.
4. The AWS backend responds with Twiml-style XML containing <Connect> and a
WebSocket URL.
5. The media server connects audio to the WebSocket for bi-directional audio streaming.
6. The AWS Server processes audio and sends synthesized responses over the same
WebSocket.
7. When the call ends, the media server sends an end-of-call summary/status webhook to
AWS server including duration, start time, end time, number details etc
>Webhook Communication
---Primary Webhook (Initial Call Event)
Example JSON Payload:
{
"call_sid": "CA1234567890abcdef",
"from": "+919876543210",
"to": "+911234567890",
"direction": "inbound",
"timestamp": "2025-07-16T10:00:00Z",
"sip_headers": {
"X-Call-ID": "abc123xyz"
},
"media_server": "asterisk",
"account_id": "your_internal_account_id"
}
Fallback Webhook (If Primary Fails)
Example JSON Payload:
{
"call_sid": "CA1234567890abcdef",
"reason": "Primary webhook failed",
"fallback_timestamp": "2025-07-16T10:00:03Z"
}
--Response from AWS Server – TwiML with WebSocket
Example XML Response:
<Response>
<Connect>
<Stream url="wss://your-backend.com/stream/server">
<Parameter name="call_sid" value="CA1234567890abcdef"/>
<Parameter name="user_id" value="42"/>
</Stream>
</Connect>
</Response>
--WebSocket Audio Streaming Format
From Media Server to AWS Server
{
"event": "start",
"stream_sid": "MZxxxxxxxxxxxxxx",
"call_sid": "CAxxxxxxxxxxxxxxxxx",
"sample_rate": 8000,
"media_format": "audio/x-mulaw"
}
{
"event": "media",
"media": {
"payload": "base64encoded-audio-chunk=="
}
}
{
}
"event": "stop"
From AWS Server to Media Server
{
"event": "media",
"media": {
"payload": "base64encoded-audio-chunk=="
}
}
>End-of-Call Summary/Status Webhook
Example JSON Payload:
{
"call_sid": "CA1234567890abcdef",
"from": "+919876543210",
"to": "+911234567890",
"start_time": "2025-07-16T10:00:00Z",
"end_time": "2025-07-16T10:01:23Z",
"duration": 83,
"termination_reason": "completed",
"media_server": "asterisk",
"sip_headers": {
"X-Call-ID": "abc123xyz"
}
}
>WebSocket Authentication
Example WebSocket URL (Backend AWS Server):
wss://your-backend.com/stream/server?call_sid=CAxxx&token=JWTxyz
>Final Summary for the Developer
• Media server (Asterisk/FreeSWITCH) will send an HTTP webhook to the AWS backend
when a call arrives.
• The backend returns a Twiml-style XML containing a <Connect> directive with a
WebSocket URL.
• Fallback webhook used if primary fails.
• Asterisk connects to WebSocket for audio streaming.
• Real-time µ-law audio sent and received (base64 in JSON).
• The backend AWS server responds with voice (in the encoded format shared above) via
same WebSocket.
• Call end triggers a summary/status webhook.
• Different API Endpoints are also required for different events like call_termination based on call_sid, call_forwarding based on call_sid, etc.
• An API is required to trigger outbound calls. Our server will send an API request with the details like the from_number, to_number, webhook_url, status_url, parameters etc. Then this API should trigger an outbound call based on the parameters/json passed. It is basically a twilio/plivo/vonage style architecture for call routing and handling.
Note: We have the AWS Server part ready, the Media server part (Asterisk/FreeSwitch) is
left with the webhooks, APIs and websocket connection from the Datacenter server
where the SIP line is terminated, to our AWS backend server.
Related categories:
Linux
Cloud Computing
Asterisk PBX
VoIP
Call Control XML
JSON
FreeSwitch
Twilio
API Development
SIP