Webhooks
Get notified in real time when a message is delivered, fails, or bounces.
Setting Up Webhooks
- Go to your app's Webhooks tab in the dashboard
- Click Create Webhook
- Enter your endpoint URL (must be HTTPS)
- Select which events you want to receive
- Save — a signing secret is generated automatically
Events
| Event | Description | Channel |
|---|---|---|
message.queued | Message queued for sending | SMS, Email |
message.sent | Message submitted to carrier | SMS, Email |
message.delivered | Carrier confirmed delivery | SMS, Email |
message.failed | Delivery failed | SMS, Email |
message.opened | Recipient opened the email | Email only |
message.clicked | Recipient clicked a link | Email only |
message.bounced | Email bounced | Email only |
message.complained | Recipient marked as spam | Email only |
Webhook Payload
{
"event": "message.delivered",
"message_id": "msg_7f3a2b9d1e4c",
"recipient_id": "rcpt_4a8b2c1d",
"recipient": "+233245972246",
"status": "delivered",
"timestamp": "2026-03-21T10:30:15Z",
"metadata": {}
}
Verifying Webhooks
Every webhook includes two headers for verification:
X-SMSGist-Signature— HMAC-SHA256 signature (sha256={hex})X-SMSGist-Timestamp— Unix timestamp (for replay protection)
The signature is computed as: HMAC-SHA256(timestamp + "." + body, secret)
Webhooks older than 5 minutes should be rejected.
Using the SDKs
Go
if zNotification.VerifyWebhookSignature(
body,
r.Header.Get("X-SMSGist-Signature"),
r.Header.Get("X-SMSGist-Timestamp"),
webhookSecret,
) {
// Valid — process the event
}
PHP
use SMSGist\Webhook;
$isValid = Webhook::verifySignature(
body: file_get_contents('php://input'),
signature: $_SERVER['HTTP_X_SMSGIST_SIGNATURE'],
timestamp: $_SERVER['HTTP_X_SMSGIST_TIMESTAMP'],
secret: 'your-webhook-secret',
);
Node.js
import { Webhook } from '@smsgist/node';
const isValid = Webhook.verifySignature({
body: rawBody,
signature: req.headers['x-smsgist-signature'],
timestamp: req.headers['x-smsgist-timestamp'],
secret: 'your-webhook-secret',
});
Retry Policy
If your endpoint returns a non-2xx status code, we retry with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | 5 seconds |
| 2 | 5 minutes |
| 3 | 30 minutes |
| 4 | 2 hours |
| 5 | 12 hours |
| 6 | 24 hours |
After 6 failed attempts, the webhook is marked as degraded and you'll see a warning in the dashboard.
Testing Webhooks
Use the Send Test Event button in the dashboard to fire a sample webhook to your endpoint. This helps verify your setup before going live.
