Difference between revisions of "MOR API flash calls"
(→Usage) |
|||
| (39 intermediate revisions by the same user not shown) | |||
| Line 3: | Line 3: | ||
The Flash Call API allows you to initiate a call to a specified destination number and receive its status (RINGING, BUSY, ANSWERED, FAILED, or TIMEOUT). The call is automatically canceled upon receiving a RINGING (PROGRESS) status or if the call is answered.<br/> | The Flash Call API allows you to initiate a call to a specified destination number and receive its status (RINGING, BUSY, ANSWERED, FAILED, or TIMEOUT). The call is automatically canceled upon receiving a RINGING (PROGRESS) status or if the call is answered.<br/> | ||
'''Availability:''' This API is available from '''MOR | '''Availability:''' This API is available from '''MOR X19'''. | ||
=Usage= | =Usage= | ||
This API does not follow standard MOR API usage and must be configured | This API does not follow standard MOR API usage and must be configured independently. Global MOR API settings do not apply to this API service. | ||
=Configuration= | =Configuration= | ||
| Line 20: | Line 20: | ||
* '''flash_calls_api_enabled''' - if set to 1, enables Flash Calls API. | * '''flash_calls_api_enabled''' - if set to 1, enables Flash Calls API. | ||
* ''' | * '''flash_calls_api_allowed_users''' - comma separated list of User IDs who are allowed to use this API. Can be set to "all" to allow all Users to use this API. | ||
* '''flash_calls_api_default_device_id''' - default Device ID that will be used when no '''device_id''' parameter is passed to the [[#/flash_calls/call | /flash_calls/call]] endpoint. | * '''flash_calls_api_default_device_id''' - default Device ID that will be used when no '''device_id''' parameter is passed to the [[#/flash_calls/call | /flash_calls/call]] endpoint. | ||
* '''flash_calls_api_default_timeout_ms''' - default timeout (in milliseconds) when no '''timeout''' parameter is passed to the [[#/flash_calls/call | /flash_calls/call]] endpoint. | * '''flash_calls_api_default_timeout_ms''' - default timeout (in milliseconds) when no '''timeout''' parameter is passed to the [[#/flash_calls/call | /flash_calls/call]] endpoint. | ||
| Line 29: | Line 29: | ||
* '''flash_calls_api_jwt_token_expiration''' - JWT token expiration time in seconds (see [[#Authentication | Authentication]] section). | * '''flash_calls_api_jwt_token_expiration''' - JWT token expiration time in seconds (see [[#Authentication | Authentication]] section). | ||
* '''flash_calls_api_jwt_secret_key''' - secret key for JWT authentication (see [[#Authentication | Authentication]] section). | * '''flash_calls_api_jwt_secret_key''' - secret key for JWT authentication (see [[#Authentication | Authentication]] section). | ||
* '''flash_calls_api_webhook_timeout''' - timeout in seconds for webhook requests (see [[#Webhooks| Webhooks]] section). | |||
<br/> | <br/> | ||
'''AMI settings''' | '''AMI settings''' | ||
Flash Calls are initiated via Asterisk AMI. The following settings should be configured with specific Asterisk server details | Flash Calls are initiated via Asterisk AMI. The following settings should be configured with specific Asterisk server details: | ||
* '''flash_calls_ami_username''' - AMI username. | * '''flash_calls_ami_username''' - AMI username. Usually 'mor'. | ||
* '''flash_calls_ami_password''' - AMI password. | * '''flash_calls_ami_password''' - AMI password. Usually 'morsecret'. | ||
* '''flash_calls_ami_host''' - AMI host. | * '''flash_calls_ami_host''' - AMI host. IP address of Asterisk server which should be used to originate Flash Calls API SIP calls. | ||
* '''flash_calls_ami_port''' - AMI port. | * '''flash_calls_ami_port''' - AMI port. Usually 5038. | ||
<br> | <br> | ||
'''Note:''' if Asterisk and GUI are on different servers, make sure that GUI IP is permitted in Asterisk manager.conf settings.<br/><br/> | |||
All settings must be configured.<br/> | |||
When these settings are configured or changed, the Flash Calls API service must be restarted in '''GUI''' server: | When these settings are configured or changed, the Flash Calls API service must be restarted in '''GUI''' server: | ||
systemctl restart mor_flash_calls | systemctl restart mor_flash_calls | ||
After restart, make sure the service is running: | |||
systemctl status mor_flash_calls | |||
If the service is not running, check '''/var/log/mor/mor_flash_calls.log'''. Fix the errors (usually some configuration is missing) and restart the service again. | |||
==Configuration from GUI== | ==Configuration from GUI== | ||
Device (and User) should be created for Flash Calls and the ID of this Device should be set in '''flash_calls_api_default_device_id''' setting. This Device will be used for initiating Flash Calls when no specific Device is requested via | Device (and User) should be created for Flash Calls and the ID of this Device should be set in '''flash_calls_api_default_device_id''' setting. This Device will be used for initiating Flash Calls when no specific Device is requested via '''device_id''' parameter. | ||
=API= | =API= | ||
| Line 109: | Line 119: | ||
===/flash_calls/token=== | ===/flash_calls/token=== | ||
Endpoint to generate JWT token for authentication in other endpoints. Only available if JWT authentication is used. Username and password must be provided in Authorization header. | Endpoint to generate JWT access token for authentication in other endpoints. Only available if JWT authentication is used. '''Username and password must be provided in Authorization header using basic authentication.''' | ||
<br/> | <br/> | ||
<br/> | <br/> | ||
| Line 127: | Line 137: | ||
'''Returns (JSON response body):''' | '''Returns (JSON response body):''' | ||
* '''access_token''' (string) - JWT access token. | |||
* '''token_type''' (string) - JWT token type. Value is always "Bearer" indicating that this token should be included in Authorization header. | |||
* '''expires_in''' (integer) - number of seconds for JWT token expiration. | * '''expires_in''' (integer) - number of seconds for JWT token expiration. | ||
* ''' | * '''expires_at''' (string) - the date when JWT expires. Date format is ISO 8601. | ||
<br/> | <br/> | ||
| Line 149: | Line 161: | ||
{ | { | ||
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhc3NpZ25lZF9kZXZpY2VzIjoiMiw4LDEwLDEyLDE4LDI2LDM2IiwiZXhwIjoxNzUyNTU1Njk4LCJpYXQiOjE3NTI0NjkyOTgsImlzcyI6IkZsYXNoIENhbGxzIEFQSSIsInN1YiI6InJpY2FyZGFzIn0.I3Sy1zrJx0mAsTLthitY8dyZfythsWzJ4V1CVfNJmYU", | |||
"token_type": "Bearer", | |||
"expires_in": 86400, | |||
"expires_at": "2025-11-04T22:52:23Z" | |||
} | } | ||
| Line 171: | Line 184: | ||
* '''dst''' (string, required) - Destination number. | * '''dst''' (string, required) - Destination number. | ||
* '''timeout_ms''' (integer, optional) - Timeout for request in milliseconds. Only allowed if '''flash_calls_api_allow_to_change_timeout''' setting is enabled. | * '''timeout_ms''' (integer, optional) - Timeout for request in milliseconds. Only allowed if '''flash_calls_api_allow_to_change_timeout''' setting is enabled. | ||
* '''device_id''' (integer, optional) - Device ID to use for calling. Only allowed if '''flash_calls_api_allow_to_change_device_id''' setting is enabled. | * '''device_id''' (integer, optional) - Device ID to use for calling. Device must belong to a user who authenticated in [[#/flash_calls/token| /flash_calls/token]] endpoint. Only allowed if '''flash_calls_api_allow_to_change_device_id''' setting is enabled. If not provided, '''flash_calls_api_default_device_id''' will be used. | ||
* '''async''' (string, optional) - Execute this request asynchronously. Allowed values are "false", "polling", "webhook". | * '''async''' (string, optional) - Execute this request asynchronously. Allowed values are "false", "polling", "webhook". | ||
** '''false''' - when set to "false" or when | ** '''false''' - when set to "false" or when '''async''' parameter is not present, requests to [[#/flash_calls/call | /flash_calls/call]] endpoint will execute synchronously - API client will need to keep HTTP connection open and wait for the call response. | ||
** '''polling''' - requests to [[#/flash_calls/call | /flash_calls/call]] endpoint will execute asynchronously - API client will receive immediate response with the URL where to check for the call response (see [[#/flash_calls/call_async_response | /flash_calls/call_async_response]] endpoint). | ** '''polling''' - requests to [[#/flash_calls/call | /flash_calls/call]] endpoint will execute asynchronously - API client will receive immediate response with the URL where to check for the call response (see [[#/flash_calls/call_async_response | /flash_calls/call_async_response]] endpoint). | ||
** '''webhook''' - requests to [[#/flash_calls/call | /flash_calls/call]] endpoint will execute asynchronously - API client will receive immediate response and once the call finishes, API client will receive HTTP POST notification to provided URL in '''webhook_url''' (see [[#Webhooks | Webhooks]] section). | ** '''webhook''' - requests to [[#/flash_calls/call | /flash_calls/call]] endpoint will execute asynchronously - API client will receive immediate response and once the call finishes, API client will receive HTTP POST notification to provided URL in '''webhook_url''' (see [[#Webhooks | Webhooks]] section). | ||
* '''webhook_url''' (string, required only when '''async''' is set to "webhook") - HTTP URL where to send notification once the call finishes. | * '''webhook_url''' (string, required only when '''async''' is set to "webhook") - HTTP URL where to send notification once the call finishes (see [[#Webhooks | Webhooks]] section). | ||
* '''webhook_secret''' (string, required only when '''async''' is set to "webhook") - secret for the webhook notification, generated by the API client. | * '''webhook_secret''' (string, required only when '''async''' is set to "webhook") - secret key for the webhook notification, generated by the API client (see [[#Webhooks | Webhooks]] section). | ||
<br/> | <br/> | ||
| Line 183: | Line 196: | ||
* '''call_status''' (string) - status of the Flash Call. Can be: RINGING, BUSY, ANSWERED, FAILED or TIMEOUT. | * '''call_status''' (string) - status of the Flash Call. Can be: RINGING, BUSY, ANSWERED, FAILED or TIMEOUT. | ||
* '''call_cause''' (integer) - only returned when '''call_status''' is FAILED. Cause code for FAILED calls, for example: ''34''. | |||
* '''call_cause_text''' (string) - only returned when '''call_status''' is FAILED. Description of '''cause_code''', for example: ''No circuit/channel available''. | |||
* '''call_uniqueid''' (string) - unique ID generated for this specific call. Can be used to find this exact call in CDRs. | * '''call_uniqueid''' (string) - unique ID generated for this specific call. Can be used to find this exact call in CDRs. | ||
* '''call_started_at''' (string) - time and date when the call was originated. Date format is ISO 8601. | * '''call_started_at''' (string) - time and date when the call was originated. Date format is ISO 8601. | ||
| Line 259: | Line 274: | ||
Endpoint is used to retrieve the actual call response from [[#/flash_calls/call | /flash_calls/call]] endpoint when requested with '''async''' parameter.<br/> | Endpoint is used to retrieve the actual call response from [[#/flash_calls/call | /flash_calls/call]] endpoint when requested with '''async''' parameter.<br/> | ||
For initiating Flash Calls, this method provides a better | For initiating Flash Calls, this method provides a better performance than synchronous requests (where async is 'false'). It enables the [[#/flash_calls/call | /flash_calls/call]] request to complete instantly, preventing long-held HTTP connections during call execution. | ||
When '''async''' parameter is set to "polling" in [[#/flash_calls/call | /flash_calls/call]] endpoint, it will return URL to [[#/flash_calls/call_async_response | /flash_calls/call_async_response]] endpoint with a short unique ID number. This URL should be periodically checked (for example every 1 or 2 seconds) for the actual call response. If this endpoint returns response with '''task_status''' PENDING or RUNNING, the request to [[#/flash_calls/call_async_response | /flash_calls/call_async_response]] should be tried again after a short delay. If the response returns '''task_status''' COMPLETED or FAILED, the request is finished and there is no need to call this request again. Once the actual call response is returned ('''task_status''' COMPLETED or FAILED), it will be removed from internal response storage and requests to [[#/flash_calls/call_async_response | /flash_calls/call_async_response]] with the same uniqueid ID will return HTTP 404 - not found. The response is valid for 5 minutes - after that, the response will expire and attempts to retrieve it will return HTTP 404 - not found. | When '''async''' parameter is set to "polling" in [[#/flash_calls/call | /flash_calls/call]] endpoint, it will return URL to [[#/flash_calls/call_async_response | /flash_calls/call_async_response]] endpoint with a short unique ID number. This URL should be periodically checked (for example every 1 or 2 seconds) for the actual call response. If this endpoint returns response with '''task_status''' PENDING or RUNNING, the request to [[#/flash_calls/call_async_response | /flash_calls/call_async_response]] should be tried again after a short delay. If the response returns '''task_status''' COMPLETED or FAILED, the request is finished and there is no need to call this request again. Once the actual call response is returned ('''task_status''' COMPLETED or FAILED), it will be removed from internal response storage and requests to [[#/flash_calls/call_async_response | /flash_calls/call_async_response]] with the same uniqueid ID will return HTTP 404 - not found. The response is valid for 5 minutes - after that, the response will expire and attempts to retrieve it will return HTTP 404 - not found. | ||
| Line 283: | Line 298: | ||
* '''call_details''' (JSON) - actual call execution response. Only present when '''task_status''' is COMPLETED. | * '''call_details''' (JSON) - actual call execution response. Only present when '''task_status''' is COMPLETED. | ||
** '''call_status''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ** '''call_status''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ||
** '''call_cause''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | |||
** '''call_cause_text''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | |||
** '''call_uniqueid''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ** '''call_uniqueid''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ||
** '''call_started_at''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ** '''call_started_at''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ||
| Line 324: | Line 341: | ||
When you initiate a Flash Call via the [[#/flash_calls/call | /flash_calls/call]] endpoint with '''"async": "webhook"''', you will receive an immediate ''HTTP/1.1 202 Accepted'' response. Subsequently, the MOR Flash Calls API service will send a notification to your provided '''webhook_url''' once the call is finalized (answered, failed, timed out, or busy). The [[#/flash_calls/call | /flash_calls/call]] endpoint still returns the polling URL, which can be used as a backup if the notification is not delivered. | When you initiate a Flash Call via the [[#/flash_calls/call | /flash_calls/call]] endpoint with '''"async": "webhook"''', you will receive an immediate ''HTTP/1.1 202 Accepted'' response. Subsequently, the MOR Flash Calls API service will send a notification to your provided '''webhook_url''' once the call is finalized (answered, failed, timed out, or busy). The [[#/flash_calls/call | /flash_calls/call]] endpoint still returns the polling URL, which can be used as a backup if the notification is not delivered. | ||
===Webhook | The timeout for Flash Calls notification to '''webhook_url''' can be controlled with '''flash_calls_api_webhook_timeout''' setting in /etc/mor/system.conf. | ||
===Webhook request details=== | |||
The webhook notification will be an HTTP POST request sent to the '''webhook_url''' you specified in the [[#/flash_calls/call | /flash_calls/call]] endpoint.<br/></br> | The webhook notification will be an HTTP POST request sent to the '''webhook_url''' you specified in the [[#/flash_calls/call | /flash_calls/call]] endpoint.<br/></br> | ||
| Line 361: | Line 380: | ||
* '''call_details''' (JSON) - actual call execution response. | * '''call_details''' (JSON) - actual call execution response. | ||
** '''call_status''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ** '''call_status''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ||
** '''call_cause''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | |||
** '''call_cause_text''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | |||
** '''call_uniqueid''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ** '''call_uniqueid''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ||
** '''call_started_at''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ** '''call_started_at''' - description in [[#/flash_calls/call | /flash_calls/call]] endpoint. | ||
| Line 403: | Line 424: | ||
} | } | ||
===Signature | ===Signature verification=== | ||
To ensure the integrity and authenticity of received webhooks, it is crucial to verify the '''X-Flash-Calls-Signature''' header. This signature is an HMAC-SHA256 hash of the raw JSON request body, using the '''webhook_secret''' API client provided when initiating the call. | To ensure the integrity and authenticity of received webhooks, it is crucial to verify the '''X-Flash-Calls-Signature''' header. This signature is an HMAC-SHA256 hash of the raw JSON request body, using the '''webhook_secret''' API client provided when initiating the call. | ||
| Line 421: | Line 442: | ||
HTTP/1.1 503 Service Unavailable | HTTP/1.1 503 Service Unavailable | ||
Content-Type: text/html; charset=iso-8859-1 | Content-Type: text/html; charset=iso-8859-1 | ||
* Method is not allowed - double check if endpoint requires GET, POST or any other method | |||
HTTP/1.1 405 Method Not Allowed | |||
{ | |||
"code": "METHOD_NOT_ALLOWED", | |||
"message": "The requested method is not allowed for this endpoint", | |||
"timestamp": "2025-07-31T10:17:12.221Z" | |||
} | |||
* Endpoint not found | |||
HTTP/1.1 404 Not Found | |||
{ | |||
"code": "ENDPOINT_NOT_FOUND", | |||
"message": "The requested endpoint does not exist", | |||
"timestamp": "2025-07-31T10:21:23.080Z" | |||
} | |||
* Username not found in the database | * Username not found in the database | ||
| Line 444: | Line 485: | ||
} | } | ||
* User is not in the list of allowed users (''' | * User is not in the list of allowed users ('''flash_calls_api_allowed_users''' setting) | ||
HTTP/1.1 403 Forbidden | HTTP/1.1 403 Forbidden | ||
Latest revision as of 13:59, 2 December 2025
Description
The Flash Call API allows you to initiate a call to a specified destination number and receive its status (RINGING, BUSY, ANSWERED, FAILED, or TIMEOUT). The call is automatically canceled upon receiving a RINGING (PROGRESS) status or if the call is answered.
Availability: This API is available from MOR X19.
Usage
This API does not follow standard MOR API usage and must be configured independently. Global MOR API settings do not apply to this API service.
Configuration
Flash Calls API must be configured in GUI server /etc/mor/system.conf configuration file.
API settings
General API settings:
- flash_calls_api_enabled - if set to 1, enables Flash Calls API.
- flash_calls_api_allowed_users - comma separated list of User IDs who are allowed to use this API. Can be set to "all" to allow all Users to use this API.
- flash_calls_api_default_device_id - default Device ID that will be used when no device_id parameter is passed to the /flash_calls/call endpoint.
- flash_calls_api_default_timeout_ms - default timeout (in milliseconds) when no timeout parameter is passed to the /flash_calls/call endpoint.
- flash_calls_api_max_timeout_ms - the maximum timeout (in milliseconds) allowed to use in /flash_calls/call endpoint via parameter timeout.
- flash_calls_api_allow_to_change_device_id - if set to 1, allows to change default device in /flash_calls/call endpoint via parameter device_id.
- flash_calls_api_allow_to_change_timeout - if set to 1, allows to change default timeout in /flash_calls/call endpoint via parameter timeout.
- flash_calls_api_auth_method - authentication method. Either basic authentication or JWT token authentication (see Authentication section).
- flash_calls_api_jwt_token_expiration - JWT token expiration time in seconds (see Authentication section).
- flash_calls_api_jwt_secret_key - secret key for JWT authentication (see Authentication section).
- flash_calls_api_webhook_timeout - timeout in seconds for webhook requests (see Webhooks section).
AMI settings
Flash Calls are initiated via Asterisk AMI. The following settings should be configured with specific Asterisk server details:
- flash_calls_ami_username - AMI username. Usually 'mor'.
- flash_calls_ami_password - AMI password. Usually 'morsecret'.
- flash_calls_ami_host - AMI host. IP address of Asterisk server which should be used to originate Flash Calls API SIP calls.
- flash_calls_ami_port - AMI port. Usually 5038.
Note: if Asterisk and GUI are on different servers, make sure that GUI IP is permitted in Asterisk manager.conf settings.
All settings must be configured.
When these settings are configured or changed, the Flash Calls API service must be restarted in GUI server:
systemctl restart mor_flash_calls
After restart, make sure the service is running:
systemctl status mor_flash_calls
If the service is not running, check /var/log/mor/mor_flash_calls.log. Fix the errors (usually some configuration is missing) and restart the service again.
Configuration from GUI
Device (and User) should be created for Flash Calls and the ID of this Device should be set in flash_calls_api_default_device_id setting. This Device will be used for initiating Flash Calls when no specific Device is requested via device_id parameter.
API
Flash Calls API accepts parameters in JSON format. Responses are also returned in JSON format.
There are 3 endpoints related to Flash Calls:
- /flash_calls/token - get a token for JWT authentication (only when JWT authentication is used).
- /flash_calls/call - initiate a Flash Call.
- /flash_calls/call_async_response - check Flash Call response when the call was initiated with async parameter.
Authentication
Flash Calls API requires user authentication - either basic authentication (username/password) or JWT token authentication. This is controlled by flash_calls_api_auth_method setting in /etc/mor/system.conf.
For basic authentication, set:
flash_calls_api_auth_method=basic
For JWT authentication, set:
flash_calls_api_auth_method=jwt
In either case, HTTPS should be used to transmit credentials securely.
Basic authentication
Basic authentication uses User's username and password to access /flash_calls/call or /flash_calls/call_async_response endpoints.
Username and password must be provided in HTTP Authorization header, "username:password" string encoded in Base64. For example:
POST http://x.x.x.x/billing/api/flash_calls/call HTTP/1.1 Authorization: Basic cmljYXJkYxM6OWtBWFpadT9yak1iayRSaA==
JWT authentication
JWT authentication uses a token (generated by MOR) with each request to /flash_calls/call or /flash_calls/call_async_response endpoints. The API client must obtain JWT token by calling /flash_calls/token endpoint and then use this token in other endpoints for authentication until token expires. Once the token is expired, a new token must be obtained from /flash_calls/token endpoint.
This is the recommended authentication method as it provides better security and better performance.
JWT token must be provided in HTTP Authorization header when requesting /flash_calls/call or /flash_calls/call_async_response endpoints. For example:
POST http://x.x.x.x/billing/api/flash_calls/call HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhc3NpZ25lZF9kZXZpY2VzIjoiMiw4LDEwLDEyLDE4LDI2LDM2IiwiZXhwIjoxNzUyNTU1Njk4LCJpYXQiOjE3NTI0NjkyOTgsImlzcyI6IkZsYXNoIENhbGxzIEFQSSIsInN1YiI6InJpY2FyZGFzIn0.I3Sy1zrJx0mAsTLthitY8dyZfythsWzJ4V1CVfNJmYU
To use JWT authentication, the following settings must be configured in /etc/mor/system.conf:
flash_calls_api_auth_method=jwt flash_calls_api_jwt_token_expiration=XXX flash_calls_api_jwt_secret_key=YYY
Here XXX is a number of seconds for JWT token expiration. For example, to set JWT token expiration to 1 day, the value should be 86400.
A secret key YYY for JWT authentication must be generated. The following command can be used to generate secret key:
head /dev/urandom | tr -dc A-Za-z0-9_.- | head -c 32 | base64
Endpoints
/flash_calls/token
Endpoint to generate JWT access token for authentication in other endpoints. Only available if JWT authentication is used. Username and password must be provided in Authorization header using basic authentication.
Method:
POST
Parameters:
None - empty request body.
Returns (JSON response body):
- access_token (string) - JWT access token.
- token_type (string) - JWT token type. Value is always "Bearer" indicating that this token should be included in Authorization header.
- expires_in (integer) - number of seconds for JWT token expiration.
- expires_at (string) - the date when JWT expires. Date format is ISO 8601.
HTTP status on success:
HTTP/1.1 200 OK
Example request:
POST http://x.x.x.x/billing/api/flash_calls/token HTTP/1.1 Authorization: Basic cmljYXJkYxM6OWtBWFpadT9yak1iayRSaA==
Example response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhc3NpZ25lZF9kZXZpY2VzIjoiMiw4LDEwLDEyLDE4LDI2LDM2IiwiZXhwIjoxNzUyNTU1Njk4LCJpYXQiOjE3NTI0NjkyOTgsImlzcyI6IkZsYXNoIENhbGxzIEFQSSIsInN1YiI6InJpY2FyZGFzIn0.I3Sy1zrJx0mAsTLthitY8dyZfythsWzJ4V1CVfNJmYU",
"token_type": "Bearer",
"expires_in": 86400,
"expires_at": "2025-11-04T22:52:23Z"
}
/flash_calls/call
Endpoint to initiate a Flash Call.
Method:
POST
Parameters (JSON request body):
- src (string, required) - Source number.
- dst (string, required) - Destination number.
- timeout_ms (integer, optional) - Timeout for request in milliseconds. Only allowed if flash_calls_api_allow_to_change_timeout setting is enabled.
- device_id (integer, optional) - Device ID to use for calling. Device must belong to a user who authenticated in /flash_calls/token endpoint. Only allowed if flash_calls_api_allow_to_change_device_id setting is enabled. If not provided, flash_calls_api_default_device_id will be used.
- async (string, optional) - Execute this request asynchronously. Allowed values are "false", "polling", "webhook".
- false - when set to "false" or when async parameter is not present, requests to /flash_calls/call endpoint will execute synchronously - API client will need to keep HTTP connection open and wait for the call response.
- polling - requests to /flash_calls/call endpoint will execute asynchronously - API client will receive immediate response with the URL where to check for the call response (see /flash_calls/call_async_response endpoint).
- webhook - requests to /flash_calls/call endpoint will execute asynchronously - API client will receive immediate response and once the call finishes, API client will receive HTTP POST notification to provided URL in webhook_url (see Webhooks section).
- webhook_url (string, required only when async is set to "webhook") - HTTP URL where to send notification once the call finishes (see Webhooks section).
- webhook_secret (string, required only when async is set to "webhook") - secret key for the webhook notification, generated by the API client (see Webhooks section).
Returns (JSON response body) - when async is false:
- call_status (string) - status of the Flash Call. Can be: RINGING, BUSY, ANSWERED, FAILED or TIMEOUT.
- call_cause (integer) - only returned when call_status is FAILED. Cause code for FAILED calls, for example: 34.
- call_cause_text (string) - only returned when call_status is FAILED. Description of cause_code, for example: No circuit/channel available.
- call_uniqueid (string) - unique ID generated for this specific call. Can be used to find this exact call in CDRs.
- call_started_at (string) - time and date when the call was originated. Date format is ISO 8601.
- call_ended_at (string) - time and date when the call ended (or request timed out). Date format is ISO 8601.
Returns (JSON response body) - when async is polling or webhook:
- response_url (string) - URL to actual call response (see /flash_calls/call_async_response endpoint).
HTTP status on success - when async is false:
HTTP/1.1 200 OK
HTTP status on success - when async is polling or webhook:
HTTP/1.1 202 Accepted
Example request when async is false:
POST http://x.x.x.x/billing/api/flash_calls/call HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhc3NpZ25lZF9kZXZpY2VzIjoiMiw4LDEwLDEyLDE4LDI2LDM2IiwiZXhwIjoxNzUyNTU1Njk4LCJpYXQiOjE3NTI0NjkyOTgsImlzcyI6IkZsYXNoIENhbGxzIEFQSSIsInN1YiI6InJpY2FyZGFzIn0.I3Sy1zrJx0mAsTLthitY8dyZfythsWzJ4V1CVfNJmYU Content-Type: application/json { "src": "37011111111", "dst": "37022222222", "timeout_ms": 10000, "device_id": 12 }
Example response when async is false:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 169
{
"call_status": "RINGING",
"call_uniqueid": "2c3a8d6c-ded3-4fb5-9888-2a12c943674a",
"call_started_at": "2025-07-14T21:37:06.876Z",
"call_ended_at": "2025-07-14T21:37:07.097Z"
}
Example request when async is polling or webhook:
POST http://x.x.x.x/billing/api/flash_calls/call HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhc3NpZ25lZF9kZXZpY2VzIjoiMiw4LDEwLDEyLDE4LDI2LDM2IiwiZXhwIjoxNzUyNTU1Njk4LCJpYXQiOjE3NTI0NjkyOTgsImlzcyI6IkZsYXNoIENhbGxzIEFQSSIsInN1YiI6InJpY2FyZGFzIn0.I3Sy1zrJx0mAsTLthitY8dyZfythsWzJ4V1CVfNJmYU Content-Type: application/json { "src": "37011111111", "dst": "37022222222", "timeout_ms": 10000, "device_id": 12, "async": "polling" }
Example response when async is polling or webhook:
HTTP/1.1 202 Accepted
Content-Type: application/json
Retry-After: 1
Content-Length: 91
{
"response_url": "http://x.x.x.x/billing/api/flash_calls/call_async_response/3f0cd022"
}
/flash_calls/call_async_response
Endpoint is used to retrieve the actual call response from /flash_calls/call endpoint when requested with async parameter.
For initiating Flash Calls, this method provides a better performance than synchronous requests (where async is 'false'). It enables the /flash_calls/call request to complete instantly, preventing long-held HTTP connections during call execution.
When async parameter is set to "polling" in /flash_calls/call endpoint, it will return URL to /flash_calls/call_async_response endpoint with a short unique ID number. This URL should be periodically checked (for example every 1 or 2 seconds) for the actual call response. If this endpoint returns response with task_status PENDING or RUNNING, the request to /flash_calls/call_async_response should be tried again after a short delay. If the response returns task_status COMPLETED or FAILED, the request is finished and there is no need to call this request again. Once the actual call response is returned (task_status COMPLETED or FAILED), it will be removed from internal response storage and requests to /flash_calls/call_async_response with the same uniqueid ID will return HTTP 404 - not found. The response is valid for 5 minutes - after that, the response will expire and attempts to retrieve it will return HTTP 404 - not found.
Method:
GET
Parameters:
None - empty request body
Returns (JSON response body):
- task_id (string) - unique ID number for this async request.
- task_status (string) - status of async call request. Can be: PENDING, RUNNING, COMPLETED or FAILED.
- call_details (JSON) - actual call execution response. Only present when task_status is COMPLETED.
- call_status - description in /flash_calls/call endpoint.
- call_cause - description in /flash_calls/call endpoint.
- call_cause_text - description in /flash_calls/call endpoint.
- call_uniqueid - description in /flash_calls/call endpoint.
- call_started_at - description in /flash_calls/call endpoint.
- call_ended_at - description in /flash_calls/call endpoint.
HTTP status on success:
HTTP/1.1 200 OK
Example request:
GET http://x.x.x.x/billing/api/flash_calls/call_async_response/5f3aa202 HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhc3NpZ25lZF9kZXZpY2VzIjoiMiw4LDEwLDEyLDE4LDI2LDM2IiwiZXhwIjoxNzUyNTU1Njk4LCJpYXQiOjE3NTI0NjkyOTgsImlzcyI6IkZsYXNoIENhbGxzIEFQSSIsInN1YiI6InJpY2FyZGFzIn0.I3Sy1zrJx0mAsTLthitY8dyZfythsWzJ4V1CVfNJmYU
Example response:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 233
{
"task_id": "5f3aa202",
"task_status": "COMPLETED",
"call_details": {
"call_status": "RINGING",
"call_uniqueid": "1442d30e-90bc-49a0-927c-4c51f29b74bf",
"call_started_at": "2025-07-15T04:14:45.393Z",
"call_ended_at": "2025-07-15T04:14:45.735Z"
}
}
Webhooks
Webhooks provide an asynchronous, push-based notification mechanism for the completion response of Flash Calls when initiated with the async parameter set to "webhook" in the /flash_calls/call endpoint. Instead of polling for updates, your configured webhook_url will receive an HTTP POST request containing the final call status details once the Flash Call completes.
This method is recommended for initiating Flash Calls due to its asynchronous nature, which prevents prolonged open HTTP connections (as in non-asynchronous requests) and eliminates the need for polling for call status (as in polling requests).
When you initiate a Flash Call via the /flash_calls/call endpoint with "async": "webhook", you will receive an immediate HTTP/1.1 202 Accepted response. Subsequently, the MOR Flash Calls API service will send a notification to your provided webhook_url once the call is finalized (answered, failed, timed out, or busy). The /flash_calls/call endpoint still returns the polling URL, which can be used as a backup if the notification is not delivered.
The timeout for Flash Calls notification to webhook_url can be controlled with flash_calls_api_webhook_timeout setting in /etc/mor/system.conf.
Webhook request details
The webhook notification will be an HTTP POST request sent to the webhook_url you specified in the /flash_calls/call endpoint.
Method:
POST
Content-Type:
application/json
User-Agent:
MOR-Flash-Calls-Webhook-Service/1.0
Headers:
- X-Webhook-Delivery-ID (string) - A unique identifier for this specific webhook delivery attempt.
- X-Flash-Calls-Signature (string) - An HMAC-SHA256 signature used to verify the authenticity and integrity of the webhook payload. See Signature Verification below for details.
Body (JSON Payload):
The JSON payload in the webhook body will contain the final status of the Flash Call, mirroring the successful response structure of the call_details object from the /flash_calls/call_async_response endpoint.
- event (string) - name of the event. Value is always "flash_calls.response".
- task_id (string) - unique ID number for this async request. Can be used as for polling URL in /flash_calls/call_async_response endpoint.
- timestamp (string) - time and date when the webhook was executed. Date format is ISO 8601.
- call_details (JSON) - actual call execution response.
- call_status - description in /flash_calls/call endpoint.
- call_cause - description in /flash_calls/call endpoint.
- call_cause_text - description in /flash_calls/call endpoint.
- call_uniqueid - description in /flash_calls/call endpoint.
- call_started_at - description in /flash_calls/call endpoint.
- call_ended_at - description in /flash_calls/call endpoint.
Example webhook request:
POST http://x.x.x.x/billing/api/flash_calls/call HTTP/1.1 Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhc3NpZ25lZF9kZXZpY2VzIjoiMiw4LDEwLDEyLDE4LDI2LDM2IiwiZXhwIjoxNzUyNTU1Njk4LCJpYXQiOjE3NTI0NjkyOTgsImlzcyI6IkZsYXNoIENhbGxzIEFQSSIsInN1YiI6InJpY2FyZGFzIn0.I3Sy1zrJx0mAsTLthitY8dyZfythsWzJ4V1CVfNJmYU Content-Type: application/json { "src": "37011111111", "dst": "37022222222", "timeout_ms": 10000, "device_id": 12, "async": "webhook", "webhook_url": "http://y.y.y.y/my_service/flash_calls_response_url", "webhook_secret": "some_secret_key" }
Example webhook request sent by Flash Calls API to webhook_url:
POST http://y.y.y.y/my_service/flash_calls_response_url HTTP/1.1 X-Webhook-Delivery-Id: e8a6c49e-efb0-4d08-9224-cd9c20b5d161 User-Agent: MOR-Flash-Calls-Webhook-Service/1.0 Content-Length: 275 Content-Type: application/json X-Flash-Calls-Signature: sha256=35cd6983406c5e168aed6c06790907da1e6a7ad166dd82afd6f114fc27387b9e { "call_details": { "call_ended_at": "2025-07-16T05:54:50.800Z", "call_started_at": "2025-07-16T05:54:44.832Z", "call_status": "RINGING", "call_uniqueid": "d1816901-b464-483f-9692-7008bf9b5f37" }, "event": "flash_call.response", "task_id": "13b6521c", "timestamp": "2025-07-16T05:54:50.800Z" }
Signature verification
To ensure the integrity and authenticity of received webhooks, it is crucial to verify the X-Flash-Calls-Signature header. This signature is an HMAC-SHA256 hash of the raw JSON request body, using the webhook_secret API client provided when initiating the call.
Verification Steps for your webhook endpoint:
- Retrieve the X-Flash-Calls-Signature header from the incoming webhook request. It will be in the format sha256=<hex_signature>. Extract the hexadecimal signature part.
- Obtain the webhook_secret that you configured for this specific webhook.
- Read the raw (unparsed) JSON request body.
- Compute an HMAC-SHA256 hash of the raw JSON request body using your webhook_secret as the key.
- Convert the computed hash to its hexadecimal representation.
- Compare your computed hexadecimal hash with the one received in the X-Flash-Calls-Signature header. If they match, the webhook is authentic and its payload has not been tampered with.
Errors
- Flash Calls API service is not running
HTTP/1.1 503 Service Unavailable Content-Type: text/html; charset=iso-8859-1
- Method is not allowed - double check if endpoint requires GET, POST or any other method
HTTP/1.1 405 Method Not Allowed
{
"code": "METHOD_NOT_ALLOWED",
"message": "The requested method is not allowed for this endpoint",
"timestamp": "2025-07-31T10:17:12.221Z"
}
- Endpoint not found
HTTP/1.1 404 Not Found
{
"code": "ENDPOINT_NOT_FOUND",
"message": "The requested endpoint does not exist",
"timestamp": "2025-07-31T10:21:23.080Z"
}
- Username not found in the database
HTTP/1.1 401 Unauthorized
Www-Authenticate: Basic realm="Flash Calls API"
{
"code": "FORBIDDEN_ACCESS_USER_NOT_FOUND",
"message": "Access to this resource is forbidden - user not found",
"timestamp": "2025-07-15T10:14:49.253Z"
}
- Wrong password
HTTP/1.1 401 Unauthorized
Www-Authenticate: Basic realm="Flash Calls API"
{
"code": "FORBIDDEN_ACCESS_USER_WRONG_PASSWORD",
"message": "Access to this resource is forbidden - wrong password",
"timestamp": "2025-07-15T10:15:18.764Z"
}
- User is not in the list of allowed users (flash_calls_api_allowed_users setting)
HTTP/1.1 403 Forbidden
{
"code": "FORBIDDEN_ACCESS",
"message": "Access to this resource is forbidden",
"timestamp": "2025-07-15T09:02:23.016Z"
}
- No Authorization header is present
HTTP/1.1 401 Unauthorized
Www-Authenticate: Basic realm="Flash Calls API"
{
"code": "AUTHENTICATION_REQUIRED",
"message": "Authentication is required",
"timestamp": "2025-07-15T10:15:55.482Z"
}
- JWT token is expired and must be obtained again
HTTP/1.1 401 Unauthorized
Www-Authenticate: Bearer realm="Flash Calls API"
{
"code": "TOKEN_EXPIRED",
"message": "The provided authentication token has expired, please re-authenticate",
"timestamp": "2025-07-15T08:11:24.239Z"
}
- Invalid JWT token
HTTP/1.1 401 Unauthorized
Www-Authenticate: Bearer realm="Flash Calls API"
{
"code": "INVALID_TOKEN",
"message": "The provided authentication token is invalid or malformed",
"timestamp": "2025-07-15T08:13:54.932Z"
}
- Invalid parameters
HTTP/1.1 400 Bad Request
{
"code": "INVALID_PARAMETERS",
"message": "One or more parameters are invalid",
"timestamp": "2025-07-15T10:20:53.637Z"
}
- General server error - service logs should be checked for specific reason
HTTP/1.1 500 Internal Server Error
{
"code": "INTERNAL_SERVER_ERROR",
"message": "An unexpected error occurred on the server",
"timestamp": "2025-07-15T10:24:41.897Z"
}
- Asynchronous response not found (or already expired)
HTTP/1.1 404 Not Found
{
"code": "NOT_FOUND",
"message": "The requested resource was not found",
"timestamp": "2025-07-15T10:25:14.201Z"
}
Debugging
In case of errors, the following logs should be checked:
- /var/log/mor/mor_flash_calls.log
- /var/log/asterisk/messages