SIP Mediaserver Service - SIP Mediaserver Examples
Download OpenAPI specification:Download
This document provides practical examples of how to use the SIP Mediaserver Service from iotcomms.io to build advanced voice applications. The service enables fine-grained control over call handling and media interactions through REST APIs and real-time callbacks. This document combines key concepts, API functionalities, and practical use cases to demonstrate how developers can leverage the SIP Mediaserver Service in their applications.
The SIP Mediaserver Service provides a robust and scalable solution for managing real-time voice communications. It allows developers to handle incoming and outgoing calls, route participants, play media, capture input, and record conversations. Applications communicate with the SIP Mediaserver Service through REST APIs and callbacks to define call flows dynamically.
Core Concepts
The service operates using three main entities:
Sessions – Represent a single call session, which may contain multiple connections and participants.
Connections – Link two or more participants within a session.
Participants – Individual entities engaged in the call, including SIP endpoints and IVR systems.
A session can be initiated in two ways:
A new call arrives at the SIP Mediaserver Service, creating an inbound participant.
An outbound call is placed using the
/placeivrcall
API, creating a participant that connects to a SIP destination.
The state logic determining how calls should be handled is implemented in the customer application. When state changes for sessions, connections, or participants, the customer application is informed about this by REST callback requests.
The key callbacks are:
/newCall
- sent to inform that a new call arrives to media service. The application should pass anaction
property in the response to tell how Mediaservice should handle the call:drop
- Disconnect the incoming callcall
- Connect the call with another destination SIP participantivr
- Connect the call with an IVR participant to play and receive media and tones
/callNotify
- these are informative events for progress updates for participants, for example, inform about ringing state/callEvent
- these are events sent to inform that a connection or participant state has changed, and the application responds with anaction
to inform how to proceed. For example, if two participants are in a call with an associated connection, and one of the parties hangs up the call there is a/callEvent
sent to inform about this. Theaction
in the response then tells what to do with the remaining participant in the call.drop
- Disconnect the remaining participantcall
- Connect the remaining participant with another destination SIP participantivr
- Connect the remaining participant with an IVR participant to play and receive media and tones
/callAnswered
- This callback request is sent when a connection has been established between two participants in a session/sessionCompleted
- This callback request is sent once all participants have left a session and therefore the session is deleted.
A special type of a participant in a session is the IVR participant. This participant act as an endpoint in a connection which can:
- Listen to DTMF tones sent by the other participant in the connection * Play out phrases to be heard by the other participant in the connection, for example: * Phrases generated by text to speech * Play out files previously recorded or uploaded using the
/promptfile
API * Play out file fetched from a remote server from a provided HTTP URL * Record audio sent by the other participant * Set a background audio that should be played continuously while no other commands are executed, for example playing music on hold.´
Once a connection have been established with an IVR participant it will trigger a /getIvrCommand
callback request. The response to this request should have an command that provide instructions to the IVR participant.
{body} Application->>Mediaservice: 200 OK
{command body} Mediaservice->>Application: POST /getIvrCommand
{body} Application->>Mediaservice: 200 OK
{command body} Mediaservice->>Application: POST /getIvrCommand
{body} Application->>Mediaservice: 200 OK
{command body,hangup:true}
The body of the /getIvrCommand
request may contain information from a previous command execution, for example collected DTMF digits.
The body of the /getIvrCommand
response contain the command to be executed, for example to play out a phrase. Once a command have been executed a new /getIvrCommand
request is sent until the response contain a hangup:true
property. This will hang up the IVR participant from the connection and trigger a /callEvent
callback to get information what to do with the party previously connected with the IVR participant.
/getIvrCommand response object
Details of /getIvrCommand
callback requests and responses can be found in the Mediaservice API documentation.
The response to the callback object contain a command that provides instructions to the IVR participant. It is a JSON object of the format:
{
"dtmf": {},
"phrases": [],
"backgroundPrompt": {},
"hangup": false,
"getIVRCommandAfter": 20,
}
Where:
dtmf
property is an object telling the IVR participant to listen for and report DTMF digits received. Received digits are reported in subsequent/getIvrCommand
requestsphrases
is an array of phrase objects. A phrase object instructs the IVR participant to play out audio to the connected participant. Once all phrases have been played a new/getIvrCommand
callback request is sent to get further commands.backgroundPrompt
is an object with information telling the IVR participant to loop audio in between command execution.hangup
is a boolean property telling the IVR participant to drop out from the connection, i.e. when either connect the connected participant with another party or to end the session. When this property is set the command provided will be executed but no further/getIvrCommand
callbacks will be sent. Instead a/callEvent
callback request will be sent indicating that the IVR participant have left the connection.getIVRCommandAfter
is a property telling the IVR participant to pause the next/getIvrCommand
request the time specified in seconds.
The list above is an overview of the most commonly used properties, for more detailed information, please look at the API documentation.
This example demonstrates how to implement an IVR-based call routing system that greets the caller, captures input, and routes them to the correct department.
Below is an example of a typical message flow where the Mediaservice interacts with a customer's application implementing an auto-attendant function.
A call arrives to the phone number provisioned for the Mediaservice. This trigger a
/newCall
callback requestThe application respond with a 200 Ok to the callback having a body telling the service to connect the caller with an IVR participant.
The SIP call is established and a
/callAnswered
callback request is sent to indicate that a connection have been established between caller and IVR participant.Media path is established between caller and Mediaservice
A
/getIvrCommand
callback request is sent to the application to get instructions.Application responds back with a command to listen for a single DTMF tone and play a greeting phrase using Amazon Polly text to speech. IVR participant will wait until the DTMF matches one digit.
Caller press digit 2. This trigger a new
/getIvrCommand
which contain the matched digit.Application responds with a connection phrase and set
hangup:true
property to hang up the IVR participant.This triggers a
/callEvent
callback indicating that IVR participant have been disconnected.Application responds with a
action:"call"
and a destination to connect the caller with.Mediaservice creates a new participant representing the callee and establish a SIP call with the provided destination.
Callee answers the call which creates a new connection in the session for caller and callee. This triggers a
/callAnswered
callback.Caller decides to hang up the call. This triggers a
/callEvent
to the application.Application responds with a
action:drop
to hang up the remaining participant representing the callee. This will trigger a SIP Bye to be sent for that call leg.No more participants exists for the session which triggers a
/sessionCompleted
callback to be sent to the application.
Below is a simplified sequence diagram where some callbacks such as /callNotify
have been omitted. A detailed description of callbacks and API can be found in the Mediaservice API documentation.
{action:ivr} iotcomms.io->>Caller: SIP 200 Ok Caller->>iotcomms.io: SIP Ack iotcomms.io->>Application: HTTPS POST /callAnswered callback Application->>iotcomms.io: HTTPS 200 OK Caller-->iotcomms.io: Media established iotcomms.io->>Application: HTTPS POST /getIvrCommand callback Application->>iotcomms.io: HTTPS 200 OK
{
dtmf:{maxDigits:1}
phrases:({format:"awstts",
awsTTSParameters:{
"Text": "Welcome. Press 1 for sales and 2 for support."
}})
} Caller-->iotcomms.io: DTMF digit two pressed iotcomms.io->>Application: HTTPS POST /getIvrCommand callback
{dtmfParams:{dtmfMatch:"2",reason:"maxDigits"}} Application->>iotcomms.io: HTTPS 200 OK
{
phrases:({format:"awstts",
awsTTSParameters:{
"Text": "Thank you, you will get connected to support."
}})
hangup:true
} iotcomms.io->>Application: HTTPS POST /callEvent callback
{event:"calledPartyDrop"} Application->>iotcomms.io: HTTPS 200 OK
{action:"call", destAddr:"sip:callee@{customer}.prod-eu-north-1.iotcomms.io" } iotcomms.io->>Caller: SIP Re-nvite iotcomms.io->>Callee: SIP Invite Callee->>iotcomms.io: SIP 200 Ok Caller->>iotcomms.io: SIP 200 Ok iotcomms.io->>Callee: Ack iotcomms.io->>Caller: Ack Caller-->Callee: Media established iotcomms.io->>Application: HTTPS POST /callAnswered callback Application->>iotcomms.io: HTTPS 200 OK Caller->>iotcomms.io: SIP Bye iotcomms.io->>Caller: SIP 200 Ok iotcomms.io->>Application: HTTPS POST /callEvent callback
{event:"callingPartyDrop"} Application->>iotcomms.io: HTTPS 200 OK
{action:"drop"} iotcomms.io->>Callee: SIP Bye Callee->>iotcomms.io: SIP 200 Ok iotcomms.io->>Application: HTTPS POST /sessionCompleted
When iotcomms.io Mediaservice receives an incoming call to a destination to be recorded, a /newCall callback request to the application. This will send a response telling the service to connect the call with the callee and enable recording. Recording is enabled by setting the
callRecording:true
property in the/newCall
callback response. A filename is also provided in the response.Mediaservice places an outbound call to the callee.
Call is connected, and parties talk to each other.
Call is disconnected.
Mediaservice sends a
/recordingReady
callback to indicate that the recording is ready for download.Recording is downloaded using the
/promptfile
API
Below is a simplified sequence diagram where some callbacks such as /callNotify
have been omitted. A detailed description of callbacks and API can be found in the Mediaservice API documentation.
callRecording:true
filename:{name} iotcomms.io->>Caller: SIP 200 Ok Caller->>iotcomms.io: SIP Ack iotcomms.io->>Callee: SIP Invite Callee->>iotcomms.io: SIP 200 Ok iotcomms.io->>Callee: SIP Ack iotcomms.io->>Application: /callAnswered callback Caller->>iotcomms.io: SIP Bye iotcomms.io->>Caller: SIP 200 Ok iotcomms.io->>Application: /callEvent callback Application->>iotcomms.io: action:drop iotcomms.io->>Callee: SIP Bye Callee->>iotcomms.io: SIP 200 Ok iotcomms.io->>Application: /sessionCompleted callback iotcomms.io->>Application: /recordingReady callback Application->>iotcomms.io: GET /promptfile\\\
Call monitoring allows a third party to listen to an ongoing call without participating in the conversation. This is enabled by providing a monitorDestAddr
property in the /newCall
response. The SIP Mediaserver Service will establish a new SIP call to this address after the initial /callAnswered
event is sent. The monitor user will receive an audio stream that contains a mix of the audio from all active participants in the call.
Message Flow
A call arrives at the Mediaservice, triggering a
/newCall
callback.The application responds with an action to connect the caller with a callee and includes
monitorDestAddr
to enable call monitoring.Mediaservice places an outbound call to the callee.
Once the callee answers, a
/callAnswered
callback is sent to the application.Mediaservice then initiates a SIP call to the monitor user.
The monitor user answers the call and begins receiving the mixed audio stream.
When the caller or callee disconnects, a
/callEvent
callback is sent, and the application decides how to proceed.If all participants disconnect, a
/sessionCompleted
callback is sent.
If you wish to make outbound calls when there are no inbound call that initiated the process it is possible to use the /placeivrcall API. It will create a participant in the same way as a call participant was created when a call comes in and the application is notified using the /newCall callback.
Here is an example on how to use the /placeivrcall API:
The sequence is initiated with a placeivrcall.
While the call is progressing a number of callbacks will be generated towards the application. Most of them are just status information indicating the progress of the call. The only callbacks that really need handling is the getIvrCommand which needs to be responded with a parameter action with value call and then a destination address parameter with the phone number of the ARC and then at the end of the call there will be a callEvent callback indicating that either party of the call has hung up. A proper response is then to send a property action with value that specify to drop either the calling party or called party.
Message flow
A /placeivrcall is initiated from the application with the destination address set to the phone number of the device to call.
As the call progress towards the device there will be a /callNotify callback telling that it is ringing in the device.
When the device answer there will be a /callAnswered callback telling that the user has answered.
The system now need to know how to process the call and sends a /getIvrCommand callback. This callback can be responded with a "action": "call" which then connects the device to another device as specified in the response to the getIvrCommand.
The call is now connected to the other device and the progress is reported in /callNotify callbacks.
Eventually the call is answered by the other device and the two devices are now able to talk to each other.
One of the devices hang up and there will be a /callEvent callback to ask what to do with call now. In this case the application decides do drop the call.
Finally there will be a /sessionCompleted callback telling that the session has ended and the call has completed.
{destAddr: "the number to call"} iotcomms.io->>Application: HTTPS 200 Ok iotcomms.io->>Alarm device: SIP Invite Alarm device->>iotcomms.io: SIP 180 Ringing iotcomms.io->>Application: HTTPS POST /callNotify callback
{event:"ringing"} Application->>iotcomms.io: HTTPS 200 OK Alarm device->>iotcomms.io: SIP 200 OK iotcomms.io->>Alarm device: SIP Ack iotcomms.io->>Application: HTTPS POST /callAnswered callback Application->>iotcomms.io: HTTPS 200 OK iotcomms.io->>Application: HTTPS POST /getIvrCommand callback Application->>iotcomms.io: HTTPS 200 OK
{action:"call", destAddr:"sip:ARC@{customer}.prod-eu-north-1.iotcomms.io" } iotcomms.io->>Alarm device: SIP Re-invite Alarm device->>iotcomms.io: SIP 200 Ok iotcomms.io->>Alarm device: Ack Alarm device-->ARC: Media established for ringback tone iotcomms.io->>ARC: SIP Invite ARC->>iotcomms.io: SIP 180 Ringing iotcomms.io->>Application: HTTPS POST /callNotify callback
{event: "ringing"} Application->>iotcomms.io: HTTPS 200 OK ARC->>iotcomms.io: SIP 200 Ok iotcomms.io->>Alarm device: SIP Re-invite Alarm device->>iotcomms.io: SIP 200 Ok iotcomms.io->>Alarm device: Ack iotcomms.io->>ARC: Ack Alarm device-->ARC: Media established for voice call iotcomms.io->>Application: HTTPS POST /callAnswered callback Application->>iotcomms.io: HTTPS 200 OK Note over ARC,Alarm device: ARC is talking to Alarm device Alarm device->>iotcomms.io: SIP Bye iotcomms.io->>Alarm device: SIP 200 Ok iotcomms.io->>Application: HTTPS POST /callEvent callback
{event:"callingPartyDrop"} Application->>iotcomms.io: HTTPS 200 OK
{action:"drop"} iotcomms.io->>ARC: SIP Bye ARC->>iotcomms.io: SIP 200 Ok iotcomms.io->>Application: HTTPS POST /sessionCompleted