Les webhooks sont une extension d'une API, mais au lieu que votre code demande des données à Smstools, Smstools vous envoie des données. Les données arrivent dans une requête web à votre application. Les webhooks sont également utilisés pour notifier votre application d'événements tels qu'un appel ou un message entrant. Comme les serveurs Smstools doivent pouvoir envoyer des données à votre application via des webhooks, vous devez configurer un serveur web pour recevoir les requêtes HTTP entrantes. Vous devez également spécifier l'URL de chaque webhook sur votre serveur web afin que les données puissent être envoyées à chacun.
{ "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 | Rapport de livraison après chaque message envoyé. Parfois, il peut y avoir 2 webhooks : d'abord un statut 'soumis' et ensuite un statut 'livré' ou 'non livré'. Parfois, des détails supplémentaires sont disponibles lorsque le message n'a pas été livré. |
| read_report | Confirmation de lecture après la lecture du message. Une confirmation de lecture n'est disponible que pour la Messagerie Sociale ou en utilisant le lien 'Demander un rapport de lecture'. |
| inbox_message | Message entrant. Disponible uniquement si vous utilisez la Messagerie Sociale ou un numéro virtuel. |
| call_forwarding | Renvoi d’appel. Disponible uniquement si vous utilisez la messagerie sociale ou un numéro virtuel. |
| add_contact | 1 contact a été ajouté via l’API ou le logiciel |
| delete_contact | 1 contact a été supprimé via l’API ou le logiciel |
| add_group | Un groupe a été ajouté via l’API ou le logiciel |
| delete_group | Un groupe a été supprimé via l’API ou le logiciel |
| add_optout | Un contact a été ajouté à la liste de désinscription via l’API ou le logiciel |
| delete_optout | Un contact a été retiré de la liste de désinscription via l’API ou le logiciel |
| funds_purchased | Le compte a effectué un nouvel achat de crédits |
| insufficient_funds | Le compte ne dispose plus de crédits disponibles |
| email2sms_received | Email2Sms a reçu un e-mail et a tenté de l’envoyer par SMS |
| api_error | Une requête API a échoué. Contient le message d'erreur, le code d'erreur et le statut HTTP de la requête échouée. |
| Code | Statut | Explication |
|---|---|---|
| 0 | SUBMITTED | Ce message a été livré avec l'opérateur mais nous n'avons pas reçu de rapport de livraison. |
| 1 | DELIVERED | Ce message a été livré avec succès. |
| 2 | NOT DELIVERED | Ce message n'a pas été livré. Raison possible : le destinataire est hors de portée du réseau, problèmes réseau, destinataire à l'étranger. |
| 3 | BUFFERED | Ce message a été livré avec l'opérateur mais pas avec le destinataire. |
| 4 | REJECTED | Ce message est refusé par l'opérateur. |
| 5 | REJECTED | Informations étendues ci-dessous ! |
| 9 | UNKNOWN | Il n'y a pas de rapports de livraison disponibles pour ce message. |
Ci-dessous un aperçu des codes d'erreur possibles que vous pourriez recevoir.
| Statut | Explication |
|---|---|
| 10 | Le numéro du destinataire est invalide ou inconnu |
| 11 | Le destinataire est temporairement hors de portée de l'opérateur de réseau |
| 12 | Problème lié au téléphone. |
| 13 | Problème de réseau de l'opérateur |
| 14 | Message expiré - raison inconnue |
| 15 | Le destinataire est répertorié sur une liste noire |
| 16 | Problème de contenu du message |
| 17 | Le destinataire ne peut pas être réglé |
| 18 | L'opérateur a refusé cela en raison de spam |
| 19 | L'abonné ne peut pas recevoir de messages premium (bloqué par l'opérateur) |
| Statut | Explication |
|---|---|
| 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 |
Si un secret de signature est défini sur votre URL de webhook, chaque requête webhook contient les en-têtes X-Smstools-Timestamp (timestamp Unix) et X-Smstools-Signature (format : t={timestamp},v1={signature}).
Pour vérifier la signature : concaténez le timestamp, un point (.) et le corps JSON brut de la requête, calculez le HMAC SHA-256 de cette chaîne avec votre secret de signature et comparez le résultat avec la valeur v1. Pour les webhooks GET, c'est la chaîne de requête qui est signée au lieu du corps JSON.
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"
}
}