type and id, not the full object. When you receive a webhook event, you need to fetch the object directly with a GET call. This avoids delivering stale data on retries and keeps every delivery small.
Supported event types
- Session events
- Vault events
- Agent events
- Deployment events
- Deployment run events
- Environment events
- Memory store events
Register an endpoint
Visit Manage > Webhooks in the OMA Console. A webhook endpoint consists of:- URL: Must be HTTPS on port 443 with a publicly resolvable hostname.
- Event types: The list of
data.typevalues this endpoint receives. An endpoint only receives events it’s subscribed to. - Signing secret: A 32-byte
whsec_-prefixed secret generated at creation. It’s shown only once, so store it securely to verify webhook deliveries.
Verify the signature
Every delivery carries thewebhook-id, webhook-timestamp, and webhook-signature headers. Use the SDK’s unwrap() helper to verify the signature and parse the event in one step. It throws if the signature is invalid or the payload is more than 5 minutes old.
Set ANTHROPIC_WEBHOOK_SIGNING_KEY to the whsec_-prefixed secret shown at endpoint creation.
Handle an event
Parse the body, switch ondata.type, and fetch the resource by ID. Return any 2xx to acknowledge. Any other response counts against the endpoint: a 3xx disables it immediately (redirects are never followed), while other failures are retried; see Delivery behavior for the retry and auto-disable rules.
Every event payload has the same structure, including the event type, identifier, and the timestamp of when the event occurred.
event.id is unique per event, not per delivery. If you receive the same event.id twice, it’s a retry and you can discard it.
Delivery behavior
-
Duplicates: An endpoint can receive the same event more than once, and every attempt delivers the same top-level
event.id(the same value as thewebhook-idheader). Deduplicate on it. - Subscription scope: An event is delivered only to endpoints subscribed to its type at the moment it’s emitted. An event emitted while no endpoint is subscribed to its type is never delivered, and subscribing later doesn’t backfill it, so subscribe to an event type before you need it.
-
Ordering is not guaranteed. Events aren’t delivered in the order they occurred:
session.status_idledmight arrive beforesession.outcome_evaluation_endedeven if the outcome was produced first, and a.deletedevent can arrive before the.archivedevent for the same resource. Drive your state from the resource you fetch, not from the order events arrive in. -
Retries: For each endpoint and event, OMA makes up to three delivery attempts (a response that triggers auto-disable, described later in this section, is never retried) with jittered exponential backoff between 5 and 120 seconds. Every attempt delivers the same
event.id. After the last attempt fails, the event is dropped: it isn’t queued for later delivery and there’s no signal that it was lost. Webhooks aren’t a durable log, so if you need to observe every transition, reconcile by listing or fetching the resource through the API. -
Timestamps: The
webhook-timestampheader is stamped when a delivery attempt is signed and is regenerated on every retry, so retries aren’t rejected by the SDK’s freshness check. It’s the clock for the delivery attempt, not for the event: use the event payload’screated_atfor when the event occurred. -
Auto-disable: An endpoint is automatically set to
disabledwith a machine-readabledisabled_reasonin three cases:- The endpoint returns a
3xxresponse. Redirects are never followed; this disables the endpoint immediately, on the first attempt, with the reasonauto-disabled: endpoint URL returned a redirect (3xx). If your endpoint moves, update the URL in Console and re-enable the endpoint. - The endpoint’s URL resolves to a non-public IP address when OMA connects. This disables the endpoint immediately, with the reason
auto-disabled: endpoint URL resolved to an invalid address. - Deliveries to the endpoint fail continuously for a sustained period, with the reason
auto-disabled after sustained delivery failures. The trigger is how long the endpoint has been failing without interruption, not a delivery count. A single2xxresets the window, so one flaky event can’t disable the endpoint.
- The endpoint returns a