NAV

SMS Messages

Endpoint

POST https://api.example.com/sms/send

import requests
url = "https://api.lertify.app/v1/sms/messages"
headers = {
"Content-Type": "application/json",
"apikey": "YOUR_API_KEY"
}
data = {
"sender": "Lertify01",
"destinations": [
"+38640123456",
"+38640987654"
],
"message": {
"content": "Test SMS message",
"isUnicode": False
},
"deliveryReportUrl": "https://example.com/delivery-report"
}
response = requests.post(url, json=data, headers=headers)
print("Status code:", response.status_code)
print("Response:", response.json())
<?php
$url = "https://api.lertify.app/v1/sms/messages";
$apiKey = "YOUR_API_KEY";
$data = [
"sender" => "Lertify01",
"destinations" => [
"+38640123456"
],
"message" => [
"content" => "Test SMS message",
"isUnicode" => false
],
"deliveryReportUrl" => "https://example.com/delivery-report"
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/json",
"apikey: " . $apiKey
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
} else {
echo "Response: " . $response;
}
curl_close($ch);

Authentication

Requests must include an API key in the HTTP header.

Header Type Required Description
apikey string Yes API key used for authentication
def greet(name):
return f"Hello, {name}"
print(greet("Authentication"))
<?php
function greet($name) {
return "Hello, " . $name;
}
echo greet("Authentication");
?>
using System
class Program
{
static void Main()
{
Console.WriteLine($"Hello, Authentication");
}
}

Request

Content-Type: application/json

Body Parameters

Field Type Required Description
sender string Yes Sender name or phone number displayed to recipient
destinations array[string] Yes List of recipient phone numbers
message.content string Yes SMS message content
message.isUnicode boolean No Indicates whether the message uses Unicode
deliveryReportUrl string No URL where delivery reports will be sent
scheduledTime long No Unix timestamp in seconds specifying scheduled send time. If in the past, message is sent immediately
curl -X GET "https://example.com"
def greet(name):
return f"Hello, {name}"
print(greet("Request"))
<?php
function greet($name) {
    return "Hello, " . $name;
}
echo greet("Request");
?>
class Main {
    public static void main(String[] args) {
        System.out.println("Hello, Request");
    }
}
using System;
class Program
{
    static void Main()
    {
        Console.WriteLine($"Hello, Request");
    }
}

Example request

{
"sender": "Lertify01",
"destinations": [
"+38640123456",
"+38640987654"
],
"message": {
"content": "Test SMS message",
"isUnicode": false
},
"deliveryReportUrl": "https://example.com/delivery-report",
"scheduledTime": 1789297200
}

def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))
<?php
function greet($name) {
    return "Hello, " . $name;
}
echo greet("Example Request");
using System;
class Program
{
    static void Main()
    {
        Console.WriteLine("Example Request");
    }
}

Response

Status code

Code Description
200 Request accepted for processing
def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Response structure

Field Type Description
messages array List of sent messages
messages[].messageId UUID Unique message identifier
messages[].destination string Recipient phone number
messages[].scheduledTime long Included only if the message is scheduled. Unix timestamp in seconds
messages[].scheduledAt datetime Included only if the message is scheduled. Scheduled sending time in UTC
status string Request status
import requests
url = "https://api.lertify.app/v1/sms/messages"
headers = {
"Content-Type": "application/json",
"apikey": "YOUR_API_KEY"
}
data = {
"sender": "Lertify01",
"destinations": [
"+38640123456",
"+38640987654"
],
"message": {
"content": "Test SMS message",
"isUnicode": False
},
"deliveryReportUrl": "https://example.com/delivery-report"
}
response = requests.post(url, json=data, headers=headers)
print("Status code:", response.status_code)
print("Response:", response.json())

Example response


{
"messages": [
{
"messageId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"destination": "+38640123456",
}
],
"status": "scheduled",
"scheduledTime": 1789297200,
"scheduledAt": "2026-09-13T09:00:00Z"
}

Webhook response for the sender status, if the URL is defined in the request:

{
"eventId":"752602f6-0dc1-4b58-8e91-20d01dc4f77f",
"senderId":"6a59d592-b450-442a-8ad6-40d3f9ba51e5",
"previousStatus":"Confirmation Pending",
"status":"Confirmed",
"occurredAt":"2026-09-15T07:34:45.8117387Z"
}

def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Notes

  • The endpoint supports sending multiple SMS messages in a single request
  • Phone numbers must be in international format with a + prefix (e.g.
    +38640123456)
  • deliveryReportUrl enables asynchronous delivery status notifications
def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Delivery report (Webhook)

Overview
If deliveryReportUrl is provided in the request, the system will send HTTP POST
requests to the specified URL with information about SMS delivery status.
If deliveryReportUrl is not provided in the request, the system will use the
deliveryReportUrl configured for the sender
, if one is configured. If neither is
configured, no delivery report webhook will be sent

Endpoint Requirements

  • Must accept HTTP POST requests
  • Must return HTTP 2xx status

If a non-2xx response is returned, the retry mechanism is triggered

def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Delivery report behavior

Delivery reports may contain multiple status updates for the same message during
its lifecycle. Each delivery report webhook contains the current message status for
the specific recipient.
Example flow: accepted → SENT → DELIVERED

def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Delivery report statuses

The delivery report webhook uses the following statuses:

Status Description
SENT The message was successfully handed over to the SMS provider
or carrier and is awaiting final delivery
DELIVERED The message was successfully delivered to the recipient’s device
FAILED Delivery failed or an error occurred during processing or sending
REJECTED The message was rejected before delivery
UNKNOWN The final delivery status could not be determined
CANCELLED The message was cancelled before delivery

Notes

  • The ACCEPTED status in the initial API response indicates that the request
    was accepted for processing.
  • The SENT status indicates that the message was successfully handed over to
    the SMS provider or carrier.
  • The FAILED status may represent sending errors, unsuccessful delivery,
    delivery timeout expiration.
  • The REJECTED status may represent insufficient balance, rejection by the
    system or carrier.
import requests
url = "https://api.lertify.app/v1/sms/messages"
headers = {
"Content-Type": "application/json",
"apikey": "YOUR_API_KEY"
}
data = {
"sender": "Lertify01",
"destinations": [
"+38640123456",
"+38640987654"
],
"message": {
"content": "Test SMS message",
"isUnicode": False
},
"deliveryReportUrl": "https://example.com/delivery-report"
}
response = requests.post(url, json=data, headers=headers)
print("Status code:", response.status_code)
print("Response:", response.json())

Inbound(Webhook)

If an inboundUrl is configured for the sender, the system will send an HTTP
POST request to that URL whenever an SMS message is received from an end user.
Inbound webhooks are used for messages sent by end users to a phone number or
sender configured in the Lertify system.
Endpoint requirements:
– Must accept HTTP POST requests
– Must return an HTTP 2xx status
If the endpoint does not return an HTTP 2xx response, the retry mechanism is
triggered

Endpoint requirements:
– Must accept HTTP POST requests
– Must return an HTTP 2xx status
If the endpoint does not return an HTTP 2xx response, the retry mechanism is
triggered

def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Webhook request structure

Field Type Description
Sender string Phone number of the user who sent the message
Recipient string Sender or phone number to which the message was sent
Message string Content of the received SMS message
Time string Time the message was received in yyyy-MM-dd HH:mm:ss format
def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Example webhook request:


{
"Sender": "+38640123456",
"Recipient": "+38631234567",
"Message": "TEST",
"Time": "2026-05-15 14:32:10"
}

Notes:
– Inbound webhooks are sent only if an inboundUrl is configured for the
sender.

– The Time field is sent as a string in the yyyy-MM-dd HH:mm:ss format.

def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Retry mechanism

If the endpoint does not return a successful response (HTTP 2xx), the system retries
delivery using the following form:

delay = (poskus²) + 1 minutes

– Maximum number of attempts: 10
– Retry intervals increase progressively

def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Retry schedule

Attempt Delay Total elapsed time
1 2 min 2 min
2 5 min 7 min
3 10 min 17 min
4 17 min 34 min
5 26 min 60 min (1 h)
6 37 min 97 min (1 h 37 min)
7 50 min 147 min (2 h 27 min)
8 65 min (1 h 5 min) 212 min (3 h 32 min)
9 82 min (1 h 22 min) 294 min (4 h 54 min)
10 101 min (1 h 41 min) 395 min (6 h 35 min)
def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))

Example webhook payload


{
"messageId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"status": "DELIVERED"
}

Notes
– Delivery reports are sent per recipient

def greet(name):
return f"Hello, {name}"
print(greet("Example Request"))