Skip to main content
A webhook is an HTTPS endpoint you register once. From then on ReasonOS sends it a signed request each time one of the events you chose happens in your organization’s projects. Agencies use it to bill on ReasonOS work; anyone can use it to follow merges, runs and issue status from another system. Webhooks are available with the core ReasonOS and QA products.

Add a webhook

Open Settings → Organization settings → Webhooks and choose Add webhook. Only organization administrators can manage webhooks; an agent working on a branch server cannot.
  • Name it after the system that receives it, so you know which one to pause later.
  • Endpoint must be https:// with no username, password or fragment. Addresses on private networks, the local machine and other special-purpose ranges are refused, both when you save and again at every delivery: the name is resolved afresh each time and the connection is made only to the addresses that passed.
  • Project limits deliveries to one project; leave it empty to receive events from every project in the organization. Deleting a project removes the webhooks limited to it; organization-wide webhooks keep their history.
  • Events: choose at least one from the list below.
When you save, ReasonOS shows the webhook’s signing secret once. Copy it into the receiving system now; it is never shown again. If you lose it, choose Rotate secret on the webhook’s row: a new secret is issued and every delivery from then on, including retries, is signed with it. A delivery that was already in flight at that moment may still arrive signed with the previous secret, so keep accepting the old one for a minute or two after rotating. An organization can hold up to 20 webhooks.

Events

The two observe.alert events come from monitors in Observe. A monitor can name the webhooks it notifies; it then delivers only to those, and otherwise to every webhook that subscribed to the event and covers the monitor’s project. value is null when the condition had no row to judge, and group is empty for a monitor without group_by. Events describe transitions, not every change: a push that only moves a branch forward, an edit to an issue’s title, or a CI run that is still running send nothing. The list in the editor comes from your workspace’s control plane, so a newly supported event appears there without a docs change.

What a delivery looks like

Each delivery is an HTTPS POST with a JSON body, Content-Type: application/json, the user agent ReasonOS-Webhooks/1.0 and these headers: The body carries the event, when it happened, the organization and project, who acted, the resource it concerns, and the fields listed above as they were at the moment of the event:
actor.id is the acting member’s id, or empty when the platform itself acted (a CI run finishing, a branch observed during a sync). The body is written once, when the event happens, and never rebuilt: a retry a day later still describes the state at that moment. Payloads are at most 256 KB and never contain secrets, issue bodies, comments, document contents or branch-server addresses.

Verify the signature

The signed text is the value of X-ReasonOS-Timestamp, a single ., and the raw request body, in that order. Compute HMAC-SHA256 over it with the webhook’s secret exactly as shown to you (the whsec_ prefix is part of the key), encode the result as lowercase hex, and compare it in constant time with the value after sha256=. Reject anything that does not match, and anything whose timestamp is older than you are willing to accept — five minutes is a common choice.
Node.js
Python
Both functions answer false (False), without raising, for a missing header, a timestamp such as "1760000000²" or "-5", a signature in uppercase hex, one that is too short or long, or one with non-ASCII characters. Answer such a delivery with a non-2xx status such as 401. ReasonOS counts it as a failed attempt and retries it on the schedule below; every delivery ReasonOS signs has these shapes. Answer with any 2xx status within ten seconds; do your own processing after you have answered. Anything else, no answer, a redirect or a certificate ReasonOS cannot verify counts as a failed attempt. ReasonOS records only the status code you answered, never the response body.

Retries and redelivery

Each delivery gets up to five attempts. After a failed attempt ReasonOS waits 10 seconds, then 1 minute, 5 minutes and 30 minutes before the next one. After the fifth failure the delivery is marked failed. Deliveries stay visible for thirty days; an event older than that is not delivered. On the webhook’s row, the chevron opens Recent deliveries: each event, the status your receiver answered, the number of attempts and the time of the next retry. Redeliver queues another attempt of a finished delivery, delivered or failed, with five fresh attempts: it keeps the same delivery id and the same payload, so your receiver’s de-duplication on X-ReasonOS-Delivery still applies. A delivery that is still pending cannot be redelivered; it will be retried on its own. Pausing a webhook stops new deliveries: events that happen while it is paused are not delivered later, and deliveries that were already queued resume when you resume it. Deleting a webhook discards its unsent deliveries. A request that is already on its way cannot be recalled.

From the MCP

With your own access token, the ReasonOS MCP offers the same operations as the settings page: list, create, update (including pause and resume), rotate, delete, list the event catalogue, list a webhook’s deliveries and redeliver. The secret is returned by create and rotate only, once. An agent working on a branch server uses a project-scoped connection: it cannot create, change, rotate or delete webhooks, and it can list its own project’s delivery summaries — event, status and the answered status code, never endpoints or payloads — only when the person whose credential it carries is an organization administrator.