AVC SMS

How to send SMS from PHP in Sri Lanka

This tutorial sends SMS to Sri Lankan mobile numbers from plain PHP and from Laravel, using the AVC SMS REST API. You need PHP with the cURL extension and an API key, which is on the Developer / API page of the portal after you create an account.

Developers4 min readUpdated

Keep the API key out of your code

Store the key in an environment variable or your framework configuration, not in a file that goes to Git. The examples read it from AVCSMS_API_KEY. In the portal you can also restrict the key to the IP address of your server.

Send one SMS

One function covers every kind of send. It posts JSON to the send endpoint and returns the data part of the reply, or throws an exception with the reason.

PHP
<?php
function send_sms(string|array $to, string $message, array $extra = []): array
{
    $ch = curl_init('https://avcsms.lk/api/v1/sms/send');
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTPHEADER => [
            'Authorization: Bearer ' . getenv('AVCSMS_API_KEY'),
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode(['to' => $to, 'message' => $message] + $extra),
    ]);
    $body = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    $reply = json_decode((string) $body, true) ?: [];
    if ($code !== 201) {
        throw new RuntimeException($reply['message'] ?? "SMS request failed (HTTP $code)");
    }
    return $reply['data'];
}

$result = send_sms('0771234567', 'Your order #1042 is ready for pick-up.');
echo $result['messages'][0]['id'];   // keep this ID to check delivery later

A successful reply has HTTP status 201 and tells you the cost, the number of parts, your new balance and an ID for each message. Numbers can be written as 0771234567, 94771234567 or +94771234567.

Send to many numbers, with names

Pass an array of numbers to send the same text to all of them, up to 10,000 in one request. To personalise it, pass name-and-number pairs and write {name} in the message.

PHP
$result = send_sms(
    [
        ['to' => '0771234567', 'name' => 'Nimal'],
        ['to' => '0712345678', 'name' => 'Kumari'],
    ],
    'Hi {name}, your November invoice is ready.',
    ['sender_id' => 'MYSHOP', 'ref' => 'invoice-nov']
);

echo "Accepted {$result['accepted']} messages, cost Rs. {$result['cost']}";

The optional fields are sender_id (an approved sender ID on your account), ref (your own reference, returned in status replies), schedule_at (a date and time in Sri Lanka time, such as 2026-12-01 09:30) and callback_url (where the delivery report should go).

Check whether a message was delivered

PHP
function sms_status(int $id): array
{
    $ch = curl_init("https://avcsms.lk/api/v1/sms/$id");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AVCSMS_API_KEY')],
    ]);
    $reply = json_decode((string) curl_exec($ch), true);
    return $reply['data'];
}

echo sms_status(9001)['status'];   // queued, sending, sent, delivered or failed

Receive delivery reports on your server

Instead of asking for the status, let the API tell you. Set a webhook URL on the Developer / API page, or pass callback_url with a send. When a message is delivered or fails, this script receives a JSON report.

PHP
<?php   // sms-status.php
$report = json_decode(file_get_contents('php://input'), true);

if (($report['event'] ?? '') === 'sms.status') {
    // $report['id'], $report['ref'], $report['to'], $report['status']
    // update the order or login record that matches the reference
}

http_response_code(200);
Each report is sent once. If your server was down, ask for the status of the message by its ID to catch up.

Laravel

In Laravel the HTTP client does the same job in a few lines. Put the key in config/services.php and read it from the environment.

PHP
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.avcsms.key'))
    ->post('https://avcsms.lk/api/v1/sms/send', [
        'to' => '0771234567',
        'message' => 'Your OTP is 482913',
    ]);

if ($response->failed()) {
    logger()->error('SMS failed: ' . $response->json('message'));
}

$messageId = $response->json('data.messages.0.id');

Errors you should handle

HTTP codeWhat it meansWhat to do
400A field is missing, or no number in the request is a valid Sri Lankan mobileFix the request
401The API key is missing or wrongCheck the key and the Authorization header
402The balance is too low for this sendTop up, then send again
422The sender ID is not approved, or the schedule time is not validUse an approved sender ID or a future time
429More than 120 requests in a minute from one keyWait a moment and retry

The full list of endpoints and fields is in the SMS API reference. If you are building login codes, read how to add OTP verification by SMS next.

More guides

All guides

Ready to send your first SMS?

Open an account in two minutes, or ask us for a volume quote.