Outbound webhooks
Register endpoints in Settings → Developer. Each event is POSTed as JSON with a stable id — retries always carry the same event id, so deduplicate on it.
Event types
client.createdlead.createdlead.stage_changedproposal.createdproposal.acceptedinvoice.issuedinvoice.paidpayment.receivedproject.completedsupport.ticket_createdbusiness.createdproposal.sentproposal.rejectedinvoice.overduesupport.ticket_status_changedmarketing.campaign_createdmarketing.campaign_activatedmarketing.campaign_pausedmarketing.campaign_completedmarketing.lead_capturedmarketing.attribution_capturedmarketing.campaign_submittedmarketing.campaign_failedmarketing.provider_sync_completed
Payload & headers
POST /your/endpoint
Content-Type: application/json
X-DIGISUBS-Event-Id: evt_9f2c41a83b7d
X-DIGISUBS-Event-Type: invoice.paid
X-DIGISUBS-Signature: t=1790000000,v1=5f8a…
{
"id": "evt_9f2c41a83b7d",
"type": "invoice.paid",
"createdAt": "2026-08-27T12:00:00.000Z",
"data": { "invoiceId": "inv_abc", "number": "INV-2026-0042" }
}Signature verification
HMAC-SHA256 of `${t}.${rawBody}` with your endpoint secret. Reject timestamps older than 5 minutes (replay protection). During secret rotation the header carries two v1= values — accept if either matches.
// Node.js
import { createHmac, timingSafeEqual } from "crypto";
function verify(header, rawBody, secret, toleranceSec = 300) {
const parts = Object.fromEntries(
header.split(",").map((p) => p.split("=", 2)),
); // NOTE: collect ALL v1 values in production code
const age = Math.abs(Date.now() / 1000 - Number(parts.t));
if (age > toleranceSec) return false; // replay
const expected = createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest();
const given = Buffer.from(parts.v1, "hex");
return given.length === expected.length && timingSafeEqual(given, expected);
}Retries & dead-lettering
- Any non-2xx response (or timeout after 10s) schedules a retry.
- Backoff: 30s, 60s, 120s, 240s — 5 attempts total.
- After the final failure the delivery is dead-lettered; you can inspect the full delivery log (attempts, status codes, durations) in Settings → Developer.
- Respond 2xx quickly and process asynchronously — slow handlers hit the timeout.