Skip to main content
s.id Logo
View Markdown

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

EventSent when
link.createdFired when a new link is created
link.updatedFired when a link's URL or title is changed
link.archivedFired when a link is archived
link.clickedFired on each redirect (per-click event)
microsite.publishedFired when a microsite is published
qr.scannedFired when a QR code is scanned
HeaderValue
X-SID-EventEvent name, for example link.created
X-SID-Signaturesha256=<hmac-hex>
X-SID-Delivery-IDUnique ID for each delivery
User-Agents.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);
}