Skip to main content

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",
"case.declined",
"payment.created",
"payment.deleted",
"chat.created"
],
"IsTestMode": false
}

Request body parameters:

ParameterTypeDefaultDescription
UrlstringThe HTTPS endpoint to deliver events to
Eventsstring[]Event types to subscribe to (see Available Events)
IsTestModebooleanfalseWhen true, this subscription only receives webhook events from test cases. When false (default), it receives events from live production cases. Can be toggled later via PUT /webhooks/{id}, which re-classifies the subscription between test and live in place.
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",
"case.declined",
"payment.created",
"payment.deleted",
"chat.created"
],
"IsActive": true,
"IsTestMode": false,
"CreatedUtc": "2026-05-29T09:15:00Z",
"UpdatedUtc": "2026-05-29T09:15:00Z",
"DisabledReason": null,
"Secret": "dGhpc2lzYWJhc2U2NGVuY29kZWRzZWNyZXQ="
}
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

List all webhooks
GET https://collectionpartner-api.debitura.com/webhooks
XApiKey: your_api_key_here
Get a specific webhook
GET https://collectionpartner-api.debitura.com/webhooks/{id}
XApiKey: your_api_key_here
Update a webhook
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 a webhook
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:

FieldTypeDescription
idstring (UUID)Unique event ID — use for idempotency
specVersionstringAlways "1.0"
eventstringEvent type (e.g., "case.assigned")
timestampstring (ISO 8601)UTC time when the event occurred
dataobjectEvent-specific payload (see sections below)
linksobjectReserved — empty for collection partner events

HTTP Headers on every delivery:

HeaderValue
X-Debitura-Signaturet={timestamp},v1={signature}
X-Debitura-TimestampUnix 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.

case.assigned payload
{
"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": {}
}
FieldTypeDescription
caseIdstring (UUID)Debitura's internal case ID. Use this to look up or reference the case via the Cases API.
referencestringHuman-readable case reference (e.g., "Q8OAXF3W"). Displayed in the Debitura portal and useful for support conversations.
lifecyclestringLifecycle state at the moment of assignment (typically "Active"). See Case Lifecycle for all states.

case.declined

Fires when you decline an exclusively-assigned case and it is sent back into the partner network. This is a distinct signal from case.updated — it exists specifically so your integration can remove the case from its own queue the moment you decline it, rather than inferring removal from a generic lifecycle change. Declining a case terminates your active engagement, ends any active collection period, and re-qualifies the case as an open lead for the rest of the partner network (excluding you).

case.declined payload
{
"id": "c6d8e0f2-4a91-4b3d-a567-889900112233",
"specVersion": "1.0",
"event": "case.declined",
"timestamp": "2026-07-01T09:20:00Z",
"data": {
"caseId": "e3d7f2a1-c845-4b9d-8f6e-aabbccddeeff",
"reference": "Q8OAXF3W",
"reason": "Outside our jurisdiction of operation"
},
"links": {}
}
FieldTypeDescription
caseIdstring (UUID)Debitura's internal case ID
referencestringHuman-readable case reference
reasonstring | nullThe decline reason you provided when declining the case, if any

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.

case.updated payload
{
"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": {}
}
FieldTypeDescription
caseIdstring (UUID)Debitura's internal case ID
referencestringHuman-readable case reference
oldLifecyclestringLifecycle state before this transition
newLifecyclestringLifecycle 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.

case.closed payload
{
"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": {}
}
FieldTypeDescription
caseIdstring (UUID)Debitura's internal case ID
referencestringHuman-readable case reference
closeCodestringReason the case was closed (e.g., "Paid", "Partially paid", "Debtor Insolvent/Bankrupt", "Case never started")
closeCommentstring | nullOptional 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.

payment.created payload
{
"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": {}
}
FieldTypeDescription
caseIdstring (UUID)Debitura's internal case ID
referencestringHuman-readable case reference
paymentIdstring (UUID)Unique identifier for this payment record
amountnumber (decimal)Gross payment amount in the case currency
currencystringISO 4217 currency code (e.g., "DKK", "EUR", "GBP")
datestring (ISO 8601)Date the payment occurred

payment.deleted

Fires when a payment is deleted (reversed) on a case assigned to your agency — for example when correcting a payment reported with the wrong amount. Same recipients as payment.created: both the creditor and your agency are notified, so a reversal is never silent on either side.

payment.deleted payload
{
"id": "a3e5c9f1-7d24-4b6a-9012-334455667788",
"specVersion": "1.0",
"event": "payment.deleted",
"timestamp": "2026-06-30T16:45: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": {}
}
FieldTypeDescription
caseIdstring (UUID)Debitura's internal case ID
referencestringHuman-readable case reference
paymentIdstring (UUID)Identifier of the deleted payment record (same paymentId from its original payment.created event)
amountnumber (decimal)Gross amount of the deleted payment, in the case currency
currencystringISO 4217 currency code (e.g., "DKK", "EUR", "GBP")
datestring (ISO 8601)Date the (now-deleted) payment originally occurred — not the deletion timestamp; use the event's top-level timestamp for when the deletion happened

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.

chat.created payload
{
"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": {}
}
FieldTypeDescription
caseIdstring (UUID)Debitura's internal case ID
referencestringHuman-readable case reference
chatIdstring (UUID)Unique identifier for this chat message
rolestringWho 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)
messagestringThe 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:

AttemptDelay before retry
1Initial 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.

Troubleshooting

For diagnosing failed deliveries, decoding error messages in the delivery log, and other common issues, see Webhook Troubleshooting.