Messagebird’s Voice Calling API enables VoIP features for your web application to make, receive, and monitor voice calls from a MessageBird voice-enabled virtual mobile number to and from any country around the world through a REST API.
The Voice Calling API uses HTTP verbs and a RESTful endpoint structure with an access key that is used as the API Authorization. Request and response payloads are formatted as JSON using UTF-8 encoding and URL encoded values.
Looking for a VoIP tool but not a developer? Check out SIP Trunking on your MessageBird Dashboard.
If you are looking for specific documentation for a step you can directly jump to callflow step documentation.
All URLs referenced in MessageBird's Voice Calling API documentation have the base URL in the code snippet on the right side:
https://voice.messagebird.com
The MessageBird API uses HTTP verbs to understand if you want to read (GET), delete (DELETE), create (POST) or update (PUT) an object. When your web application cannot do a PUT, POST or DELETE, we provide the ability to set the method through the query parameter _method.
GET /call-flows/POST /call-flows/GET /call-flows/{id}PUT /call-flows/{id}DELETE /call-flows/{id}GET /call-flows/{id}/numbersPOST /call-flows/{id}/numbersPUT /call-flows/{id}/numbersPOST /calls/GET /calls/GET /calls/{callID}PUT /calls/{callID}DELETE /calls/{callID}POST /calls/{callID}/{destination}GET /calls/{callID}/legsGET /calls/{callID}/legs/{legID}DELETE /legs/{legID}POST /legs/{legID}/holdPOST /legs/{legID}/unholdGET /calls/{callID}/legs/{legID}/recordingsGET /recordings/{recordingID}GET /recordings/{recordingID}.wav# DEPRECATED:GET /calls/{callID}/legs/{legID}/recordings/{recordingID}GET /calls/{callID}/legs/{legID}/recordings/{recordingID}.wavGET /recordings/{recordingID}/transcriptionsPOST /recordings/{recordingID}/transcriptionsGET /transcriptions/{transcriptionID}GET /transcriptions/{transcriptionID}.txt# DEPRECATED:GET /calls/{callID}/legs/{legID}/recordings/{recordingID}/transcriptionsGET /calls/{callID}/legs/{legID}/recordings/{recordingID}/transcriptions/{transcriptionID}GET /calls/{callID}/legs/{legID}/recordings/{recordingID}/transcriptions/{transcriptionID}.txtPOST /calls/{callID}/legs/{legID}/recordings/{recordingID}/transcriptionsGET /webhooks/GET /webhooks/{id}POST /webhooks/PUT /webhooks/{id}DELETE /webhooks/{id}
POST and PUT requests to the API should contain a JSON-formatted payload in the request body.
{"steps": [{"id": "foo","action": "transfer","options": {"destination": "31612345678"}},{"id": "bar","action": "hangup"}]}
MessageBird's Voice Calling API uses API keys to authenticate requests. You can view and manage your API keys in your MessageBird dashboard
Test API keys have the prefix test_ and live API keys have the prefix live_
With each API call, you will need to set request headers including your access key to authenticate yourself.
Header | Description | Required |
---|---|---|
Authorization | Must be in the form of AccessKey {accessKey}. | Yes |
Codes in the 2xx range indicate that a request was successfully processed and codes in the 4xx range indicate that there was an error that resulted from the information sent (e.g. authentication, no balance or a missing or wrong parameter).
In case of an error, the body of the response includes a json formatted response that tells you exactly what is wrong.
Attribute | Type | Description |
---|---|---|
errors[].code | integer | An integer that represents the error type. |
errors[].description | string | A human-readable description of the error. You can provide your users with this information to indicate what they can do about the error. |
{"errors": [{"description": "The 'steps' parameter is required.","code": 11}]}
POST and PUT requests to the API should contain a JSON-formatted payload of less than 64KB in the request body.
MessageBird uses standard HTTP status codes to indicate success or failure of an API request.
HTTP status code | Description |
---|---|
200 Found | The requested resource was found. |
201 Created | A resource has been created. |
204 No Content | The requested resource is empty. |
400 Bad Request | The request contains invalid/missing data, or is malformed. |
401 Unauthorized | The access key is missing or incorrect. |
403 Forbidden | Access to the requested resource was forbidden. |
404 Not Found | The resource could not be found. |
405 Method Not Allowed | The HTTP method is not allowed. |
409 Conflict | Request conflict with the current state of the server. |
500 Internal Server Error | Something went wrong on our end, please try again. |
The following error codes have been deprecated in favor of relying on the status codes listed above.
Code | Description |
---|---|
11 | A required parameter is missing in the request. |
12 | A parameter has an invalid value. |
13 | The requested resource could not be found. |
14 | Access to the requested resource was forbidden. |
15 | Authentication is missing from the HTTP request. |
16 | The request body could not be parsed. Check if the body contents correspond with the supplied Content-Type HTTP header. |
18 | A query parameter has an invalid value. |
21 | An internal server error on the MessageBird platform occured. |
25 | A requested action on the object can't be processed. |
A call flow describes the flow of operations (steps) to be executed when handling an incoming call. Call flows can be assigned to multiple numbers. A number in this context is a purchased number that can be called on the traditional phone network. Each object in the steps array in a call flow describes an operation that executes during a call, e.g. transferring a call or playing back an audio file. The call flow must not exceed 32KB.
https://voice.messagebird.com/call-flows
GET /call-flows/POST /call-flows/GET /call-flows/{id}PUT /call-flows/{id}DELETE /call-flows/{id}GET /call-flows/{id}/numbersPOST /call-flows/{id}/numbersPUT /call-flows/{id}/numbers
This is an object representing a voice call flow at MessageBird.com.
Attribute | Type | Description |
---|---|---|
id | string | The unique ID of the call flow. |
record | bool | Says whether a full call recording is enabled on this call flow, the default value for this attribute is false. |
steps | array | An array of step objects. The sequence of the array items describe the order of execution, where the first item will be executed first, than the second, etcetera. See steps |
default | bool | The default attribute says whether the call flow will be used when no call flow was found for an inbound number. Only one default call flow is allowed. |
createdAt | datetime | The date-time the call flow was created, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
updatedAt | datetime | The date-time the call flow was last updated, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
{"id": "de3ed163-d5fc-45f4-b8c4-7eea7458c635","record": true,"steps": [{"id": "3538a6b8-5a2e-4537-8745-f72def6bd393","action": "transfer","options": {"destination": "31612345678"},}],"createdAt": "2017-03-06T13:34:14Z","updatedAt": "2017-03-06T13:34:14Z"}
This request retrieves a listing of all call flows.
If successful, this request will return an object with a data, _links and pagination properties.
If the request failed, an error object will be returned.
The data property is an array of call flow objects, can be null if there are no call flows. The _links property is an object with HATEOAS links related to the object listing. The pagination property is an object with details about the result page count, total count, and pagination numbers.
GET https://voice.messagebird.com/call-flows
curl -X GET "https://voice.messagebird.com/call-flows" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "de3ed163-d5fc-45f4-b8c4-7eea7458c635","record": false,"steps": [{"id": "3538a6b8-5a2e-4537-8745-f72def6bd393","action": "transfer","options": {"destination": "31612345678"}}],"createdAt": "2017-03-06T13:34:14Z","updatedAt": "2017-03-06T13:34:14Z","_links": {"self": "/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635"}}],"_links": {"self": "/call-flows?page=1"},"pagination": {"totalCount": 1,"pageCount": 1,"currentPage": 1,"perPage": 10}}
This request retrieves a call flow resource.
The single parameter is the unique ID that was returned upon creation.
Parameter | Type | Description |
---|---|---|
id | string | The unique ID which was returned upon creation of a call flow. |
If successful, this request will return an object with a data property, which is an array that has a single call flow object. If the request failed, an error object will be returned.
GET https://voice.messagebird.com/call-flows/{callflowID}
curl -X GET https://voice.messagebird.com/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635 \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "de3ed163-d5fc-45f4-b8c4-7eea7458c635","record": false,"steps": [{"id": "3538a6b8-5a2e-4537-8745-f72def6bd393","action": "transfer","options": {"destination": "31611223344"}}],"createdAt": "2017-03-06T13:34:14Z","updatedAt": "2017-03-06T15:02:38Z",}],"_links": {"self": "/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635"}}
Attribute | Type | Description | Required |
---|---|---|---|
steps | array | An array of step objects. | Yes |
default | bool | The default attribute says whether the call flow will be used when no call flow found for inbound number. Only one default call flow is allowed and the default value for this attribute is false. | No |
record | bool | Informs if a full call recording should be performed. If this option is set to true the call will be recorded, the default is false. | No |
If successful, this request will return an object with a data property, which is an array that has a single call flow object. If the request failed, an error object will be returned.
POST https://voice.messagebird.com/call-flows
curl -X POST https://voice.messagebird.com/call-flows \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM" \-H "Content-Type: application/json" \-d $'{"record": true,"steps": [{"options": {"destination": "31612345678"},"action": "transfer"}]}'
{"data": [{"id": "de3ed163-d5fc-45f4-b8c4-7eea7458c635","record": true,"steps": [{"id": "2fa1383e-6f21-4e6f-8c36-0920c3d0730b","action": "transfer","options": {"destination": "31612345678"}}],"createdAt": "2017-03-06T14:52:22Z","updatedAt": "2017-03-06T14:52:22Z"}],"_links": {"self": "/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635"}}
Each step object describes an action that can be taken in a call flow and holds the parameters for that action.
If you are looking for specific documentation for a step you can directly use the links below:
The say step pronounces a text message with a given voice and language.
Attribute | Type | Description |
---|---|---|
id | string | The unique (within the call flow) identifier of the step. |
action | string | Must be say to perform this action |
options | object | Contains zero or more key-value pairs, where the key is the identifier of the option and value is the option value. See below. |
onKeypressVar | string | The name of the variable used for storing a keypress value when a key is pressed during this step. Setting this will trigger a default timeout of 3 seconds after the sound is played waiting for a keypress. Variables can be used with conditionals. |
onKeypressGoto | string | The ID of the step to jump to when the caller presses a key during this step. If maxNumKeys the jump will happen only after reaching this number or timeout is reached. |
endKey | string | If set, determines which DTMF can trigger the next step (before the maxNumKeys or timeout is reached). The end key is not included in the resulting variable. |
conditions | array | See conditionals |
Attribute | Type | Description | Required |
---|---|---|---|
payload | string | The text to pronounce. Max length 3000 symbols | Yes |
language | string | The language of the text that is to be pronounced. For a list of allowed values see supported languages | Yes |
voice | string | The preferred voice to use for pronouncing text. Allowed values: "male", "female". This preference is ignored if the desired voice is not available for the selected language. See also supported languages | Yes |
repeat | integer | The amount of times to repeat the payload. Allowed values: Between 1 and 10. | No |
timeout | int | The number of seconds to wait after the say step has finished for any keypress. Only taken into account if either onKeypressVar or onKeypressGoto are set. Default value is 3 | No |
ifMachine | string | Action to do when a machine picks up the phone. Possible values are: "continue" - do not check, just play the message; "delay" if a machine answers, wait until the machine stops talking; "hangup" hangup when a machine answers. See AMD | No |
machineTimeout | integer | The time (in milliseconds) to analyze if a machine has picked up the phone. Used in combination with the "delay" and "hangup" values of the "ifMachine" attribute. Minimum: 400, maximum: 10000. Default: 7000. | No |
loop | bool | If set to true the say step will be repeated indefinitely or until another step is executed when used in combination with the onKeypressGoto parameter. | No |
engine | string | If set, specifies the Text to Speech (TTS) engine that will be used to say the message. Possible TTS engines include google, amazon or microsoft. Not all language and voice combinations are possible for each provider; for details consult the list of supported languages by engine. | No |
{"steps": [{"action": "say","options": {"payload": "Hello, I am a robot. This is an example message.","language": "en-GB","voice": "male","repeat": 2},"onKeypressGoto": "bar","onKeypressVar": "foo"}]}
The table below contains a list of locales with the options for the voice attribute of the say step. M denotes male and F female.
Locale | Description | Voices |
---|---|---|
af-ZA | Afrikaans (South Africa) | M, F |
ar-EG | Arabic (Egypt) | M, F |
ar-SA | Arabic (Saudi Arabia) | M, F |
ar-XA | Arabic | M, F |
bg-BG | Bulgarian (Bulgaria) | M, F |
bn-IN | Bangla (India) | M, F |
ca-ES | Catalan (Spain) | M, F |
cmn-CN | Chinese (China) | M, F |
cmn-TW | Chinese (Taiwan) | M, F |
cs-CZ | Czech (Czechia) | M, F |
cy-GB | Welsh (United Kingdom) | M, F |
da-DK | Danish (Denmark) | M, F |
de-AT | Austrian German | M, F |
de-CH | Swiss High German | M, F |
de-DE | German (Germany) | M, F |
el-GR | Greek (Greece) | M, F |
en-AU | Australian English | M, F |
en-CA | Canadian English | M, F |
en-GB | British English | M, F |
en-GB-WLS | British English | M |
en-IE | English (Ireland) | M, F |
en-IN | English (India) | M, F |
en-US | American English | M, F |
es-ES | European Spanish | M, F |
es-MX | Mexican Spanish | M, F |
es-US | Spanish (United States) | M, F |
fi-FI | Finnish (Finland) | M, F |
fil-PH | Filipino (Philippines) | M, F |
fr-CA | Canadian French | M, F |
fr-CH | Swiss French | M, F |
fr-FR | French (France) | M, F |
gu-IN | Gujarati (India) | M, F |
he-IL | Hebrew (Israel) | M, F |
hi-IN | Hindi (India) | M, F |
hr-HR | Croatian (Croatia) | M, F |
hu-HU | Hungarian (Hungary) | M, F |
id-ID | Indonesian (Indonesia) | M, F |
is-IS | Icelandic (Iceland) | M, F |
it-IT | Italian (Italy) | M, F |
ja-JP | Japanese (Japan) | M, F |
jv-ID | Javanese (Indonesia) | M, F |
kn-IN | Kannada (India) | M, F |
ko-KR | Korean (South Korea) | M, F |
lv-LV | Latvian (Latvia) | M, F |
ml-IN | Malayalam (India) | M, F |
ms-MY | Malay (Malaysia) | M, F |
nb-NO | Norwegian Bokmål (Norway) | M, F |
nl-BE | Flemish | M, F |
nl-NL | Dutch (Netherlands) | M, F |
pa-IN | Punjabi (India) | M, F |
pl-PL | Polish (Poland) | M, F |
pt-BR | Brazilian Portuguese | M, F |
pt-PT | European Portuguese | M, F |
ro-RO | Romanian (Romania) | M, F |
ru-RU | Russian (Russia) | M, F |
sk-SK | Slovak (Slovakia) | M, F |
sl-SI | Slovenian (Slovenia) | M, F |
sr-RS | Serbian (Serbia) | M, F |
sv-SE | Swedish (Sweden) | M, F |
ta-IN | Tamil (India) | M, F |
te-IN | Telugu (India) | M, F |
th-TH | Thai (Thailand) | M, F |
tr-TR | Turkish (Turkey) | M, F |
uk-UA | Ukrainian (Ukraine) | M, F |
vi-VN | Vietnamese (Vietnam) | M, F |
yue-HK | Cantonese (Hong Kong SAR China) | M, F |
zh-CN | Chinese (China) | M, F |
zh-HK | Chinese (Hong Kong SAR China) | M, F |
zh-TW | Chinese (Taiwan) | M, F |
If a voice provider is temporarily unavailable and it is necessary, we will automatically choose another text-to-speech engine to pronounce the provided text. This could temporarily change the type of voice and character of the pronunciation.
Not all text to speech engines provide the same combinations of languages and voices. By default we will automatically select an engine if one is not specified, or will fall back to a suitable engine if the one provided in the Say step does not have the appropriate language & voice combination. Before selecting a different engine, a different voice will be attempted first when the engine option is specified.
Locale | Description | Amazon | Microsoft | |
---|---|---|---|---|
af-ZA | Afrikaans (South Africa) | - | M, F | F |
ar-EG | Arabic (Egypt) | - | M, F | - |
ar-SA | Arabic (Saudi Arabia) | - | M, F | - |
ar-XA | Arabic | - | - | M, F |
bg-BG | Bulgarian (Bulgaria) | - | M, F | F |
bn-IN | Bangla (India) | - | M, F | M, F |
ca-ES | Catalan (Spain) | - | M, F | F |
cmn-CN | Chinese (China) | F | - | M, F |
cmn-TW | Chinese (Taiwan) | - | - | M, F |
cs-CZ | Czech (Czechia) | - | M, F | F |
cy-GB | Welsh (United Kingdom) | F | M, F | - |
da-DK | Danish (Denmark) | M, F | M, F | M, F |
de-AT | Austrian German | - | M, F | - |
de-CH | Swiss High German | - | M, F | - |
de-DE | German (Germany) | M, F | M, F | M, F |
el-GR | Greek (Greece) | - | M, F | F |
en-AU | Australian English | M, F | M, F | M, F |
en-CA | Canadian English | - | M, F | - |
en-GB | British English | M, F | M, F | M, F |
en-GB-WLS | British English | M | - | - |
en-IE | English (Ireland) | - | M, F | - |
en-IN | English (India) | F | M, F | M, F |
en-US | American English | M, F | M, F | M, F |
es-ES | European Spanish | M, F | M, F | M, F |
es-MX | Mexican Spanish | F | M, F | - |
es-US | Spanish (United States) | M, F | M, F | M, F |
fi-FI | Finnish (Finland) | - | M, F | F |
fil-PH | Filipino (Philippines) | - | M, F | M, F |
fr-CA | Canadian French | F | M, F | M, F |
fr-CH | Swiss French | - | M, F | - |
fr-FR | French (France) | M, F | M, F | M, F |
gu-IN | Gujarati (India) | - | M, F | M, F |
he-IL | Hebrew (Israel) | - | M, F | - |
hi-IN | Hindi (India) | F | M, F | M, F |
hr-HR | Croatian (Croatia) | - | M, F | - |
hu-HU | Hungarian (Hungary) | - | M, F | F |
id-ID | Indonesian (Indonesia) | - | M, F | M, F |
is-IS | Icelandic (Iceland) | M, F | M, F | F |
it-IT | Italian (Italy) | M, F | M, F | M, F |
ja-JP | Japanese (Japan) | M, F | M, F | M, F |
jv-ID | Javanese (Indonesia) | - | M, F | - |
kn-IN | Kannada (India) | - | M, F | M, F |
ko-KR | Korean (South Korea) | F | M, F | M, F |
lv-LV | Latvian (Latvia) | - | M, F | M |
ml-IN | Malayalam (India) | - | M, F | M, F |
ms-MY | Malay (Malaysia) | - | M, F | M, F |
nb-NO | Norwegian Bokmål (Norway) | F | M, F | M, F |
nl-BE | Flemish | - | M, F | M, F |
nl-NL | Dutch (Netherlands) | M, F | M, F | M, F |
pa-IN | Punjabi (India) | - | - | M, F |
pl-PL | Polish (Poland) | M, F | M, F | M, F |
pt-BR | Brazilian Portuguese | M, F | M, F | F |
pt-PT | European Portuguese | M, F | M, F | M, F |
ro-RO | Romanian (Romania) | F | M, F | F |
ru-RU | Russian (Russia) | M, F | M, F | M, F |
sk-SK | Slovak (Slovakia) | - | M, F | F |
sl-SI | Slovenian (Slovenia) | - | M, F | - |
sr-RS | Serbian (Serbia) | - | M, F | F |
sv-SE | Swedish (Sweden) | F | M, F | F |
ta-IN | Tamil (India) | - | M, F | M, F |
te-IN | Telugu (India) | - | M, F | M, F |
th-TH | Thai (Thailand) | - | M, F | F |
tr-TR | Turkish (Turkey) | F | M, F | M, F |
uk-UA | Ukrainian (Ukraine) | - | M, F | F |
vi-VN | Vietnamese (Vietnam) | - | M, F | M, F |
yue-HK | Cantonese (Hong Kong SAR China) | - | - | M, F |
zh-CN | Chinese (China) | - | M, F | - |
zh-HK | Chinese (Hong Kong SAR China) | - | M, F | - |
zh-TW | Chinese (Taiwan) | - | M, F | - |
The record step initiates an audio recording during a call, e.g. for capturing a user response. The recording can be stopped by using one or more of the attributes maxLength, timeout, finishOnKey.
Attribute | Type | Description |
---|---|---|
id | string | The unique (within the call flow) identifier of the step. |
action | string | Must be record to perform this action |
options | object | Contains zero or more key-value pairs, where the key is the identifier of the option and value is the option value. See below. |
conditions | array | See conditionals |
Attribute | Type | Description | Required |
---|---|---|---|
onFinish | string | A URL from which a new call flow is fetched after the recording stops. The request is a POST request and contains details of the recording. | No |
onFinishTimeout | integer | The timeout in seconds for fetching the call flow from the onFinish URL. Allowed values: Between 1 and 30. For backwards compatibility it defaults to the timeout value if set and otherwise defaults to 5 seconds. | No |
timeout | integer | Seconds of silence allowed before the recording is automatically stopped. If you omit this parameter, silence detection is disabled. If set, it is advised to also explicitly set onFinishTimeout. | No |
maxLength | integer | Maximum length of the recording in seconds. The default is no limit on the recording length. | No |
finishOnKey | string | Key DTMF input to stop the recording. Values allowed are "any", #, *, "none". The default is "none", which means that the recording will not be stopped by a DTMF. | No |
transcribe | bool | If you want to have a transcription of the recording, after the recording has finished. Default value is false. | No |
transcribeLanguage | string | The language of the recording that is to be transcribed. Required when transcribe is true. Allowed values: "de-DE", "en-AU", "en-UK", "en-US", "es-ES", "es-LA", "fr-FR", "it-IT", "nl-NL", "pt-BR". | No |
ifMachine | string | Action to do when a machine picks up the phone. Possible values are: "continue" - do not check; "delay" if a machine answers, wait until the machine stops talking; "hangup" hangup when a machine answers. See AMD | No |
machineTimeout | integer | The time (in milliseconds) to analyze if a machine has picked up the phone. Used in combination with the "delay" and "hangup" values of the "ifMachine" attribute. Minimum: 400, maximum: 10000. Default: 7000. | No |
beep | bool | Whether or not to play a beep when recording begins. Default is true | No |
{"steps": [{"action": "record","options": {"onFinish": "https://messagebird.com/onfinish","timeout": 10,"maxLength": 30,"finishOnKey": "any","transcribe": true,"transcribeLanguage": "en-UK"}}]}
The transfer step transfers the call to a different phone/server. When used with the steps option listed below, the transfer will be completed to the destination only after finishing those steps. For more information on this option and how to use it, see our guide on Call Screening.
Attribute | Type | Description |
---|---|---|
id | string | The unique (within the call flow) identifier of the step. |
action | string | Must be transfer to perform this action |
options | object | Contains zero or more key-value pairs, where the key is the identifier of the option and value is the option value. See below. |
conditions | array | See conditionals |
Attribute | Type | Description | Required |
---|---|---|---|
destination | string | The destination (E.164 formatted number, SIP URI or Client URI) to transfer a call to. E.g. 31612345678, sip:foobar@example.com, or client:name_of_client. The Client URI is in early access at this moment as part of our Client SDK. | Yes |
source | string | Source to override the source for the transfer leg and mask the original source. For more details see Masking numbers. See allowed caller IDs | No |
mask | bool | If set to true the transfer call will appear to be coming from the destination of the primary leg effectively masking the original caller/source. If the source option of the transfer step is also set this value is ignored. For more details see Masking numbers. | |
record | string | Use this option if the transfer leg should be recorded. Option in is being used to record the voice of the destination and out for the source. You can use both to record both source and destination individually. Allowed values: in, out and both options. | No |
ifMachine | string | Action to do when a machine picks up the phone. Possible values are: "continue" - do not check; "delay" if a machine answers, wait until the machine stops talking; "hangup" hangup when a machine answers. See AMD | No |
machineTimeout | integer | The time (in milliseconds) to analyze if a machine has picked up the phone. Used in combination with the "delay" and "hangup" values of the "ifMachine" attribute. Minimum: 400, maximum: 10000. Default: 7000. | No |
noAnswerTimeout | integer | Ringing timeout for not answered call in seconds. Minimum: 20. Maximum: 90. Default: 30. | No |
maxDuration | integer or string | Maximum duration of the call in seconds or as a string. Can contain units of time: e.g. 50s/10m/2h. Minimum: "30s". Maximum: "8h". Default: "8h". | No |
steps | array | Array of steps to execute after the transfer call is picked up but before connecting the parties. Applicable steps are limited to say, play, pause, and hangup. For more information consult these options and our guide on Call Screening. | No |
{"steps": [{"action": "transfer","options": {"destination": "31612345678","record": "both"}}]}
The maskedTransfer step is used on inbound flows to create a number-masking call. When one of the numbers in the numbers array option is matched to the calling party (source) the call is transferred to the other number in this array. However the Calling Line Identity will be replaced with the number that this flow is connected to. If there is no match no transfer will happen and the inbound call will fail. For more masking options see Masking numbers.
Attribute | Type | Description |
---|---|---|
id | string | The unique (within the call flow) identifier of the step. |
action | string | Must be maskedTransfer to perform this action |
options | object | Contains zero or more key-value pairs, where the key is the identifier of the option and value is the option value. See below. |
conditions | array | See conditionals |
Attribute | Type | Description | Required |
---|---|---|---|
numbers | array | An array of strings, where each string is an E.164 formatted number (e.g. 31612345678). | Yes |
record | string | Use this option if the transfer leg should be recorded. Option in is being used to record the voice of the destination and out for the source. You can use both to record both source and destination individually. Allowed values: in, out and both options. | No |
ifMachine | string | Action to do when a machine picks up the phone. Possible values are: "continue" - do not check; "delay" if a machine answers, wait until the machine stops talking; "hangup" hangup when a machine answers. See AMD | No |
machineTimeout | integer | The time (in milliseconds) to analyze if a machine has picked up the phone. Used in combination with the "delay" and "hangup" values of the "ifMachine" attribute. Minimum: 400, maximum: 10000. Default: 7000. | No |
noAnswerTimeout | integer | Ringing timeout for not answered call in seconds. Minimum: 20. Maximum: 90. Default: 30. | No |
maxDuration | integer or string | Maximum duration of the call in seconds or as a string. Can contain units of time: e.g. 50s/10m/2h. Minimum: "30s". Maximum: "8h". Default: "8h". | No |
steps | array | Array of steps to execute after the transfer call is picked up but before connecting the parties. Applicable steps are limited to say, play, pause, and hangup. For more information consult these options and our guide on Call Screening. | No |
{"steps": [{"action": "maskedTransfer","options": {"numbers": ["31612345678", "31612345679"]}}]}
There are three ways to mask numbers for calls you place using the Voice API depending on your use case. In all scenarios two parties A and B would be able to talk to each other without knowing each other's numbers but using a Proxy Number from Messagebird denoted as N.
Use a maskedTransfer step in the callflow of an incoming call to recognize and link two parties together without exposing their numbers to each other. e.g. If N is a Proxy number you own and A and B are numbers that should talk to each other but remain anonymous you could achieve it by letting them both call number N, and setting the callflow of N to be the following:
{"steps": [{"action": "maskedTransfer","options": {"numbers": ["A", "B"]}}]}
In that example if A calls N then B will receive the transferred call as coming from N. Equally, if B calls N then A would receive the call as coming from N.
Set the mask option to true for a transfer step when you want any incoming call to be forwarded to the transfer destination appearing to come from the same number that they originally dialed-in. e.g. If N is a Proxy number you own and A called N you can transfer the call to B with both sides being anonymous by setting the callflow of N to be the following:
{"steps": [{"action": "transfer","options":{"destination": "B"}}]}
This option is similar to the maskedTransfer above but behaves the same without requiring the caller's number in the callflow. Note that this convenience method does not work well for calls originated by the API but only incoming calls.
Set the source option for a transfer step when you want to have full control over how the transfer leg appears to the transfer destination. This is the suggested way when placing a call to party A and then transferring them to party B but requiring anonymity of the two parties. e.g. In the following example A is receiving a call from N and then gets transferred to B. B will see the caller of the transfer leg being C (you may also opt for reusing the number N as C).
{"destination": "A","source": "N","steps": [{"action": "transfer","options":{"destination": "B","source": "C"}}]}
The hangup step ends the call.
Attribute | Type | Description |
---|---|---|
id | string | The unique (within the call flow) identifier of the step. |
action | string | Must be hangup to perform this action |
options | object | Contains zero or more key-value pairs, where the key is the identifier of the option and value is the option value. See below. |
conditions | array | See conditionals |
{"steps": [{"action": "hangup"}]}
The fetchCallFlow step fetches a new call flow from the supplied URL and transfers control to that flow, see Dynamic call flows.
Attribute | Type | Description |
---|---|---|
id | string | The unique (within the call flow) identifier of the step. |
action | string | Must be fetchCallFlow to perform this action |
options | object | Contains zero or more key-value pairs, where the key is the identifier of the option and value is the option value. See below. |
conditions | array | See conditionals |
Attribute | Type | Description | Required |
---|---|---|---|
url | string | The URL to fetch the new call flow from. | Yes |
timeout | integer | The timeout in seconds for fetching the call flow from the url. Allowed values: Between 1 and 30. Defaults to 5. | No |
ifMachine | string | Action to do when a machine picks up the phone. Possible values are: "continue" - do not check; "delay" if a machine answers, wait until the machine stops talking; "hangup" hangup when a machine answers. See AMD | No |
machineTimeout | integer | The time (in milliseconds) to analyze if a machine has picked up the phone. Used in combination with the "delay" and "hangup" values of the "ifMachine" attribute. Minimum: 400, maximum: 10000. Default: 7000. | No |
token | string | Token that will be used to sign the request to the supplied URL in order to verify it is coming from MessageBird. See Validation of signatures | No |
{"steps": [{"action": "fetchCallFlow","options": {"url": "https://messagebird.com/fetchcallflow","timeout": 30}}]}
The play step plays back an audio file.
Attribute | Type | Description |
---|---|---|
id | string | The unique (within the call flow) identifier of the step. |
action | string | Must be play to perform this action |
options | object | Contains zero or more key-value pairs, where the key is the identifier of the option and value is the option value. See below. |
onKeypressVar | string | The name of the variable used for storing a keypress value when a key is pressed during this step. Setting this will trigger a default timeout of 3 seconds after the sound is played waiting for a keypress. Variables can be used with conditionals. |
onKeypressGoto | string | The ID of the step to jump to when the caller presses a key during this step. If maxNumKeys the jump will happen only after reaching this number or timeout is reached. |
endKey | string | If set, determines which DTMF can trigger the next step (before the maxNumKeys or timeout is reached). The end key is not included in the resulting variable. |
maxNumKeys | integer | An optional limit to the number of DTMF events that should be gathered before continuing to the next step. By default, this is set to 1, so any key will trigger the next step. If EndKey is set and MaxNumKeys is unset, no limit for the number of keys that will be gathered will be imposed. It is possible for less keys to be gathered if the EndKey is pressed or the timeout being reached. |
conditions | array | See conditionals |
Attribute | Type | Description | Required |
---|---|---|---|
media | string | The URL of the media file to play. See Supported Media Types for a full list of audio files Messagebird supports. Note that the file extension can also be part of the last query parameter, so http://www.example.com/test.mp3?foo=bar&format=.mp3 is a valid format. | Yes |
loop | bool | If set to true the say step will be repeated indefinitely or until another step is executed when used in combination with the onKeypressGoto parameter. | No |
ifMachine | string | Action to do when a machine picks up the phone. Possible values are: "continue" - do not check, just play the media; "delay" if a machine answers, wait until the machine stops talking; "hangup" hangup when a machine answers. See AMD | No |
machineTimeout | integer | The time (in milliseconds) to analyze if a machine has picked up the phone. Used in combination with the "delay" and "hangup" values of the "ifMachine" attribute. Minimum: 400, maximum: 10000. Default: 7000. | No |
timeout | int | The number of seconds to wait after the play step has finished for any keypress. Only taken into account if either onKeypressVar or onKeypressGoto are set. Default value is 3 | No |
{"steps": [{"action": "play","options": {"media": "https://messagebird.com/play.wav"},"onKeypressGoto": "bar","onKeypressVar": "foo"}]}
Messagebird supports media types with the following file extensions .wav, .mp3, .g722, .gsm, .alaw, .al, .pcm, .ulaw, .raw, .sln, .sln12, .sln16, .sln24, .sln32, .sln44, .sln48, .sln96, .sln192, .vox.
By default, the audio file provided in the media is cached on Messagebird's media server before being played for the user. We do this in order to ensure that the audio file is played more quickly for your users and will result in higher resilience when playing audio in the event that the source file's media server experiences latency or downtime. Messagebird's media server has a cache retention period of 7 days, however we will respect the caching policy as dictated by the source file. To make the most of (or override) Messagebird's caching, note that we preserve the following headers for the media file: Cache-Control, Max-Age, Etag, and Last-Modified.
The pause step pauses (silently) for a given duration.
Attribute | Type | Description |
---|---|---|
id | string | The unique (within the call flow) identifier of the step. |
action | string | Must be pause to perform this action |
options | object | Contains zero or more key-value pairs, where the key is the identifier of the option and value is the option value. See below. |
onKeypressVar | string | The name of the variable used for storing a keypress value when a key is pressed during this step. Variables can be used with conditionals. |
onKeypressGoto | string | The ID of the step to jump to when the caller presses a key during this step. |
endKey | string | If set, determines which DTMF can trigger the next step (before the maxNumKeys or timeout is reached). The end key is not included in the resulting variable. |
maxNumKeys | integer | An optional limit to the number of DTMF events that should be gathered before continuing to the next step. By default, this is set to 1, so any key will trigger the next step. If EndKey is set and MaxNumKeys is unset, no limit for the number of keys that will be gathered will be imposed. It is possible for less keys to be gathered if the EndKey is pressed or the timeout being reached. |
conditions | array | See conditionals |
Attribute | Type | Description | Required |
---|---|---|---|
length | integer or string | The length of the pause. If an integer is given, the pause duration will be in seconds. When providing a string, the unit must be specified. Supported units include us, ms and s. Acceptable pause durations are between 0 - 59s. | Yes |
ifMachine | string | Action to do when a machine picks up the phone. Possible values are: "continue" - do not check; "delay" if a machine answers, wait until the machine stops talking; "hangup" hangup when a machine answers. See AMD | No |
machineTimeout | integer | The time (in milliseconds) to analyze if a machine has picked up the phone. Used in combination with the "delay" and "hangup" values of the "ifMachine" attribute. Minimum: 400, maximum: 10000. Default: 7000. | No |
{"steps": [{"action": "pause","options": {"length": "2s"},"onKeypressGoto": "bar","onKeypressVar": "foo"}]}
The sendKeys step sends DTMF signals during a call.
Attribute | Type | Description |
---|---|---|
id | string | The unique (within the call flow) identifier of the step. |
action | string | Must be sendKeys to perform this action |
options | object | Contains zero or more key-value pairs, where the key is the identifier of the option and value is the option value. See below. |
conditions | array | See conditionals |
Attribute | Type | Description | Required |
---|---|---|---|
keys | string | Keys to send. Allowed set of characters: 0-9, A-D, #, *; with a maximum of 100 keys. | Yes |
duration | integer | Duration of DTMF tone per key in milliseconds. Allowed values: Between 100 and 1000. | No |
interval | integer | Interval between sending keys in milliseconds. Allowed values: Between 0 and 5000. | No |
ifMachine | string | Action to do when a machine picks up the phone. Possible values are: "continue" - do not check; "delay" if a machine answers, wait until the machine stops talking; "hangup" hangup when a machine answers. See AMD | No |
machineTimeout | integer | The time (in milliseconds) to analyze if a machine has picked up the phone. Used in combination with the "delay" and "hangup" values of the "ifMachine" attribute. Minimum: 400, maximum: 10000. Default: 7000. | No |
{"steps": [{"action": "sendKeys","options": {"keys": "*101#","duration": 500,"interval": 2000}}]}
Besides JSON, you can also create an XML based call flow. They offer the same features as JSON, but can be more readable, especially when using step conditions.
To use XML when creating a call flow, the Content-Type HTTP header needs to be set to application/xml. Upon creation, an XML call flow is parsed into a flat array of steps. Any conditional structures with If are ket intact.
By default, steps are sequentially executed. Using the onKeypressGoto attribute in tags, you can alter flow control by skipping to a specific part of the call flow.
XML Element tags and attributes are case-sensitive. For example, using <play> instead of <Play> will give an error.
curl -X POST https://voice.messagebird.com/call-flows \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM" \-H "Content-Type: application/xml" \-d $'<?xml version="1.0" encoding="UTF-8"?><CallFlow><Say language="en-US" voice="male" onKeypressVar="foo" onKeypressGoto="bar">Hello! Press 1, 2, or 3 to continue.</Say><Pause length="10s" onKeypressVar="foo" onKeypressGoto="bar"/><Say language="en-US" voice="male">You did not press anything. Good bye!</Say><Hangup/><If id="bar" condition="foo == 1"><Say language="en-US" voice="male">You pressed 1. Bye!</Say><Hangup/></If><If condition="foo == 2"><Say language="en-US" voice="male">You pressed 2. Bye!</Say><Hangup/></If><If condition="foo == 3"><Say language="en-US" voice="male">You pressed 3. Bye!</Say><Hangup/></If><Say language="en-US" voice="male">You pressed something, but it was not 1, 2 or 3. Bye!</Say></CallFlow>'
{"data": [{"id": "9e568623-a158-45f5-aa71-d877349abafc","record": false,"steps": [{"id": "800a9655-92b0-4f80-bdf7-63d5c7650ec6","action": "say","options": {"payload": "Hello! Press 1, 2, or 3 to continue.","language": "en-US","voice": "male"},"onKeypressGoto": "bar","onKeypressVar": "foo"},{"id": "71090bab-0683-438b-af57-490d7cdb94c8","action": "pause","options": {"length": "10s"},"onKeypressGoto": "bar","onKeypressVar": "foo"},{"id": "184019d3-5f58-4e7a-a770-cd1401440367","action": "say","options": {"payload": "You didn't press anything. Good bye!","language": "en-US","voice": "male"}},{"id": "3b903119-821e-4e4f-baa3-83beb898f427","action": "hangup"},{"id": "bar","action": "say","options": {"payload": "You pressed 1. Bye!","language": "en-US","voice": "male"},"conditions": [{"variable": "foo","operator": "==","value": "1"}]},{"id": "8570f016-c27c-44c1-9327-236df34684d3","action": "hangup","conditions": [{"variable": "foo","operator": "==","value": "1"}]},{"id": "a5fadcfd-1c2a-4017-9e5a-72c5e4df8007","action": "say","options": {"payload": "You pressed 2. Bye!","language": "en-US","voice": "male"},"conditions": [{"variable": "foo","operator": "==","value": "2"}]},{"id": "a144f0e6-3702-4990-a63e-27d497ef801b","action": "hangup","conditions": [{"variable": "foo","operator": "==","value": "2"}]},{"id": "4c6f803b-2e2f-458d-94a6-6698d53b0cc7","action": "say","options": {"payload": "You pressed 3. Bye!","language": "en-US","voice": "male"},"conditions": [{"variable": "foo","operator": "==","value": "3"}]},{"id": "a9bbba8b-ed1b-4fa4-bdae-85c668723103","action": "hangup","conditions": [{"variable": "foo","operator": "==","value": "3"}]},{"id": "38eb5a4c-3a2a-4475-a056-e8ece4e57e17","action": "say","options": {"payload": "You pressed something, but it wasn't 1, 2 or 3. Bye!","language": "en-US","voice": "male"}}],"createdAt": "2017-03-13T13:39:52Z","updatedAt": "2017-03-13T13:39:52Z"}],"_links": {"self": "/v1/call-flows/9e568623-a158-45f5-aa71-d877349abafc"}}
The Transfer tag transfers the call to a different phone/server. The Transfer tag may be optionally used as a container for other tags (steps) that are executed for the destination number before the transfer is complete. Applicable tags for such flows include the Play, Say, Hangup, Pause and If tags. For more information on this functionality, please see our guide on Call Screening.
Attribute | Type | Description | Required |
---|---|---|---|
id | string | The identifier of the step. | No |
destination | string | The destination (E.164 formatted number, SIP URI or Client URI) to transfer a call to. E.g. 31612345678, sip:foobar@example.com, or client:name_of_client. The Client URI is in early access at this moment as part of our Client SDK. | Yes |
The Say tag pronounces a text message with a given voice and language. The XML tag content should contain the text to pronounce. The maximum amount of characters for the payload is 3000.
Attribute | Type | Description | Required |
---|---|---|---|
id | string | The identifier of the step. | No |
language | string | The language of the text that is to be pronounced. For a list of allowed values see supported languages | Yes |
voice | string | The voice to use for pronouncing text. Allowed values: male, female. Note that if the selected voice is not available in the target language, Messagebird will fall back to using the alternate available voice. | Yes |
repeat | integer | The amount of times to repeat the payload. | No |
onKeypressVar | string | The name of the variable used for storing a keypress value when a key is pressed during this step. Variables can be used in If conditions. | No |
onKeypressGoto | string | The ID of the step to jump to when the caller presses a key during this step. | No |
endKey | string | If set, determines which DTMF triggers the next step. The end key is not included in the resulting variable. If not set, no key will trigger the next step. | No |
maxNumKeys | integer | An optional limit to the number of DTMF events that should be gathered before continuing to the next step. By default, this is set to 1, so any key will trigger the next step. If EndKey is set and MaxNumKeys is unset, no limit for the number of keys that will be gathered will be imposed. It is possible for less keys to be gathered if the EndKey is pressed or the timeout being reached. | No |
loop | bool | If set to true the say step will be repeated indefinitely or until another step is executed when used in combination with the onKeypressGoto attribute. | No |
engine | string | If set, specifies the Text to Speech (TTS) engine that will be used to say the message. Possible TTS engines include google, amazon or microsoft. Not all language and voice combinations are possible for each provider; for details consult the list of supported languages by engine. | No |
The Play tag plays back an audio file. The tag should not contain any content, only attributes.
Attribute | Type | Description | Required |
---|---|---|---|
id | string | The identifier of the step. | No |
media | string | The URL of the media file to play. See Supported Media Types for a full list of audio files Messagebird supports. Note that the file extension can also be part of the last query parameter, so http://www.example.com/test.mp3?foo=bar&format=.mp3 is a valid format. | Yes |
onKeypressVar | string | The name of the variable used for storing a keypress value when a key is pressed during this step. Variables can be used in If conditions. | No |
onKeypressGoto | string | The ID of the step to jump to when the caller presses a key during this step. | No |
endKey | string | If set, determines which DTMF triggers the next step. The end key is not included in the resulting variable. If not set, no key will trigger the next step. | No |
loop | bool | If set to true the say step will be repeated indefinitely or until another step is executed when used in combination with the onKeypressGoto attribute. | No |
The Pause tag pauses (silently) for a given duration. The tag should not contain any content, only attributes.
Attribute | Type | Description | Required |
---|---|---|---|
id | string | The identifier of the step. | No |
length | integer or string | The length of the pause. If an integer is given, the pause duration will be in seconds. When providing a string, the unit must be specified. Supported units include us, ms and s. Acceptable pause durations are between 0 - 59s. | Yes |
onKeypressVar | string | The name of the variable used for storing a keypress value when a key is pressed during this step. Variables can be used in If conditions. | No |
onKeypressGoto | string | The ID of the step to jump to when the caller presses a key during this step. | No |
endKey | string | If set, determines which DTMF triggers the next step. The end key is not included in the resulting variable. If not set, no key will trigger the next step. | No |
maxNumKeys | integer | An optional limit to the number of DTMF events that should be gathered before continuing to the next step. By default, this is set to 1, so any key will trigger the next step. If EndKey is set and MaxNumKeys is unset, no limit for the number of keys that will be gathered will be imposed. It is possible for less keys to be gathered if the EndKey is pressed or the timeout being reached. | No |
The Record tag initiates an audio recording during a call, e.g. for capturing a user response. The tag should not contain any content, only attributes. The recording can be stopped by using one or more of the attributes maxLength, timeout, finishOnKey.
Attribute | Type | Description | Required |
---|---|---|---|
id | string | The identifier of the step. | No |
maxLength | integer | Maximum length of a recording in seconds. The default is no limit on the recording length. | No |
timeout | integer | The amount in seconds of silence after which a recording should be stopped. Note that silence detection in noisy environments might not always provide the best results, so it is advised to also set a maxLength as fallback. The default is that silence detection is disabled. | No |
finishOnKey | string | Key DTMF input to stop recording. Values allowed are any, #, *, none. The default is none, which means that a recording can not be stopped by a DTMF. | No |
transcribe | bool | Set to true if you want to have a transcription of the recording. The default is false. | No |
transcribeLanguage | string | If transcribe is set transcribeLanguage is required then. See transcribeLanguage for the list of available languages. | No |
beep | bool | Whether or not to play a beep when recording begins. Default is true | No |
<CallFlow><Say language="en-US" voice="male">Unfortunately we are not able to answer the phone right now. Please leave your name and number.</Say><Record maxLength="120" timeout="3" transcribe="true" transcribeLanguage="en-US" /><Say language="en-US" voice="male">Thanks for calling, we will get back to you shortly.</Say><Hangup/></CallFlow>
The SendKeys tag sends the DTMF signals during a call.
It can be used to dial a number that is reachable via an extension number or to simulate the keypresses of a physical phone to walk through an IVR system.
Attribute | Type | Description | Required |
---|---|---|---|
id | string | The identifier of the step. | No |
keys | string | Keys to send. Allowed set of characters: 0-9, A-D, #, *; with a maximum of 100 keys. | Yes |
curl -X POST https://voice.messagebird.com/calls \-H "Content-Type: application/json" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM" \-d $'{"source": "31644556677","destination": "31626146604","callFlow": {"steps": [{"action": "sendKeys","options": {"keys": "1234567890"}}]},"webhook": {"url": "https://example.com","token": "foobar"}}'
The FetchCallFlow tag fetches a call flow from a remote URL. See: Dynamic call flows. Any steps following this tag are ignored. The tag should not contain any content, only attributes.
Attribute | Type | Description | Required |
---|---|---|---|
id | string | The identifier of the step. | No |
url | string | The URL to fetch a call flow from. Required when steps[].action is fetchCallFlow. | Yes |
timeout | integer | The timeout for fetching the XML/JSON callflow from the URL the user specified at the fetchCallFlow action. It is optional with the default value being 5 seconds. | No |
token | string | Token that will be used to sign the request to the supplied URL in order to verify it is coming from MessageBird. See Validation of signatures | No |
The Hangup tag ends the call. This is an empty-element tag that has no attributes.
The If tag is a container where the contents are other tags (steps) that are executed when the condition in the condition attribute evaluates to true.
Attribute | Type | Description | Required |
---|---|---|---|
id | string | The identifier of the If tag. | No |
condition | string | An expression which will be evaluated before any nested steps are executed, e.g. foobar == 1. Variables need to be stored before the If tag is reached, by using the onKeypressVar in an earlier step. Valid operators are == and !=. | Yes |
<CallFlow><Say language="en-US" voice="male" onKeypressVar="foo" onKeypressGoto="bar">Hello! Press 1, 2, or 3 to continue.</Say><Pause length="10s" onKeypressVar="foo" onKeypressGoto="bar"/><Say language="en-US" voice="male">You did not press anything. Good bye!</Say><Hangup/><If id="bar" condition="foo == 1"><Say language="en-US" voice="male">You pressed 1. Bye!</Say><Hangup/></If><If condition="foo == 2"><Say language="en-US" voice="male">You pressed 2. Bye!</Say><Hangup/></If><If condition="foo == 3"><Say language="en-US" voice="male">You pressed 3. Bye!</Say><Hangup/></If><Say language="en-US" voice="male">You pressed something, but it wasn't 1, 2 or 3. Bye!</Say></CallFlow>
This request updates a call flow resource. The single parameter is the unique ID that was returned upon creation.
Parameter | Type | Description | Required |
---|---|---|---|
id | string | The unique ID which was returned upon creation of a call flow. | Yes |
Parameter | Type | Description | Required |
---|---|---|---|
steps | array | An array of step objects that replaces the current array of steps. | No |
record | bool | Enables or disables full call recording. | No |
If successful, this request will return an object with a data property, which is an array that has a single call flow object. If the request failed, an error object will be returned.
PUT https://voice.messagebird.com/call-flows/{callflowID}
curl -X PUT https://voice.messagebird.com/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635 \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM' \-d $'{"steps": [{"options": {"destination": "31611223344"},"action": "transfer"}]}'
{"data": [{"id": "de3ed163-d5fc-45f4-b8c4-7eea7458c635","record": false,"steps": [{"id": "3538a6b8-5a2e-4537-8745-f72def6bd393","action": "transfer","options": {"destination": "31611223344"}}],"createdAt": "2017-03-06T13:34:14Z","updatedAt": "2017-03-06T15:02:38Z"}],"_links": {"self": "/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635"}}
This request deletes a call flow. The single parameter is the unique ID that was returned upon creation.
Parameter | Type | Description | Required |
---|---|---|---|
id | string | The unique ID which was returned upon creation of a call flow. | Yes |
If successful, this request will return an HTTP header of 204 No Content and an empty response. If the request failed, an error object will be returned.
DELETE https://voice.messagebird.com/call-flows/{callflowID}
curl -X DELETE https://voice.messagebird.com/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635 \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM'
To use a call flow for incoming calls to your number(s), you'll need to assign these numbers to the callflow first. This can be accomplished either by adding (using method POST) or replacing (using method PUT) the numbers for the callflow. Apart from this the two endpoints will behave the same with the same request and responses.
Parameter | Type | Description | Required |
---|---|---|---|
id | string | The unique ID which was returned upon creation of a call flow. | Yes |
numbers | array | An array of strings, where each string is an E.164 formatted number (e.g. 31612345678) you own. | Yes |
If successful, this request will return an object with a data property, which is an array that has a single call flow object. If the request failed, an error object will be returned.
POST https://voice.messagebird.com/call-flows/{callflowID}/numbersPUT https://voice.messagebird.com/call-flows/{callflowID}/numbers
# Add number to the call flowcurl -X POST https://voice.messagebird.com/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635/numbers \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM' \-d $'{"numbers": ["31611111111", "31622222222"]}'# Replace the numbers of the call flowcurl -X PUT https://voice.messagebird.com/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635/numbers \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM' \-d $'{"numbers": ["31611111111", "31622222222"]}'
This request retrieves a listing of all numbers currently assigned to a call flow.
If successful, the request will return an object with a data, _links and pagination properties. If the request failed, an error object will be returned.
The data property is an array of number objects. The _links property is an object with HATEOAS links related to the object listing. The pagination property is an object with details about the result page count, total count, and pagination numbers.
GET https://voice.messagebird.com/call-flows/{callflowID}/numbers
curl -X GET "https://voice.messagebird.com/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635/numbers" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "13f38f34-7ff4-45b3-8783-8d5b1143f22b","number": "31611111111","callFlowId": "de3ed163-d5fc-45f4-b8c4-7eea7458c635","createdAt": "2017-03-16T13:49:24Z","updatedAt": "2017-09-12T08:59:50Z","_links": {"self": "/numbers/13f38f34-7ff4-45b3-8783-8d5b1143f22b"}}],"_links": {"self": "/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635/numbers?page=1"},"pagination": {"totalCount": 1,"pageCount": 1,"currentPage": 1,"perPage": 10}}
Answering Machine Detection (AMD) allows you to determine whether the receiving side of an outgoing call is detected to be a machine (voicemail or fax). Depending on the outcome of the detection you can choose to either hangup the call (ifMachine: "hangup") or to wait until the answering machine has finished talking (ifMachine: "delay") before executing any further steps.
To enable AMD on the first leg of your callflow (for example a call with a simple callflow of a say step) you need to add an ifMachine attribute in the options of its first step. For available values see the callflow object.
{"destination": "31612345678","source": "31644556677","callFlow": {"steps": [{"action": "say","options": {"payload": "Testing hangup on AMD for OTP. Call should hangup","voice": "male","language": "en-GB","ifMachine": "hangup"}}]},"webhook": {"url": "https://some-callback-url"}}
For transfers (where the primary leg is being connected to a secondary leg towards another number) the same options can be set directly as options of the transfer step. For available values see the callflow object.
{"destination": "31612345678","source": "31644556677","callFlow": {"steps": [{"action": "say","options": {"payload": "Testing hangup on AMD for transfers. Call should hangup shortly after ringing.","voice": "male","language": "en-GB"}},{"action":"transfer","options":{"destination":"31612345555","ifMachine":"hangup"}}]},"webhook": {"url": "https://some-callback-url"}}
If the first step of the callflow happens also to be a transfer step the directions will only have effect for the transfer step. If you wish to have AMD detection for the first leg you are advised to use an intermediate step to host the AMD options such as a short "Pause" step.
Answering Machine Detection doesn't come without side-effects. The algorithm works by detecting if the callee answered with an initial silence of a few seconds or started speaking for an unreasonable period without acknowledgement of the other party. Since the callflow will be delayed until a decision is made, especially for transfers that might mean that a part of the call might not be heard by both parties and could lead to some confusion.
The outcome of the Answering Machine Detection is also sent as a separate event in callbacks. For more information read the callback section.
This is an object representing an AMDComplete event.
Attribute | Type | Description |
---|---|---|
Call | Object | The Call object corresponding to the event. See: call. |
Leg | Object | The Leg object corresponding to the event. See: leg |
Status | string | The status of the AMD. Possible values: HUMAN, MACHINE, NOTSURE,HANGUP. |
Cause | string | Indicates the cause that led to the conclusion. e.g. INITIALSILENCE-2500-2500 if a machine was detected due to some unusual silence when starting the call. |
Timestamp | datetime | The date-time the AMD occurred, in RFC 3339 format (e.g. 2020-08-03T15:58:41.56831062Z). |
At the moment AMD configuration is limited to json callflows and XML callflows may only use the `IfMachine` attribute for Say steps.
Call flow steps can be programmed to be executed depending on which key is pressed in an IVR menu. This is a bit more straightforward and easy to code with XML as shown in the if tag but gets more complex when using JSON because there is no way of grouping actions together.
In JSON each step can have a conditions array of condition objects.
Option | Type | Description |
---|---|---|
variable | string | The name of the variable to check its value. This would be set in previous steps via the onKeypressVar option of say/play/pause steps. |
operator | string | == for equality or != for inequality of the variable contents against contents of the value option. |
value | string | The value to compare with the variable contents. |
Each action that needs to be executed under specific conditions must have them defined in the conditions option array. When looking for an action to execute next, the callflow will continue with the first action that follows the last executed step that either has all its conditions evaluated as true or has no conditions.
Let's consider the following example:
{"steps": [{"action": "say","options": {"payload": "press 1 to talk to department A, press 2 to talk to department B","language": "en-US","voice": "male"},"onKeypressVar": "digitpressed","onKeypressGoto": "transferdept"},{"action": "pause","options": {"length": "5s"},"onKeypressVar": "digitpressed","onKeypressGoto": "transferdept"},{"action": "say","options": {"payload": "you didn't press anything. Hanging up","language": "en-US","voice": "male"}},{"action": "hangup"},{"id": "transferdept","action": "say","options": {"payload": "you are being transferred to department A","language": "en-US","voice": "male"},"conditions": [{"variable": "digitpressed","condition": "==","value": "1"}]},{"action": "transfer","options": {"destination": "316123456781"},"conditions": [{"variable": "digitpressed","condition": "==","value": "1"}]},{"action": "say","options": {"payload": "you are being transferred to department B","language": "en-US","voice": "male"},"conditions": [{"variable": "digitpressed","condition": "==","value": "2"}]},{"action": "transfer","options": {"destination": "35123123123"},"conditions": [{"variable": "digitpressed","condition": "==","value": "2"}]},{"action": "say","options": {"payload": "goodbye","language": "en-US","voice": "male"}}]}
In the scenario above the user is presented with an IVR (Interactive voice response) menu. They can choose to be transfered to one of the 2 departments available. If no key is pressed or the wrong key is pressed we'll say something different and hangup.
There are a few key points to pay attention to:
Call flows can be statically created as described in the Creating a call flow. However, you might want something dynamic to happen based on business logic inside your application or organization. For example: Transfer an incoming call to a 24/7 support line when the caller is a priority customer.
To achieve this, our platform can retrieve a call flow from your web service as a call is being received. Your web service can then dynamically provide the call flow to execute, based on the properties of the incoming call (e.g. the caller ID or the dialed number).
When there is a failure during the fetching of the call-flow, for example a time-out or a wrong attribute, you can look at the logs in the dashboard.
First, create a call flow with a fetchCallFlow step (as detailed above), passing the URL of your web service as a url step option.
curl -X POST https://voice.messagebird.com/call-flows \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM" \-H "Content-Type: application/json" \-d $'{"steps": [{"options": {"url": "https://example.com"},"action": "fetchCallFlow"}]}'
Next, incoming calls will trigger an HTTP request to the configured URL with the following parameters:
Parameters | Example | Description |
---|---|---|
callID | 1ebbae0e-e1a6-4b85-8ccb-de609d0b4510 | The unique ID of the call. |
destination | 31612345678 | The destination number that is/was called. |
firstLegDirection | outgoing/incoming | Can be either 'incoming' or 'outgoing' and be used to distinguish whether the originating call was an incoming one or triggered via the API |
source | 31644556677/anonymous | The source number that triggered the call. Only owned or verified numbers can be used. See allowed caller IDs |
variables | {"user_pressed": "5"} | Json object containing metadata of the call. Can include key presses if used together with onKeypressVar in steps or via the Flow Builder. |
In case the previous step is a Transfer or a MaskedTransfer step the variables parameter will contain these additional fields:
GET /?callID=97f9b1d2-b8b4-4db7-8829-ec3e660d2cdb&destination=19027064857&firstLegDirection=incoming&source=%2B31611171210&variables=%7B%22testingvar%22%3A%222%22%7D HTTP/1.1Host: example.comAccept-encoding: gzipUser-Agent: Go-http-client/1.1X-MessageBird-Signature: OomF7gSVo5TdL6mxFvdlYodiTnJtPaEk7V6czObUUI0=Connection: keep-alive
When receiving an incoming HTTP request, your platform should respond with either an XML or JSON call flow (see: The call flow object). Additionally, the response should have a 200 OK status code, and a Content-Type HTTP header with application/xml or application/json as the value, based on what type of call flow you return.
<?xml version="1.0" encoding="UTF-8"?><CallFlow><Say language="en-GB" voice="female">The quick brown fox jumped over the lazy dog.</Say><Hangup/></CallFlow>
When a statically created call flow contains a `fetchCallFlow` step, the fetched call flow will be executed and overrides the previous call flow for the call. If a call flow contained steps after a `fetchCallFlow` step, those will not be executed.
Voice signature generation used for fetching dynamic call flows differs from both the signature generation used in Voice webhooks and the generic signature generation used by other MessageBird services
Each Dynamic Call Flow HTTP request is signed with a signature when provided with a token, a base64 encoded HMAC found in the X-MessageBird-Signature HTTP header. To ensure the callback is coming from the MessageBird platform, we strongly advise you to validate its signature by calculating the HMAC of the callback and base64 encoding it.
Using HMAC-SHA256, the HTTP QUERY PARAMS are the message and the optional token of the related fetchCallFlow step is the secret.
# Emulate the X-Messagebird-Signature generation from the command line using openssl and base64.$ echo -n 'callID=97f9b1d2-b8b4-4db7-8829-ec3e660d2cdb&destination=19027064857&firstLegDirection=incoming&source=%2B31611171210&variables=%7B%22testingvar%22%3A%222%22%7D'| openssl dgst -sha256 -hmac "some-custom-token" -binary |base64v3HpIXiFBDvwiwA4wwgRg6T85Vs7o74w8wAvkOoyDo8=
// Note that the query params should be sorted by alphabetically order of the keys including the variables arraysignature = HMAC_SHA_256(QUERY_PARAMS,signing_key)if HMAC_EQUALS(signature, BASE_64_DECODE(request_signature)) {// Yay!}
A call describes a voice call.
A call is made to a number. A call has legs which are incoming or outgoing voice connections. An incoming leg is created when somebody calls a number. Outgoing legs are created when a call is transferred.
https://voice.messagebird.com/calls
POST /calls/GET /calls/GET /calls/{callID}PUT /calls/{callID}DELETE /calls/{callID}POST /calls/{callID}/{destination}GET /calls/{callID}/legsGET /calls/{callID}/legs/{legID}DELETE /legs/{legID}POST /legs/{legID}/holdPOST /legs/{legID}/unhold
This is an object representing a voice call at MessageBird.com.
Attribute | Type | Description |
---|---|---|
id | string | The unique ID of the call. |
status | string | The status of the call. Possible values: queued, starting, ongoing, ended. |
source | string | The source number of the call, without leading +, ommited if not available. Only owned or verified numbers can be used. See allowed caller IDs |
sourcePool | string | Number pool name to use to select a source number. Can't be specified when using source. |
destination | string | The destination number of the call, without leading +, ommited if not available |
webhook.url | string | The URL to use for status callbacks. See: webhooks. |
webhook.token | string | The token to use for status callbacks. See: webhooks |
createdAt | datetime | The date-time the call was created, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
updatedAt | datetime | The date-time the call was last updated, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
endedAt | datetime | The date-time the call ended, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
{"id": "f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58","status": "ended","source": "31644556677","destination": "31612345678","createdAt": "2017-02-16T10:52:00Z","updatedAt": "2017-02-16T10:59:04Z","endedAt": "2017-02-16T10:59:04Z"}
This request retrieves a listing of all calls.
If successful, this request will return an object with a data, _links and pagination properties. If the request failed, an error object will be returned.
The data property is an array of call objects, can be null if there are no calls. The _links property is an object with HATEOAS links related to the object listing. The pagination property is an object with details about the result page count, total count, and pagination numbers.
To ensure high availability, the `totalCount` value returned from `GET /calls` may return `999999999` when determining the precise count takes more than 2 seconds to calculate. Because this pagination value may be unreliable, we recommend checking that the data property of the response object is not null when scripting requests as you can expect that this value will be null when no results have been found.
GET https://voice.messagebird.com/calls
curl -X GET "https://voice.messagebird.com/calls" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58","status": "ended","source": "31644556677","destination": "31612345678","createdAt": "2017-02-16T10:52:00Z","updatedAt": "2017-02-16T10:59:04Z","endedAt": "2017-02-16T10:59:04Z","_links": {"self": "/calls/f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58"}},{"id": "ac07a602-dbc1-11e6-bf26-cec0c932ce01","status": "ended","source": "31644556677","destination": "31612345678","createdAt": "2017-01-16T07:51:56Z","updatedAt": "2017-01-16T07:55:56Z","endedAt": "2017-01-16T07:55:56Z","_links": {"self": "/calls/ac07a602-dbc1-11e6-bf26-cec0c932ce01"}}],"_links": {"self": "/calls?page=1"},"pagination": {"totalCount": 2,"pageCount": 1,"currentPage": 1,"perPage": 10}}
This request retrieves a call resource. The single parameter is the unique ID that was returned upon creation.
Parameter | Type | Description | Required |
---|---|---|---|
id | string | The unique ID of a call generated upon creation. | Yes |
If successful, this request will return an object with a data property, which is an array that has a single call object. If the request failed, an error object will be returned.
GET https://voice.messagebird.com/calls/{callID}
curl -X GET https://voice.messagebird.com/calls/f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58 \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM'
{"data": [{"id": "f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58","status": "ended","source": "31644556677","destination": "31612345678","createdAt": "2017-02-16T10:52:00Z","updatedAt": "2017-02-16T10:59:04Z","endedAt": "2017-02-16T10:59:04Z"}],"_links": {"self": "/calls/f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58"}}
This request initiates an outbound call. When placing a call, you pass the source (the caller ID), the destination(the number/address that will be called), and the callFlow (the call flow to execute when the call is answered).
Parameter | Type | Description | |
---|---|---|---|
source | string | The caller ID of the call. Only owned or verified numbers can be used. See allowed caller IDs | |
destination | string | The number/address to be called. This can be an E.164 formatted number, SIP URI or Client URI. E.g. 31612345678, sip:foobar@example.com, or client:name_of_client. | |
callFlow | object | The call flow object to be executed when the call is answered. |
Parameter | Type | Description |
---|---|---|
callFlow.noAnswerTimeout | integer | Ringing timeout for not answered call in seconds. Must be set in the callFlow object of the call. Minimum: 20. Maximum: 90. Default: 30. |
callFlow.maxDuration | integer or string | Maximum duration of the call in seconds or as a string. Can contain units of time: e.g. 50s/10m/2h. Minimum: "30s". Maximum: "8h". Default: "8h". |
webhook.url | string | The URL to use for status callbacks. See: webhooks. Setting a webhook URL when creating a call will override any webhook resource settings if they exist. |
webhook.token | string | The token to use for status callbacks. See: webhooks. |
If successful, this request will return an object with a data property, which is an array that has a single call object. If the request failed, an error object will be returned.
POST https://voice.messagebird.com/calls
curl -X POST https://voice.messagebird.com/calls \-H "Content-Type: application/json" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM" \-d $'{"source": "31644556677","destination": "31612345678","callFlow": {"steps": [{"action": "say","options": {"payload": "This is a journey into sound. Good bye!","voice": "male","language": "en-US"}}]},"webhook": {"url": "https://example.com","token": "token_to_sign_the_call_events_with"}}'
{"data": [{"id": "21025ed1-cc1d-4554-ac05-043fa6c84e00","status": "queued","source": "31644556677","destination": "31612345678","createdAt": "2017-08-30T07:35:37Z","updatedAt": "2017-08-30T07:35:37Z","endedAt": null}],"_links": {"self": "/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00"}}
This request updates an active call. You can update steps of an ongoing call by providing a new call-flow url. When you update the call through the API, the API will request the new call-flow at the by you provided new URL. Once the new call-flow is fetched, current ongoing steps will be stopped and the new call-flow will be executed.
Parameter | Type | Description | Required |
---|---|---|---|
fetchCallFlowUrl | string | The URL to fetch the new call flow from. See: Dynamic call flows. | Yes |
Parameter | Type | Description | Required |
---|---|---|---|
fetchCallFlowToken | string | The token that we will use to sign the request. See: Dynamic call flows. | No |
If successful, this request will return an object with a data property, which is an array that has a single call object. If the request failed, an error object will be returned.
PUT https://voice.messagebird.com/calls/{callID}
curl -X PUT https://voice.messagebird.com/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00 \-H "Content-Type: application/json" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM" \-d $'{"fetchCallFlowUrl": "https://www.example.com","fetchCallFlowToken": "foobar"}'
{"data": [{"id": "21025ed1-cc1d-4554-ac05-043fa6c84e00","status": "ongoing","source": "31644556677","destination": "31612345678","createdAt": "2017-08-30T07:35:37Z","updatedAt": "2017-08-30T07:35:37Z","endedAt": null}],"_links": {"legs": "/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00/legs","self": "/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00"}}
This request will hang up all the legs of the call.
Parameter | Type | Description | Required |
---|---|---|---|
id | string | The unique ID of the call. | Yes |
If successful, this request returns an HTTP header of 204 No Content and an empty response. If the request failed, an error object will be returned.
DELETE https://voice.messagebird.com/calls/{callID}
curl -X DELETE https://voice.messagebird.com/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00 \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM'
This request will add a new destination number to an ongoing call. The new participant will receive the call, by default, with a caller ID matching the call originator's number. This can be overriden with the source parameter as described below.
This endpoint should only be used for Inbound calls. Unexpected behavior may result for Outbound originated calls in either how the call ends, or how the remaining steps of the Call Flow proceed.
Parameter | Type | Description | Required |
---|---|---|---|
callID | string | The unique ID of the call. | Yes |
destination | string | The destination (E.164 formatted number, SIP URI or Client URI) to transfer a call to. E.g. 31612345678, sip:foobar@example.com, or client:name_of_client. The Client URI is in early access at this moment as part of our Client SDK. | Yes |
source | string | A source parameter can be added to the body of the request to override the Caller ID displayed for the new call participant. | No |
POST https://voice.messagebird.com/calls/{callID}/{destination}
curl -X POST https://voice.messagebird.com/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00/31612345678 \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM' \-d $'{"source": "310123456789"}'
A leg describes a leg object (inbound or outbound) that belongs to a call. At least one leg exists per call.
Inbound legs are being created when an incoming call to a Number is being initiated.
Outbound legs are created when a call is transferred or when a call is being originated from the API.
https://voice.messagebird.com/calls/{callID}/legs
GET /calls/{callID}/legsGET /calls/{callID}/legs/{legID}DELETE /legs/{legID}POST /legs/{legID}/holdPOST /legs/{legID}/unhold
This is an object representing a leg at MessageBird.com.
Attribute | Type | Description |
---|---|---|
id | string | The unique ID of the leg. |
callID | string | The unique ID of the call that this leg belongs to. |
source | string | The number/SIP/Client URL that is making the connection. |
destination | string | The number/SIP/Client URL that a connection is made to. |
sipResponseCode | integer | If applicable, provides the final SIP status code for the leg. If not available, this field will not be returned. Possible values are listed here. |
status | string | The status of the leg. Possible values: starting, ringing, ongoing, busy, no_answer, failed and hangup. |
direction | string | The direction of the leg, indicating if it's an incoming connection or outgoing (e.g. for transferring a call). Possible values: incoming, outgoing. |
cost | float | The cost of the leg. The amount relates to the currency parameter. |
currency | string | The three-letter currency code (ISO 4217) related to the cost of the leg. |
duration | integer | The duration of the leg, in seconds. |
createdAt | datetime | The date-time the leg was created, in RFC 3339 format (e.g.2017-03-06T13:34:14Z). |
updatedAt | datetime | The date-time the leg was last updated, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
answeredAt | datetime | The date-time the leg was answered, in RFC 3339 format (e.g.2017-03-06T13:34:14Z). |
endedAt | datetime | The date-time the leg ended, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
{"id": "d4f07ab3-b17c-44a8-bcef-2b351311c28f","callId": "f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58","source": "31644556677","destination": "31612345678","status": "hangup","sipResponseCode": 200,"direction": "outgoing","duration": 31,"createdAt": "2017-02-16T10:52:00Z","updatedAt": "2017-02-16T10:52:30Z","answeredAt": "2017-02-16T10:52:30Z","endedAt": "2017-02-16T10:52:30Z"}
This request retrieves a listing of all legs.
Parameter | Type | Description | Required |
---|---|---|---|
id | string | The unique ID of a call generated upon creation. | Yes |
If successful, this request will return an object with a data property containing the leg objects, can be null if there are no legs. If the request failed, an error object will be returned. The _links property is an object with HATEOAS links related to the object listing. The pagination property is an object with details about the result page count, total count, and pagination numbers.
To ensure high availability, the `totalCount` value returned from `GET /legs` may return `999999999` when determining the precise count takes more than 2 seconds to calculate. Because this pagination value may be unreliable, we recommend checking that the data property of the response object is not null when scripting requests as you can expect that this value will be null when no results have been found.
GET https://voice.messagebird.com/calls/{callID}/legs
curl -X GET "https://voice.messagebird.com/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00/legs" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "d4f07ab3-b17c-44a8-bcef-2b351311c28f","callId": "f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58","source": "31123456789","destination": "31123456777","status": "hangup","sipResponseCode": 200,"direction": "outgoing","duration": 31,"cost": 0.000385,"currency": "USD","createdAt": "2017-02-16T10:52:00Z","updatedAt": "2017-02-16T10:52:30Z","answeredAt": "2017-02-16T10:52:30Z","endedAt": "2017-02-16T10:52:30Z","_links": {"self": "/calls/f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58/legs/d4f07ab3-b17c-44a8-bcef-2b351311c28f"}},{"id": "e60ca497-0cf3-4954-b74c-265e95633ec8","callId": "f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58","source": "31123456789","destination": "31123456788","status": "hangup","sipResponseCode": 200,"direction": "incoming","duration": 31,"cost": 0.000385,"currency": "USD","createdAt": "2017-02-16T10:52:00Z","updatedAt": "2017-02-16T10:52:30Z","answeredAt": "2017-02-16T10:52:30Z","endedAt": "2017-02-16T10:52:30Z","_links": {"self": "/calls/f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58/legs/e60ca497-0cf3-4954-b74c-265e95633ec8"}}],"_links": {"self": "/calls/f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58/legs?page=1"},"pagination": {"totalCount": 2,"pageCount": 1,"currentPage": 1,"perPage": 10}}
This request retrieves a leg resource. The parameters are the unique ID of the call and of the leg that were returned upon their respective creation.
Parameter | Type | Description | Required |
---|---|---|---|
callID | string | The unique ID of a call generated upon creation. | Yes |
legId | string | The unique ID of a leg generated upon creation. | Yes |
If successful, this request returns an object with a data property, which is an array that has a single call object. If the request failed, an error object will be returned.
GET https://voice.messagebird.com/calls/{callID}/legs/{legID}
curl -X GET https://voice.messagebird.com/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00/legs/d4f07ab3-b17c-44a8-bcef-2b351311c28f \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM'
{"data": [{"id": "d4f07ab3-b17c-44a8-bcef-2b351311c28f","callId": "f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58","source": "31644556677","destination": "31612345678","status": "hangup","sipResponseCode": 200,"direction": "outgoing","duration": 31,"cost": 0.000385,"currency": "USD","createdAt": "2017-02-16T10:52:00Z","updatedAt": "2017-02-16T10:52:30Z","answeredAt": "2017-02-16T10:52:30Z","endedAt": "2017-02-16T10:52:04Z"}],"_links": {"self": "/calls/f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58/legs/d4f07ab3-b17c-44a8-bcef-2b351311c28f"}}
This request deletes a leg which will result in the leg being immediately disconnected. In a two-way conversation, performing this operation on any leg will hangup the call as a whole.
The parameters are the unique ID of the leg.
Parameter | Type | Description | Required |
---|---|---|---|
legId | string | The unique ID of a leg generated upon creation. | Yes |
If successful or if either the call or the requested leg is already in a final status, this request will return an HTTP header of 204 No Content and an empty response. If the request failed, an error object will be returned.
DELETE https://voice.messagebird.com/legs/{legID}
curl -X DELETE "https://voice.messagebird.com/legs/07fda3f9-ddd3-4267-ab01-71cf55df31df" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
This request places a leg on hold. This results in the caller on that leg being placed in a state separate from the rest of the call participants, unable to hear or speak to other callers.
Audio can be played to the user with the musicOnHold parameter. Note that if not specified, the user will hear silence during the hold. If specified, the audio provided will be played on loop for the duration of the hold.
Parameter | Type | Description |
---|---|---|
legId | string | The unique ID of a leg generated upon creation. |
Parameter | Type | Description |
---|---|---|
musicOnHold | string | Audio to play to the user on hold. |
POST https://voice.messagebird.com/legs/{legID}/hold
curl -X POST "https://voice.messagebird.com/legs/07fda3f9-ddd3-4267-ab01-71cf55df31df/hold" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"\-d $'{"musicOnHold": "https://path.to/hold-music.wav"}'
This request removes a leg from hold. This results in the caller rejoining the other call participant(s) after having been on hold.
Parameter | Type | Description |
---|---|---|
legId | string | The unique ID of a leg generated upon creation. |
POST https://voice.messagebird.com/legs/{legID}/unhold
curl -X POST "https://voice.messagebird.com/legs/07fda3f9-ddd3-4267-ab01-71cf55df31df/unhold" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
Leg objects returned from HTTP requests and via Webhooks that return a leg object may contain a sipResponseCode field if a SIP Status could be determined for a leg. Because this is in some situations not possible, this field may not always be returned. The following table provides an overview of the SIP statuses that MessageBird currently provides. Note that only the numerical value of the SIP Status will be returned.
SIP Status | Description | Common Cause |
---|---|---|
200 - OK | Successful | The call was connected and completed successfully. |
403 - Forbidden | The server understood the request, but is refusing to fulfill it. | The user or the network might have rejected the call. Typically by pressing the reject button on a mobile phone. Occasionally the destination number might not be allowed to be dialed from your account, for example for high-cost destinations such as premium numbers. If this occurs, please contact support. |
404 - Not Found | The server has definitive information that the user does not exist at the domain specified in the Request-URI. | The number is unallocated to a subscriber or does not exist. Please check if the number is correct and in the correct international format.† |
408 - Request Timeout | Couldn't find the user in time. | This could happen when the called party's mobile phone did not respond to the network, typically when there is no cellular / mobile signal or when the battery has died. In case your account ran out of sufficient balance to place the call this resonse code is also used. |
410 - Gone | The user existed once, but is not available here any more. | This could happen when the number has changed and is not allocated anymore. |
480 - Temporarily Unavailable | Callee currently unavailable. | This could happen when the called party's mobile phone did not respond to the network, typically when there is no cellular / mobile signal or when the battery has died. This code may also be used if the user rejects the call, or your account has insufficient balance to place the call. |
484 - Address Incomplete | Request-URI incomplete. | The number does not contain enough digits or does not exist. Please check if the number is correct and in the correct international format.† |
486 - Busy Here | Callee is busy. | The destination is valid, but the user was busy with another call. |
488 - Not Acceptable Here | Some aspect of the session description or the Request-URI is not acceptable. | Typically this indicates the used codecs on a SIP trunking call are not accepted, in rare cases it could also be related to either the number of the called or calling party. |
500 - Internal Server Error | The server could not fulfill the request due to some unexpected condition. | This could indicate an internal server error at one of the MessageBird servers or a downstream carrier. If this happens only for a certain number please check if the number is correct and in the correct international format.† |
501 - Not Implemented | The server does not have the ability to fulfill the request, such as because it does not recognize the request method. | This error comes from a downstream carrier. If this happens only for a certain number please check if the number is correct and in the correct international format.† |
502 - Bad Gateway | The server is acting as a gateway or proxy, and received an invalid response from a downstream server while attempting to fulfill the request. | This error comes from a downstream carrier. If this happens only for a certain number please check if the number is correct and in the correct international format.† |
503 - Service Unavailable | The server is undergoing maintenance or is temporarily overloaded and so cannot process the request. | This could indicate unavailability of one of the MessageBird servers or of a downstream carrier. If this happens only for a certain number please check if the number is correct and in the correct international format.† |
† When dialing internationally, it is often required that the number begins with a country code and omits any "trunk prefixes" like 0.
A recording describes a voice recording of a leg. You can initiate a recording of a leg by having a step in your callflow with the record action set.
https://voice.messagebird.com/calls/{callID}/legs/{legID}/recordings
GET /calls/{callID}/legs/{legID}/recordingsGET /recordings/{recordingID}GET /recordings/{recordingID}.wav# DEPRECATED:GET /calls/{callID}/legs/{legID}/recordings/{recordingID}GET /calls/{callID}/legs/{legID}/recordings/{recordingID}.wav
This is an object representing a recording.
Attributes | Type | Description |
---|---|---|
id | string | The unique ID of the recording. |
format | string | The format of the recording. Supported formats are: wav. |
type | string | The type of the recording, possible values are ivr(result of a record step), transfer(result of a transfer step recording) or call(in case of full call recording). |
legId | string | The ID of the leg that the recording belongs to. |
status | string | The status of the recording. Available statuses are:initialised, recording, done and failed |
duration | integer | The duration of the recording in seconds. |
createdAt | datetime | The date-time the recording entry was created, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
updatedAt | datetime | The date-time the recording entry was last updated, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
startedAt | datetime | The date-time the recording was started, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). Might be null for older recordings. |
finishedAt | datetime | The date-time the recording was finished, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). Might be null for older recordings. |
_links | hash | A hash with HATEOAS links related to the object. This includes the file link that has the URI for downloading the wave file of the recording. |
{"data": [{"id": "3b4ac358-9467-4f7a-a6c8-6157ad181123","format": "wav","legId": "227bd14d-3eee-4380-b01f-fe7723c69a31","status": "done","duration": 7,"createdAt": "2017-05-17T11:42:57Z","updatedAt": "2017-05-17T11:43:04Z","startedAt": "2017-05-17T11:43:03Z","finishedAt": "2017-05-17T11:43:10Z"}],"_links": {"self": "/recordings/3b4ac358-9467-4f7a-a6c8-6157ad181123","file": "/recordings/3b4ac358-9467-4f7a-a6c8-6157ad181123.wav"}}
This request retrieves a recording resource. The parameters are the unique ID of the recording, the leg and the call with which the recording is associated.
Parameter | Type | Description | Required |
---|---|---|---|
callID | string | The unique ID of a call generated upon creation. | Yes |
legId | string | The unique ID of a leg generated upon creation. | Yes |
recordingId | string | The unique ID of a recording generated upon creation. | Yes |
If successful, this request returns an object with a data property, which is an array that has a single recording object. If the request failed, an error object will be returned. The _links property is an object with HATEOAS links related to the object listing. The pagination property is an object with details about the result page count, total count, and pagination numbers.
To ensure high availability, the `totalCount` value returned from `GET /recordings` may return `999999999` when determining the precise count takes more than 2 seconds to calculate. Because this pagination value may be unreliable, we recommend checking that the data property of the response object is not null when scripting requests as you can expect that this value will be null when no results have been found.
GET https://voice.messagebird.com/recordings/{recordingID}
curl -X GET "https://voice.messagebird.com/recordings/4c2ac358-b467-4f7a-a6c8-6157ad181142" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"_links": {"self": "/recordings/796c6d68-d307-46c0-8925-05bf069a7d14","transcriptions": "/recordings/796c6d68-d307-46c0-8925-05bf069a7d14/transcriptions"},"data": [{"id": "796c6d68-d307-46c0-8925-05bf069a7d14","format": "wav","legId": "a6a2a420-bed7-4200-b87b-3d20e6a258c3","status": "done","duration": 18,"type": "call","createdAt": "2020-05-19T06:43:34Z","updatedAt": "2020-05-19T06:43:55Z","deletedAt": null,"startedAt": "2020-05-19T06:43:34Z","finishedAt": "2020-05-19T06:43:55Z","_links": {"file": "/recordings/796c6d68-d307-46c0-8925-05bf069a7d14.wav","self": "/recordings/796c6d68-d307-46c0-8925-05bf069a7d14"}}]}
To list all recordings, you can do a GET request on the /recordings endpoint. The parameters are the unique ID of the recording, as well as filters detailed below.
Parameter | Type | Description | Required |
---|---|---|---|
callID | string | The unique ID of a call generated upon creation. | Yes |
legId | string | The unique ID of a leg generated upon creation. | Yes |
Besides listing all Recordings, the MessageBird Voice Recordings API also provides some filters that can be used as query parameters:
Filter | Type | Description |
---|---|---|
limit | integer | Limit the amount of recordings listed. |
offset | integer | Skip first n results. |
If successful, this request returns an object with a list of recordings, which is an array. If the request failed, an error object will be returned.
GET https://voice.messagebird.com/calls/{callID}/legs/{legID}/recordings
curl -X GET "https://voice.messagebird.com/calls/fdcf0391-4fdc-4e38-9551-e8a01602984f/legs/317bd14d-3eee-4380-b01f-fe7723c6913a/recordings" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
The file HATEOAS link has the appropriate URI for downloading a wave file for the recording. The file is accessible only if you provide the correct API access key for your account and the recording is for a leg/call in your account.
/recordings/{recordingID}.wav
GET https://voice.messagebird.com/recordings/{recordingID}.wav
curl -X GET "https://voice.messagebird.com/recordings/4c2ac358-b467-4f7a-a6c8-6157ad181142.wav" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
Status code | Description |
---|---|
200 | Request has succeeded. It is possible that recording file is partially served. |
404 | Requested recording doesn't exist. |
This request deletes a recording. The parameters are the unique ID of the recording, the leg and the call with which the recording is associated.
Parameter | Type | Description | Required |
---|---|---|---|
callID | string | The unique ID of a call generated upon creation. | Yes |
legId | string | The unique ID of a leg generated upon creation. | Yes |
recordingId | string | The unique ID of a recording generated upon creation. | Yes |
If successful, this request will return an HTTP header of 204 No Content and an empty response. If the request failed, an error object will be returned.
DELETE https://voice.messagebird.com/recordings/{recordingID}
curl -X DELETE "https://voice.messagebird.com/recordings/07fda3f9-ddd3-4267-ab01-71cf55df31df" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
A transcription is a textual representation of a recording as text. You can request an automated transcription for a recording by doing a POST request to the API.
MessageBird supports several languages: de-DE, en-AU, en-UK, en-US, es-ES, es-LA, fr-FR, it-IT, nl-NL, pt-BR. We expect to release support for more languages soon.
https://voice.messagebird.com/recordings/{recordingID}/transcriptions
GET /recordings/{recordingID}/transcriptionsPOST /recordings/{recordingID}/transcriptionsGET /transcriptions/{transcriptionID}GET /transcriptions/{transcriptionID}.txt# DEPRECATED:GET /calls/{callID}/legs/{legID}/recordings/{recordingID}/transcriptionsGET /calls/{callID}/legs/{legID}/recordings/{recordingID}/transcriptions/{transcriptionID}GET /calls/{callID}/legs/{legID}/recordings/{recordingID}/transcriptions/{transcriptionID}.txtPOST /calls/{callID}/legs/{legID}/recordings/{recordingID}/transcriptions
This is an object representing a transcription.
Attribute | Type | Description |
---|---|---|
id | string | The unique ID of the transcription. |
recordingId | string | The ID of the recording that the transcription belongs to. |
status | string | The status of the transcription. Possible values: created, transcribing, done, failed. |
createdAt | datetime | The date-time the transcription was created/requested, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
updatedAt | datetime | The date-time the transcription was last updated, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
_links | hash | A hash with HATEOAS links related to the object. This includes the file link that has the URI for downloading the text transcription of a recording. |
{"data": [{"id": "87c377ce-1629-48b6-ad01-4b4fd069c53c","recordingId": "123da3f9-ddd3-4267-ab01-71cf55df31df","status": "done","createdAt": "2017-06-20T10:03:14Z","updatedAt": "2017-06-20T10:03:14Z"}],"_links": {"self": "/transcriptions/87c377ce-1629-48b6-ad01-4b4fd069c53c","file": "/transcriptions/87c377ce-1629-48b6-ad01-4b4fd069c53c.txt"}}
In order to create a transcription request for an existing recording, you must do a POST request to the following URI:
https://voice.messagebird.com/recordings/{recordingID}/transcriptions
A transcription request is asynchronous. That means that it will take some time before the result has been generated. This depends on the total duration of the recording.
Parameter | Type | Description | Required |
---|---|---|---|
recordingId | string | The unique ID of a recording generated upon creation. | Yes |
language | string | The language of the recording that is to be transcribed. Allowed values: de-DE, en-AU, en-UK, en-US, es-ES, es-LA, fr-FR, it-IT, nl-NL, pt-BR. | Yes |
If successful, this request returns an object with a data property, which is an array that has a single transcription object. If the transcription request failed, an error object will be returned. The _links property is an object with HATEOAS links related to the object listing. The pagination property is an object with details about the result page count, total count, and pagination numbers.
To ensure high availability, the `totalCount` value returned from `GET /transcriptions` may return `999999999` when determining the precise count takes more than 2 seconds to calculate. Because this pagination value may be unreliable, we recommend checking that the data property of the response object is not null when scripting requests as you can expect that this value will be null when no results have been found.
curl -X POST "https://voice.messagebird.com/recordings/07fda3f9-ddd3-4267-ab01-71cf55df31df/transcriptions/" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM" \-d $'{"language": "en-EN"}'
This request retrieves a transcription resource. The parameters are the unique ID of the recording, the leg and, the call with which this recording is associated.
Parameter | Type | Description | Required |
---|---|---|---|
recordingId | string | The unique ID of a recording generated upon creation. | Yes |
If successful, this request returns an object with a data property, which is an array that has a single transcription object. If the request failed, an error object will be returned.
GET https://voice.messagebird.com/recordings/{recordingID}/transcriptions
curl - X GET "https://voice.messagebird.com/transcriptions/87c377ce-1629-48b6-ad01-4b4fd069c53c" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "87c377ce-1629-48b6-ad01-4b4fd069c53c","recordingId": "07fda3f9-ddd3-4267-ab01-71cf55df31df","status": "done","createdAt": "2017-06-20T10:03:14Z","updatedAt": "2017-06-20T10:03:14Z","_links": {"self": "/transcriptions/87c377ce-1629-48b6-ad01-4b4fd069c53c","file": "/transcriptions/87c377ce-1629-48b6-ad01-4b4fd069c53c.txt"}}}
The file HATEOAS link has the appropriate URI for downloading a text file for the transcription. The file is accessible only if you provide the correct API access key for your account and the transcription is for a recording/leg/call in your account.
/transcriptions/{transcriptionID}.txt
A number is a MessageBird number purchased with the voice feature. You can query voice-specific number details. The numbers can have callflows and webhooks associated with them.
https://voice.messagebird.com/numbers
GET /numbersGET /numbers/{number}/call-flowPOST /numbers/{number}/webhookGET /numbers/{number}/webhook
This is an object representing a number. It has number and voice specific metadata
Attribute | Type | Description |
---|---|---|
id | string | The unique ID of the purchased number. |
number | string | The phone number |
callFlowId | string | The unique ID of call flow associated if any. |
createdAt | datetime | The date-time the number was purchased, in RFC 3339 format (e.g. 2018-10-24T16:12:03Z). |
updatedAt | datetime | The date-time the number was last updated, in RFC 3339 format (e.g. 2018-10-24T16:12:03Z) |
{"id": "d212d28a-bfe7-1235-1abd-f01fafdf8755","number": "31123456789","callFlowId": "200d95ee-4fcf-46e7-b75a-32a26cb6ebf4","createdAt": "2019-11-11T14:53:47Z","updatedAt": "2020-07-30T14:30:11Z"}
This request retrieves a listing of all numbers with the voice feature.
https://voice.messagebird.com/numbers
If successful, the request will return an object with data, _links and pagination properties. If the request failed, an error object will be returned.
The data property is an array of number objects. The _links property is an object with HATEOAS links related to the object listing. The pagination property is an object with details about the result page count, total count, and pagination numbers.
GET https://voice.messagebird.com/numbers
curl -X GET "https://voice.messagebird.com/numbers?page=1" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "d212d28a-bfe7-1235-1abd-f01fafdf8755","number": "31123456789","callFlowId": "200d95ee-4fcf-46e7-b75a-32a26cb6ebf4","createdAt": "2019-11-11T14:53:47Z","updatedAt": "2020-07-30T14:30:11Z"},{"id": "023746d4-4ba4-44eb-a619-ba50da3b16f1","number": "32460205634","callFlowId": "e7b768eb-df78-4271-8940-9ffb9149dae7","createdAt": "2018-10-24T16:12:03Z","updatedAt": "2019-02-05T14:38:19Z"}],"_links": {"self": "/numbers?page=1"},"pagination": {"totalCount": 2,"pageCount": 1,"currentPage": 1,"perPage": 10}}
This request retrieves all the webhooks associated with the number (if any).
https://voice.messagebird.com/numbers/{number}/webhook
If successful, the request will return an object with a data and _links. If the request failed, an error object will be returned.
The data property is an array of webhook objects.
GET https://voice.messagebird.com/numbers/{number}/webhook
curl -X GET "https://voice.messagebird.com/numbers/{number}/webhook" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "5f3cf195-b9c2-40fb-b4a6-aad529115f8f","url": "https://example.com/343334","token": "foobar123","createdAt": "2020-08-03T22:50:14Z","updatedAt": "2020-08-03T22:50:14Z"}],"_links": {"self": "/numbers/3123XXXXXX/webhook"}}
This request creates a webhook and associates it with a purchased number if the number is purchased with the voice feature enabled. There is a limit of 5 webhooks allowed per number. Unused webhooks may be deleted via the delete webhook endpoint.
Parameter | Type | Description | Required |
---|---|---|---|
url | string | URL to be used for the callback | Yes |
token | string | Token for authorising the URL | No |
https://voice.messagebird.com/numbers/{number}/webhook
If successful, the request will return an object with a data and _links. If the request failed, an error object will be returned. Duplicate webhooks are silently ignored and will appear as successful.
The data property is an array of webhook objects with only one object in it.
POST https://voice.messagebird.com/numbers/{number}/webhook
curl -X POST "https://voice.messagebird.com/numbers/{number}/webhook" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM" \-H 'Content-Type: application/json' \-d $'{"url": "https://example.com/test","token": "foobar123"}'
{"data": [{"id": "a3105944-703d-413f-bb13-42027dbee2ab","url": "https://example.com/test","token": "foobar123","createdAt": "2020-08-04T00:31:10Z","updatedAt": "2020-08-04T00:31:10Z"}],"_links": {"self": "/webhooks/a3105944-703d-413f-bb13-42027dbee2ab"}}
Webhooks are a way of receiving event data for your calls and associated resources by your own servers.
There are three types of webhooks each with its own purpose.
Generic webhooks
These webhooks are account-wide webhooks and maintainable via the API endpoints described in the next section. They can be used to receive events from all your calls, both inbound and outbound without any extra configuration. You may create up to 5 generic webhooks for your user account.
Call webhooks
Call webhook is a short-lived webhook for outbound calls that can be passed with the create call request via the webhook object. If there is a call webhook set for an outbound call, that (and only that) will be used for all callbacks associated with the call so any generic webhooks will be ignored. Call webhooks only affect the call they are assigned to (including its legs), do not have any effect on other calls and will not appear in the API endpoints defined below.
Number webhooks
Number webhooks are webhooks for inbound calls associated with purchased numbers as described in the numbers section. They can be set once and assigned to one or multiple numbers and will trigger for all inbound calls without any other action needed. There is a limit of 5 number webhooks per number and that limit is seperate from the generic-webhook limit. They will appear in the API endpoints defined below for transparency but creation still needs to happen via the number endpoints.
Some number webhooks might be automatically set just by using our Flowbuilder product and these are critical for the operation of your Flowbuilder flows. For transparency these webhooks will also appear in the API endpoints below and it is advised not to alter nor delete them.
This object represents a configuration for delivering webhooks.
Attribute | Type | Description |
---|---|---|
id | string | The unique ID of the webhook. |
url | string | The callback URL that will be requested when our platform sends a webhook. |
token | string | The secret used for signing webhook requests. It's suggested to be of at least 32bytes long. |
number | string | (Optional) The number shown in the case of number webhooks. |
createdAt | string | The date-time when webhook was created, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
updatedAt | string | The date-time when webhook was updated, in RFC 3339 format (e.g. 2017-03-06T13:34:14Z). |
{"id": "534e1848-235f-482d-983d-e3e11a04f58a","url": "https://example.com/","token": "foobar","createdAt": "2017-03-15T14:10:07Z","updatedAt": "2017-03-15T14:10:07Z"}
https://voice.messagebird.com/webhooks
GET /webhooks/GET /webhooks/{id}POST /webhooks/PUT /webhooks/{id}DELETE /webhooks/{id}
This request retrieves a listing of all webhooks.
If successful, this request returns an object with a data, _links and pagination properties. If the request failed, an error object will be returned.
The data property is an array of webhook objects, can be null if there are no webhooks. The pagination property is an object with details about the result page count, total count, and pagination numbers.
curl -X GET "https://voice.messagebird.com/webhooks" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "534e1848-235f-482d-983d-e3e11a04f58a","url": "https://example.com/","token": "foobar","createdAt": "2017-03-15T13:28:32Z","updatedAt": "2017-03-15T13:28:32Z","_links": {"self": "/webhooks/534e1848-235f-482d-983d-e3e11a04f58a"}}],"_links": {"self": "/webhooks?page=1"},"pagination": {"totalCount": 1,"pageCount": 1,"currentPage": 1,"perPage": 10}}
This request retrieves a webhook resource. The single parameter is the unique ID that was returned upon creation.
Parameter | Type | Description | Required |
---|---|---|---|
id | string | The unique ID which was returned upon creation of a webhook. | Yes |
If successful, this request returns an object with a data property, which is an array that has a single webhook object. If the request failed, an error object will be returned.
GET https://voice.messagebird.com/webhooks/{id}
curl -X GET "https://voice.messagebird.com/webhooks/534e1848-235f-482d-983d-e3e11a04f58a" \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM"
{"data": [{"id": "534e1848-235f-482d-983d-e3e11a04f58a","url": "https://example.com/","token": "foobar","createdAt": "2017-03-15T13:28:32Z","updatedAt": "2017-03-15T13:28:32Z"}],"_links": {"self": "/webhooks/534e1848-235f-482d-983d-e3e11a04f58a"}}
This request creates a new webhook. There is currently a limit of 5 (non-number) webhooks allowed per account and 5 per number.
Parameter | Type | Description | Required |
---|---|---|---|
url | string | The URL to use for status callbacks. Setting a webhook URL when creating a call will override any webhook resource settings if they exist. | Yes |
Parameter | Type | Description | Required |
---|---|---|---|
token | string | The secret used for signing webhook requests. | No |
If successful, this request returns an object with a data property, which is an array that has a single webhook object. If the request failed, an error object will be returned. Duplicate webhooks are silently ignored and will appear as successful.
POST https://voice.messagebird.com/webhooks/
curl -X POST https://voice.messagebird.com/webhooks \-H "Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM" \-H "Content-Type: application/json" \-d $'{"url": "https://example.com/","token": "foobar"}'
{"data": [{"id": "534e1848-235f-482d-983d-e3e11a04f58a","url": "https://example.com/","token": "foobar","createdAt": "2017-03-15T14:10:07Z","updatedAt": "2017-03-15T14:10:07Z"}],"_links": {"self": "/webhooks/534e1848-235f-482d-983d-e3e11a04f58a"}}
This request updates a webhook resource. The single parameter is the unique ID that was returned upon creation.
Parameter | Type | Description | Required |
---|---|---|---|
id | string | The unique ID that was returned upon creation of a webhook. | Yes |
Parameter | Type | Description | Required |
---|---|---|---|
token | string | The secret used for signing webhook requests. | No |
If successful, this request returns an object with a data property, which is an array that has a single webhook object. If the request failed, an error object will be returned.
PUT https://voice.messagebird.com/webhooks/{id}
curl -X PUT https://voice.messagebird.com/webhooks/534e1848-235f-482d-983d-e3e11a04f58a \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM' \-d $'{"url": "https://example.com/baz"}'
{"data": [{"id": "534e1848-235f-482d-983d-e3e11a04f58a","url": "https://example.com/baz","token": "foobar","createdAt": "2017-03-15T13:27:02Z","updatedAt": "2017-03-15T13:28:01Z"}],"_links": {"self": "/webhooks/534e1848-235f-482d-983d-e3e11a04f58a"}}
This request deletes a webhook. The single parameter is the unique ID that was returned upon creation. This can also be used to delete webhooks for a number.
Parameter | Type | Description | Required |
---|---|---|---|
id | string | The unique ID that was returned upon creation of a webhook. | Yes |
If successful, this request returns an HTTP header of 204 No Content and an empty response. If the request failed, an error object will be returned.
DELETE https://voice.messagebird.com/webhooks/{id}
curl -X DELETE https://voice.messagebird.com/webhooks/534e1848-235f-482d-983d-e3e11a04f58a \-H 'Authorization: AccessKey test_gshuPaZoeEG6ovbc8M79w0QyM'
Callbacks are HTTP requests sent to your platform when a call is created or updated. A callback is triggered by a webhook. To set up webhooks, please refer to the webhooks documentation.
Each HTTP request has a body with a JSON object of the created/updated resource.
Attribute | Type | Description |
---|---|---|
timestamp | datetime | The date-time the callback was created, in RFC 3339 format (e.g. 2020-08-03T15:58:41.56831062Z). |
items | array | An array of items that triggered a callback. When sending callbacks, our platform might batch items, where each item will be an object in this array. |
items[].type | string | The type of the resource that got created/updated. e.g. call, leg,transcription. |
items[].event | string | The event that triggered the callback. e.g. callCreated, callUpdated,amdComplete. Optional |
items[].payload | object | The resource related to the event. |
Callbacks are sent for multiple types of events and the items in the callback body may vary per type. Web callbacks are currently supported for the following:
Event Type | Events | Payload |
---|---|---|
call | callCreated,callUpdated | call |
leg | leg | |
AMDCompleteEvent | amdComplete | amdComplete |
recording | recordingStarted,recordingUpdated | recording |
transcription | transcriptionCreated,transcriptionFinished,transcriptionTranscribing | transcription |
Your platform should respond with a 200 OK HTTP header.
POST / HTTP/1.1Host: example.comContent-Type: application/jsonX-MessageBird-Signature: roAnwpDfIzW6G3JpKVS6866CKHcJQUiAC9DqswzGY6s/xFPUIa5Qla9AZuCOSQ=Content-Length: 760{"timestamp": "2017-08-30T07:56:46Z","items": [{"type": "call","event": "callUpdated","payload": {"id": "5a0dfae6-c809-4f6f-9e3d-c593149e4c0f","status": "ended","source": "31644556677","destination": "31612345678","createdAt": "2017-08-30T07:54:22Z","updatedAt": "2017-08-30T07:56:46Z","endedAt": "2017-08-30T07:56:46Z",}}]}
POST / HTTP/1.1Host: example.comContent-Type: application/jsonX-MessageBird-Signature: roAnwpDfIzW6G3JpKVS6866CKHcJQUiAC9DqswzGY6s/xFPUIa5Qla9AZuCOSQ=Content-Length: 376{"timestamp": "2017-09-14T07:40:12Z","items": [{"type": "leg","payload": {"id": "f3e699db-68a5-49dc-8f5b-e5272a7349c7","callId": "2452531a-b7a9-4797-a45e-20f5feaf46ce","source": "31644556677","destination": "31612345678","status": "ringing","direction": "outgoing","duration": 0,"createdAt": "2017-09-14T07:40:07Z","updatedAt": "2017-09-14T07:40:07Z","answeredAt": null,"endedAt": null}}]}
AMD events will mainly have a status and a cause.
The status can have the values: MACHINE,HUMAN,NOTSURE,HANGUP and the cause will give more information about the detection. e.g. INITIALSILENCE-2500-2500 if a machine was detected due to some unusual silence when starting the call.
POST / HTTP/1.1Host: example.comAccept-Encoding: gzipContent-Type: application/jsonMessagebird-Request-Timestamp: 1593666577Messagebird-Signature: VasRR95LGHzM2DJ1tF/qaegtzUm8alUPVhiLNQoQjmQ=User-Agent: MessageBirdHTTPQueue/1386X-Messagebird-Request-Id: 3a13544c-bc22-11ea-a9a1-363c205f94d1Content-Length: 817Connection: keep-alive{"timestamp": "2020-07-02T05:09:37.745741202Z","items": [{"type": "AMDCompleteEvent","event": "amdComplete","payload": {"Call": {"id": "c95ac24f-10e7-48ad-aa03-2887727d03b0","status": "ongoing","source": "31644556677","destination": "31612345678","webhook": {"url": "https://example.com"},"createdAt": "2020-07-02T05:09:29Z","updatedAt": "2020-07-02T05:09:33Z","endedAt": null},"Leg": {"id": "46733c65-0865-4c53-9e65-f7a09f0ec588","callId": "c95ac24f-a0e7-48ad-aa03-2887727d03b0","source": "31207009850","destination": "31624973844","status": "ongoing","direction": "outgoing","duration": null,"createdAt": "2020-07-02T05:09:29Z","updatedAt": "2020-07-02T05:09:37Z","answeredAt": "2020-07-02T05:09:33.183Z","endedAt": null},"Status": "MACHINE","Cause": "INITIALSILENCE-2500-2500","Timestamp": "2020-07-02T05:09:37.745741202Z"}}]}
It is suggested not to depend on the completeness of the data received in the callbacks as some fields' availability may vary depending on the type and state of call. For example legs will not always have a duration nor cost and some other fields like answeredAt might be null. For AMD events specifically the call and leg data might not be fully synchronised with the actual state of the call and is provided mainly matching with other call and leg data via the call and leg ID's.
Voice webhook/callback signature generation used in POST HTTP requests differs from both the signature generation used for fetching Dynamic call flows and the generic signature generation used by other MessageBird services
Each Webhook callback HTTP request is signed with a signature, a base64 encoded HMAC found in the X-MessageBird-Signature HTTP header. To ensure the callback is coming from the MessageBird platform, we strongly advise you to validate its signature by calculating the binary HMAC of the callback and base64 encoding it.
Using HMAC-SHA256, the HTTP body is the message and the token of the related webhook resource is the secret. Only handle the webhook if the computed value matches the signature in the HTTP header.
# Emulate the X-Messagebird-Signature generation from the command line using openssl and base64.$ echo -n 'callID=97f9b1d2-b8b4-4db7-8829-ec3e660d2cdb&destination=19027064857&firstLegDirection=incoming&source=%2B31611171210&variables=%7B%22testingvar%22%3A%222%22%7D'| openssl dgst -sha256 -hmac "some-custom-token" -binary |base64v3HpIXiFBDvwiwA4wwgRg6T85Vs7o74w8wAvkOoyDo8=
signature = HMAC_SHA_256(SHA_256_SUM(BODY),signing_key)if HMAC_EQUALS(signature, BASE_64_DECODE(request_signature)) {// Yay!}
Only phone numbers which are owned or verified can be used as a caller ID.
An owned number is a MessageBird-hosted number that you bought via your account.
A verified number is non-MessageBird-hosted number which is verified in your account. You can find more about verified numbers in the article.