Webhooks
Register endpoints, receive events and verify signatures.
Webhooks let integrations react to changes in Resolved without polling the API. Resolved delivers events with an HTTP POST to URLs you configure.
There are two outbound webhook systems. They are separate resources with different ownership and delivery rules.
| System | Belongs to | Configured via | Signing |
|---|---|---|---|
| Client webhooks | A client (creditor profile) | CMS (client → Webhooks) or POST /api/client_webhooks |
HMAC-SHA256 (X-Resolved-Signature) |
| App Store app webhooks | Your App definition in the App Store | POST /api/app_webhooks (API only today) |
No signature header |
Webhooks are not “one HTTPS URL per installation”. Client webhooks are scoped to a client. App Store webhooks are scoped to the App (the app definition), not to each customer AppSubscription / install. You may register multiple endpoints on the same client or app.
Client webhooks
Use client webhooks when a customer wants payment events for their own client profile. You can create several webhooks per client; each has its own URL, event subscription list, and secret.
Registration
Create a webhook with the client IRI, a name, one or more event names, and a publicly reachable URL (http or https, with a real TLD — private / loopback hosts are rejected).
On create, Resolved generates a secret and returns it on the webhook resource. Store it securely; you need it to verify deliveries.
Events (currently delivered)
| Event | When it fires |
|---|---|
case_file.payment.confirmed |
A case-file payment to the client (not the agency) becomes confirmed |
Only active webhooks that list the event receive a delivery.
Delivery
- Method:
POST - Headers:
Content-Type: application/json,X-Resolved-Signature: sha256=<hex> - Body: JSON payment snapshot plus
caseFileand@event
Example shape:
{
"@event": "case_file.payment.confirmed",
"id": 123,
"amount": 15000,
"paidTo": "client",
"confirmedAt": "2026-07-09T08:30:00+00:00",
"createdAt": "2026-07-09T08:29:00+00:00",
"updatedAt": "2026-07-09T08:30:00+00:00",
"caseFile": {
"id": 456
}
}
Verifying signatures
Recompute HMAC-SHA256 over the raw request body with the webhook secret and compare it to the hex digest in X-Resolved-Signature (strip the sha256= prefix) in constant time before trusting the payload.
Verify against the raw body, before JSON parsing or re-serialisation. Re-encoding the body changes the bytes and breaks the check.
Responding and retries
Return a 2xx status quickly to acknowledge receipt. Do the real work asynchronously. Non-2xx responses and transport errors are retried. Inactive webhooks or mismatched events are not retried.
Deliveries can arrive more than once — make handlers idempotent (for example by payment id + @event).
App Store app webhooks
App Store developers register webhooks on the App resource itself (AppWebhook), not on each customer installation.
Registration
Use the API:
- Collection:
GET /api/apps/{id}/app_webhooks - Create / update / delete:
/api/app_webhooks
Writable fields include:
app— the App IRIwebhookUrl— publicly reachable URL (same URL rules as client webhooks)events— list of event name strings you subscribe to (1–100)responseHandlingType—1(FIRE_AND_FORGET) or2(WAIT_FOR_SUCCESSFUL_RESPONSE)active— whether the endpoint should receive deliveries
You can attach many webhooks to one App (different URLs or event filters). Changing an install does not create or remove these rows.
Delivery behaviour
The App Store webhook API lets you register endpoints, event filters and response handling on your App. When a matching event is dispatched to an active app webhook, Resolved POSTs JSON to webhookUrl and injects @event into the payload.
FIRE_AND_FORGET— HTTP status is ignoredWAIT_FOR_SUCCESSFUL_RESPONSE— non-2xx responses are retried
App webhooks do not currently send X-Resolved-Signature. Prefer client webhooks when you need HMAC verification, or protect your endpoint another way (private URL, network controls, etc.).
Today, the only production-delivered outbound event documented above is the client webhook case_file.payment.confirmed. Treat App Store app webhooks as the registration model on the App resource; do not assume a broad event catalog is already emitting until it is listed here.
Keep webhook URLs on your server infrastructure. Never put secrets in query strings that end up in browser history or third-party logs.