Webhooks
Real-time event notifications for messages, reactions, chats, and more.
Webhook Subscriptions allow you to receive real-time notifications when events occur on your account.
Configure webhook endpoints to receive events such as messages sent/received, delivery status changes, reactions, typing indicators, and more.
Failed deliveries (5xx, 429, network errors) are retried up to 10 times over ~25 minutes with exponential backoff. Each event includes a unique ID for deduplication.
Webhook Headers
Each webhook request includes the following headers:
| Header | Description |
|---|---|
X-Webhook-Event | The event type (e.g., message.sent, message.received) |
X-Webhook-Subscription-ID | Your webhook subscription ID |
X-Webhook-Timestamp | Unix timestamp (seconds) when the webhook was sent |
X-Webhook-Signature | HMAC-SHA256 signature for verification |
Verifying Webhook Signatures
All webhooks are signed using HMAC-SHA256. You should always verify the signature to ensure the webhook originated from Linq and hasn’t been tampered with.
Signature Construction:
The signature is computed over a concatenation of the timestamp and payload:
{timestamp}.{payload}
Where:
timestampis the value from theX-Webhook-Timestampheaderpayloadis the raw JSON request body (exact bytes, not re-serialized)
Verification Steps:
- Extract the
X-Webhook-TimestampandX-Webhook-Signatureheaders - Get the raw request body bytes (do not parse and re-serialize)
- Concatenate:
"{timestamp}.{payload}" - Compute HMAC-SHA256 using your signing secret as the key
- Hex-encode the result and compare with
X-Webhook-Signature - Use constant-time comparison to prevent timing attacks
Example (Python):
import hmac
import hashlib
def verify_webhook(signing_secret, payload, timestamp, signature):
message = f"{timestamp}.{payload.decode('utf-8')}"
expected = hmac.new(
signing_secret.encode('utf-8'),
message.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Example (Node.js):
const crypto = require('crypto');
function verifyWebhook(signingSecret, payload, timestamp, signature) {
const message = `${timestamp}.${payload}`;
const expected = crypto
.createHmac('sha256', signingSecret)
.update(message)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
Security Best Practices:
- Reject webhooks with timestamps older than 5 minutes to prevent replay attacks
- Always use constant-time comparison for signature verification
- Store your signing secret securely (e.g., environment variable, secrets manager)
- Return a 2xx status code quickly, then process the webhook asynchronously
Setting up webhooks
Section titled “Setting up webhooks”Create a webhook subscription to start receiving events. Each subscription targets a URL you own, filters to the events you care about, and returns a signing secret you use to verify inbound requests. See Webhook Subscriptions for the full subscription lifecycle — create, list, retrieve, update, delete, and phone-number filtering.
Webhook versioning
Section titled “Webhook versioning”Webhook payloads are versioned using dates. Specify a version by adding ?version=YYYY-MM-DD to your subscription URL:
https://your-server.com/webhook?version=2026-02-03| Subscription created | Webhook version |
|---|---|
| Before 2026-02-03 | 2025-01-01 |
| 2026-02-03 or later | 2026-02-03 |
If no version is specified, the subscription uses the latest available version at creation time.
Tip: Always specify a version explicitly to avoid unexpected payload format changes.
Delivery guarantees
Section titled “Delivery guarantees”| Guarantee | Value |
|---|---|
| Response timeout | 10 seconds |
| Retry attempts | 10 per endpoint |
| Retry backoff | Exponential with jitter, capped at 10 minutes |
| Total retry window | ~25 minutes |
| Delivery model | At-least-once (duplicates possible) |
Retried: HTTP 5xx, HTTP 429, connection timeout, connection refused. Not retried: HTTP 4xx (except 429), DNS failures, invalid hostnames.
Your endpoint should:
- Return
200quickly — process asynchronously if needed - Verify the HMAC signature using your subscription’s signing secret
- Deduplicate using
event_id - Be idempotent
Related
Section titled “Related”- Webhook Subscriptions — create, list, update, delete subscriptions
- Webhook Events — full event list, shared envelope, and representative payloads
- API Reference: Webhook Events
- API Reference: Webhook Subscriptions