Difference between revisions of "MOR API flash calls"
| Line 48: | Line 48: | ||
==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= | ||
Revision as of 09:33, 17 July 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 X18 onwards.
Usage
This API does not follow standard MOR API usage and must be configured manually. 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.
- flash_calls_ami_password - AMI password.
- flash_calls_ami_host - AMI host.
- flash_calls_ami_port - AMI port.
When these settings are configured or changed, the Flash Calls API service must be restarted in GUI server:
systemctl restart mor_flash_calls
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 token for authentication in other endpoints. Only available if JWT authentication is used. Username and password must be provided in Authorization header.
Method:
POST
Parameters:
None - empty request body.
Returns (JSON response body):
- expires_in (integer) - number of seconds for JWT token expiration.
- token (string) - JWT token.
- token_type (string) - JWT token type. Value is always "Bearer" indicating that this token should be included in Authorization header.
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
{
"expires_in": 86400,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhc3NpZ25lZF9kZXZpY2VzIjoiMiw4LDEwLDEyLDE4LDI2LDM2IiwiZXhwIjoxNzUyNTkzNjc1LCJpYXQiOjE3NTI1MDcyNzUsImlzcyI6IkZsYXNoIENhbGxzIEFQSSIsInN1YiI6InJpY2FyZGFzIn0.dDsxxKIbW2S3uG7uzKskdGkfLEFsApBW5ETOWzuhmG8",
"token_type": "Bearer"
}
/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. Only allowed if flash_calls_api_allow_to_change_device_id setting is enabled.
- async (string, optional) - Execute this request asynchronously. Allowed values are "false", "polling", "webhook".
- false - when set to "false" or when this 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_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 experience 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_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_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
- 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