Skip to main content

Webhooks

Subscribe to real-time events for client onboarding, linking, and case status changes.

Create a Webhook Subscription

POST https://referral-api.debitura.com/v1/Webhooks
Content-Type: application/json
XApiKey: your_partner_api_key_here

{
"Url": "https://your-platform.com/webhooks/debitura",
"Events": [
"client.onboarding.poa_signed",
"client.onboarding.contract_signed",
"client.linked",
"client.link_declined",
"client.link_requested",
"client.link_expired",
"case.created",
"case.updated",
"case.closed",
"cases.replay_failed"
],
"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 /v1/Webhooks/{id}, which re-classifies the subscription between Test and Production.
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 (200 OK):

{
"Id": "550e8400-e29b-41d4-a716-446655440000",
"Url": "https://your-platform.com/webhooks/debitura",
"Events": ["client.linked", "case.created", "case.updated", "case.closed"],
"IsActive": true,
"IsTestMode": false,
"CreatedUtc": "2026-01-31T15:23:45Z",
"UpdatedUtc": "2026-01-31T15:23:45Z",
"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 /v1/Webhooks/{id} with RegenerateSecret: true.

Manage Subscriptions

List all webhooks
GET https://referral-api.debitura.com/v1/Webhooks
XApiKey: your_partner_api_key_here
Update a webhook
PUT https://referral-api.debitura.com/v1/Webhooks/{id}
Content-Type: application/json
XApiKey: your_partner_api_key_here

{
"Url": "https://new-endpoint.com/webhooks",
"Events": ["client.linked", "case.created"],
"IsActive": true,
"RegenerateSecret": false
}
Delete a webhook
DELETE https://referral-api.debitura.com/v1/Webhooks/{id}
XApiKey: your_partner_api_key_here

For the full API reference, see Webhook endpoints.

Payload Structure

All events use a CloudEvents-inspired format with these envelope fields:

FieldTypeDescription
idstring (UUID)Unique event ID for idempotency
specVersionstringAlways "1.0"
eventstringEvent type (e.g., "client.linked")
timestampstring (ISO 8601)When the event occurred
dataobjectEvent-specific payload
links.clientstringAPI URL for this client

HTTP Headers:

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

Creditor Object

Client onboarding and linking events include a creditor object with these fields:

FieldTypeDescription
creditor.idstring (UUID)Debitura's internal creditor ID
creditor.companyNamestringLegal company name
creditor.registrationNumberstringVAT or company registration number (e.g., "DK12345678")
creditor.countryIdintegerCountry identifier
creditor.isAttributedbooleanWhether this is an attributed client — determines revenue share eligibility. Not present in client.link_declined events.

Available Events

client.onboarding.poa_signed

Fires when a PoA document is created or signed for a client. This event fires for all PoA creation paths:

  • Main onboarding wizard flow
  • Standalone PoA signing flow
  • Admin-uploaded PoA (a Debitura admin uploads a pre-signed document on behalf of the client)
client.onboarding.poa_signed payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "client.onboarding.poa_signed",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"externalTenantId": "partner-client-123",
"creditor": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"companyName": "Acme Corporation Ltd",
"registrationNumber": "DK12345678",
"countryId": 208,
"isAttributed": false
},
"signedAt": "2026-01-31T15:23:45Z"
},
"links": {
"client": "https://api.debitura.com/referral-partner/v1/clients/partner-client-123"
}
}
FieldTypeDescription
externalTenantIdstringYour identifier for this client (from onboarding init)
creditorobjectClient details — see Creditor Object
signedAtstring (ISO 8601)UTC timestamp when PoA was signed

client.onboarding.contract_signed

Fires when a client signs the Standard Debt Collection Agreement (SDCA) with 2FA verification. This event fires for all SDCA signing paths:

  • Main onboarding wizard flow
  • Signing via the Creditor portal (outside the wizard)
  • Admin-triggered signing via BackendAdmin
client.onboarding.contract_signed payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "client.onboarding.contract_signed",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"externalTenantId": "partner-client-123",
"creditor": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"companyName": "Acme Corporation Ltd",
"registrationNumber": "DK12345678",
"countryId": 208,
"isAttributed": false
},
"signedAt": "2026-01-31T15:23:45Z"
},
"links": {
"client": "https://api.debitura.com/referral-partner/v1/clients/partner-client-123"
}
}
FieldTypeDescription
externalTenantIdstringYour identifier for this client
creditorobjectClient details — see Creditor Object
signedAtstring (ISO 8601)UTC timestamp when contract was signed

client.linked

Fires when a client is linked to your partnership through the 409 conflict resolution flow. This covers both paths: the user connecting an existing Debitura account and the user creating a new account from the choice page.

creditor.isAttributed is always false for this event — the user already existed in Debitura before your referral. You earn fees only on cases submitted through your API using bearer tokens. See Attribution for details.

client.linked payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "client.linked",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"externalTenantId": "partner-client-123",
"creditor": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"companyName": "Acme Corporation Ltd",
"registrationNumber": "DK12345678",
"countryId": 208,
"isAttributed": false
},
"linkedAt": "2026-01-31T15:23:45Z"
},
"links": {
"client": "https://api.debitura.com/referral-partner/v1/clients/partner-client-123"
}
}
FieldTypeDescription
externalTenantIdstringYour identifier for this client
creditorobjectClient details — see Creditor Object. isAttributed is always false for linked clients.
linkedAtstring (ISO 8601)UTC timestamp when link was approved

Fires when a link request is declined. This event fires in two situations:

  • Manual decline: the existing Debitura client explicitly declines your link request (resolves 409 conflict)
  • Auto-decline of duplicates: when one pending link request is approved, any other pending requests for the same client are automatically declined — each fires its own client.link_declined event

No link is created in either case, so you cannot submit cases for this client.

client.link_declined payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "client.link_declined",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"externalTenantId": "partner-client-123",
"creditor": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"companyName": "Acme Corporation Ltd",
"registrationNumber": "DK12345678",
"countryId": 208
},
"declinedAt": "2026-01-31T15:23:45Z"
},
"links": {
"client": "https://api.debitura.com/referral-partner/v1/clients/partner-client-123"
}
}
info

The creditor.isAttributed field is not present in decline events because no link is created.

FieldTypeDescription
externalTenantIdstringYour identifier for this client
creditorobjectClient details — see Creditor Object. Note: isAttributed field is absent.
declinedAtstring (ISO 8601)UTC timestamp when link was declined

Fires when a 409 carry-through triggers a link approval request to an existing Debitura client. This gives you confirmation that the approval URL was issued and the link request is now pending. Use this event to know when a user is in the approval queue — you can prompt them to check their email or the Debitura portal.

client.link_requested payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "client.link_requested",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"externalTenantId": "partner-client-123",
"requestId": "9f2c1b6e-7a3d-4e21-9b0f-2d8c4a1e6f33",
"requestedAt": "2026-01-31T15:23:45Z",
"expiresAt": "2026-02-07T15:23:45Z"
},
"links": {
"client": "https://api.debitura.com/referral-partner/v1/clients/partner-client-123"
}
}
FieldTypeDescription
externalTenantIdstringYour identifier for this client
requestIdstring (UUID)Identifier for this link request — correlate with the matching client.link_expired event
requestedAtstring (ISO 8601)UTC timestamp when the link request was issued
expiresAtstring (ISO 8601) | nullWhen the approval URL expires if not acted on
creditorobject (optional)Present when the matched creditor is known — see Creditor Object. Omitted otherwise.

Fires when a pending link approval request expires without the client acting. Link requests expire after 7 days by default (configurable per partner, maximum 30 days). Once you receive this event, call POST /clients again with the same externalTenantId to generate a new approval URL and restart the flow.

client.link_expired payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "client.link_expired",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"externalTenantId": "partner-client-123",
"requestId": "9f2c1b6e-7a3d-4e21-9b0f-2d8c4a1e6f33",
"creditor": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"companyName": "Acme Corporation Ltd",
"registrationNumber": "DK12345678",
"countryId": 208
},
"expiresAt": "2026-02-07T15:23:45Z",
"expiredAt": "2026-02-07T15:23:45Z"
},
"links": {
"client": "https://api.debitura.com/referral-partner/v1/clients/partner-client-123"
}
}
FieldTypeDescription
externalTenantIdstringYour identifier for this client
requestIdstring (UUID)Identifier for the expired link request — matches the requestId from the originating client.link_requested event
creditorobjectClient details — see Creditor Object. isAttributed is absent.
expiresAtstring (ISO 8601) | nullWhen the approval URL was set to expire
expiredAtstring (ISO 8601)UTC timestamp when the link request expired

case.created

Fires when a new collection case is created for any linked client.

case.created payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "case.created",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"externalTenantId": "partner-client-123",
"caseId": "123e4567-e89b-12d3-a456-426614174000",
"reference": "Q8OAXF3W",
"lifecycle": "Pending contract signing",
"creditorReference": "INV-001",
"creditorId": "789e4567-e89b-12d3-a456-426614174222"
},
"links": {
"client": "https://api.debitura.com/referral-partner/v1/clients/partner-client-123"
}
}
FieldTypeDescription
externalTenantIdstringYour identifier for the client who owns this case
caseIdstring (UUID)Debitura's internal case ID
referencestringHuman-readable case reference (e.g., "Q8OAXF3W")
lifecyclestringInitial lifecycle state of the case at creation time — see Lifecycle States for all values
creditorReferencestring | nullThe case reference you provided in your original POST /clients submission (echoed back). Use this to correlate case.created events with your submissions — especially on the 409 path where cases are created asynchronously. Null if no reference was submitted.
creditorIdstring (UUID)Debitura's internal creditor ID for the client who owns this case

case.updated

Fires when a case lifecycle state changes for any linked client.

case.updated payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "case.updated",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"externalTenantId": "partner-client-123",
"caseId": "123e4567-e89b-12d3-a456-426614174000",
"reference": "Q8OAXF3W",
"oldLifecycle": "Active",
"newLifecycle": "Closed"
},
"links": {
"client": "https://api.debitura.com/referral-partner/v1/clients/partner-client-123"
}
}
FieldTypeDescription
externalTenantIdstringYour identifier for the client who owns this case
caseIdstring (UUID)Debitura's internal case ID
referencestringHuman-readable case reference
oldLifecyclestringPrevious lifecycle state
newLifecyclestringNew lifecycle state

See Case Lifecycle for all lifecycle states and their meanings.

case.closed

Fires when a case reaches its terminal state (closed). This is the final event for a case — no further case.updated events will follow. Use it to show clients whether their case is finally settled and with what outcome.

case.closed payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "case.closed",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"externalTenantId": "partner-client-123",
"caseId": "123e4567-e89b-12d3-a456-426614174000",
"reference": "XAVSVWM7",
"closeCode": "Paid",
"closeComment": "Paid in full by debtor"
},
"links": {
"client": "https://api.debitura.com/referral-partner/v1/clients/partner-client-123"
}
}
FieldTypeDescription
externalTenantIdstringYour identifier for the client who owns this case
caseIdstring (UUID)Debitura's internal case ID
referencestringHuman-readable case reference
closeCodestringReason the case was closed (e.g., "Paid", "Partially paid", "Debtor Insolvent", "Case Never Started")
closeCommentstring | nullOptional additional context about the closure

See Case Lifecycle for all close codes and their meanings.

cases.replay_failed

Fires when an individual case creation fails during the 409 carry-through replay — i.e., after a client signs their contracts, Debitura tries to replay the cases you submitted and one of them is rejected with a soft failure. This is a per-case event; other cases in the same batch may succeed and emit case.created events.

Use this event to surface failed cases to your users so they can correct and resubmit.

cases.replay_failed payload
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"specVersion": "1.0",
"event": "cases.replay_failed",
"timestamp": "2026-01-31T15:23:45Z",
"data": {
"creditorId": "789e4567-e89b-12d3-a456-426614174abc",
"externalTenantId": "partner-client-123",
"creditorReference": "INV-001",
"failureReason": "Invoice amount is below the minimum threshold",
"attemptedAt": "2026-01-31T15:23:45Z"
}
}
FieldTypeDescription
creditorIdstring (UUID)Debitura's internal creditor ID for the client
externalTenantIdstringYour identifier for the client
creditorReferencestring | nullThe case reference you provided in your original submission. Use this to identify which case in your system failed. Null if no reference was provided.
failureReasonstringHuman-readable explanation of why this specific case was rejected
attemptedAtstring (ISO 8601)UTC timestamp when the creation attempt occurred

Verify the webhook signature before processing events. For production patterns, see Webhook Best Practices. To test your handler, see Webhook Testing.

Business context: See Webhook events (business meaning glossary) for what each event means in business terms.