Skip to Content

Webhooks API

Subscribe to org events, verify deliveries, debug failures, rotate secrets. All routes require Authorization: Bearer <access_token> with IdentityOrgPermission.WebhooksEdit (write) or .WebhooksView (read).

For the conceptual model — when to use webhooks, how delivery works, retry semantics — read Webhooks. This page is the route reference.

Subscribe

POST /identity/organizations/:orgSlug/webhooks

Request

{ url: string // must be HTTPS events: string[] // event names or ['*'] }

Response (201)

{ id: string // 'wh_…' url: string events: string[] secret: string // 'whsec_…' — ONLY returned at creation enabled: boolean createdAt: string // Internal counters reset on create: consecutiveFailures: number // always 0 here }

Store secret immediately. It is shown only this once.

Errors

HTTPcodeWhen
400validation_failedURL is not HTTPS, events list invalid.
403forbiddenMissing org.webhooks.edit.
409conflictDuplicate (url, events) subscription. Update existing instead.

List

GET /identity/organizations/:orgSlug/webhooks

Requires org.webhooks.view.

{ items: Array<{ id: string url: string events: string[] enabled: boolean consecutiveFailures: number lastDeliveredAt?: string disabledAt?: string // present after auto-disable createdAt: string updatedAt: string }> total: number }

No secret in any list response.

Get one

GET /identity/organizations/:orgSlug/webhooks/:id

Same shape as a list item.

Update

PATCH /identity/organizations/:orgSlug/webhooks/:id

{ url?: string events?: string[] enabled?: boolean // re-enable after auto-disable }

Setting enabled: true after auto-disable also resets consecutiveFailures to 0.

Delete

DELETE /identity/organizations/:orgSlug/webhooks/:id

Returns 204.

Rotate the secret

POST /identity/organizations/:orgSlug/webhooks/:id/rotate-secret

Response

{ secret: string }

The previous secret becomes invalid immediately. For zero-dropped deliveries:

  1. Generate the new secret (this endpoint).
  2. Update your verifier to accept either old or new.
  3. After a transition window (1–2 minutes), drop the old secret.

@synqid/js’s verifyWebhookSignature accepts a [old, new] array.

Test delivery

POST /identity/organizations/:orgSlug/webhooks/:id/test

Fires a synthetic webhook.test event to the URL.

Response (200)

{ delivery: { id: string // delivery id event: 'webhook.test' url: string status: 'pending' | 'succeeded' | 'failed_status' | 'failed_timeout' | 'failed_network' responseCode?: number responseBodyExcerpt?: string attemptCount: number queuedAt: string deliveredAt?: string } }

The response captures the first attempt; retries on failure happen in the background.

Delivery logs

GET /identity/organizations/:orgSlug/webhooks/:id/deliveries

Query params:

ParamTypeDefault
statussucceeded | failed_* | pending(any)
eventevent name(any)
sinceISO 8601(any)
untilISO 8601(any)
limit1–20050
offsetnumber0

Response

{ items: Array<{ id: string event: string url: string status: 'succeeded' | 'failed_timeout' | 'failed_status' | 'failed_network' | 'pending' responseCode?: number responseBodyExcerpt?: string // first 200 chars of response body attemptCount: number queuedAt: string deliveredAt?: string nextAttemptAt?: string // when status is 'pending' and queued for retry }> total: number }

Replay a delivery

POST /identity/organizations/:orgSlug/webhooks/:id/deliveries/:deliveryId/replay

Re-attempts the original delivery (same payload, fresh Synq-Delivery id). Useful when your endpoint was down and you want to redeliver specific events.

Returns a new delivery record.

Delivery headers (reference)

Every POST to your URL includes:

HeaderValue
Synq-SignatureHMAC-SHA256(rawBody, secret), hex-encoded
Synq-EventEvent name, e.g. consent.granted
Synq-DeliveryUUID of this specific delivery
Synq-TimestampUnix seconds, decimal string
Content-Typeapplication/json
User-AgentSynq-Webhooks/1.x

Verification code is in Webhooks.

Rate limits

Endpoint patternLimit
POST /webhooks10/min/org
POST /webhooks/:id/test30/min/webhook
POST /webhooks/:id/rotate-secret5/min/webhook
GET /deliveries60/min/webhook
Last updated on