POST / sms/send
Base URL: https://backend.easify.app/api/v2
This endpoint is used to send SMS/MMS.
This endpoint allows users to send SMS/MMS messages using their Easify phone number.
To prevent abuse, there is a rate limit of 15 requests per minute per user. If you exceed this limit, you will receive a 429 Too Many Requests status with a message indicating when you can try again.
Authentication
The Easify API token used for authentication is passed in the header as a Bearer token, which can be obtained from the easify app under Settings > API Settings.
Headers
Authorization string required Bearer << YOUR_EASIFY_API_TOKEN_HERE >>
Query Parameters
from_number string |
From number to send SMS *Ensure that you are using a phone number associated with the api token,please use the Phone Numbers API to retrieve the associated phone numbers. *No need of attaching country code |
Required |
to_number string | To number to send SMS (No need of attaching country code) | Required |
message string | The content to be sent | Required without media |
media string/file | To attach media files | Required without message |
lead_id string | CRM lead id(If you have a CRM and need to associate the SMS history with a specific lead, you can use the lead_id to connect the SMS records to the corresponding lead in your CRM) | Optional |
country_code string | Country code for to_number (Currently support +1, +972 and +44 codes) | Required |
force_send integer | If you send an SMS outside of open hours and closing hours, it will be scheduled for the next opening hour. If you need to send it immediately despite being outside of these hours, set force_send to 1 | Optional |
Sample Request and Success Response:
Request:
{
"from_number": "315293****",
"to_number": "315135****",
"country_code": "+1",
"message": "Hai"
}
Success Response:
{
"status": true,
"message": " SMS Processed successfully.",
"data": {
"sms_id": "315**"
}
}
Easify DNC Registry and chat block will not prevent sending SMS; they only block blacklisted numbers
Api Response Status
Case | Status Code | Response |
---|---|---|
If the user provides an invalid Easify API token or does not pass the Easify API token in the header. | 401 |
{
"status":false,
"message":"Unauthenticated",
"errors":[]
}
|
If user not provided from_number | 422 |
{
"message":"The from_number is required.",
"errors": {
"from_number": ["The from number is required."]
}
}
|
If user provided invalid from_number | 400 |
{
"status":false,
"message":"Selected from number is invalid",
"errors": []
}
|
If user provided invalid to_number | 400 |
{
"status":false,
"message":"InvalidRecipient!",
"errors": []
}
|
If the number is blacklisted | 400 |
{
"status":false,
"message":" Sorry, this recipient is blacklisted! ",
"errors": []
}
|
If the user does not have enough credits | 400 |
{
"status": false,
"message": "Sorry, you do not have enough credits to send this SMS. Please recharge for more.",
"errors": []
}
|
If the user provided invalid country code | 422 |
{
"message": "Currently, this service is only available in the following countries: Canada, United States, Israel, United Kingdom. Please verify the country code.",
"errors": {
"country_code": ["Currently, this service is only available in the following countries: Canada, United States, Israel, United Kingdom. Please verify the country code."]
}
}
|
If the user not providedcountry_code | 400 |
{
"message": "The country code field is required.",
"errors": {
"country_code": ["The country code field is required."]
}
}
|
If the user exceeds the allowed rate limit for requests | 429 |
{
"status":false,
"message":"Too many requests. Try again in 59 seconds",
"errors":[]
}
|
If the user's subscription has ended | 402 |
{
"status":false,"message":"You need to recharge your account to proceed","errors":[]
}
|
If the user does not have an enterprise plan | 403 |
{
"status": false,
"message": "Access denied. Your current plan does not allow access to this feature. Please upgrade to the Enterprise plan.",
"errors": []
}
|
PHP-cURL
php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://backend.easify.app/api/v2/sms/send',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => json_encode([
'from_number' => '+1320301****',
'to_number' => '7736389****',
'message' => 'Haii',
'country_code' => '+1'
]),
CURLOPT_HTTPHEADER => [
'Accept: application/json',
'Authorization: Bearer 1955|43da5bb5-5c2b-4059-a4de-d44bf5****',
'Content-Type: application/json'
],
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
SMS Event Webhook Configuration
This section explains how users can configure webhooks in the Easify application and securely verify signatures using the provided signature verification secret.
Adding a Webhook URL
Steps to Add a Webhook:
- Go to Settings -> API Settings -> SMS
Webhook Event Structure:
When an event is triggered, the application will send a POST request to the onfigured webhook URL with the following headers and body:
Headers
- X-Easify-Signature: A Base64-encoded signature of the payload, generated using the verification secret.
- X-Easify-Timestamp: The UNIX timestamp of the request.
Payload
The POST body contains the event data. Example:
{
"sms_id": "63f7a88b2e4b6c001f33****",
"sender": "+1234567***",
"receiver": "+0987654***",
"sms_type": "sms",
"message": "Hai.",
"media_url": “”
"status": "Delivered",
"remarks": "",
"created_at": "2025-01-16 10:45:00"
}
Steps for Validating the Signature
Extract Header and Payload Information
X-Easify-Timestamp from the request headers.
X-Easify-Signature from the request headers.
Raw JSON payload from the request body
Extract Header and Payload Information
To validate the signature, recreate it using the following process:
- Use the raw JSON payload as the input:
$payloadString = json_encode($payload);
- Generate an HMAC signature using the shared webhook_secret:
$computedSignature = hash_hmac('sha256', $payloadString, $webhook_secret)
- Encode the generated signature in Base64:
$computedSignatureBase64 = base64_encode($computedSignature);
Compare the Signatures
Compare the computed signature with the one received in the X-Easify-Signature header:
if (hash_equals($computedSignatureBase64, $receivedSignature)) {
// Signature is valid
} else {
// Signature is invalid
}
Validate the Timestamp
To prevent replay attacks, ensure that the timestamp in X-Easify-Timestamp is within an acceptable range (e.g., ±15 minutes):
$currentTime = time();
if (abs ($currentTime - $receivedTimestamp) > 900) {
// 15 minutes
// Reject the request as expired
}