Webhooks
A webhook is an address of yours that is told when an event happens in the organization: a POST, with what is said of the event as its body and the organization’s webhook token beside it (see Organization). One event per webhook. A tool subscribes by making one and unsubscribes by deleting it; the same webhooks are on the dashboard, under Webhooks, with how each sending went.
Events
Section titled “Events”trigger |
When |
|---|---|
webinarRegistration.created |
Somebody took a seat in a webinar, whichever way. |
surveyResponse.created |
A registration sent a response to a survey. |
What a webhook is for is said in what its event is of. For
webinarRegistration.created, webinars: allWebinars is every webinar, the ones
made later too, else the ones in webinarIds. For surveyResponse.created,
surveys the same way: allSurveys or surveyIds. The ones picked have to be
yours and not deleted (404 WEBINAR_NOT_FOUND, 404 SURVEY_NOT_FOUND).
Active and inactive
Section titled “Active and inactive”active says whether events reach it. An active webhook needs all of these, and
is refused with what it lacks:
| It lacks | Refused with |
|---|---|
A name |
409 ORGANIZATION_WEBHOOK_NAME_MISSING |
A trigger |
409 ORGANIZATION_WEBHOOK_TRIGGER_MISSING |
Webinars, for webinarRegistration.created |
409 ORGANIZATION_WEBHOOK_WEBINARS_MISSING |
Surveys, for surveyResponse.created |
409 ORGANIZATION_WEBHOOK_SURVEYS_MISSING |
An inactive webhook needs only its name and its url: trigger may be null
and it may be for nothing.
While inactive, an event makes no delivery, then or later. A delivery made
while it was active still goes out, its retries too, and a failed one can still
be tried again from the dashboard. A test can be sent from the dashboard while
inactive, if it has an event.
Deleting a webinar or a survey takes it out of webinarIds or surveyIds on every
webhook that has it, and restoring it does not put it back. A webhook it was all
that was left for becomes inactive, with nothing picked, and the organization’s
owners and managers are told; one with others left stays active with those, and
one for every webinar or survey goes on as it was.
Make one
Section titled “Make one”POST /public/v1/webhooks{ "name": "CRM sign-ups", "active": true, "trigger": "webinarRegistration.created", "allWebinars": true, "webinarIds": [], "allSurveys": false, "surveyIds": [], "url": "https://hooks.example.com/sparkwebinar"}name and url are always sent. The rest may be left out: active starts
true, trigger null, and what it is for empty, so what is left out has to fit
its state. url is http or https; an address that
resolves to a private network is refused as it is sent, and the delivery says so.
List, read, change, delete
Section titled “List, read, change, delete”GET /public/v1/webhooksGET /public/v1/webhooks/:organizationWebhookIdPATCH /public/v1/webhooks/:organizationWebhookIdDELETE /public/v1/webhooks/:organizationWebhookIdA change sends whichever of the fields changed, "trigger": null to clear the
event, and what the webhook comes to has to fit its state.
A webhook deleted is told nothing more; sendings already on their way are not
recalled.
What is sent
Section titled “What is sent”Every sending is a POST to the webhook’s url, content-type: application/json, with the organization’s token in x-webhook-token —
check it, and answer any 2xx. The body opens with the delivery’s own
id — the same on every attempt at it, so a request received twice is
known to be one — createdAt, the instant the event happened, and
test, true on one sent from the dashboard to see it arrive; then the
event:
{ "id": 318, "createdAt": "2026-10-26T15:26:15.600Z", "test": false, "event": "webinarRegistration.created", "webinarRegistration": { "id": 109, "webinarId": 2, "email": "ana@example.com", "...": "..." }, "webinarSession": { "id": 412, "startsAt": "2026-10-26T22:00:00.000Z", "status": "scheduled" }, "webinar": { "id": 2, "name": "Launch webinar", "title": "How we launch", "method": "evergreen" }}webinarRegistration is the registration whole, their access token
with them. webinarSession is the session their seat is in: its id,
startsAt, its status (scheduled, running, canceled or
closed); null only where there is no registration.
webinar is its id, name, title and method (live or
evergreen), which is what its sessions are too. On surveyResponse.created there are also survey — id and
name — and answers, each fieldId, value and the question’s
title.
Not answered with a 2xx, a delivery is tried again a minute later, then after five minutes, half an hour, two hours and twelve — six attempts in all, over about fourteen hours — and then given up on.
Deliveries
Section titled “Deliveries”GET /public/v1/webhooks/:organizationWebhookId/deliveriesOne row per event sent to this webhook, newest first: the body as it
was sent, attempts, the last attempt’s instant and status — or
lastError: ADDRESS_NOT_ALLOWED, REQUEST_TIMED_OUT, REQUEST_FAILED
—, nextAttemptAt while one is due, and its status: pending while
attempts go on, then delivered or failed, with deliveredAt or
failedAt.
One that ended is deleted 15 days after that instant, so the list and its
total go back no further, and the dashboard can no longer try a failed one
again. One pending is never deleted this way.