Webhooks
Webhooks send events from your s.id account straight to your server. Register an endpoint in Dashboard > Developer > Webhooks, then select the events you need.
Events and headers
| Event | Sent when |
|---|---|
link.created | Fired when a new link is created |
link.updated | Fired when a link's URL or title is changed |
link.archived | Fired when a link is archived |
link.clicked | Fired on each redirect (per-click event) |
microsite.published | Fired when a microsite is published |
qr.scanned | Fired when a QR code is scanned |
| Header | Value |
|---|---|
X-SID-Event | Event name, for example link.created |
X-SID-Signature | sha256=<hmac-hex> |
X-SID-Delivery-ID | Unique ID for each delivery |
User-Agent | s.id-Webhooks/1.0 |
json
{
"event": "link.created",
"link": {
"id": 123,
"short": "[your-alias]",
"short_url": "https://s.id/[your-alias]",
"long_url": "https://example.com/long-url",
"title": "My Link",
"created": "2026-06-22T10:00:00Z"
},
"timestamp": "2026-06-22T10:00:00Z"
}Delivery
- Sent as POST with Content-Type: application/json.
- Up to 3 attempts per event, with delays of 0, 5, and 30 seconds.
- The webhook is disabled after 5 consecutive failed events.
- The Test button sends a sample payload, and history is available under Deliveries.
Verify signatures
Each delivery is signed with HMAC-SHA256 over the raw body, using your webhook secret. Recompute the signature before processing the payload.
javascript
const crypto = require('node:crypto');
function verifySignature(secret, rawBody, sigHeader) {
if (typeof sigHeader !== 'string' || !sigHeader.startsWith('sha256=')) {
return false;
}
const expected = 'sha256=' +
crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const receivedBuffer = Buffer.from(sigHeader, 'utf8');
const expectedBuffer = Buffer.from(expected, 'utf8');
return receivedBuffer.length === expectedBuffer.length &&
crypto.timingSafeEqual(receivedBuffer, expectedBuffer);
}