Webhook events
The delivery envelope, signature headers, and event types.
Everything Stacklink delivers to your project webhook uses one envelope and one signature scheme. Receiving and configuring is covered in Webhooks; this is the wire reference.
Event types
| Type | Fired when |
|---|---|
stacklink.trigger.event | A subscribed provider event was ingested and matched. |
stacklink.connected_account.expired | An account's credentials expired and can't be refreshed. |
stacklink.trigger.disabled | A subscription was disabled (e.g. repeated polling failures). |
Envelope
{
"version": "v1",
"id": "evt_...",
"type": "stacklink.trigger.event",
"metadata": {
"trigger_id": "...",
"trigger_slug": "...",
"connected_account_id": "...",
"tenant_id": "...",
"provider_key": "...",
"auth_config_id": "...",
"raw_event_id": "..."
},
"data": { /* normalized provider payload */ },
"timestamp": "2026-05-08T05:30:00+05:30"
}Signature headers
| Header | Content |
|---|---|
webhook-id | The delivery id. |
webhook-timestamp | Unix seconds — reject if outside your tolerance (default 300 s). |
webhook-signature | v1,<base64 HMAC-SHA256> over `${id}.${timestamp}.${body}`. |
import { verifyWebhookSignature } from '@stacklink/sdk';
const ok = await verifyWebhookSignature({
id: req.headers['webhook-id'],
timestamp: req.headers['webhook-timestamp'],
signature: req.headers['webhook-signature'],
body: rawBody, // the exact raw bytes
secret: process.env.STACKLINK_WEBHOOK_SECRET!,
});The comparison is constant-time, multiple v1, candidates in one header are supported (secret
rotation), and timestamps outside tolerance fail closed.
Delivery behavior
Failed deliveries retry with backoff and land in a dead-letter queue after max attempts. Inspect
and recover via GET /v1/logs/webhook-deliveries, POST .../retry, redrive, and replay — or the
SDK's stacklink.webhooks.redriveDeadLetters() / replayEvent().
Always verify before trusting a delivery, and always read the raw request body — re-serialized JSON will not match the signature.
Workflow notifications
| Type | Meaning |
|---|---|
stacklink.workflow.changed | A definition, publication or pause state changed |
stacklink.workflow.run.updated | A saved run changed status |
These are metadata notifications through the same signed project-webhook pipeline. They carry customer/workflow identity and, for runs, run ID, purpose, mode, status and parent run ID. They do not carry private inputs, outputs or credentials. Verify the signature, deduplicate deliveries, then fetch current authorized details with the workflow SDK. Browser callbacks are not a replacement for server records.