How webhooks are delivered
The guarantees //SCHEMA's webhooks make, the ones they deliberately do not, and the reasons for both.
An event arrives only after its data is readable#
When something changes — a delivery is processed, a release goes live — the event announcing it is recorded in the same database transaction as the change itself. The two commit together or not at all, and the sender only ever sees committed events.
So by the time your receiver is told about something, it is already readable through the API. There is no window in which an event names a release the API cannot find yet, and no event is ever lost because a process stopped between making a change and announcing it.
Thin payloads#
An event says what changed and how to look it up — identifiers, the old and new state — not the catalog data itself. Three reasons:
- Access stays with the API. Reading a release needs a credential with
catalog_read. A payload carrying the release would be a second way to read it that bypassed that check. - No stale snapshots. A delivery retried hours later would present old titles as current. Fetching on receipt always gets what is true now.
- Less to trust. Titles, names and notes are written by whoever delivered the release. Keeping them out of payloads keeps them out of systems that act on payloads automatically.
Membership events are the exception: they carry the person's address and role, because a removed member cannot be looked up afterwards.
At least once, in no particular order#
A delivery counts as done when your receiver answers 2xx within 10 seconds.
If //SCHEMA's sender stops after you answered but before it recorded the
answer, it sends again — so an event can arrive twice. Every attempt
carries the same webhook-id; deduplicate on it.
Retries also mean events can arrive out of order: a retried
release.state_changed can land after a later one for the same release. Treat
each event as a prompt to fetch the current state, not as the state itself.
Retries and automatic disabling#
A failed delivery is retried at widening intervals — 30 seconds, 2 minutes, 10 minutes, an hour, 3 hours, then every 6 hours — for about three days, and then marked failed. Every attempt is in the endpoint's delivery log, with your receiver's status and the first 4 KiB of what it answered.
An endpoint whose every delivery has failed for five consecutive days is turned off, and your organization's owners are emailed. "Consecutive" is meant literally: a failure more than a day after the previous one starts the count again, so an endpoint that was down a week ago and has been quiet since is not turned off by one unlucky retry.
Turning an endpoint back on delivers events from that moment. What it missed is not replayed automatically — redeliver what you need from its log.
When an endpoint receives an event#
An endpoint receives an event when it is enabled, subscribed to the event's type, and — for an event that belongs to a catalog — covers that catalog. It receives only events that happen after it was created or last turned on: creating an endpoint never replays history.
release.available has one subtlety. A release can go live with an
availability date in the future, and on that date nothing in the catalog
changes. //SCHEMA checks every minute for releases whose date has come, and
sends release.available dated by the date itself. It looks back a day, so
nothing is announced late as news, and each release and date is announced
once. If a sender later moves the date, the new date is a new event.
Where webhooks can be sent#
Only to https:// on the default port, and never to a private, loopback or
link-local address. The address a name resolves to is checked at the moment of
connecting, and redirects are never followed, so a public URL cannot be used to
reach something inside //SCHEMA's network.
Every owner of your organization is emailed when an endpoint is created or widened. Webhook configuration is not available to agents over MCP, whatever a key's scopes.