Thrayne emits an event for every state change a release goes through. Webhooks deliver those events to an endpoint you control, signed so you can verify they came from us.
Subscribing
thrayne webhooks create \
--url https://hooks.internal.example/thrayne \
--events promotion.started,promotion.succeeded,rollout.rolled_back
Omit --events to receive everything. You can register up to ten endpoints per
workspace, each with its own event selection.
Event payload
Every delivery has the same envelope. The data object varies by event type.
{
"id": "evt_01J8ZQ4M7K",
"type": "rollout.rolled_back",
"created": "2026-07-28T09:14:22Z",
"workspace": "acme",
"data": {
"release": "2414",
"service": "checkout",
"environment": "production",
"reason": "signal_threshold_breached",
"signal": "error_rate",
"observed": 0.031,
"threshold": 0.010
}
}
Verifying the signature
Each request carries Thrayne-Signature and Thrayne-Timestamp. The signature
is an HMAC-SHA256 of timestamp + "." + body, keyed with your endpoint secret.
Thrayne-Timestamp: 1785571262
Thrayne-Signature: v1=4f2c8a...
Compare using a constant-time function, and reject anything with a timestamp more than five minutes old — that window is what stops a captured delivery being replayed at you later.
Delivery and retries
A delivery is successful when your endpoint returns any 2xx within ten seconds. Anything else is retried with exponential backoff for up to 24 hours: after roughly 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours.
Deliveries are at least once, not exactly once. A network timeout after your
handler committed still counts as a failure and will be retried, so treat id
as an idempotency key and ignore one you have already processed.
Order is not guaranteed either. Two events created milliseconds apart can arrive
in either order; use created rather than arrival time when sequence matters.
Events
| Event | Fired when |
|---|---|
promotion.started |
A promotion enters its first stage |
promotion.succeeded |
Every stage has passed and production is live |
promotion.failed |
A stage failed and the promotion stopped |
approval.requested |
A gate is waiting on a human decision |
approval.granted |
An approver allowed the promotion to continue |
rollout.step_advanced |
A canary step advanced to the next percentage |
rollout.rolled_back |
A rollout reverted, automatically or by hand |
See the CLI reference for managing endpoints, and progressive rollout for what drives the rollout events.