Source: https://docs.debitura.com/api/collection-partner-api/webhook-events

# Webhook events — Collection Partner API

Webhooks

Base URL: `https://collectionpartner-api.debitura.com`

Authentication: `XApiKey` API key; see [authentication](https://docs.debitura.com/developer-concepts/authentication.md).

Generated from [OpenAPI](https://docs.debitura.com/openapi/collection-partner-api.json). Examples are schema illustrations, not observed responses. Complete schemas, including recursive types, are in OpenAPI.

<a id="list-webhook-events-dispatched-for-a-case"></a>

## List webhook events dispatched for a case.

`GET /webhooks/events`

Returns all webhook events dispatched for the given case, scoped to your webhook subscriptions.
Results are ordered newest-first.

**Use cases:**
- Verify that a specific event (e.g. `case.updated`) fired after a state transition.
- Inspect the exact payload delivered on each attempt.
- Find the event ID to replay via `POST /webhooks/events/{id}/replay`.
- Part of the CI-loop ASSERT step: after advancing a test case, query this endpoint to confirm the correct events fired.

**Filtering:**
- `caseId` (required): restricts to events for this case.
- `since` (optional): only returns events created at or after this ISO 8601 timestamp.

**Note:** Only events for your subscriptions are returned — events from other collection partners' subscriptions are never exposed.

Managed-event payloads are also hidden when current case ownership, classification, event selection,
feature status or chat engagement no longer permits access. Hidden payloads cannot be replayed.

**Retention:** event payloads are kept for 28 days. After that the event is still listed, with an empty `payload`, and can no longer be replayed.

### Query parameters

- `caseId` (uuid): 
- `since` (datetime): 

### Response 200

List of webhook events

- `id` (uuid): Unique identifier for this event record.
Use this ID to replay the event via `POST /webhooks/events/{id}/replay`.
- `subscriptionId` (uuid): The webhook subscription this event was dispatched to.
- `caseId` (uuid, nullable): The collection case this event relates to.
- `eventType` (string, nullable): The event type (e.g. "case.assigned", "case.updated", "case.closed", "payment.created", "chat.created").
- `payload` (string, nullable): The full JSON payload that was (or will be) delivered.
- `createdAt` (datetime): When this event was first recorded (UTC).
- `deliveredAt` (datetime, nullable): When the event was successfully delivered (UTC).
Null if delivery has not yet succeeded.
- `attemptCount` (integer): Number of delivery attempts made so far.
- `lastResponseCode` (integer, nullable): HTTP status code returned by the subscriber endpoint on the last attempt.
- `lastError` (string, nullable): Error message from the last failed delivery attempt. Null on successful delivery.

```json
[
  {
    "id": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "subscriptionId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "caseId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
    "eventType": "string",
    "payload": "string",
    "createdAt": "2026-10-01T14:05:00Z",
    "deliveredAt": "2026-10-01T14:05:00Z",
    "attemptCount": 42,
    "lastResponseCode": 3,
    "lastError": null
  }
]
```

### Response 400

Missing or invalid query parameters

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

<a id="replay-a-specific-webhook-event"></a>

## Replay a specific webhook event.

`POST /webhooks/events/{id}/replay`

Re-enqueues the exact payload from a previously recorded event to its original subscription.

The event is re-queued as a fresh delivery attempt (attempt 1) using the original payload unchanged.
Delivery follows the normal retry schedule if the endpoint is unavailable.

**Replay signal:** Replayed deliveries include the header `X-Debitura-Replay: true` so your endpoint can distinguish a replay from a live event and implement idempotency correctly.

**When to use:**
- Your endpoint was temporarily unavailable and you want to re-deliver a specific event.
- You want to test idempotency of your event handler.
- Part of CI-loop ASSERT: confirm an event was dispatched via `GET /webhooks/events`, then replay to a different receiver.

**Relationship to `replay-last-event`:** `POST /test/cases/{id}/replay-last-event` is a convenience wrapper over this endpoint — it looks up the most recent event ID for you. Use that endpoint when you don't yet know the event ID; use this endpoint when you have the ID from `GET /webhooks/events`.

**Tenant isolation:** Only events belonging to your own subscriptions can be replayed.

**Retention:** events older than 28 days have had their payload cleared and return `410 Gone` with error `WebhookEventExpired`.

### Path parameters

- `id` (uuid, required): 

### Response 200

Event re-enqueued for delivery

- `eventId` (uuid): The ID of the event that was replayed.
- `subscriptionId` (uuid): The subscription the event was re-enqueued to.
- `eventType` (string, nullable): The event type that was replayed (e.g. "case.updated").

```json
{
  "eventId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "subscriptionId": "3f2b6c1e-8a4d-4b7f-9c2e-5d1a0b9e7f31",
  "eventType": "string"
}
```

### Response 400

ID missing or empty

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 404

Event not found or not owned by this collection partner

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```

### Response 410

Event is older than 28 days; its payload is no longer available

- `error` (string, nullable): Short human-readable error label (legacy field — preserved for backward compatibility).
- `message` (string, nullable): Human-readable error description (legacy field — preserved for backward compatibility).
- `businessErrors` (array of objects, nullable): Canonical structured error array. Consumers should migrate to reading this field.
- `businessErrors[].type` (string, nullable): The type of business error (e.g., "MissingDebtCollectionContract", "MissingPowerOfAttorney", "NoPartnerAvailable").
- `businessErrors[].message` (string, nullable): A human-readable description of the error.
- `businessErrors[].solutionUrl` (string, nullable): A URL where the user can resolve this <i>specific</i> error (e.g., sign a contract).
            

Partners who want a <b>single URL</b> that walks the user through every pending
signing in one chain — instead of forwarding one URL per
`BusinessErrorApiDTO` — should use
SigningHandoff's `CombinedSigningUrl`.
The two are complementary: `SolutionUrl` is granular per-error;
`CombinedSigningUrl` is the chain-walking alternative for signing-related errors.

```json
{
  "error": null,
  "message": "Payment plan agreed with the debtor.",
  "businessErrors": [
    {
      "type": "string",
      "message": "Payment plan agreed with the debtor.",
      "solutionUrl": "https://app.debitura.com/…"
    }
  ]
}
```
