Webhook subscriptions select event types, destination URL, optional headers, enabled state, and an HMAC-SHA256 signing secret. Operators can inspect recent attempts, send a test, rotate signing material, and re-enqueue any non-delivering delivery through the API.
Delivery is at least once
Attempts track status, response code, error, attempt_count, and retry timing. The API redelivers any non-delivering row; a delivering row returns 400 in_flight. Receivers must be idempotent because automatic retries, tests, and manual redelivery may produce another POST for the same logical event. Successful-delivery replays can duplicate receiver side effects.
Secrets have a rotation moment
Create, list, and update responses never echo signing_secret, even when create supplied it. Persist a caller-supplied secret before creation, or call rotate_secret after creation and capture its one-time value before configuring the receiver; there is no promised overlap window.
Before you begin
A signed-in browser session with a selected workspace backed by an active membership is required; an archived workspace remains readable but rejects mutations. Every /api/v1/operator endpoint rejects API credentials and bearer tokens, regardless of their scopes.
Any role on an active membership can read subscriptions and deliveries. Owner or admin membership is required to create, update, delete, rotate, test, or redeliver.
Prepare an HTTPS receiver that preserves the raw request body, verifies signatures, handles duplicate event IDs, and returns promptly.
How it works
Configure narrowly
Subscribe only to event types the receiver uses and keep custom headers non-sensitive. /app/admin can create, test, and retry failed deliveries; the API redelivery route accepts any non-delivering row. Use CSRF-protected PATCH, DELETE, and rotate_secret operator routes for update, removal, or secret rotation.
Test and observe
Send a synthetic delivery, then read the subscription's deliveries. Treat 202 from test or redeliver as queued—not delivered—and wait for delivered_at or inspect last_response_code and last_error.
Examples
These examples are illustrative. Replace the sample values with your own.
Keep credentials in environment variables or a secret manager, never in client-side code.
Inspect subscriptions and recent attempts
The collection includes each subscription plus a hard-capped workspace list of the 30 most recent delivery records.
javascript
const response = await fetch("/api/v1/operator/webhook_subscriptions", {
credentials: "same-origin",
headers: {"Accept": "application/json"}
});
const body = await response.json();
if (!response.ok) throw new Error(`${response.status}: ${body.detail}`);
console.log(body);
What to expect
200 OK with top-level webhook_subscriptions and recent_deliveries arrays. Subscription rows omit signing_secret; delivery rows expose status and retry diagnostics.
Troubleshooting
A test returns 202 but nothing arrives
202 only confirms enqueueing. Read the delivery list for response code, error, next_attempt_at, and attempt_count, then verify receiver reachability and signature handling.
A subscription or delivery is 404
Both IDs are workspace-scoped. Confirm the current workspace and use an ID returned by its own list; cross-workspace records are intentionally hidden.
Endpoint reference
Ready to integrate? Open an endpoint for its required permissions, request fields,
response format, and status codes. The examples above explain the workflow;
these details define each individual request.
GET
/api/v1/operator/webhook_subscriptions
Web Session
List webhook subscriptions
Description
Returns webhook subscriptions and the 30 most recent delivery records for the workspace. recent_deliveries are delivery-attempt rows (status, attempt_count, last_error), not the outbound POST payload. Operator routes require a browser session. Workspace admin at /app/admin can create subscriptions, send a test, list attempts, and retry.
Auth
Web Session
Responses
200
Webhook subscriptions
Response Body
Field
Type
Required
Description
recent_deliveries
array<object>
Yes
Hard-capped list of the 30 most recent delivery records
recent_deliveries[].id
string
Yes
Webhook delivery UUID
recent_deliveries[].status
string (pending, succeeded, failed)
Yes
Delivery status
recent_deliveries[].test
boolean
No
true only for webhook.test sample deliveries (absent from the subscription list's recent_deliveries)
recent_deliveries[].inserted_at
datetime (ISO 8601)
Yes
Record insertion timestamp
recent_deliveries[].attempt_count
integer
Yes
Number of delivery attempts
recent_deliveries[].event_type
string
Yes
Event type delivered
recent_deliveries[].delivered_at
datetime (ISO 8601)
No
When delivery succeeded
recent_deliveries[].last_error
string
No
Most recent delivery error
recent_deliveries[].last_response_code
integer
No
Most recent HTTP response status code
recent_deliveries[].next_attempt_at
datetime (ISO 8601)
No
When the next retry is scheduled
recent_deliveries[].webhook_subscription_id
string
Yes
Webhook subscription UUID
webhook_subscriptions
array<object>
Yes
List of webhook subscriptions
webhook_subscriptions[].enabled
boolean
Yes
Whether the subscription is enabled
webhook_subscriptions[].id
string
Yes
Webhook subscription UUID
webhook_subscriptions[].name
string
Yes
Webhook subscription name
webhook_subscriptions[].url
string
Yes
Webhook destination URL
webhook_subscriptions[].headers
object
Yes
Additional headers sent with deliveries. Values are [REDACTED] for roles below admin. Framing, hop-by-hop, content-type and x-agentops-* headers are rejected.
/api/v1/operator/webhook_subscriptions
Web Session
Create webhook subscription
Description
Registers a webhook destination and event subscriptions. Omitting event_types creates a wildcard subscription (["*"]). Create never returns signing_secret — only POST .../rotate_secret adds the secret to the JSON.
Auth
Web Session
Request Body
Field
Type
Required
Description
webhook_subscription
object
Yes
Webhook subscription attributes
webhook_subscription.enabled
boolean
No
Whether the subscription is enabled
webhook_subscription.name
string
Yes
Webhook subscription name
webhook_subscription.url
string
Yes
Absolute http(s) webhook destination URL, at most 2048 characters; must pass the outbound URL policy.
webhook_subscription.headers
object
No
Extra request headers as a name→value map (at most 50). Names must be RFC 9110 tokens of at most 256 characters; host, content-length, transfer-encoding, connection, keep-alive, te and other hop-by-hop names, content-type, and names starting with proxy- or x-agentops- are rejected. Values are single-line strings of at most 8 KB with no CR, LF or NUL. On GET/list, values are returned only to owner/admin sessions; members and auditors see each value as [REDACTED].
webhook_subscription.event_types
array<string>
No
Event types to subscribe to. Omitted values default to ["*"] before validation.
webhook_subscription.signing_secret
string
No
Optional signing secret used for webhook verification; generated automatically when omitted. Never echoed on create. Must be non-blank when supplied.
Responses
201
Webhook subscription created (no signing_secret)
Response Body
Field
Type
Required
Description
enabled
boolean
Yes
Whether the subscription is enabled
id
string
Yes
Webhook subscription UUID
name
string
Yes
Webhook subscription name
url
string
Yes
Webhook destination URL
headers
object
Yes
Additional headers sent with deliveries. Values are [REDACTED] for roles below admin. Framing, hop-by-hop, content-type and x-agentops-* headers are rejected.
Validation failed. metadata.partner_id is refused: it is reserved for subscriptions a marketplace registers.
PATCH
/api/v1/operator/webhook_subscriptions/:id
Web Session
Update webhook subscription
Description
Updates destination, secret behavior, or subscribed events. A subscription a marketplace partner registered on this workspace is read-only here and answers 403.
Auth
Web Session
Request Body
Field
Type
Required
Description
webhook_subscription
object
Yes
Webhook subscription attributes to update
webhook_subscription.enabled
boolean
No
Whether the subscription is enabled
webhook_subscription.name
string
No
Webhook subscription name
webhook_subscription.url
string
No
Absolute http(s) webhook destination URL, at most 2048 characters; must pass the outbound URL policy.
webhook_subscription.headers
object
No
Extra request headers as a name→value map (at most 50). Names must be RFC 9110 tokens of at most 256 characters; host, content-length, transfer-encoding, connection, keep-alive, te and other hop-by-hop names, content-type, and names starting with proxy- or x-agentops- are rejected. Values are single-line strings of at most 8 KB with no CR, LF or NUL. On GET/list, values are returned only to owner/admin sessions; members and auditors see each value as [REDACTED].
webhook_subscription.event_types
array<string>
No
Array of event types to subscribe to
webhook_subscription.signing_secret
string
No
Replace the signing secret used for webhook verification
Parameters
Name
In
Type
Required
Description
id
path
string
Yes
Webhook subscription UUID
Responses
200
Webhook subscription updated
Response Body
Field
Type
Required
Description
enabled
boolean
Yes
Whether the subscription is enabled
id
string
Yes
Webhook subscription UUID
name
string
Yes
Webhook subscription name
url
string
Yes
Webhook destination URL
headers
object
Yes
Additional headers sent with deliveries. Values are [REDACTED] for roles below admin. Framing, hop-by-hop, content-type and x-agentops-* headers are rejected.
Problem JSON with error "partner_managed_subscription": the subscription belongs to the marketplace partner that provisioned this workspace. It is listed here but only the partner plane manages it; disconnecting the marketplace disables it.
404
Webhook subscription not found
422
Validation failed. metadata.partner_id is refused: it is reserved for subscriptions a marketplace registers.
DELETE
/api/v1/operator/webhook_subscriptions/:id
Web Session
Delete webhook subscription
Description
Deletes a webhook subscription. A marketplace partner's subscription answers 403 instead, until disconnecting the marketplace has disabled it: nothing re-enables a disabled partner subscription, so it can then be deleted here.
Auth
Web Session
Parameters
Name
In
Type
Required
Description
id
path
string
Yes
Webhook subscription UUID
Responses
204
Webhook subscription deleted
401
An authenticated operator session is required
403
Problem JSON with error "partner_managed_subscription": the subscription belongs to the marketplace partner that provisioned this workspace and is still enabled. Disconnecting the marketplace disables it, after which it can be deleted.
404
Webhook subscription not found
POST
/api/v1/operator/webhook_subscriptions/:id/rotate_secret
Web Session
Rotate webhook signing secret
Description
Generates and returns a new webhook signing secret. This is the only operator action that includes signing_secret in the JSON.
Auth
Web Session
Parameters
Name
In
Type
Required
Description
id
path
string
Yes
Webhook subscription UUID
Responses
200
Signing secret rotated
Response Body
Field
Type
Required
Description
enabled
boolean
Yes
Whether the subscription is enabled
id
string
Yes
Webhook subscription UUID
name
string
Yes
Webhook subscription name
url
string
Yes
Webhook destination URL
headers
object
Yes
Additional headers sent with deliveries. Values are [REDACTED] for roles below admin. Framing, hop-by-hop, content-type and x-agentops-* headers are rejected.
Problem JSON with error "partner_managed_subscription": the subscription belongs to the marketplace partner that provisioned this workspace. It is listed here but only the partner plane manages it; disconnecting the marketplace disables it.
404
Webhook subscription not found
POST
/api/v1/operator/webhook_subscriptions/:id/test
Web Session
Send a test webhook delivery
Description
Enqueues a signed sample event (event_type webhook.test, payload.test true) and returns the delivery record as 202.
Auth
Web Session
Parameters
Name
In
Type
Required
Description
id
path
string
Yes
Webhook subscription UUID
Responses
202
Test delivery enqueued
Response Body
Field
Type
Required
Description
id
string
Yes
Webhook delivery UUID
status
string (pending, succeeded, failed)
Yes
Delivery status
test
boolean
No
true only for webhook.test sample deliveries (absent from the subscription list's recent_deliveries)
/api/v1/operator/webhook_deliveries/:id/redeliver
Web Session
Redeliver a webhook delivery
Description
Resets the delivery's attempt_count and re-enqueues it. Non-delivering states are eligible; an in-flight delivery returns 400 in_flight. A successful redelivery can duplicate side effects. Returns 202 with the delivery record.
Auth
Web Session
Parameters
Name
In
Type
Required
Description
id
path
string
Yes
Webhook delivery UUID
Responses
202
Delivery re-enqueued
Response Body
Field
Type
Required
Description
id
string
Yes
Webhook delivery UUID
status
string (pending, succeeded, failed)
Yes
Delivery status
test
boolean
No
true only for webhook.test sample deliveries (absent from the subscription list's recent_deliveries)