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

# Ownership and access

> Understand company credentials and API terms, invoice ownership, subscription requirements, and collection handover.

Mahnservice takes invoices from several places: connected bookkeeping systems,
a CSV import, manual entry in the portal, and this API. They all land in one
invoice list, but they are not all yours to change.

## One writer per invoice

Every write in this API — correct, release, report a payment, cancel, write
off, upload a document — applies only to invoices **this API created**. An
invoice synchronized from a connected bookkeeping system is fully readable
here (list, retrieve, its payments, its documents, its dunning state) and
answers `409 not_api_invoice` on every write, before any other conflict is
evaluated. `HEAD` on the `payments` and `documents` routes mirrors the
corresponding `GET` — same status, empty body — and never writes, whatever
body accompanies it.

That is not tidiness. Releasing a synced invoice would bypass the import
cut-off date the customer configured; an API payment would collide with the
bookkeeping system's own payment detection; and a document upload would replace
the accounting system's original PDF. The bookkeeping system owns those rows.

The practical consequence for an integration: a company that connects a
bookkeeping system does not need this API for those invoices, and this API
cannot be used to take them over. Read them, and write only what you submitted.

Debtors and invoices cannot be deleted through the API. An invoice ends
through payment, cancellation, or write-off.

## API credentials and terms

Mahnservice requests use the current `/mahnservice/v1/` routes and the same
company-bound Bearer key as the Case Management API. Create the key in the
developer portal. The `X-On-Behalf-Of-Company` header is not accepted on
Mahnservice routes (`400 unexpected_company_context`).

If a credential is not permitted for an operation, the API returns
`403 permission_denied`. Contact paywise support if access is unexpectedly
denied.

The API terms of use your company accepts for that key cover both APIs. A
production write (every `POST` or `PATCH` except payment reporting) requires
the current terms to have been accepted. Without acceptance the write returns
`403 terms_acceptance_required`; if the terms cannot be verified, it returns
`503 api_terms_unavailable`. Retry the latter later; the request was not
applied. Reads, `/info/`, payment reporting, and the sandbox are exempt.

## Reads and payment reporting survive a lapsed subscription

In production, Mahnservice is a subscribed product. Writes require an active
subscription and answer `403 subscription_required` without one — also when
the subscription state cannot be verified at that moment. The sandbox allows
integration testing without purchasing a subscription or providing a payment
method.

Two things stay open through a lapse:

* **every read**, so an integration keeps reconciling instead of going blind;
* **payment reporting**, deliberately. A customer whose subscription lapsed
  must still be able to stop dunning on an invoice that was paid. Leaving that
  path open is a product decision, not an oversight.

Everything else write-shaped — submitting, correcting, releasing, cancelling,
writing off, uploading a document — needs the subscription.

An administrative lock is different. When paywise has locked a company's
Mahnservice account, **every** write — payment reporting included, and
regardless of the credential's `access_mode` — answers `403 company_locked`
("Your Mahnservice account is currently locked by paywise. Please contact
support."). The lock outranks the subscription check, so a locked company
with a lapsed subscription hears `company_locked`, not `subscription_required`.
Reads stay open. The three `403` codes on this API are therefore
`permission_denied` (the credential is not permitted for the operation, or is
not bound to a company), `subscription_required`,
and `company_locked`; production writes additionally require the accepted API
terms of use (`403 terms_acceptance_required`, see
[API credentials and terms](#api-credentials-and-terms)).

A credential must be bound to a company. A key without a company binding
answers `403 permission_denied` with "This credential is not bound to a
company." on every route, `GET /mahnservice/v1/info/` included. Disabling API
access for the key's user and company
in the portal's API settings turns every request into
`401 authentication_failed` with "API access is disabled for this company."
(this switch also covers the legacy Case Management API v1; the current
`/v2/` APIs do not consult it).

## Debt collection ends this API's authority over a claim

When a claim is handed to paywise debt collection, its `dunning_state` becomes
`inkasso`, and the collection case — not this API — decides the outcome:

* `cancel`, `write-off`, `PATCH`, document upload, `dunning/pause`, and
  `dunning/resume` answer `409 invoice_in_inkasso`. Retracting a transferred
  claim goes through paywise support.
* A payment **is recorded** and does not settle the claim. Even a payment
  covering the full amount leaves the state at `inkasso`.

**That last point is intended behaviour, and it is worth designing around.**
Reporting a payment on a transferred claim through this API stores it, and it
does not close the collection case, reduce what the case is collecting, or
notify the collection side. There is no write-back closing that loop. If a
debtor pays you directly after a handover, report it to paywise support (or
through the Case Management API against the mandate) so the collection case
reflects it; the record you create here is data, not a settlement.

The collection case starts when paywise accepts the handover order. If your
company withdraws that order before acceptance, or paywise rejects it, no
collection case will exist. The invoice then leaves `inkasso` for `completed`:
`current_level` and `next_action_date` become `null`, `updated` advances,
dunning does **not** resume, and no webhook is sent for this change. If the payments reported while the invoice was in
`inkasso` cover its amount, it goes on to `paid` with the usual `invoice.paid`
event instead. From then on it behaves like any completed invoice: `cancel`
and `write-off` work again, and you can hand it over to collection again in
the paywise Mahnservice app, which creates a new order.

## Environments

Production and sandbox are separate hosts with separate, non-interchangeable
credentials. A key works only in its own environment; a key of the other
environment is refused with `401`.

`GET /mahnservice/v1/info/` reports the installation in `environment`
(`sandbox` or `production`), matching the `X-Paywise-Environment` response
header. Check it before a rehearsal that writes.

`access_mode` appears on the credential, on debtors, and on invoices. It is a
read-only compatibility field for the credential's data lane. **Modern keys
return `production` in both installations**, including `pw_sbx_` sandbox keys.
That allows the sandbox to exercise the dunning lifecycle while outbound mail
is still captured and all data stays in the sandbox. It does not select an
environment or enable production effects.

Legacy `test`-mode credentials still exist for some long-standing integrations;
those invoices remain visible in the portal of their installation but are
never dunned. Do not use `access_mode` to detect the sandbox or send it as a
writable property.

To develop against the sandbox, see
[Sandbox environment](/api-docs/case-management-api/concepts/sandbox).

## Related reference

* [GET `/mahnservice/v1/invoices/`](/api-docs/mahnservice-api/reference/invoices/list-invoices)
* [POST `/mahnservice/v1/invoices/{uuid}/payments/`](/api-docs/mahnservice-api/reference/invoices/report-a-payment)
* [POST `/mahnservice/v1/invoices/{uuid}/cancel/`](/api-docs/mahnservice-api/reference/invoices/cancel-an-invoice-storno)


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