Webhooks
Clara delivers webhook callbacks when card transaction events occur. You register a subscription — a callback URL, the transaction statuses you care about, and a signing secret — and ClaraPOSTs the event to your URL, signed with HMAC-SHA256.
Webhooks v1 (
/api/v1/subscribers) is no longer available. See how to migrate to v3.How it works
- Create a subscription with
POST /api/v3/webhooks/subscriptions. - When a matching transaction event occurs, Clara signs the exact JSON bytes and
POSTs them to yourcallbackUrl. - Verify the
X-Clara-Signatureheader before processing. - Deduplicate by event, then return
2xxquickly. Transient failures are retried (see Retries).
Events
Webhooks are scoped to one entity,CARD_TRANSACTIONS, with these statuses:
Subscribe only to the statuses you need:
NOTIFICATION, PRE_AUTHORIZED and AUTHORIZED fire for every card purchase, and a single transaction usually goes through several of them, so they produce far more deliveries than the other statuses.
Payload
The body is the transaction event exactly as Clara’s transactions service publishes it: Clara does not wrap, filter or re-serialize it. Top-level fields:
A refund is notified once, as
REFUNDED, when it is finalized (status AUTHORIZED). Its earlier stages are not notified, and a subscription to AUTHORIZED alone does not receive refunds. A rejected or deleted refund is notified as REJECTED or DELETED.
Billing fields (for example
billable and the billing dates) are filled after the event is emitted, so they are usually null in webhook payloads. Fetch the transaction from the Transactions API when you need them.data.operationInfo.operationDateis the transaction’s creation time. There is no last-updated timestamp.data.useris the cardholder.data.labelsanddata.commentare not populated yet: expect them empty or absent.data.invoiceanddata.invoiceTypeDescriptionare the bank concept of the movement; usetypeto tell purchases, refunds, fees, credits and payments apart.
DELETED events are emitted when a transaction is cleaned up and can carry fewer data fields than other events. data.uuid and data.companyUUID are always present.Delivery
Each delivery is aPOST to your callbackUrl with:
The body is the raw JSON event. Do not re-serialize it before verifying the signature.
Your endpoint must:
- Be a public
httpsURL. Private, loopback, link-local and cloud-metadata addresses are rejected when you create the subscription and again before every delivery. - Answer directly: redirects are not followed, and a
3xxcounts as a failed delivery. - Accept the connection within 3 seconds and respond within 10 seconds. Acknowledge with
2xxfirst and process asynchronously.
Verifying the signature
The signature isHMAC-SHA256(secret, t + "." + rawBody), where secret is the subscription secret you provided, t is the t= value from the header, and rawBody is the exact request body.
- Verify the signature over the raw body.
- Reject timestamps older than your tolerance (5 minutes is recommended) to block replays.
- Deduplicate (see Delivery guarantees).
Delivery guarantees
Delivery is at-least-once. Clara does not deduplicate on your behalf: retries, resends and rare races can deliver the same event more than once. Store a key per processed event and ignore repeats. Usedata.uuid together with the subscribed status (for example 6f1d0c2e-…:REJECTED): data.uuid identifies the transaction, which can produce more than one event.
Retries
Retries wait about 1 minute, 5 minutes, 15 minutes, 1 hour, 4 hours, 8 hours and 12 hours. A delivery is abandoned after 8 attempts or 48 hours, whichever comes first. Use resend to recover events after a long outage.
Circuit breaking
A circuit breaker per company and entity opens after repeated failures, so a failing endpoint does not receive a burst of requests. While it is open, deliveries are postponed and retried after the cooldown instead of being sent.Sandbox
Test webhooks end to end without production data:POST /api-test/v3/webhooks/subscriptions— register a sandbox subscription (environment = SANDBOX).POST /api-test/v3/webhooks/events— submit a transaction event in the payload format. Clara delivers the exact bytes you submit, signed like a production delivery, synchronously to your enabled sandbox subscriptions, and returns the results.
Resend stored events
Re-deliver stored events of your company within a date range to your current enabled subscriptions — not the subscription that originally received them, which may have been deleted. Useful to recover events after a callback outage.POST /api/v3/webhooks/{entity}/resend — scope write:subscribers. entity is CARD_TRANSACTIONS.
202 Accepted — events are queued and delivered asynchronously (paced), so the counts describe queued work, not deliveries that already reached the subscriber:
deliveriesQueuedis the number of attempts submitted (one per current enabled subscription).- When the window holds more than 1000 events, only the oldest are queued and
truncatedistrue; call again withafter=nextCursorto continue. - Errors:
400(missingdateFrom/dateTo, or a malformed cursor),422(unsupported entity, or a range wider than 90 days).
Delivery is at-least-once: deduplicate as described in Delivery guarantees. A resend shares the per-company/entity circuit breaker with live deliveries.
Next steps
- Webhook Subscriptions — create, list, update, and delete subscriptions.
