> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paywise.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook events

> Choose Case Management events for orders, mandates, payments, and statements, and understand their payloads.

Company webhooks notify you about orders, accepted collection cases, payments,
and statements. Each subscription belongs to one company. Create one through
[POST `/v2/webhooks/`](/api-docs/case-management-api/reference/webhooks/create-webhook)
or use the developer portal described below.

For receiver setup, signature verification, retries, and troubleshooting, use
[Webhooks](/api-docs/essentials/webhooks). For a complete API example, follow
[Consume Case webhooks](/api-docs/case-management-api/workflows/consume-webhooks).

A company holds at most 20 endpoints, enabled or disabled; the cap is
enforced atomically, so concurrent creates never exceed it and the 21st is
`409 webhook_limit_reached`. `POST /v2/webhook-deliveries/{id}/redeliver/`
accepts settled deliveries only (`success` or `failed`); a `pending`,
`retrying`, or `delivering` delivery answers `409 delivery_in_progress`.
`rotate-secret` and `redeliver` take no request body (`400 unexpected_body`),
and the `expensive:webhook-delivery` budget is charged only when a redeliver
is accepted with `202`. A Partner key acting with `X-On-Behalf-Of-Company`
cannot manage company endpoints: writes on `/v2/webhooks/` and redeliver
answer `403 use_partner_webhooks` before any `If-Match` or query-parameter
check.

The 18 event types below and the six
[Mahnservice events](/api-docs/mahnservice-api/concepts/invoice-lifecycle#webhook-events)
form the 24-event company subscription catalog. Use the exact event keys in
`events`; the same keys arrive in the payload's `type`. Partner integrations
use [Partner-owned subscriptions](/api-docs/partner-api/concepts/webhook-ownership#receive-case-and-mahnservice-events)
to receive these events for connected companies.

The Case OpenAPI schema publishes the event envelope as `CaseWebhookEvent`,
a discriminated union on `type`. Each event type maps to one payload family;
its `data` contains the keys listed below, with optional keys marked explicitly.
Dispatch on `type`, then read `data` using that family's model. The objects
are open: new `data` members and new event types can arrive within `/v2/`, so
ignore members you do not know and acknowledge, then skip, unknown types (see
[Versioning](/api-docs/essentials/versioning)).

## Order management

Order lifecycle events use `OrderWebhookEvent`, with `company_id`, `order_id`,
`order_url`, and `claim_ids` in `data`. `order.accepted` uses
`OrderAcceptedWebhookEvent`, which adds `mandate_id` and `mandate_url` — the
case the order's claims were accepted into — so a consumer can fetch the
mandate without reading the order first. `order.message.created` uses
`OrderMessageWebhookEvent` and adds `message_id` to the order keys; it is not a
lifecycle event and does not include `claim_ids`.

| Event key | When it is sent |
| - | - |
| `order.submitted` | An order was submitted for review. Draft construction is silent. |
| `order.withdrawn` | A submitted order was withdrawn before acceptance, through the API or by a cancellation in the paywise portal. |
| `order.rejected` | An order was rejected during review. |
| `order.accepted` | An order was accepted and converted into a collection case. Uses `OrderAcceptedWebhookEvent`; `mandate_id` equals the order's `mandate` field. Acceptance also emits `mandate.created`. |
| `order.expired` | An order draft expired and was automatically deleted. |
| `order.message.created` | A message **from the client to paywise** was received on an order. It does not announce a message from paywise to the client. |

Every newly emitted `order.submitted`, `order.accepted`, `order.rejected`,
`order.withdrawn`, and `order.expired` event contains the exact sorted, unique
claim UUID snapshot captured with that transition, including `[]` when the
order has no claims. These abbreviated payload examples show the lifecycle
data boundary:

| Event | `data` example |
| - | - |
| **order.submitted** | `{"company_id":"10000000-0000-4000-8000-000000000001","order_id":"20000000-0000-4000-8000-000000000001","order_url":"https://api.paywise.de/v2/orders/20000000-0000-4000-8000-000000000001/","claim_ids":["30000000-0000-4000-8000-000000000001","30000000-0000-4000-8000-000000000002"]}` |
| **order.accepted** | `{"company_id":"10000000-0000-4000-8000-000000000001","order_id":"20000000-0000-4000-8000-000000000002","order_url":"https://api.paywise.de/v2/orders/20000000-0000-4000-8000-000000000002/","claim_ids":["30000000-0000-4000-8000-000000000001"],"mandate_id":"40000000-0000-4000-8000-000000000001","mandate_url":"https://api.paywise.de/v2/mandates/40000000-0000-4000-8000-000000000001/"}` |
| **order.rejected** | `{"company_id":"10000000-0000-4000-8000-000000000001","order_id":"20000000-0000-4000-8000-000000000003","order_url":"https://api.paywise.de/v2/orders/20000000-0000-4000-8000-000000000003/","claim_ids":["30000000-0000-4000-8000-000000000003"]}` |
| **order.withdrawn** | `{"company_id":"10000000-0000-4000-8000-000000000001","order_id":"20000000-0000-4000-8000-000000000004","order_url":"https://api.paywise.de/v2/orders/20000000-0000-4000-8000-000000000004/","claim_ids":["30000000-0000-4000-8000-000000000004"]}` |
| **order.expired** | `{"company_id":"10000000-0000-4000-8000-000000000001","order_id":"20000000-0000-4000-8000-000000000005","order_url":"https://api.paywise.de/v2/orders/20000000-0000-4000-8000-000000000005/","claim_ids":["30000000-0000-4000-8000-000000000005"]}` |

The accepted example deliberately has a different order from the submitted
example: review may move a stored claim before acceptance. Reconcile using the
claim UUID from `claim_ids`, then refetch `/v2/claims/{claim_id}/` to obtain its
current `order_id`, status, and `mandate_id`. There is no
`claim.order_changed` event.

Retained event and delivery envelopes materialized before this contract may
omit `claim_ids`. Omission means the historical snapshot is unavailable; it
does not mean an empty claim set. Do not synthesize `[]`. Current emissions,
retries, feeds, and redeliveries use the immutable snapshot stored with the
event.

## Cases

These events concern accepted collection cases (mandates), their balances,
messages, and client requests. Client requests can also belong to an order or
CSV upload; their payload uses one of the three contexts below.

| Family | `data` |
| - | - |
| `MandateWebhookEvent` | `company_id`, `mandate_id`, `mandate_url` |
| `MandateStatusUpdateWebhookEvent` | `company_id`, `mandate_id`, `mandate_url`, `status_update_id` |
| `MandateMessageWebhookEvent` | `company_id`, `mandate_id`, `mandate_url`, `message_id` |
| `RequestToClientWebhookEvent` | Always `company_id` and `request_to_client_id`. A case request also requires `mandate_id` and `request_to_client_url`; an order request requires `order_id`; a CSV-upload request has neither parent reference. These contexts cannot be mixed. |
| `PaymentWebhookEvent` | `company_id`, `payment_id`, `payment_url` |

| Event key | When it is sent |
| - | - |
| `mandate.created` | A collection case was created. Uses `MandateWebhookEvent`. |
| `mandate.state.changed` | A case's public procedure, processing, or payment state changed. Uses `MandateWebhookEvent`. |
| `mandate.status_update.published` | A standalone status update was published on a case. Uses `MandateStatusUpdateWebhookEvent`. A resource action that creates a wrapper status emits only its specific event. |
| `mandate.balance_updated` | A payment booked by paywise or a cost calculation changed the case's legal balance. Uses `MandateWebhookEvent`; fetch `mandate_url` and re-read `legal_balance`, since the event contains no amounts. |
| `mandate.message.created` | A message **from the client to paywise** was received on a case. Uses `MandateMessageWebhookEvent`. It does not announce a message from paywise to the client. |
| `request_to_client.created` | paywise published a request for the client concerning an order, case, or CSV upload. Uses `RequestToClientWebhookEvent`. |
| `request_to_client.answered` | A request to the client concerning an order, case, or CSV upload was answered. Uses `RequestToClientWebhookEvent`. |
| `payment.reported` | The company finalized a payment report. Uses `PaymentWebhookEvent`; this is about a payment reported by the company, not one received by paywise. Draft reports are silent, and there is no payment-reversal event. |

For an order request, combine `data.order_id` and `data.request_to_client_id`
to read `/v2/orders/{order_id}/requests-to-client/{id}/` and submit its
`/answer/` command. The mandate routes apply only when the event carries
`mandate_id`. See [Messages and client requests](/api-docs/case-management-api/workflows/messages-and-client-requests).

## Statements

Statement events announce publication and cancellation of accounting
statements. They are separate from Mahnservice invoice events.

| Family | `data` |
| - | - |
| `StatementWebhookEvent` | `company_id`, `statement_id`, `statement_url` |
| `SingleMandateStatementWebhookEvent` | `company_id`, `single_mandate_statement_id`, `single_mandate_statement_url` |

| Event key | When it is sent |
| - | - |
| `statement.published` | A clearing-run statement (Sammelabrechnung) was published and is available to retrieve. Uses `StatementWebhookEvent`. |
| `statement.cancelled` | A published clearing-run statement was cancelled. Uses `StatementWebhookEvent`. |
| `single_mandate_statement.published` | A statement for one case (Aktenabrechnung) was published and is available to retrieve. Uses `SingleMandateStatementWebhookEvent`. |
| `single_mandate_statement.cancelled` | A published single-case statement was cancelled. Uses `SingleMandateStatementWebhookEvent`. |

## Document processing

Document-processing events have been retired with URL-based ingestion. They
are not selectable and no new document-processing events are delivered or
added to the event feed, including for wildcard subscriptions. Follow
`status` and `updated_at` through the document's parent-scoped list or detail
endpoint instead; see [Manage documents](/api-docs/case-management-api/workflows/manage-documents).
Scanning remains asynchronous.

## Configure a subscription in the portal

In the German developer portal, expand **Neuen Endpoint hinzufügen** to enter the
callback URL, the maximum consecutive failures before deactivation, and an
optional description. Select events by their exact keys; each has a German
explanation. The sections are **Mahnservice** (Mahnservice API),
**Auftragsverwaltung**, **Inkassofälle**, and **Abrechnungen**.

Each section has **Alle auswählen** / **Alle abwählen**. It changes only that
section; selections in other sections remain intact. Selecting every current
event in a section stores those explicit keys, not the API wildcard `"*"`.
Collapsing and reopening the create form preserves the draft.

Production and sandbox are separate environments selected by host and
credential. There is no Test/Production selector on a current subscription.
Create and test sandbox subscriptions in the sandbox; see
[Authentication and environments](/api-docs/essentials/authentication-and-environments).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.