Source: https://docs.debitura.com/collection-partners/integration-guides/webhooks

# Webhooks

Subscribe to real-time event notifications for cases assigned to your agency, lifecycle changes, payments, and chat messages. If you also submit cases for your own clients as a [managing partner](https://docs.debitura.com/collection-partners/concepts/managed-cases.md), you can opt in to a separate, minimal set of `managed_case.*` events for those cases.

| Your role on the case | Events | Where |
| --- | --- | --- |
| **Collecting** — the case is assigned to your agency | `case.assigned`, `case.updated`, `case.closed`, `case.declined`, `payment.created`, `payment.deleted`, `chat.created` | [Available Events](https://docs.debitura.com/collection-partners/integration-guides/webhooks.md#available-events) |
| **Managing** — you submitted the case for your client | `managed_case.created`, `managed_case.assigned`, `managed_case.updated`, `managed_case.closed`, `managed_case.declined`, `managed_case.payment.created`, `managed_case.payment.deleted`, `managed_case.chat.created` | [Managing-role events](https://docs.debitura.com/collection-partners/integration-guides/webhooks.md#managing-role-events) |

The two catalogs are independent. Existing event names, payloads and URLs are unchanged, and no subscription receives a `managed_case.*` event unless it lists that exact name in `Events`.

<a id="create-a-webhook-subscription"></a>

## Create a Webhook Subscription

```http
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:**

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `Url` | string | — | The HTTPS endpoint to deliver events to |
| `Events` | string\[\] | — | Event types to subscribe to (see [Available Events](https://docs.debitura.com/collection-partners/integration-guides/webhooks.md#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. 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](https://docs.debitura.com/developer-concepts/webhooks.md#test-vs-live-subscriptions) for details.

Response (`201 Created`):

```json
{
  "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`.

<a id="manage-subscriptions"></a>

## Manage Subscriptions

List all webhooks

```http
GET https://collectionpartner-api.debitura.com/webhooks
XApiKey: your_api_key_here
```

Get a specific webhook

```http
GET https://collectionpartner-api.debitura.com/webhooks/{id}
XApiKey: your_api_key_here
```

Update a webhook

```http
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

```http
DELETE https://collectionpartner-api.debitura.com/webhooks/{id}
XApiKey: your_api_key_here
```

For the full API reference, see [Webhook endpoints](https://docs.debitura.com/api/collection-partner-api/webhooks.md#create-a-new-webhook-subscription).

<a id="payload-structure"></a>

## 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](https://docs.debitura.com/developer-concepts/webhooks.md#signature-verification).

<a id="available-events"></a>

## Available Events

<a id="caseassigned"></a>

### 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

```json
{
  "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](https://docs.debitura.com/api/collection-partner-api/cases.md#fetch-case-by-id). |
| `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 `"Pending Verification"` — call `POST /cases/{id}/start` to make the case `Active`). See [Case Lifecycle](https://docs.debitura.com/developer-concepts/case-lifecycle.md) for all states. |

<a id="casedeclined"></a>

### 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](https://docs.debitura.com/developer-concepts/engagement-phase.md), 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

```json
{
  "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": {}
}
```

| Field | Type | Description |
| --- | --- | --- |
| `caseId` | string (UUID) | Debitura's internal case ID |
| `reference` | string | Human-readable case reference |
| `reason` | string | null | The decline reason you provided when declining the case, if any |

<a id="caseupdated"></a>

### 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

```json
{
  "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](https://docs.debitura.com/developer-concepts/case-lifecycle.md) for all lifecycle states and valid transitions.

<a id="caseclosed"></a>

### case.closed

Fires when a case reaches its terminal state. A closed case can be reopened (for example when a payment is edited or deleted); you then receive a `case.updated` with `oldLifecycle: "Closed"`. Use it to update your internal records with the outcome and close code.

case.closed payload

```json
{
  "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](https://docs.debitura.com/developer-concepts/case-lifecycle.md#close-codes) for all close codes and their meanings.

<a id="paymentcreated"></a>

### 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

```json
{
  "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 |

<a id="paymentdeleted"></a>

### 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](https://docs.debitura.com/collection-partners/integration-guides/correct-or-remove-payments.md). 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

```json
{
  "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": {}
}
```

| Field | Type | Description |
| --- | --- | --- |
| `caseId` | string (UUID) | Debitura's internal case ID |
| `reference` | string | Human-readable case reference |
| `paymentId` | string (UUID) | Identifier of the deleted payment record (same `paymentId` from its original `payment.created` event) |
| `amount` | number (decimal) | Gross amount of the deleted payment, in the case currency |
| `currency` | string | ISO 4217 currency code (e.g., `"DKK"`, `"EUR"`, `"GBP"`) |
| `date` | string (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 |

<a id="chatcreated"></a>

### 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.

For an earlier partner's conversation, `reference` is empty when its case facts are unavailable. Use `caseId` to identify the case.

chat.created payload

```json
{
  "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 |

<a id="managing-role-events"></a>

## Managing-role events

If you submit cases with `POST /managed-cases`, you can subscribe to eight additional events about those cases. They are separate from the collecting events above: different names, a smaller payload, and a different audience.

**Who receives them.** Only the partner that currently manages the case. A case you manage and also collect yourself produces both kinds of event, each with its own `id`; treat them as two independent streams.

**Opt-in.** A managing event is delivered only to a subscription whose `Events` list contains its exact name. There are no wildcards, and existing subscriptions are never opted in automatically. You can add the names to a subscription at any time:

```http
PUT https://collectionpartner-api.debitura.com/webhooks/{id}
Content-Type: application/json
XApiKey: your_api_key_here

{
  "Events": ["managed_case.created", "managed_case.assigned", "managed_case.updated", "managed_case.closed", "managed_case.payment.created"]
}
```

**No historical backfill.** Selecting an event starts delivery of events from that moment. Nothing that already happened is sent. To read the current state of existing cases, use the authorized [managed-case endpoints](https://docs.debitura.com/collection-partners/concepts/managed-cases.md#api-endpoints).

**Test and live stay separate.** A subscription with `IsTestMode: true` receives managing events for test cases only; a live subscription receives them for live cases only. Every payload carries `classification` (`production`, `test` or `demo`) so you can assert on it.

**Minimal by design.** A managing notification tells you that something happened and which case it is about. It never contains chat text, close or decline comments, debtor details or any other case content. Fetch details through the managed-case API, which applies your current access.

<a id="payload"></a>

### Payload

The envelope is the same as for every other event (`id`, `specVersion` `"1.0"`, `event`, `timestamp`, `data`, `links` empty). Every managing event has these `data` fields; the event-specific fields follow in the next table.

| Field | Type | Description |
| --- | --- | --- |
| `caseId` | string (UUID) | Debitura's internal case ID |
| `reference` | string | Human-readable case reference |
| `classification` | string | `production`, `test` or `demo` |

managed\_case.updated payload

```json
{
  "id": "5d1c7a42-93be-8f10-a6c4-0e7b2d9f3a18",
  "specVersion": "1.0",
  "event": "managed_case.updated",
  "timestamp": "2026-10-12T08:30:00Z",
  "data": {
    "caseId": "e3d7f2a1-c845-4b9d-8f6e-aabbccddeeff",
    "reference": "Q8OAXF3W",
    "classification": "production",
    "oldLifecycle": "Active",
    "newLifecycle": "Active"
  },
  "links": {}
}
```

<a id="event-catalog"></a>

### Event catalog

| Event | Fires when | Event-specific `data` fields |
| --- | --- | --- |
| `managed_case.created` | The case has been submitted | `lifecycle` |
| `managed_case.assigned` | A collection partner has been assigned to the case | `lifecycle` |
| `managed_case.updated` | The case lifecycle is updated | `oldLifecycle`, `newLifecycle` |
| `managed_case.closed` | The case is closed | `closeCode` |
| `managed_case.declined` | The assigned collection partner declined the case | `collectingPartnerId` (UUID) |
| `managed_case.payment.created` | A payment is registered | `paymentId` (UUID), `amount` (decimal), `currency`, `date` |
| `managed_case.payment.deleted` | A payment is reversed | `paymentId`, `amount`, `currency`, `date` — the original payment, unchanged |
| `managed_case.chat.created` | A chat message is posted | `chatId` (UUID), `role`, `caseEngagementId` (UUID) |

Field meanings match the same-named fields of the [collecting events](https://docs.debitura.com/collection-partners/integration-guides/webhooks.md#available-events). Two points differ:

-   **`payment.deleted`** repeats the original payment snapshot. The event name is what tells you it was reversed; `date` is still the payment date, not the deletion time.
-   **`chat.created`** carries identifiers only, no `message`. `role` is the sender's role as in `chat.created`.

<a id="timing"></a>

### Timing

Managing events are derived from the same moments as the collecting events, so their timing is exactly as precise as those signals — and no more:

-   **`managed_case.created`** is sent when the case is submitted.
-   **`managed_case.assigned`** is sent when assignment is signalled. Depending on the case that is immediately at submission or after Debitura's validation, so it can arrive right after `managed_case.created` or later. Do not infer that validation has happened from it, or assume a fixed gap.
-   **`managed_case.updated`** can carry equal `oldLifecycle` and `newLifecycle` values. Treat it as "something about the lifecycle was updated", not as a guaranteed phase change. There is no dedicated signal for a phase change or for reassignment to a different collection partner; to see the current assignee, read the case.
-   **`managed_case.declined`** is sent when the assigned collection partner declines. It does not name a reason.
-   Delivery is asynchronous and at-least-once, and events can arrive out of order. Use `timestamp` and the case data, not arrival order.

<a id="chat-notifications"></a>

### Chat notifications

`managed_case.chat.created` identifies the conversation's engagement, including a retained historical engagement. Ending an engagement alone does not stop notifications or clear earlier payloads. The conversation must still be accessible and the case must still be managed by you.

<a id="when-a-delivery-is-not-sent"></a>

### When a delivery is not sent

Before every delivery attempt, including each retry and each replay, Debitura re-checks that you are still entitled to the notification. If any check fails, **no request is sent to your endpoint**, no failed attempt is counted against the subscription, and no history entry is created. Reasons include:

-   the subscription was deleted, deactivated or no longer lists the event name;
-   the subscription's test/live mode does not match the case;
-   the case is no longer managed by you, was deleted, or belongs to an account that has been erased;
-   for chat, the conversation or its engagement is no longer available.

An entitlement check cannot be cancelled once your endpoint has been called: a request that has already started is not recalled. If Debitura temporarily cannot verify entitlement, it retries on the normal [retry schedule](https://docs.debitura.com/collection-partners/integration-guides/webhooks.md#retry-and-auto-disable) and sends nothing until the check passes.

<a id="event-history"></a>

### Event history

Managing events appear in `GET /webhooks/events?caseId={id}` with `eventType` set to the `managed_case.*` name, like any other event. The stored `payload` is returned only while you still have access. When you do not — the case moved, the subscription no longer selects the event, the chat conversation or its engagement is no longer available, an account was erased, or 28 days have passed — the entry is still listed, but its `payload` is empty. Entries of a subscription you deleted are no longer listed at all.

The `id` of a history entry identifies the delivery record and is what you pass to the replay call. It is not the envelope `id` inside `payload`.

<a id="replay"></a>

### Replay

`POST /webhooks/events/{id}/replay` re-sends the stored payload unchanged:

-   The delivery carries `X-Debitura-Replay: true`, and the envelope `id` is **the same as the original**. Deduplicate on `id`, not on the header: a replay of an event you already processed must not be applied twice.
-   Replay is available for 28 days after the event, and only while the entitlement checks above still pass. Otherwise the call returns `410 Gone` (`WebhookEventExpired`). The same checks run again when the replay is delivered.
-   You can only replay events of your own subscriptions; an unknown ID, or an event of a deleted subscription, returns `404`.
-   A replay creates a new history entry of its own; its envelope `id` equals the original's.

<a id="receiver-idempotency"></a>

### Receiver idempotency

The `id` of a managing event is derived from the source event, the event name and your partner account. A retry or replay of the same notification always carries the same `id`; a different notification never shares one. Store processed `id` values and ignore repeats. Also ignore `data` fields you do not recognise, so an approved addition does not break your parser.

<a id="testing-managing-events"></a>

### Testing managing events

Use `POST /test/webhooks/fire` with a managing event name against a **test case you currently manage** (created with `isTest: true` via `POST /managed-cases`) and a test-mode subscription that selects that exact event. The event is built from the case's current state, so it uses real fixtures:

| Event | Fixture the case must have |
| --- | --- |
| `managed_case.payment.created` | at least one payment |
| `managed_case.payment.deleted` | at least one deleted payment |
| `managed_case.chat.created` | a chat message on the case's active engagement |
| `managed_case.assigned`, `managed_case.declined` | a collection partner assigned or engaged |

| Status | Cause |
| --- | --- |
| `200` | `enqueuedCount` is the number of deliveries queued. Without `subscriptionId` the event goes to all your active test subscriptions that select it, and `enqueuedCount` is `0` when there are none |
| `400` | Not a test case, invalid event name, or the `subscriptionId` is not one of your test subscriptions that selects this event |
| `404` | Case not found, or not a case you manage |
| `422` | A required fixture above is missing |

See [CI Testing](https://docs.debitura.com/developer-concepts/webhooks/ci-testing.md#managing-role-events) for a complete subscribe → fire → history → replay example.

<a id="signature-verification"></a>

## Signature Verification

Always verify the `X-Debitura-Signature` header before processing events. See [Signature Verification](https://docs.debitura.com/developer-concepts/webhooks.md#signature-verification) for implementation details and code examples.

<a id="retry-and-auto-disable"></a>

## 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.

A response that redirects (`3xx`) is treated as a failed attempt: Debitura does not follow redirects, so register the final URL.

**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`.

<a id="secret-rotation"></a>

## Secret Rotation

Rotate your signing secret without deleting and recreating the subscription:

```http
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.

<a id="testing-webhooks-in-ci"></a>

## 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](https://docs.debitura.com/developer-concepts/webhooks/ci-testing.md) for the full guide and code examples.

**Business context:** See [Collection Partners: Case status definitions and allowed actions](https://support.debitura.com/en/articles/13910011-collection-partners-case-status-definitions-and-allowed-actions) for what each lifecycle state and close code means in your collection workflow.

<a id="troubleshooting"></a>

## Troubleshooting

For diagnosing failed deliveries, decoding error messages in the delivery log, and other common issues, see [Webhook Troubleshooting](https://docs.debitura.com/developer-concepts/webhooks/troubleshooting.md).
