Webhooks
TalkNTalk can push real-time HTTP notifications to your server whenever a message event occurs — no polling required. Configure one or more endpoints in your dashboard and we'll POST a JSON payload to each one.
How it works
- Create an endpoint in your dashboard under Webhooks → Endpoints
- Select the events you want to receive (
sms.sent,sms.delivered, etc.) - TalkNTalk fires a POST request to your URL within seconds of the event
- Your server responds
2xxto acknowledge receipt - If your server is unavailable or returns a non-
2xxstatus, TalkNTalk retries 3 times with exponential backoff (1 min → 5 min → 30 min)
Payload format
Every webhook delivery is a POST request with Content-Type: application/json:
{
"event": "sms.delivered",
"timestamp": "2026-05-20T11:30:04+03:00",
"data": {
"id": 9041,
"mobile": "254712345678",
"sender_id": "TALKNTALK",
"message": "Your OTP is 847291.",
"status": "delivered",
"network": "safaricom",
"source": "api",
"created_at": "2026-05-20T11:30:00+03:00",
"updated_at": "2026-05-20T11:30:04+03:00"
}
}| Field | Description |
|---|---|
event | Event name — see Events below |
timestamp | ISO 8601 time when the event was fired (Africa/Nairobi) |
data | The message object related to the event |
Events
| Event | Fired when… |
|---|---|
sms.sent | Message was successfully submitted to the SMS provider |
sms.delivered | Provider confirmed delivery to the handset |
sms.failed | Submission to the provider failed |
sms.undelivered | Provider could not deliver (e.g. number unreachable) |
sms.cancelled | A queued message was cancelled before sending |
Request headers
Every webhook request includes:
| Header | Description |
|---|---|
Content-Type | application/json |
X-TalkNTalk-Event | The event name, e.g. sms.delivered |
X-TalkNTalk-Signature | HMAC-SHA256 signature — only present if you set a signing secret |
Verifying signatures
If you set a signing secret on your endpoint, every request includes an X-TalkNTalk-Signature header:
X-TalkNTalk-Signature: sha256=3b5d9f2a...Verify it on your server to ensure the payload came from TalkNTalk and was not tampered with:
// Node.js
const crypto = require('crypto');
function verifySignature(rawBody, secret, header) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody) // use the raw request body bytes
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(header)
);
}# Python
import hmac, hashlib
def verify_signature(raw_body: bytes, secret: str, header: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, header)Important: Always use a constant-time comparison (
timingSafeEqual/hmac.compare_digest) to prevent timing attacks.
Retries
| Attempt | Delay after failure |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
After 3 failed attempts the delivery is marked Failed. You can manually Resend any failed delivery from the Webhooks → Logs view in your dashboard.
Testing your endpoint
The easiest way to test your webhook integration before you build your server is to use Beeceptor (opens in a new tab) — a free online HTTP mock server that captures requests in real time.
Quick start with Beeceptor
- Open Beeceptor (opens in a new tab) and create a free endpoint — you get a URL like
https://my-hook.free.beeceptor.com - Paste that URL into your TalkNTalk webhook endpoint (dashboard → Webhooks → Add endpoint)
- Send a test SMS from the dashboard or API
- Watch the request arrive in Beeceptor's live inspector — you can inspect headers, the full JSON body, and replay past requests
Tip: Beeceptor lets you define mock responses so you can simulate your server returning
200 OK(or a failure) to verify TalkNTalk's retry behaviour.
Managing webhooks in the dashboard
- Dashboard → Webhooks → Endpoints — create, edit, toggle, or delete endpoints
- Dashboard → Webhooks → Logs — inspect every delivery attempt, see the response body, filter by status, and manually resend failures
- Click any log row to expand and see the full response body returned by your server
Best practices
- Respond quickly. Return
2xxwithin 10 seconds. For slow processing, return200immediately and handle the payload asynchronously. - Be idempotent. The same event may be delivered more than once if your server was temporarily unavailable. Use the
data.idfield to deduplicate. - Use HTTPS. TalkNTalk only delivers to HTTPS endpoints in production.
- Verify signatures. Always validate
X-TalkNTalk-Signaturewhen you have a secret set.