API Reference.
Manage webhook endpoints, inspect delivery events, replay deliveries, and monitor worker health through the Webhook Safe Cloud HTTP API.
Authentication
Management API requests require a Bearer token in the Authorization header.
For a Cloud workspace, an owner creates a scoped token in API tokens. Save its secret when it is shown once. Browser session cookies and provider signing secrets are not management API tokens. Tokens retain their creator's workspace authority and stop working if revoked, expired, or their creator loses membership.
endpoints:read: list and retrieve endpoints.endpoints:write: create endpoints and change enabled state.events:read: list events and read payloads/attempts.events:replay: request a replay.monitoring:read: readGET /v1/operations.
When team administration is enabled, verified customers use Team and invitations in account controls. Owners can reserve seven-day invitations, cancel them and remove members. Recipients explicitly accept with the matching verified email. No invitation email is sent; account registration remains restricted. Removing a member permanently revokes their API tokens, including after rejoining. Existing owners are protected. Higher-tier purchases and owner transfer are not available.
Team controls use cookie-only /dashboard/auth/team/ routes: GET roster (selected owner) and invitations (own verified email); POST invite with an email, or cancel, remove, accept and decline with an ID. Writes require canonical Origin and JSON. Workspace/account/role fields never grant authority; bearer API tokens cannot manage members.
Keep tokens in server-side secret configuration. A 401 indicates rejected authentication; a 403 can indicate insufficient scope. The workspace handbook includes troubleshooting and read-only examples.
curl "$BASE_URL/v1/endpoints" \
-H "Authorization: Bearer $API_TOKEN"Set BASE_URL to your deployment URL and API_TOKEN to the configured management API token. Incoming webhooks use the separate public ingestion route POST /v1/webhooks/:endpointId.
Available endpoints
The following routes are available under the /v1 API prefix.
| Method | Path | Description |
|---|---|---|
| GET | /v1/endpoints | List configured webhook endpoints. |
| POST | /v1/endpoints | Create a webhook endpoint. |
| GET | /v1/endpoints/:id | Retrieve an endpoint. |
| PATCH | /v1/endpoints/:id | Enable or disable an endpoint. |
| GET | /v1/endpoints/:id/events | List events received by an endpoint. |
| GET | /v1/events/:id | Retrieve an event and its delivery attempts. |
| POST | /v1/events/:id/replay | Request a replay of an event. |
| GET | /v1/operations | Inspect queue counts and worker status. |
Create an endpoint
POST /v1/endpoints creates a webhook endpoint. Required fields are id, name, destinationUrl, and provider.
curl -X POST "$BASE_URL/v1/endpoints" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "orders",
"name": "Order events",
"destinationUrl": "https://your-app.example/webhooks",
"provider": "generic",
"signingSecret": "REPLACE_WITH_YOUR_SECRET"
}'Supported providers are generic, stripe, github, shopify, and slack. A signing secret is required for Stripe, GitHub, Shopify, and Slack. Generic endpoints can omit it.
A successful request returns HTTP 201 and the endpoint's public configuration:
{
"id": "orders",
"name": "Order events",
"destinationUrl": "https://your-app.example/webhooks",
"enabled": true,
"provider": "generic",
"createdAt": "2026-01-01T12:00:00.000Z"
}The createdAt value is illustrative. Signing secrets are never included in endpoint API responses.
List, retrieve, and update endpoints
List all configured endpoints or retrieve one by its ID:
curl "$BASE_URL/v1/endpoints" \
-H "Authorization: Bearer $API_TOKEN"
curl "$BASE_URL/v1/endpoints/orders" \
-H "Authorization: Bearer $API_TOKEN"The list response contains an endpoints array. Each endpoint includes its ID, name, destination URL, enabled state, provider, and creation timestamp.
Currently, the update API supports changing only the enabled state:
curl -X PATCH "$BASE_URL/v1/endpoints/orders" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'A successful update returns HTTP 200 with the updated endpoint configuration.
Signing-secret rotation · next Cloud release
Cloud rotation is prepared for the next deployment. The npm library already supports rotation in 0.8.0. Check your deployed Cloud version before using these routes.
GET /v1/endpoints/:id/signing-secret returns a version and active previous-secret expiry. It requires endpoints:read. Signing secrets are never returned.
POST /v1/endpoints/orders/signing-secret
Authorization: Bearer REPLACE_WITH_API_TOKEN
Content-Type: application/json
{"expectedVersion":1,"signingSecret":"REPLACE_WITH_NEW_SECRET","overlapSeconds":3600}POST requires endpoints:write. Configure the same replacement in your provider before the overlap ends. Choose 0–86400 whole seconds; zero removes the old key immediately. Cloud retains at most one previous key. An active overlap must expire or be revoked before another rotation.
DELETE /v1/endpoints/:id/signing-secret with {"expectedVersion":2} and endpoints:write immediately revokes the previous key. Success returns the new version and previousSecretExpiresAt (ISO timestamp or null). HTTP 409 means reload status before retrying. A request already being verified may finish using its earlier key snapshot.
The dashboard offers the same controls under Endpoints → Manage signing secret. Adding a key to an unsigned generic endpoint immediately requires signatures. Provider configuration and key generation remain your responsibility.
List events and paginate
GET /v1/endpoints/:id/events returns events received by a specific endpoint. Use the limit and cursor query parameters to navigate through results.
curl "$BASE_URL/v1/endpoints/orders/events?limit=20" \
-H "Authorization: Bearer $API_TOKEN"Example response:
{
"events": [
{
"id": "11111111-1111-4111-8111-111111111111",
"endpointId": "orders",
"providerEventId": "evt_example",
"receivedAt": "2026-01-01T12:00:00.000Z",
"method": "POST",
"contentType": "application/json",
"payloadBytes": 42,
"status": "queued"
}
],
"nextCursor": "ENCODED_CURSOR"
}The values above are illustrative. When nextCursor is not null, pass the returned cursor as the cursor query parameter to request the next page. Treat cursors as opaque strings.
curl "$BASE_URL/v1/endpoints/orders/events?limit=20&cursor=ENCODED_CURSOR" \
-H "Authorization: Bearer $API_TOKEN"Invalid pagination parameters return HTTP 400 with an error field. An unknown endpoint returns HTTP 404.
providerEventId is the stored provider deduplication identity, or null when none was supplied. For Slack it is the verified event_id. The Cloud id identifies the stored event. Delivery retries and replay retain that event and add attempts; they do not create new event rows.
Retrieve event details
GET /v1/events/:id returns the event, its original payload encoded as Base64, and its delivery attempts.
curl "$BASE_URL/v1/events/EVENT_ID" \
-H "Authorization: Bearer $API_TOKEN"The response includes id, endpointId, receivedAt, method, contentType, payloadBytes, payload, payloadEncoding, status, and attempts.
The detail response also includes providerEventId. The workspace displays the number of recorded attempts from attempts; event receipt time and attempt times describe different stages.
Each delivery attempt includes an attempt ID, attempt number, start and completion timestamps, status, response status when available, and error message when available.
Replay an event
POST /v1/events/:id/replay requests another delivery of an existing event.
curl -X POST "$BASE_URL/v1/events/EVENT_ID/replay" \
-H "Authorization: Bearer $API_TOKEN"A successful request returns HTTP 200:
{
"id": "11111111-1111-4111-8111-111111111111",
"endpointId": "orders",
"status": "queued"
}The values are illustrative. The response reports the event's status after the replay request. An unknown event returns HTTP 404.
Operations and worker status
GET /v1/operations exposes delivery queue counts and worker heartbeat information.
curl "$BASE_URL/v1/operations" \
-H "Authorization: Bearer $API_TOKEN"The response contains queuedCount, deliveringCount, exhaustedCount, oldestQueuedAt, and a worker object containing status and lastHeartbeatAt.
Timestamps can be null when no corresponding queue entry or heartbeat is available.