Log in Create workspace
Skip to content

API reference

Operator - Webhooks

Deliver signed workspace events to external systems and inspect delivery health.

Jump to 8 endpoints
On this page

Overview

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

  1. 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.

  2. 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.
webhook_subscriptions[].inserted_at datetime (ISO 8601) Yes Record insertion timestamp
webhook_subscriptions[].updated_at datetime (ISO 8601) Yes Record update timestamp
webhook_subscriptions[].event_types array<string> Yes Subscribed event types
webhook_subscriptions[].last_triggered_at datetime (ISO 8601) No Most recent successful trigger timestamp
Example
{
  "recent_deliveries": [
    {
      "attempt_count": 1,
      "delivered_at": "2026-03-12T09:05:03Z",
      "event_type": "trace.finalized",
      "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
      "inserted_at": "2026-03-12T09:05:02Z",
      "last_error": null,
      "last_response_code": 200,
      "next_attempt_at": null,
      "status": "succeeded",
      "webhook_subscription_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
    }
  ],
  "webhook_subscriptions": [
    {
      "enabled": true,
      "event_types": [
        "trace.finalized",
        "command.complete",
        "command.fail"
      ],
      "headers": {},
      "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
      "inserted_at": "2026-03-10T14:00:00Z",
      "last_triggered_at": "2026-03-12T09:05:03Z",
      "name": "Production alerts",
      "updated_at": "2026-03-12T09:05:03Z",
      "url": "https://example.com/webhooks/agentops"
    }
  ]
}
401

An authenticated operator session is required

POST
/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.
inserted_at datetime (ISO 8601) Yes Record insertion timestamp
updated_at datetime (ISO 8601) Yes Record update timestamp
event_types array<string> Yes Subscribed event types
last_triggered_at datetime (ISO 8601) No Most recent successful trigger timestamp
Example
{
  "enabled": true,
  "event_types": [
    "trace.finalized",
    "command.complete",
    "command.fail"
  ],
  "headers": {},
  "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "inserted_at": "2026-03-10T14:00:00Z",
  "last_triggered_at": "2026-03-12T09:05:03Z",
  "name": "Production alerts",
  "updated_at": "2026-03-12T09:05:03Z",
  "url": "https://example.com/webhooks/agentops"
}
401

An authenticated operator session is required

403

An owner or admin membership is required

422

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.
inserted_at datetime (ISO 8601) Yes Record insertion timestamp
updated_at datetime (ISO 8601) Yes Record update timestamp
event_types array<string> Yes Subscribed event types
last_triggered_at datetime (ISO 8601) No Most recent successful trigger timestamp
Example
{
  "enabled": true,
  "event_types": [
    "trace.finalized",
    "command.complete",
    "command.fail"
  ],
  "headers": {},
  "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "inserted_at": "2026-03-10T14:00:00Z",
  "last_triggered_at": "2026-03-12T09:05:03Z",
  "name": "Production alerts",
  "updated_at": "2026-03-12T09:05:03Z",
  "url": "https://example.com/webhooks/agentops"
}
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. 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.
inserted_at datetime (ISO 8601) Yes Record insertion timestamp
updated_at datetime (ISO 8601) Yes Record update timestamp
event_types array<string> Yes Subscribed event types
last_triggered_at datetime (ISO 8601) No Most recent successful trigger timestamp
signing_secret string Yes One-time rotated signing secret
Example
{
  "enabled": true,
  "event_types": [
    "trace.finalized",
    "command.complete",
    "command.fail"
  ],
  "headers": {},
  "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "inserted_at": "2026-03-10T14:00:00Z",
  "last_triggered_at": "2026-03-12T09:05:03Z",
  "name": "Production alerts",
  "signing_secret": "dGhpcyBpcyBhIHRlc3Qgc2VjcmV0",
  "updated_at": "2026-03-12T09:05:03Z",
  "url": "https://example.com/webhooks/agentops"
}
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. 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)
inserted_at datetime (ISO 8601) Yes Record insertion timestamp
attempt_count integer Yes Number of delivery attempts
event_type string Yes Event type delivered
delivered_at datetime (ISO 8601) No When delivery succeeded
last_error string No Most recent delivery error
last_response_code integer No Most recent HTTP response status code
next_attempt_at datetime (ISO 8601) No When the next retry is scheduled
webhook_subscription_id string Yes Webhook subscription UUID
Example
{
  "attempt_count": 1,
  "delivered_at": null,
  "event_type": "webhook.test",
  "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
  "inserted_at": "2026-03-12T09:05:02Z",
  "last_error": null,
  "last_response_code": null,
  "next_attempt_at": null,
  "status": "pending",
  "test": true,
  "webhook_subscription_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
}
400

Delivery is currently in_flight

401

An authenticated operator session is required

403

An owner or admin membership is required

404

Webhook subscription not found

GET
/api/v1/operator/webhook_subscriptions/:id/deliveries Web Session

List recent webhook deliveries

Description

Returns recent delivery-attempt records for the subscription. limit defaults to 30 and is capped at 100.

Auth

Web Session
Parameters
Name In Type Required Description
id path string Yes Webhook subscription UUID
limit query integer No Page size (default 30, maximum 100)
Responses
200

Recent deliveries

Example
{
  "deliveries": [
    {
      "attempt_count": 1,
      "delivered_at": "2026-03-12T09:05:03Z",
      "event_type": "trace.finalized",
      "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
      "inserted_at": "2026-03-12T09:05:02Z",
      "last_error": null,
      "last_response_code": 200,
      "next_attempt_at": null,
      "status": "succeeded",
      "webhook_subscription_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
    }
  ]
}
401

An authenticated operator session is required

404

Webhook subscription not found

POST
/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)
inserted_at datetime (ISO 8601) Yes Record insertion timestamp
attempt_count integer Yes Number of delivery attempts
event_type string Yes Event type delivered
delivered_at datetime (ISO 8601) No When delivery succeeded
last_error string No Most recent delivery error
last_response_code integer No Most recent HTTP response status code
next_attempt_at datetime (ISO 8601) No When the next retry is scheduled
webhook_subscription_id string Yes Webhook subscription UUID
Example
{
  "attempt_count": 1,
  "delivered_at": "2026-03-12T09:05:03Z",
  "event_type": "trace.finalized",
  "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
  "inserted_at": "2026-03-12T09:05:02Z",
  "last_error": null,
  "last_response_code": 200,
  "next_attempt_at": null,
  "status": "succeeded",
  "webhook_subscription_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
}
400

Delivery is currently in_flight

401

An authenticated operator session is required

403

An owner or admin membership is required

404

Webhook delivery not found

Where to go next

see also