Skip to main content

Webhooks

Receive real-time notifications when case events occur instead of polling the API.

This guide assumes you've completed the Quickstart.

Overview

Webhooks push event data to your endpoint as cases progress through collection. Subscribe to specific events to keep your systems synchronized without repeated API calls.

Available Events

EventDescription
case.createdNew case submitted
case.updatedCase lifecycle state changed
case.closedCase resolved (paid, written off, or otherwise closed)
payment.createdPayment registered on a case
chat.createdChat message added to a case

Create a Webhook Subscription

You can create webhooks via the API (shown below) or through the Debitura portal. See Webhooks in the portal for UI instructions.

Create webhook request
POST https://customer-api.debitura.com/webhooks
Content-Type: application/json
XApiKey: YOUR_API_KEY

{
"url": "https://your-domain.com/webhooks/debitura",
"events": ["case.created", "case.updated", "case.closed", "payment.created"]
}
201Created
Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://your-domain.com/webhooks/debitura",
"events": ["case.created", "case.updated", "case.closed", "payment.created"],
"isActive": true,
"createdUtc": "2026-01-31T15:23:45Z",
"secret": "dGhpc2lzYWJhc2U2NGVuY29kZWRzZWNyZXQ="
}
Save Your Secret

The secret is returned only once during creation. Store it immediately. You cannot retrieve it later.

To regenerate: PATCH /webhooks/{id} with "regenerateSecret": true.

Event Payload Structure

All events use a CloudEvents-inspired format:

Event envelope structure
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "case.created",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"caseId": "123e4567-e89b-12d3-a456-426614174000",
"reference": "Q8OAXF3W"
},
"links": {
"self": "https://customer-api.debitura.com/cases/123e4567-e89b-12d3-a456-426614174000"
}
}
FieldDescription
idUnique event ID—use for idempotency
eventEvent type
timestampWhen the event occurred (ISO 8601 UTC)
dataEvent-specific payload
links.selfAPI URL for the affected resource

HTTP Headers:

HeaderValue
X-Debitura-Signaturet={timestamp},v1={signature}
X-Debitura-TimestampUnix timestamp

The event type is available in the JSON body under the event field.

Event Payloads

case.created

{
"data": {
"caseId": "123e4567-e89b-12d3-a456-426614174000",
"reference": "Q8OAXF3W"
}
}

case.updated

{
"data": {
"caseId": "123e4567-e89b-12d3-a456-426614174000",
"reference": "Q8OAXF3W",
"oldLifecycle": "Active",
"newLifecycle": "Pending Verification"
}
}

See Case Lifecycle for all lifecycle values and their meanings.

case.closed

{
"data": {
"caseId": "123e4567-e89b-12d3-a456-426614174000",
"reference": "Q8OAXF3W",
"closeCode": "Paid",
"closeComment": "Paid in full by debtor"
}
}

See Case Lifecycle for all close codes and their meanings.

payment.created

{
"data": {
"caseId": "123e4567-e89b-12d3-a456-426614174000",
"reference": "Q8OAXF3W",
"paymentId": "789e4567-e89b-12d3-a456-426614174999",
"amount": 5000.00,
"currency": "EUR",
"date": "2026-01-31T12:00:00Z"
}
}

chat.created

{
"data": {
"caseId": "123e4567-e89b-12d3-a456-426614174000",
"reference": "Q8OAXF3W",
"chatId": "456e4567-e89b-12d3-a456-426614174888",
"role": "Partner",
"message": "Please provide updated payment plan"
}
}

Role values: Partner (collection partner), Creditor (you), ManagedByPartner (partner acting on your behalf)

Signature Verification

Verify every webhook request using webhook signature verification. The signature proves the request came from Debitura and wasn't tampered with.

Quick summary:

  1. Extract t (timestamp) and v1 (signature) from X-Debitura-Signature
  2. Construct: signed_payload = timestamp + "." + raw_json_body
  3. Decode your secret from Base64
  4. Compute HMAC-SHA256 of signed payload
  5. Compare signatures using constant-time comparison
  6. Verify timestamp is within 5 minutes

Processing Best Practices

Respond Quickly

Return 2xx within 10 seconds. Verify the signature, acknowledge immediately, then process the event asynchronously via a queue or background job.

Idempotent Processing

Use the id field to detect duplicates—Debitura may retry delivery. Store processed event IDs and skip duplicates. See idempotent webhook processing for implementation patterns.

Retry Behavior

Debitura retries failed deliveries with exponential backoff:

AttemptDelayCumulative
10s0s
2~60s~1 min
3~120s~3 min
4~240s~7 min
5~480s~15 min
6~960s~31 min
7-8~1800s~1.5 hours

After 8 consecutive failures, the webhook is automatically disabled. Fix your endpoint and re-enable via the API.

A 410 Gone response immediately disables the webhook.

Managing Webhooks

List subscriptions:

List all webhooks
GET https://customer-api.debitura.com/webhooks

Update subscription:

Update webhook
PATCH https://customer-api.debitura.com/webhooks/{id}

{
"url": "https://new-endpoint.com/webhooks",
"events": ["case.created", "payment.created"],
"isActive": true
}

Delete subscription:

Delete webhook
DELETE https://customer-api.debitura.com/webhooks/{id}

Test delivery:

Test webhook delivery
POST https://customer-api.debitura.com/webhooks/{id}:test

Test deliveries include X-Debitura-Test: true header.

Common Issues

Webhook not received

Your endpoint must be publicly accessible via HTTPS with a valid TLS certificate. Private IP addresses and localhost are blocked.

Signature verification fails

Ensure you're using the raw request body (not parsed JSON) and decoding the secret from Base64 before computing HMAC.

Webhook disabled

Check disabledReason in the webhook details. Fix the underlying issue, then update with "isActive": true.