POST to your registered endpoint with a signed JSON payload. You verify the signature with your subscription secret, process the event, and respond 2xx. Managing subscriptions (create, list, update, rotate secret) is done through the endpoints below.
Supported event types
| Event | When it fires |
|---|---|
identity.snapshot.created | A new snapshot is created for a subject in your tenant. |
refresh_request.created | A counterparty tenant has created a refresh request for a subject you own. |
refresh_request.fulfilled | A refresh request your tenant created has been fulfilled by the subject owner. |
Create a subscription
POST /v1/webhook-subscriptions
Creates a new webhook subscription and returns a one-time plaintext secret you must save immediately. The secret is used to verify the HMAC signature on every subsequent delivery.
Requires at least the tenant_reader role in the specified tenant.
Body parameters
The tenant whose events you want to subscribe to.
The HTTPS URL Tally will
POST events to. Leading and trailing whitespace is
stripped.The event types to subscribe to. Must be a non-empty array containing only
supported event types.
Response
201 Created
Example
List subscriptions
GET /v1/webhook-subscriptions
Returns all webhook subscriptions for a tenant.
Requires at least the tenant_reader role.
Query parameters
Filter subscriptions to this tenant.
Response
200 OK — { "items": [WebhookSubscription] }
Get a subscription
GET /v1/webhook-subscriptions/:subscription_id
Returns a single webhook subscription by ID.
Requires at least the tenant_reader role in the subscription’s tenant.
Path parameters
The
subscription_id (e.g. wsub_a1b2c3d4-...).Response
200 OK — { "webhook_subscription": WebhookSubscription }
Update a subscription
PATCH /v1/webhook-subscriptions/:subscription_id
Updates one or more attributes of an existing subscription. All body fields are optional — only the fields you include are changed.
Requires at least the tenant_reader role in the subscription’s tenant.
Path parameters
The ID of the subscription to update.
Body parameters
A new delivery URL to replace the existing one.
A new set of event types to subscribe to. Replaces the existing list
entirely. Must be a non-empty array of supported event types.
"active" or "disabled". Set to "disabled" to pause delivery without
deleting the subscription.Response
200 OK — { "webhook_subscription": WebhookSubscription } with the updated fields.
Examples
Rotate signing secret
POST /v1/webhook-subscriptions/:subscription_id/rotate-secret
Generates a new signing secret for the subscription and returns it in plaintext. Deliveries signed with the old secret will begin failing immediately after rotation.
Requires at least the tenant_reader role in the subscription’s tenant.
Path parameters
The ID of the subscription whose secret you want to rotate.
Response
200 OK — { "webhook_subscription": WebhookSubscription, "secret": "..." } with the new plaintext secret and an updated secret_last_rotated_at timestamp.
Payload verification
Every delivery includes anX-Tally-Signature HTTP header containing the HMAC-SHA256 hex digest of the raw request body, keyed with your subscription secret. You must verify this signature before processing any event.
How to verify
- Read the raw request body as bytes — do not parse it first.
- Compute
HMAC-SHA256(secret, raw_body)and encode the result as a lowercase hex string. - Compare your computed digest to the value in
X-Tally-Signatureusing a timing-safe comparison function. - Reject the request with
401if the signatures do not match.
Node.js example
Example delivery headers
Tally delivers events with a short retry backoff if your endpoint returns a
non-
2xx status. Return 200 OK (or any 2xx) as quickly as possible —
enqueue the payload for async processing if your handler is slow, rather than
doing heavy work inline during the HTTP response window.