Developers
Outgoing webhooks
SIGNL can call a URL of yours when something happens: a call is booked, a payment lands, a form is submitted. Use it to feed your own systems, Zapier, Make or n8n.
53 events
Set one up
Where
Agency settings
*), and optionally set a signing secret. An organisation can have up to 100 active endpoints.Zapier
instant triggers
Zapier: … and limited to that Zap's client. Leave them alone: switching the Zap off removes its endpoint.Formats
signl · discord
Who sees what
every client, or one
data.clientId. Limit an endpoint to one client when its receiver should not see the others' leads and payments; it then gets only that client's events, and none that name no client.What arrives
Request
POST, JSON
Content-Type: application/json and this envelope. id is the delivery id (the same value as the X-SIGNL-Delivery header, and the same on every retry of it), and data is the event's own fields.{
"id": "9b1f0c2e-…",
"event": "call.booked",
"data": { "clientId": "…", "leadId": "…", "scheduledAt": "2026-10-01T14:00:00Z" },
"timestamp": "2026-09-30T09:12:44.120Z"
}Signature
signed by default
X-SIGNL-Signature: sha256=<hex>, an HMAC-SHA256 of the raw body keyed with the secret. An endpoint created before this without a secret stays unsigned until you rotate one in; a Discord endpoint is never signed.Headers
on signed endpoints
X-SIGNL-Event (the event name), X-SIGNL-Timestamp (the envelope's own timestamp, to reject a replayed request), X-SIGNL-Delivery (the delivery id, the same on every retry) and Idempotency-Key (the same value, under the name most receivers already de-duplicate on). A replay from the log carries its own delivery id.import { createHmac, timingSafeEqual } from 'node:crypto'
// rawBody is the exact request body, before any JSON parsing; secret is the one you set on the endpoint.
const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex')
const given = req.headers['x-signl-signature'] ?? ''
const ok = given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected))Delivery
retried on failure
X-SIGNL-Delivery id, so you can tell you have already seen it. Any other 4xx is not retried, and a 410 pauses the endpoint. After the last attempt the delivery stays in the log, marked failed, in Agency settings, Webhooks, where you can replay it by hand. Answer quickly with a 2xx and do the work afterwards.Send test
from the endpoint
Not live
workspaces
Events
53 across 16 areas. Under each, the fields of data: a field marked ? is sent by some sources only, and an event marked open may carry further scalar fields its source attaches. Times are ISO 8601; money is whole minor units (pence, cents).
visitor
visitor.identified
call
call.booked
call.cancelled
call.rescheduled
call.showed
call.no_show
call.won
call.lost
call.confirmed
open payload
call.reconfirmation_lapsed
open payload
call.inbound_dni
open payload
call.scored
call.score_below_threshold
deal
deal.created
deal.won
deal.stage_changed
open payload
deal.updated
open payload
deal.outcome_updated
deal.went_stale
open payload
payment
payment.received
payment.refunded
payment.dispute.opened
payment.dispute.resolved
payment.failed
open payload
payment.deposit_received
open payload
payment.matched
payment.unmatched
form
form.submitted
report
report.submitted
lead
lead.tag_added
open payload
lead.tag_removed
open payload
lead.updated
open payload
lead.hot
contract
contract.signed
open payload
contract.declined
open payload
contract.expired
open payload
contract.viewed
open payload
checkout
checkout.abandoned
open payload
membership
membership.started
open payload
membership.cancelled
open payload
booking
booking.disqualified
open payload
routing
routing.lost
open payload
sms
sms.received
open payload
sms.failed
open payload
email.bounced
open payload
email.complained
open payload
recording
recording.watched
open payload
recording.cta_clicked
open payload
webinar
webinar.registered
open payload
webinar.attended
open payload
webinar.cta_clicked
open payload
webinar.replay_expiring
open payload
webinar.replay_expired
open payload