Webhooks
Subscribe to real-time event notifications for cases assigned to your agency, lifecycle changes, payments, and chat messages.
Create a Webhook Subscription
POST https://collectionpartner-api.debitura.com/webhooks
Content-Type: application/json
XApiKey: your_api_key_here
{
"Url": "https://your-platform.com/webhooks/debitura",
"Events": [
"case.assigned",
"case.updated",
"case.closed",
"payment.created",
"chat.created"
],
"IsTestMode": false
}
Request body parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
Url | string | — | The HTTPS endpoint to deliver events to |
Events | string[] | — | Event types to subscribe to (see Available Events) |
IsTestMode | boolean | false | When true, this subscription only receives webhook events from test cases. When false (default), it receives events from live production cases. Cannot be changed after creation. |
:::tip Test mode
During integration development, set "IsTestMode": true to receive events from test cases only — your live production data is unaffected. See Test vs Live subscriptions for details.
:::
Response (201 Created):
{
"Id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"Url": "https://your-platform.com/webhooks/debitura",
"Events": [
"case.assigned",
"case.updated",
"case.closed",
"payment.created",
"chat.created"
],
"IsActive": true,
"IsTestMode": false,
"CreatedUtc": "2026-05-29T09:15:00Z",
"UpdatedUtc": "2026-05-29T09:15:00Z",
"DisabledReason": null,
"Secret": "dGhpc2lzYWJhc2U2NGVuY29kZWRzZWNyZXQ="
}
:::danger Save Your Secret
The Secret is only returned once during creation. Store it immediately in your secrets manager. You cannot retrieve it later. If lost, regenerate via PUT /webhooks/{id} with RegenerateSecret: true.
:::
Manage Subscriptions
GET https://collectionpartner-api.debitura.com/webhooks
XApiKey: your_api_key_here
GET https://collectionpartner-api.debitura.com/webhooks/{id}
XApiKey: your_api_key_here
PUT https://collectionpartner-api.debitura.com/webhooks/{id}
Content-Type: application/json
XApiKey: your_api_key_here
{
"Url": "https://new-endpoint.com/webhooks",
"Events": ["case.assigned", "case.updated", "case.closed"],
"IsActive": true,
"RegenerateSecret": false
}
DELETE https://collectionpartner-api.debitura.com/webhooks/{id}
XApiKey: your_api_key_here
For the full API reference, see Webhook endpoints.
Payload Structure
All events use a CloudEvents-inspired envelope format:
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique event ID — use for idempotency |
specVersion | string | Always "1.0" |
event | string | Event type (e.g., "case.assigned") |
timestamp | string (ISO 8601) | UTC time when the event occurred |
data | object | Event-specific payload (see sections below) |
links | object | Reserved — empty for collection partner events |
HTTP Headers on every delivery:
| Header | Value |
|---|---|
X-Debitura-Signature | t={timestamp},v1={signature} |
X-Debitura-Timestamp | Unix timestamp (seconds) |
For signature verification implementation, see Signature Verification.
Available Events
case.assigned
Fires when a case has been validated by Debitura and assigned to your agency. This is the starting event for a case — it confirms the case is yours to work. It is semantically distinct from case.created (which fires for creditor integrations at submission time): collection partners see case.assigned after Debitura's routing and validation step, not at submission.
{
"id": "7f3c9e1a-bb42-4d87-a123-556677889900",
"specVersion": "1.0",
"event": "case.assigned",
"timestamp": "2026-05-29T09:15:30Z",
"data": {
"caseId": "e3d7f2a1-c845-4b9d-8f6e-aabbccddeeff",
"reference": "Q8OAXF3W",
"lifecycle": "Active"
},
"links": {}
}
| Field | Type | Description |
|---|---|---|
caseId | string (UUID) | Debitura's internal case ID. Use this to look up or reference the case via the Cases API. |
reference | string | Human-readable case reference (e.g., "Q8OAXF3W"). Displayed in the Debitura portal and useful for support conversations. |
lifecycle | string | Lifecycle state at the moment of assignment (typically "Active"). See Case Lifecycle for all states. |
case.updated
Fires when a case moves to a new lifecycle state — for example from Active to Paused, or when a progress update triggers a transition.
{
"id": "b2e4f8a0-dc61-4f92-b345-778899001122",
"specVersion": "1.0",
"event": "case.updated",
"timestamp": "2026-05-29T11:42:00Z",
"data": {
"caseId": "e3d7f2a1-c845-4b9d-8f6e-aabbccddeeff",
"reference": "Q8OAXF3W",
"oldLifecycle": "Active",
"newLifecycle": "Paused"
},
"links": {}
}
| Field | Type | Description |
|---|---|---|
caseId | string (UUID) | Debitura's internal case ID |
reference | string | Human-readable case reference |
oldLifecycle | string | Lifecycle state before this transition |
newLifecycle | string | Lifecycle state after this transition |
See Case Lifecycle for all lifecycle states and valid transitions.
case.closed
Fires when a case reaches its terminal state. This is the final event for a case — no further case.updated events follow. Use it to update your internal records with the outcome and close code.
{
"id": "9c5a3d7b-ef84-4201-c678-990011223344",
"specVersion": "1.0",
"event": "case.closed",
"timestamp": "2026-05-29T14:05:00Z",
"data": {
"caseId": "e3d7f2a1-c845-4b9d-8f6e-aabbccddeeff",
"reference": "Q8OAXF3W",
"closeCode": "Paid",
"closeComment": "Paid in full by debtor via bank transfer"
},
"links": {}
}
| Field | Type | Description |
|---|---|---|
caseId | string (UUID) | Debitura's internal case ID |
reference | string | Human-readable case reference |
closeCode | string | Reason the case was closed (e.g., "Paid", "Partially paid", "Debtor Insolvent/Bankrupt", "Case never started") |
closeComment | string | null | Optional additional context about the closure decision |
See Case Lifecycle for all close codes and their meanings.
payment.created
Fires when a payment is registered on a case assigned to your agency. This includes both payments you record yourself via the API and payments registered by other parties.
{
"id": "d1f6b2c8-a037-4512-d789-001122334455",
"specVersion": "1.0",
"event": "payment.created",
"timestamp": "2026-05-29T10:30:00Z",
"data": {
"caseId": "e3d7f2a1-c845-4b9d-8f6e-aabbccddeeff",
"reference": "Q8OAXF3W",
"paymentId": "f4a7e9c2-b158-4823-e890-112233445566",
"amount": 12500.00,
"currency": "DKK",
"date": "2026-05-29T00:00:00Z"
},
"links": {}
}
| Field | Type | Description |
|---|---|---|
caseId | string (UUID) | Debitura's internal case ID |
reference | string | Human-readable case reference |
paymentId | string (UUID) | Unique identifier for this payment record |
amount | number (decimal) | Gross payment amount in the case currency |
currency | string | ISO 4217 currency code (e.g., "DKK", "EUR", "GBP") |
date | string (ISO 8601) | Date the payment occurred |
chat.created
Fires when a chat message is posted on a case assigned to your agency. Chat messages are the primary communication channel between your agency and the creditor. Use this event to surface new messages in your own interface without polling.
{
"id": "e8a2c4f9-b361-4734-f901-223344556677",
"specVersion": "1.0",
"event": "chat.created",
"timestamp": "2026-05-29T13:15:00Z",
"data": {
"caseId": "e3d7f2a1-c845-4b9d-8f6e-aabbccddeeff",
"reference": "Q8OAXF3W",
"chatId": "c7b5d3a1-e249-4615-c012-334455667788",
"role": "Creditor",
"message": "Please confirm whether the debtor has responded to the first notice."
},
"links": {}
}
| Field | Type | Description |
|---|---|---|
caseId | string (UUID) | Debitura's internal case ID |
reference | string | Human-readable case reference |
chatId | string (UUID) | Unique identifier for this chat message |
role | string | Who sent the message — "Creditor" (the case owner), "Partner" (your agency), or "ManagedByPartner" (your agency acting on behalf of a creditor in a managed-case flow) |
message | string | The full text content of the message |
Signature Verification
Always verify the X-Debitura-Signature header before processing events. See Signature Verification for implementation details and code examples.
Retry and Auto-disable
If your endpoint does not return a 2xx status within 10 seconds, Debitura retries with exponential backoff:
| Attempt | Delay before retry |
|---|---|
| 1 | Initial delivery |
| 2 | ~60 seconds |
| 3 | ~120 seconds |
| 4 | ~240 seconds |
| 5 | ~480 seconds |
| 6 | ~960 seconds |
| 7 | ~1800 seconds |
| 8 | ~1800 seconds |
Each delay includes ±10% random jitter to prevent thundering-herd problems across subscriptions.
Auto-disable triggers:
- Your endpoint returns
410 Gone— subscription is immediately disabled (signals the endpoint has been retired) - All 8 delivery attempts fail — subscription is disabled with reason
"Exceeded maximum retry attempts (8 failures)"
Re-enable after auto-disable: fix your endpoint, then call PUT /webhooks/{id} with "IsActive": true.
Secret Rotation
Rotate your signing secret without deleting and recreating the subscription:
PUT https://collectionpartner-api.debitura.com/webhooks/{id}
Content-Type: application/json
XApiKey: your_api_key_here
{
"RegenerateSecret": true
}
The response includes the new secret in the Secret field. Update your verification code immediately — the old secret stops working as soon as the response is received.
Testing Webhooks in CI
For running automated webhook tests, Debitura provides a full CI loop: create a test case, advance it through lifecycle states, inspect delivery history, and clean up — without pointing at an external receiver. See CI Testing for the full guide and code examples.
Business context: See Collection Partners: Case status definitions and allowed actions for what each lifecycle state and close code means in your collection workflow.