SpeechCall Messages
SpeechCall is an interactive voice response (IVR) message type that allows you to make automated voice calls with menu options and DTMF (dual-tone multi-frequency) interactions.
Overview
SpeechCall enables businesses to:
- Make automated voice calls to customers
- Play introductory audio messages
- Present interactive menu options
- Handle DTMF keypress responses (0-9, *, #)
- Define custom behavior for invalid/timeout inputs
- Trigger webhooks with custom bodies and headers based on user selections
- Manage call flow dynamically (navigate between menus)
Use Cases
- Customer Surveys - Collect feedback via phone menu options
- Appointment Reminders - Confirm or reschedule with voice interaction
- Order Tracking - Provide order status updates
- Interactive Notifications - Deliver important information with action options
- Voice Verification - Multi-factor authentication via voice calls
Request Format
Basic Structure
{
"messages": [
{
"from": "YourSender",
"to": "+380XXXXXXXXX",
"text": "ivr",
"type": "speechcall",
"menu": [
{
"introUrl": "ivr_XXXXX",
"idleTimeoutMsec": 10000,
"dtmfActions": {
"d1": [
{
"action": "webhook",
"url": "https://YourWebhookURL/0",
"body": {
"confirm": true
},
"headers": {
"test-header": "test"
}
},
{
"action": "hangup"
}
],
"d2": [
{
"action": "webhook",
"url": "https://YourWebhookURL/1",
"body": {
"confirm": false
}
},
{
"action": "hangup"
}
],
"wrong": [
{
"action": "gotoMenu",
"menu": "1"
}
]
}
}
]
}
]
}
Parameter Description
| Parameter | Type | Required | Description |
|---|---|---|---|
from | string | Yes | Sender identifier (alpha name or ID) |
to | string | Yes | Recipient phone number in international format |
text | string | Yes | Text value, typically “ivr” for SpeechCall |
type | string | Yes | Must be "speechcall" |
menu | array | Yes | Array of menu configurations for the call |
Menu Configuration
Each menu object contains:
| Parameter | Type | Required | Description |
|---|---|---|---|
introUrl | string | Yes | URL or identifier of the introductory audio file |
idleTimeoutMsec | integer | No | Timeout in milliseconds to wait for a keypress (e.g., 10000). If the user does not respond, the actions configured under the wrong key will be executed |
dtmfActions | object | Yes | Map of DTMF keys to actions |
DTMF Actions
The dtmfActions object maps DTMF keys or special conditions to arrays of actions:
| DTMF Key | Description |
|---|---|
d0 | Press 0 |
d1 | Press 1 |
d2 | Press 2 |
| … | … |
d9 | Press 9 |
d* | Press * |
d# | Press # |
wrong | Triggers when an invalid key is pressed or when idleTimeoutMsec is reached without any input |
Each DTMF key/condition maps to an array of actions that will be executed in sequence.
Supported Actions
| Action | Parameters | Description |
|---|---|---|
webhook | url (string, required)body (object, optional)headers (object, optional) | Sends an HTTP POST request in JSON format to the specified URL. The body object will be nested under the action field in the webhook request. Custom headers are included as HTTP headers. |
hangup | None | Ends the call |
gotoMenu | menu (string or integer) | Navigates the call to another menu in the menu array using its 0-based index (e.g., "1") |
Detailed Action Behavior
Webhook Action (webhook)
The webhook action sends an HTTP POST request to your callback URL with the call metadata and optional custom data:
- If a
bodyis provided, its key-value pairs are sent inside theactionfield of the payload body. - If
headersare provided, they are sent as custom HTTP headers in the request.
Hangup Action (hangup)
The hangup action terminates the active call immediately. No further actions in the sequence or menus will be processed after a hangup action.
Go to Menu Action (gotoMenu)
The gotoMenu action redirects the flow of the call to a different menu structure within the menu array. It takes a single parameter menu which specifies the 0-based index of the target menu (e.g., "1" to go to the second menu, or "0" to restart the first menu).
Inactivity & Error Handling (wrong)
The wrong key inside dtmfActions is a special fallthrough handler. It executes its array of actions sequence in two scenarios:
- Invalid Input: The caller presses a DTMF key that is not defined in
dtmfActions(for example, they press3but the menu only definesd1andd2). - Idle Timeout: The caller does not press any key within the duration specified by
idleTimeoutMsec.
If wrong is not defined and the caller presses an invalid key or times out, the call flow will hang up by default. Defining wrong allows you to build loop menus (e.g. going back to the same menu with "action": "gotoMenu", "menu": "0") or redirecting the user to a help menu.
Webhook Delivery Format
When the webhook action is triggered, the system sends an HTTP POST request to the configured url with Content-Type: application/json.
Webhook Request Headers
If the action is configured with the headers parameter, those key-value pairs are included as HTTP headers in the request.
Webhook Request Body
The JSON payload sent to your webhook URL has the following structure:
{
"from": "0443914272",
"to": "50001",
"mid": "7748021",
"action": {
"confirm": true
}
}
| Field | Type | Description |
|---|---|---|
from | string | Caller phone number / Sender ID |
to | string | Recipient phone number |
mid | string | Message ID |
action | object | The custom JSON object defined in the action’s body field |
Complete Example
Simple IVR with Timeout & Input Validation
{
"messages": [
{
"from": "YourSender",
"to": "+380XXXXXXXXX",
"text": "ivr",
"type": "speechcall",
"menu": [
{
"introUrl": "ivr_651854",
"idleTimeoutMsec": 10000,
"dtmfActions": {
"d1": [
{
"action": "webhook",
"url": "https://YourWebhookURL/0",
"body": {
"confirm": true
}
},
{
"action": "hangup"
}
],
"d2": [
{
"action": "webhook",
"url": "https://YourWebhookURL/1",
"body": {
"confirm": false
}
},
{
"action": "hangup"
}
],
"wrong": [
{
"action": "hangup"
}
]
}
}
]
}
]
}
Complex IVR with Multiple Menus and DTMF Routing
This example demonstrates how to define multiple menus and navigate between them using the gotoMenu action when the user inputs an invalid key or when the call times out. It also shows custom bodies and custom HTTP headers sent with the webhook triggers.
{
"messages": [
{
"from": "YourSender",
"to": "+380XXXXXXXXX",
"text": "ivr",
"type": "speechcall",
"menu": [
{
"introUrl": "ivr_XXXXX",
"idleTimeoutMsec": 10000,
"dtmfActions": {
"d1": [
{
"action": "webhook",
"url": "https://YourWebhookURL/0",
"body": {
"confirm": true
},
"headers": {
"test-header": "test"
}
},
{
"action": "hangup"
}
],
"d2": [
{
"action": "webhook",
"url": "https://YourWebhookURL/1",
"body": {
"confirm": false
}
},
{
"action": "hangup"
}
],
"wrong": [
{
"action": "gotoMenu",
"menu": "1"
}
]
}
},
{
"introUrl": "ivr_651854",
"idleTimeoutMsec": 10000,
"dtmfActions": {
"d1": [
{
"action": "webhook",
"url": "https://YourWebhookURL/0",
"body": {
"confirm": true
}
},
{
"action": "hangup"
}
],
"d2": [
{
"action": "webhook",
"url": "https://YourWebhookURL/1",
"body": {
"confirm": false
}
},
{
"action": "hangup"
}
],
"wrong": [
{
"action": "hangup"
}
]
}
}
]
}
]
}
Response Format
Success Response
{
"messages": [
{
"messageId": "unique-message-id",
"recipient": "+380XXXXXXXXX",
"status": "sent"
}
]
}
Error Handling
| HTTP Status | Description |
|---|---|
| 200 | Request successful |
| 400 | Invalid request format |
| 401 | Authentication failed |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
cURL Example
curl -X POST https://restapi.smsbat.com/bat/messagelist \
-u "username:password" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"from": "YourSender",
"to": "+380XXXXXXXXX",
"text": "ivr",
"type": "speechcall",
"menu": [
{
"introUrl": "ivr_XXXXX",
"idleTimeoutMsec": 10000,
"dtmfActions": {
"d1": [
{
"action": "webhook",
"url": "https://YourWebhookURL/0",
"body": {
"confirm": true
},
"headers": {
"test-header": "test"
}
},
{
"action": "hangup"
}
],
"d2": [
{
"action": "webhook",
"url": "https://YourWebhookURL/1",
"body": {
"confirm": false
}
},
{
"action": "hangup"
}
],
"wrong": [
{
"action": "gotoMenu",
"menu": "1"
}
]
}
},
{
"introUrl": "ivr_651854",
"idleTimeoutMsec": 10000,
"dtmfActions": {
"d1": [
{
"action": "webhook",
"url": "https://YourWebhookURL/0",
"body": {
"confirm": true
}
},
{
"action": "hangup"
}
],
"d2": [
{
"action": "webhook",
"url": "https://YourWebhookURL/1",
"body": {
"confirm": false
}
},
{
"action": "hangup"
}
],
"wrong": [
{
"action": "hangup"
}
]
}
}
]
}
]
}'
Best Practices
- Audio Files - Ensure intro URLs are accessible and audio files are in supported formats
- Webhook Reliability - Design webhooks to respond quickly (within 2 seconds)
- DTMF Options - Limit menu options to 4-6 choices for better user experience
- Timeout Handling - Use
idleTimeoutMsecto specify custom inactivity limits (e.g. 10000 ms), and configure a graceful fallback under thewrongDTMF key (like repeating the menu or hanging up) - Multi-Menu Call Flow - Use
gotoMenucarefully to prevent infinite loops when routing users back to previous menus - Fallback Strategy - Use fallback messages for users who don’t answer or disconnect
Related Topics
- Send Message - General message sending guide
- Flash Call - Simple voice verification calls
- Check Status - Track message delivery status
- Message Types - Overview of all supported message types