Webhooks are an extension of an API, but instead of your code requesting data from Smstools, Smstools sends data to you. The data arrives in a web request to your application. Webhooks are also used to notify your application of events such as an incoming call or message. Since the Smstools servers need to be able to send data to your application via webhooks, you need to set up a webserver to receive the incoming HTTP requests. You also need to specify the URL of each webhook on your webserver so that data can be sent to each one.
{ "webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09", "webhook_type": "delivery_report", "username": "myusername", "timezone": "Europe/Brussels", "method": "POST", "created": "2026-01-01 09:00:06", "created_utc": "2026-01-01 08:00:06", "message": { "messageid": "e1qk89exbzgf6fzfunceym2sd67h88", "datetime": "2026-01-01 09:00:00", "content": "here comes your message body", "sender": "yoursender", "receiver": "32470123456", "reference": "yourref", "message_type": "sms", "delivery_code": "1", "delivery_status": "delivered", "delivery_status_datetime": "2026-01-01 09:00:05", "cost": 1, "cost_type": "credits" }}
| Type | Description |
|---|---|
| delivery_report | Delivery report after each sent message. Sometimes there can be 2 webhooks: first a 'submitted' status and later a 'delivered' or 'not delivered' status. Sometimes there are additional details available when the message was not delivered. |
| read_report | Read confirmation after the message is read. A read confirmation is only available for Social Messaging or by using the 'Ask for a read report' link. |
| inbox_message | Incoming message. Only available if you are using Social Messaging or a virtual number. |
| call_forwarding | Oproepdoorschakeling. Enkel beschikbaar als je Social Messaging of een virtueel nummer gebruikt. |
| add_contact | 1 contact werd toegevoegd via de API of software |
| delete_contact | 1 contact werd verwijderd via de API of software |
| add_group | Een groep werd toegevoegd via de API of software |
| delete_group | Een groep werd verwijderd via de API of software |
| add_optout | Een contact werd toegevoegd aan de opt-outlijst via de API of software |
| delete_optout | Een contact werd verwijderd uit de opt-outlijst via de API of software |
| funds_purchased | Het account heeft een nieuwe aankoop van tegoed voltooid |
| insufficient_funds | Het account heeft geen beschikbaar tegoed meer |
| email2sms_received | Email2Sms heeft een e-mail ontvangen en geprobeerd deze via SMS te verzenden |
| api_error | Een API-aanvraag is mislukt. Bevat de foutmelding, foutcode en HTTP-status van de mislukte aanvraag. |
| Code | Status | Explanation |
|---|---|---|
| 0 | SUBMITTED | This message was delivered with the operator but we did not receive any delivery report. |
| 1 | DELIVERED | This message is delivered successfully. |
| 2 | NOT DELIVERED | This message was not delivered. Possible reason: receiver is outside the range of the network, network problems, receiver in foreign country. |
| 3 | BUFFERED | This message is delivered with the operator but not delivered with the receiver. |
| 4 | REJECTED | This message is refused by the operator. |
| 5 | REJECTED | Extended info below! |
| 9 | UNKNOWN | There are no delivery reports available for this message. |
Below an overview of the possible error codes you may receive.
| Status | Explanation |
|---|---|
| 10 | Receiver number is invalid or unknown |
| 11 | Receiver is temporarily outside the range of the network operator |
| 12 | Phone related problem. |
| 13 | Operator network problem |
| 14 | Message expired - reason unknown |
| 15 | Receiver is listed on a blacklist |
| 16 | Message content problem |
| 17 | Receiver cannot be settled |
| 18 | Operator refused this due to spam |
| 19 | Subscriber cannot receive premium messages (blocked by operator) |
| Status | Explanation |
|---|---|
| 2000 | INSUFFICIENT_FUNDS |
| 2001 | TOO_LONG |
| 2002 | TOO_SHORT |
| 2003 | TIMEOUT |
| 2004 | GATEWAY_ISSUES |
| 2005 | INVALID_SENDER |
| 2006 | INVALID_NUMBER |
| 4000 | UNKNOWN |
| 4001 | EMPTY_MESSAGE |
| 4002 | EMPTY_CLIENT |
| 4003 | LOCKED |
| 4004 | BLOCKED |
| 4005 | JOB_FAILED |
| 4006 | DUPLICATE |
| 4007 | INVALID_CONTENT |
Als er een signing secret is ingesteld op je webhook-URL, bevat elke webhook-aanvraag de headers X-Smstools-Timestamp (Unix-timestamp) en X-Smstools-Signature (formaat: t={timestamp},v1={signature}).
Om de handtekening te controleren: voeg de timestamp, een punt (.) en de onbewerkte JSON-body samen, bereken de HMAC SHA-256 van deze tekst met je signing secret en vergelijk het resultaat met de v1-waarde. Bij GET-webhooks wordt de querystring ondertekend in plaats van de JSON-body.
POST /your/webhook/endpoint HTTP/1.1 Content-Type: application/json X-Smstools-Timestamp: 1767254406 X-Smstools-Signature: t=1767254406,v1=20bb9bf973ab6471e64f88a73fa11926c882dba87234f6760b87b5cbb0bf5aaa
$signedPayload = $timestamp . "." . $rawBody;
$signature = hash_hmac("sha256", $signedPayload, $secret);
hash_equals($signature, $v1);
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "delivery_report",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:00:06",
"created_utc": "2026-01-01 08:00:06",
"message": {
"messageid": "e1qk89exbzgf6fzfunceym2sd67h88",
"datetime": "2026-01-01 09:00:00",
"content": "here comes your message body",
"sender": "yoursender",
"receiver": "32470123456",
"reference": "yourref",
"message_type": "sms",
"delivery_code": "1",
"delivery_status": "delivered",
"delivery_status_datetime": "2026-01-01 09:00:05",
"cost": 1,
"cost_type": "credits"
}
}
{
"webhook_id": "wh_b1c67831-8bed-4d89-b15e-73632e2e4c10",
"webhook_type": "delivery_report",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:00:15",
"created_utc": "2026-01-01 08:00:15",
"message": {
"messageid": "f2rl90fycahg7gagvodfzn3te78i99",
"datetime": "2026-01-01 09:00:00",
"content": "here comes your message body",
"sender": "yoursender",
"receiver": "32470123456",
"reference": "yourref",
"message_type": "sms",
"delivery_code": "2",
"delivery_status": "not delivered",
"delivery_status_datetime": "2026-01-01 09:00:12",
"delivery_code_detail": "10",
"delivery_code_detail_description": "Unknown Subscriber",
"cost": 1,
"cost_type": "credits"
}
}
{
"webhook_id": "wh_c2d78942-9cfe-4e9a-8c26-84743f3f5d21",
"webhook_type": "delivery_report",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:02:35",
"created_utc": "2026-01-01 08:02:35",
"message": {
"messageid": "e1qk89exbzgf6fzfunceym2sd67h88",
"datetime": "2026-01-01 09:00:00",
"content": "here comes your message body",
"sender": "yoursender",
"receiver": "32470123456",
"reference": "yourref",
"message_type": "sms",
"delivery_code": "1",
"delivery_status": "delivered",
"delivery_status_datetime": "2026-01-01 09:00:05",
"confirm_type": "replies_yes_no_answer",
"confirm_date": "2026-01-01 09:02:30",
"confirm_memo": "YES",
"cost": 1,
"cost_type": "credits"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "read_report",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:01:01",
"created_utc": "2026-01-01 08:01:01",
"message": {
"messageid": "e1qk89exbzgf6fzfunceym2sd67h88",
"datetime": "2026-01-01 09:00:00",
"content": "here comes your message body",
"sender": "yoursender",
"receiver": "32470123456",
"reference": "yourref",
"message_type": "sms",
"delivery_code": "1",
"delivery_status": "delivered",
"delivery_status_datetime": "2026-01-01 09:00:05",
"read_status": "message_read",
"read_datetime": "2026-01-01 09:01:00"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "inbox_message",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:05:01",
"created_utc": "2026-01-01 08:05:01",
"message": {
"id": "12345678",
"public_id": "inb_46f4c0e37652d4149352e1cb54fed50b",
"date": "2026-01-01 09:05:00",
"date_iso8601": "2026-01-01T09:05:00+01:00",
"date_utc": "2026-01-01 08:05:00",
"date_utc_iso8601": "2026-01-01T08:05:00+00:00",
"sender": "sendernumber",
"receiver": "12345678",
"content": "message content",
"type": "sms",
"file": null,
"processed": 0
},
"isreply": {
"reply": true,
"orig_message_content": "original message content",
"orig_messageid": "985zvqipp73csuuha2079fbshx",
"orig_messagedate": "2026-01-01 09:00:00",
"orig_messagedate_iso8601": "2026-01-01T09:00:00+01:00",
"orig_messagedate_utc": "2026-01-01 08:00:00",
"orig_messagedate_utc_iso8601": "2026-01-01T08:00:00+00:00",
"orig_sender": "32471123456",
"orig_receiver": "12345678",
"orig_reference": ""
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "call_forwarding",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:10:01",
"created_utc": "2026-01-01 08:10:01",
"message": {
"id": "12345678",
"public_id": "inb_7ecad8b1a486b73732b897fde12f080c",
"date": "2026-01-01 09:10:00",
"date_iso8601": "2026-01-01T09:10:00+01:00",
"date_utc": "2026-01-01 08:10:00",
"date_utc_iso8601": "2026-01-01T08:10:00+00:00",
"sender": "sendernumber",
"receiver": "12345678",
"content": "Incoming VOIP Call - Forwarded to XXXXX",
"content_type": "complete",
"type": "call"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "add_contact",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:15:00",
"created_utc": "2026-01-01 08:15:00",
"contact": {
"action": "add",
"groupid": "12345",
"groupname": "Groupname",
"receiver": "32498123456",
"firstname": "John",
"lastname": "Doe",
"Custom1": null,
"Custom2": null,
"Custom3": null,
"Custom4": null,
"Custom5": null,
"Custom6": null,
"Custom7": null,
"Custom8": null,
"unsubscribed": false,
"unsubscribe_date": null
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "delete_contact",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:16:00",
"created_utc": "2026-01-01 08:16:00",
"contact": {
"action": "delete",
"groupid": "12345",
"groupname": "Groupname",
"receiver": "32498123456",
"firstname": "John",
"lastname": "Doe",
"Custom1": null,
"Custom2": null,
"Custom3": null,
"Custom4": null,
"Custom5": null,
"Custom6": null,
"Custom7": null,
"Custom8": null,
"unsubscribed": false,
"unsubscribe_date": null
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "add_group",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:20:00",
"created_utc": "2026-01-01 08:20:00",
"group": {
"action": "add",
"groupid": "12345",
"groupname": "Groupname"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "delete_group",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:21:00",
"created_utc": "2026-01-01 08:21:00",
"group": {
"action": "delete",
"groupid": "12345",
"groupname": "Groupname"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "add_optout",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2025-08-04 14:30:00",
"created_utc": "2025-08-04 12:30:00",
"optout": {
"action": "add",
"id": "1234",
"number": "32498123456",
"memo": "Sample opt-out",
"date": "2025-08-04",
"date_utc": "2025-08-04"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "delete_optout",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2025-08-04 14:31:00",
"created_utc": "2025-08-04 12:31:00",
"optout": {
"action": "delete",
"number": "32498123456",
"date": "2025-08-04",
"date_utc": "2025-08-04"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "funds_purchased",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2025-08-04 14:33:50",
"created_utc": "2025-08-04 12:33:50",
"funds": {
"order_id": "1234",
"item_amount": 1,
"currency": "eur",
"total_price": 10,
"price_excl": 0,
"purchase_type": "credits",
"payment_mode": "online",
"reference": "Reference",
"date": "2025-08-04 14:33:45",
"date_utc": "2025-08-04 12:33:45"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "insufficient_funds",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2025-08-04 14:34:22",
"created_utc": "2025-08-04 12:34:22",
"funds": {
"item_amount": "0.000",
"item_type": "balance",
"message": "Insufficient funds",
"date": "2025-08-04 14:34:22",
"date_utc": "2025-08-04 12:34:22"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "email2sms_received",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2025-01-01 10:00:02",
"created_utc": "2025-01-01 09:00:02",
"email2sms": {
"sender": "[email protected]",
"receiver": {
"group": false,
"receiver": "32498123456"
},
"result": "Success",
"status": "Message Sent",
"email_message_id": "abc123def456",
"sms_message_id": "985zvqipp73csuuha2079fbshx",
"date": "2025-01-01 10:00:00",
"date_utc": "2025-01-01 09:00:00"
}
}
{
"webhook_id": "wh_a9b56720-7adc-4c78-a04d-62521d1d3b09",
"webhook_type": "api_error",
"username": "myusername",
"timezone": "Europe/Brussels",
"method": "POST",
"created": "2026-01-01 09:25:00",
"created_utc": "2026-01-01 08:25:00",
"error": {
"error": "Destination number 32498123456 missing or invalid",
"error_code": 103,
"sender": "yoursender",
"receiver": "32498123456",
"http_code": 400,
"date": "2026-01-01 09:25:00",
"date_utc": "2026-01-01 08:25:00"
}
}