Nothing found

Bulk delivery confirmation of incoming messages

How bulk reports differ

By default one request per message arrives at your address. At high volumes that means thousands of requests — the bulk variant groups them into batches.

One by one In bulk
Method HTTP GET HTTP POST
Format Parameters in the query string JSON in the request body
Content A single message An array of records

Both carry the same thing — delivery reports as well as incoming messages. The one-by-one variant is described on Delivery confirmations and incoming SMS.

How to turn bulk sending on

Tick Bulk DLRs - bulk request in the webhook settings. The address and the other options stay the same — only the way the data reaches you changes.

The Delivery reports setting with the bulk sending option ticked

The whole procedure, including where to find the setting, is described on Webhooks.

What the request looks like

It arrives by POST with the Content-Type: application/json header. The body is an array mixing delivery reports and incoming messages — you tell them apart by status.

POST /hook/delivery-report HTTP/1.1 Host: example.com Content-Type: application/json [ { "status": "1", "smsID": "3t2563af3ff285", "price": "0.71", "date": "1904111007;1904111011" }, { "status": "2", "smsID": "2t2563af3ff285", "price": "0.71", "date": "1904111007;1904111011" }, { "status": "10", "from": "420777777777", "message": "text of the reply" } ]

Record parameters

Parameter Value When it arrives
status The status code — see delivery statuses Always
smsID The unique ID of the message With a delivery report
price The price of the message in credits With a delivery report
date The time of sending and of delivery separated by a semicolon, CET timezone With a delivery report
from The sender's phone number Only with status 10
message The text of the message in UTF-8 Only with status 10

The date value has the form YYMMDDHHMM;YYMMDDHHMM — so 1904111007;1904111011 means sent on 11 April 2019 at 10:07 and delivered at 10:11.

Delivery statuses

Code Meaning
1 The message was delivered
2 The message is queued on the operator's side — the recipient is unavailable at the moment and delivery will be retried
3 The message could not be delivered — the recipient is unknown or permanently unavailable
10 An incoming message or a reply, not a delivery report
13 The message was read (Viber only)
Note

Status 2 is not final — another record with the resulting status arrives for the same message later. Expect to see the same smsID more than once, possibly even within the same batch.

An example of processing

The script reads the request body, walks the array and routes each record by status:

<?php declare(strict_types=1); const STATUS = [ 1 => 'delivered', 2 => 'queued at operator', 3 => 'not delivered', 13 => 'read', ]; function log_line(string $file, string $message): void { file_put_contents( __DIR__ . "/$file.log", '[' . date('Y-m-d H:i:s') . '] ' . $message . PHP_EOL, FILE_APPEND ); } function parse_date(string $value): string { // the form YYMMDDHHMM, for example 1904111007 $date = DateTimeImmutable::createFromFormat('ymdHi', $value); return $date ? $date->format('Y-m-d H:i') : '?'; } $body = file_get_contents('php://input'); $records = json_decode($body ?: '', true); if (!is_array($records)) { http_response_code(400); exit; } foreach ($records as $record) { $status = (int) ($record['status'] ?? 0); if ($status === 10) // an incoming message { log_line('inbox', sprintf( 'From: [%s] Message: [%s]', $record['from'] ?? '', $record['message'] ?? '' )); } else if (isset(STATUS[$status])) // a delivery report { [$sent, $delivered] = array_pad(explode(';', $record['date'] ?? ''), 2, ''); log_line('delivery', sprintf( 'Message [%s]: %s, price %.4f, sent %s, delivered %s', $record['smsID'] ?? '', STATUS[$status], (float) ($record['price'] ?? 0), parse_date($sent), parse_date($delivered) )); } } http_response_code(200);
Warning

The address has to answer quickly and with the status code 200. The whole batch waits on a single response, so push heavy processing onto a queue and acknowledge the request right away.

Was this page helpful?