Direct debits
| Operation | Summary | Scope | Idempotency-Key |
|---|---|---|---|
POST /v1/direct-debit-exports |
Release direct debits as a pain.008 file | post |
required |
GET /v1/entities/{entity}/customers/{party}/mandates |
List a customer's SEPA mandates | read |
|
POST /v1/entities/{entity}/customers/{party}/mandates |
Record a customer's SEPA mandate | draft |
required |
POST /v1/entities/{entity}/direct-debit-proposals |
Suggest invoices to collect by direct debit | read |
|
POST /v1/entities/{entity}/direct-debit-runs |
Collect the invoices of a proposal | draft |
required |
GET /v1/entities/{entity}/direct-debits |
List direct debit collections | read |
|
PUT /v1/mandates/{mandate_id}/account |
Change the debtor account of a mandate | draft |
|
POST /v1/mandates/{mandate_id}/revoke |
Revoke a mandate | draft |
POST /v1/direct-debit-exports
Release direct debits as a pain.008 file
Release posted direct debit collections as a SEPA pain.008.001.08 file.
The rules of a pain.001 file apply: agents cannot release (403), nor the person who created
a collection; each is sent once (409 when already sent); a test copy makes no file (409).
The collection date is the receipt's date, at the earliest the TARGET2 business day after the
next one (D-1), rolled forward onto a TARGET2 business day. 422 when a collection cannot be
released (see problems in GET /v1/entities/{entity}/direct-debits) or is no direct debit.
Download the file with GET /v1/payment-exports/{id}/file.
| Required scope | post (admin implies every scope) |
| Idempotency-Key | required |
| Operation id | export_direct_debits_v1_direct_debit_exports_post |
Request body
application/json (required): DirectDebitExportInput
| Field | Type | Required | Description |
|---|---|---|---|
entity |
string | yes | Code (or id) of the entity collecting, e.g. DE01. |
collections |
array of string (uuid) | yes | Ids of the receipts to collect (GET /v1/entities/{entity}/direct-debits): posted, not yet sent, each listed once. (min items 1; max items 5000) |
Example request
curl -X POST "$ERP_URL/v1/direct-debit-exports" \
-H "Authorization: Bearer $ERP_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"collections": [
"3fa85f64-5717-4562-b3fc-2c963f66afa6"
],
"entity": "DE01"
}'
Responses
| Status | Meaning | Body |
|---|---|---|
| 201 | Created | PaymentExportOut |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 409 | The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"entity": "string",
"message_id": "string",
"format": "string",
"filename": "string",
"sha256": "string",
"payment_count": 1,
"control_sum": "string",
"created_by": {},
"created_at": "2026-09-21T09:30:00Z",
"payments": [
"string"
],
"execution_dates": [
{
"payment": "string",
"currency": "string",
"requested": "2026-09-21",
"execution_date": "2026-09-21",
"adjusted": true,
"calendars": [
"string"
],
"convention": "string",
"dataset_version": "string"
}
]
}
GET /v1/entities/{entity}/customers/{party}/mandates
List a customer's SEPA mandates
The customer's SEPA direct debit mandates, newest signature first, each with its status
(pending_approval, active, rejected, revoked, expired after 36 months without a
collection, used for a one-off mandate collected from), the sequence type of its next
collection and any change waiting for a second person. 404 for an unknown customer.
| Required scope | read (admin implies every scope) |
| Operation id | list_mandates_v1_entities__entity__customers__party__mandates_get |
Parameters
| In | Name | Type | Required | Description |
|---|---|---|---|---|
| path | entity |
string | yes | Entity code, e.g. CH01 (GET /v1/entities). |
| path | party |
string | yes | Customer code, e.g. C-DE, or its id. A vendor is not a customer: its statement is GET .../vendors/{party}/statement. |
Example request
curl "$ERP_URL/v1/entities/CH01/customers/C-DE/mandates" \
-H "Authorization: Bearer $ERP_KEY"
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | array of MandateOut |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 404 | The resource does not exist, or belongs to another organization (not_found). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
[
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"entity": "string",
"customer": "string",
"customer_name": "string",
"reference": "string",
"signed_on": "2026-09-21",
"debtor_name": "string",
"iban": "string",
"bic": "string",
"scheme": "B2B",
"recurring": true,
"prenotification_days": 1,
"status": "active",
"first_collected_on": "2026-09-21",
"last_collected_on": "2026-09-21",
"expires_on": "2026-09-21",
"next_sequence": "FNAL",
"amendment": true,
"pending_change": {
"approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"kind": "account",
"iban": null,
"bic": null,
"debtor_name": null,
"requested_by": {}
},
"revoked_on": "2026-09-21",
"created_by": {},
"created_at": "2026-09-21T09:30:00Z"
}
]
POST /v1/entities/{entity}/customers/{party}/mandates
Record a customer's SEPA mandate
Record a SEPA direct debit mandate the customer signed (CORE or B2B, recurring or
one-off). It waits for a second person's approval (POST /v1/approvals/{id}/approve) before
anything is collected under it; agents cannot record mandates (403). Refuses with 409 when the
reference is already used in the entity (in any case), 422 for an invalid reference or IBAN,
an IBAN outside SEPA, or a signature date after today.
| Required scope | draft (admin implies every scope) |
| Idempotency-Key | required |
| Operation id | create_mandate_v1_entities__entity__customers__party__mandates_post |
Parameters
| In | Name | Type | Required | Description |
|---|---|---|---|---|
| path | entity |
string | yes | Entity code, e.g. CH01 (GET /v1/entities). |
| path | party |
string | yes | Customer code, e.g. C-DE, or its id. A vendor is not a customer: its statement is GET .../vendors/{party}/statement. |
Request body
application/json (required): MandateInput
| Field | Type | Required | Description |
|---|---|---|---|
reference |
string | yes | The mandate reference (Mandatsreferenz) the customer signed, unique for the company in any case: 1 to 35 letters, digits or / - ? : ( ) . , ' +, no space. (pattern ^[A-Za-z0-9/?:().,'+\-]{1,35}$) |
signed_on |
string (date) | yes | The day the customer signed the mandate. |
debtor_name |
string or null | The account holder who signed; default the customer's name. (min length 1; max length 140) | |
iban |
string | yes | The IBAN the customer is debited from (SEPA). (max length 42) |
bic |
string or null | BIC of the customer's bank; optional (SEPA). (pattern ^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$) |
|
scheme |
"B2B" | "CORE" |
CORE (SEPA Core, any debtor; 8 weeks' refund right) or B2B (SEPA Business to Business: businesses only, no refund, the debtor's bank must hold the mandate too). (default "CORE") |
|
recurring |
boolean | true: recurring collections (RCUR); false: one collection only (OOFF), after which the mandate is used. (default true) |
|
prenotification_days |
integer | Calendar days the customer is told of a collection before its date (the invoice is the pre-notification). Default 14 (the rulebook); shorter only as agreed with the customer. (min 1; max 60; default 14) |
Example request
curl -X POST "$ERP_URL/v1/entities/CH01/customers/C-DE/mandates" \
-H "Authorization: Bearer $ERP_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"iban": "DE44 5001 0517 5407 3249 31",
"recurring": true,
"reference": "C-HH-2026-01",
"scheme": "B2B",
"signed_on": "2026-01-15"
}'
Responses
| Status | Meaning | Body |
|---|---|---|
| 201 | Created | MandateOut |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 404 | The resource does not exist, or belongs to another organization (not_found). |
ErrorEnvelope |
| 409 | The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"entity": "string",
"customer": "string",
"customer_name": "string",
"reference": "string",
"signed_on": "2026-09-21",
"debtor_name": "string",
"iban": "string",
"bic": "string",
"scheme": "B2B",
"recurring": true,
"prenotification_days": 1,
"status": "active",
"first_collected_on": "2026-09-21",
"last_collected_on": "2026-09-21",
"expires_on": "2026-09-21",
"next_sequence": "FNAL",
"amendment": true,
"pending_change": {
"approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"kind": "account",
"iban": "string",
"bic": "string",
"debtor_name": "string",
"requested_by": {}
},
"revoked_on": "2026-09-21",
"created_by": {},
"created_at": "2026-09-21T09:30:00Z"
}
POST /v1/entities/{entity}/direct-debit-proposals
Suggest invoices to collect by direct debit
Open posted EUR sales invoices of customers with a SEPA mandate that are due by the
collection date, or whose cash discount is still open on it (collected less the discount),
with the mandate and sequence type each is collected under. Nothing is stored; confirm the
reviewed lines with POST /v1/entities/{entity}/direct-debit-runs. skipped lists the
invoices of such customers that cannot be collected on the date, and why (no usable mandate,
the pre-notification too short, not due yet); problems what stops collecting at all (no EUR
bank account with a SEPA creditor identifier, no payments-in-transit account).
| Required scope | read (admin implies every scope) |
| Idempotency-Key | not used |
| Operation id | propose_collections_v1_entities__entity__direct_debit_proposals_post |
Parameters
| In | Name | Type | Required | Description |
|---|---|---|---|---|
| path | entity |
string | yes | Entity code, e.g. CH01 (GET /v1/entities). |
Request body
application/json (required): CollectionCriteria
| Field | Type | Required | Description |
|---|---|---|---|
collection_date |
string (date) | yes | When the money is to be collected (the requested collection date). |
customers |
array of string or null | Only these customers (codes); default all with a mandate. | |
bank_account |
string or null | The EUR bank account collected into (it needs a creditor identifier); default the first EUR bank account that has one. |
Example request
curl -X POST "$ERP_URL/v1/entities/CH01/direct-debit-proposals" \
-H "Authorization: Bearer $ERP_KEY" \
-H "Content-Type: application/json" \
-d '{
"collection_date": "2026-10-20",
"customers": [
"C-HH"
]
}'
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | CollectionProposal |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 404 | The resource does not exist, or belongs to another organization (not_found). |
ErrorEnvelope |
| 409 | The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"entity": "string",
"collection_date": "2026-09-21",
"bank_account": "string",
"creditor_id": "string",
"lines": [
{
"document_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"number": "string",
"customer": "string",
"customer_name": "string",
"document_date": "2026-09-21",
"due_date": "2026-09-21",
"open": "string",
"amount": "string",
"discount": "string",
"mandate_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"mandate_reference": "string",
"scheme": "B2B",
"sequence_type": "FNAL",
"prenotified_on": "2026-09-21"
}
],
"skipped": [
{
"document_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"number": "string",
"customer": "string",
"customer_name": "string",
"open": "string",
"code": "string",
"reason": "string",
"details": {}
}
],
"total": "string",
"problems": [
{
"code": "string",
"message": "string",
"details": {}
}
]
}
POST /v1/entities/{entity}/direct-debit-runs
Collect the invoices of a proposal
Create the receipts of a reviewed proposal, all or none: one per mandate, dated the
collection date and booked on the payments-in-transit account until the bank statement shows
the money, each through the approval policy. 422 when an invoice is not a posted EUR sales
invoice, is listed twice, its customer has no usable mandate or its pre-notification is too
short. Release them with POST /v1/direct-debit-exports.
| Required scope | draft (admin implies every scope) |
| Idempotency-Key | required |
| Operation id | run_collections_v1_entities__entity__direct_debit_runs_post |
Parameters
| In | Name | Type | Required | Description |
|---|---|---|---|---|
| path | entity |
string | yes | Entity code, e.g. CH01 (GET /v1/entities). |
Request body
application/json (required): CollectionRunInput
| Field | Type | Required | Description |
|---|---|---|---|
collection_date |
string (date) | yes | The requested collection date. |
bank_account |
string or null | The EUR bank account collected into (see the proposal). | |
lines |
array of CollectionRunLine |
yes | The invoices to collect, each once. (min items 1; max items 5000) |
Example request
curl -X POST "$ERP_URL/v1/entities/CH01/direct-debit-runs" \
-H "Authorization: Bearer $ERP_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"collection_date": "2026-10-20",
"lines": [
{
"amount": "5000.00",
"document": "INV-2026-000003"
}
]
}'
Responses
| Status | Meaning | Body |
|---|---|---|
| 201 | Created | CollectionRunResult |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 404 | The resource does not exist, or belongs to another organization (not_found). |
ErrorEnvelope |
| 409 | The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"entity": "string",
"collection_date": "2026-09-21",
"collections": [
{
"payment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"customer": "string",
"customer_name": "string",
"mandate_reference": "string",
"sequence_type": "FNAL",
"amount": "string",
"documents": [
"string"
],
"status": "string",
"approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
],
"posted": 1,
"pending_approval": 1
}
GET /v1/entities/{entity}/direct-debits
List direct debit collections
The receipts collected by direct debit, newest first (at most 200): mandate, scheme,
sequence type, collection date, whether the bank booked them, the file they were sent in, and
problems, what stops releasing one now.
| Required scope | read (admin implies every scope) |
| Operation id | list_collections_v1_entities__entity__direct_debits_get |
Parameters
| In | Name | Type | Required | Description |
|---|---|---|---|---|
| path | entity |
string | yes | Entity code, e.g. CH01 (GET /v1/entities). |
| query | sent |
boolean or null | false: not yet in a file; true: sent. Default both. |
Example request
curl "$ERP_URL/v1/entities/CH01/direct-debits" \
-H "Authorization: Bearer $ERP_KEY"
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | array of CollectionRow |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 404 | The resource does not exist, or belongs to another organization (not_found). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
[
{
"payment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"number": "string",
"customer": "string",
"customer_name": "string",
"mandate_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"mandate_reference": "string",
"scheme": "B2B",
"sequence_type": "FNAL",
"collection_date": "2026-09-21",
"amount": "string",
"currency": "string",
"status": "string",
"bank_account": "string",
"bank_status": "executed",
"export": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"message_id": "string",
"created_at": "2026-09-21T09:30:00Z",
"created_by": {}
},
"problems": [
{
"code": "string",
"message": "string",
"details": {}
}
],
"bank_refusal": {
"kind": "rejected",
"code": null,
"text": null,
"source": "string",
"on": "2026-09-21",
"status": "pending_approval"
}
}
]
PUT /v1/mandates/{mandate_id}/account
Change the debtor account of a mandate
The customer's account holder name or BIC apply at once; a new IBAN waits for a second
person (pending_change), and nothing is collected under the mandate meanwhile. Once
approved, the next collection under a used mandate tells the bank of the change. 409 when the
mandate is not active or expired, or a change of it already waits; 403 for an agent.
| Required scope | draft (admin implies every scope) |
| Idempotency-Key | not used |
| Operation id | change_mandate_account_v1_mandates__mandate_id__account_put |
Parameters
| In | Name | Type | Required | Description |
|---|---|---|---|---|
| path | mandate_id |
string (uuid) | yes | Mandate id (GET /v1/entities/{entity}/customers/{party}/mandates). |
Request body
application/json (required): MandateAccountInput
| Field | Type | Required | Description |
|---|---|---|---|
debtor_name |
string or null | The account holder's name. (min length 1; max length 140) | |
iban |
string | yes | The customer's new (or same) IBAN. (max length 42) |
bic |
string or null | BIC of the customer's bank. (pattern ^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$) |
Example request
curl -X PUT "$ERP_URL/v1/mandates/3fa85f64-5717-4562-b3fc-2c963f66afa6/account" \
-H "Authorization: Bearer $ERP_KEY" \
-H "Content-Type: application/json" \
-d '{
"bic": "COBADEFFXXX",
"iban": "DE89 3704 0044 0532 0130 00"
}'
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | MandateOut |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 404 | The resource does not exist, or belongs to another organization (not_found). |
ErrorEnvelope |
| 409 | The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"entity": "string",
"customer": "string",
"customer_name": "string",
"reference": "string",
"signed_on": "2026-09-21",
"debtor_name": "string",
"iban": "string",
"bic": "string",
"scheme": "B2B",
"recurring": true,
"prenotification_days": 1,
"status": "active",
"first_collected_on": "2026-09-21",
"last_collected_on": "2026-09-21",
"expires_on": "2026-09-21",
"next_sequence": "FNAL",
"amendment": true,
"pending_change": {
"approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"kind": "account",
"iban": "string",
"bic": "string",
"debtor_name": "string",
"requested_by": {}
},
"revoked_on": "2026-09-21",
"created_by": {},
"created_at": "2026-09-21T09:30:00Z"
}
POST /v1/mandates/{mandate_id}/revoke
Revoke a mandate
The customer cancelled the mandate: nothing more is collected under it. Collections made already stay; reverse a receipt that is not to be sent. 409 when it is not active or a change of it waits for approval; 403 for an agent.
| Required scope | draft (admin implies every scope) |
| Idempotency-Key | not used |
| Operation id | revoke_mandate_v1_mandates__mandate_id__revoke_post |
Parameters
| In | Name | Type | Required | Description |
|---|---|---|---|---|
| path | mandate_id |
string (uuid) | yes | Mandate id (GET /v1/entities/{entity}/customers/{party}/mandates). |
Example request
curl -X POST "$ERP_URL/v1/mandates/3fa85f64-5717-4562-b3fc-2c963f66afa6/revoke" \
-H "Authorization: Bearer $ERP_KEY"
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 | OK | MandateOut |
| 401 | Missing or invalid API key (unauthorized). |
ErrorEnvelope |
| 403 | The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). |
ErrorEnvelope |
| 404 | The resource does not exist, or belongs to another organization (not_found). |
ErrorEnvelope |
| 409 | The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). |
ErrorEnvelope |
| 422 | Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. |
HTTPValidationError |
Example response (shape)
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"entity": "string",
"customer": "string",
"customer_name": "string",
"reference": "string",
"signed_on": "2026-09-21",
"debtor_name": "string",
"iban": "string",
"bic": "string",
"scheme": "B2B",
"recurring": true,
"prenotification_days": 1,
"status": "active",
"first_collected_on": "2026-09-21",
"last_collected_on": "2026-09-21",
"expires_on": "2026-09-21",
"next_sequence": "FNAL",
"amendment": true,
"pending_change": {
"approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"kind": "account",
"iban": "string",
"bic": "string",
"debtor_name": "string",
"requested_by": {}
},
"revoked_on": "2026-09-21",
"created_by": {},
"created_at": "2026-09-21T09:30:00Z"
}
Schemas
CollectionCriteria
| Field | Type | Required | Description |
|---|---|---|---|
collection_date |
string (date) | yes | When the money is to be collected (the requested collection date). |
customers |
array of string or null | Only these customers (codes); default all with a mandate. | |
bank_account |
string or null | The EUR bank account collected into (it needs a creditor identifier); default the first EUR bank account that has one. |
CollectionLine
| Field | Type | Required | Description |
|---|---|---|---|
document_id |
string (uuid) | yes | Id of the invoice. |
number |
string | yes | Invoice number. |
customer |
string | yes | Customer code. |
customer_name |
string | yes | Customer name. |
document_date |
string (date) | yes | Invoice date. |
due_date |
string (date) | yes | Due date. |
open |
string | yes | Open amount in EUR. |
amount |
string | yes | Amount to collect: the open amount less the discount. |
discount |
string | yes | Cash discount (Skonto) taken: the invoice's terms, when the collection date is within its discount period. |
mandate_id |
string (uuid) | yes | The mandate collected under. |
mandate_reference |
string | yes | Its reference. |
scheme |
"B2B" | "CORE" |
yes | CORE or B2B. |
sequence_type |
"FNAL" | "FRST" | "OOFF" | "RCUR" |
yes | RCUR or OOFF. |
prenotified_on |
string (date) | yes | The day the customer was told of the collection: the invoice date. |
CollectionProposal
| Field | Type | Required | Description |
|---|---|---|---|
entity |
string | yes | Code of the entity. |
collection_date |
string (date) | yes | The requested collection date. |
bank_account |
string or null | yes | The bank account collected into. |
creditor_id |
string or null | yes | Its SEPA creditor identifier. |
lines |
array of CollectionLine |
yes | The invoices proposed: due by the collection date, or within their cash discount period. |
skipped |
array of SkippedInvoice |
yes | Invoices due of customers with a mandate that are not proposed, and why. |
total |
string | yes | Sum of the amounts proposed. |
problems |
array of BlockerOut |
yes | What stops collecting at all (no account with a creditor identifier). |
CollectionRow
| Field | Type | Required | Description |
|---|---|---|---|
payment_id |
string (uuid) | yes | Id of the receipt. |
number |
string or null | yes | Receipt number: the end-to-end id in the file. |
customer |
string | yes | Customer code. |
customer_name |
string | yes | Customer name. |
mandate_id |
string (uuid) | yes | The mandate. |
mandate_reference |
string | yes | Its reference. |
scheme |
"B2B" | "CORE" |
yes | CORE or B2B. |
sequence_type |
"FNAL" | "FRST" | "OOFF" | "RCUR" |
yes | RCUR or OOFF. |
collection_date |
string (date) | yes | Requested collection date (receipt date). |
amount |
string | yes | Amount. |
currency |
string | yes | Always EUR. |
status |
string | yes | Receipt status: posted, pending_approval, reversed. |
bank_account |
string | yes | The bank account collected into. |
bank_status |
"executed" | "in_transit" or null |
yes | in_transit until a bank line shows the money arrived, then executed. |
export |
ExportInfo or null |
yes | The pain.008 file it was sent in, if any. |
problems |
array of BlockerOut |
yes | What stops releasing it now. |
bank_refusal |
BankRefusal or null |
When the bank rejected it or the debtor's bank returned it. |
CollectionRunInput
| Field | Type | Required | Description |
|---|---|---|---|
collection_date |
string (date) | yes | The requested collection date. |
bank_account |
string or null | The EUR bank account collected into (see the proposal). | |
lines |
array of CollectionRunLine |
yes | The invoices to collect, each once. (min items 1; max items 5000) |
CollectionRunLine
| Field | Type | Required | Description |
|---|---|---|---|
document |
string | yes | Invoice id or number. |
amount |
decimal string | yes | Amount to collect, at most the open amount. (greater than 0) |
discount |
decimal string | Cash discount taken (see the proposal): only within the invoice's discount period, at most its terms. (min 0; default "0") |
CollectionRunResult
| Field | Type | Required | Description |
|---|---|---|---|
entity |
string | yes | Code of the entity. |
collection_date |
string (date) | yes | The requested collection date. |
collections |
array of RunCollection |
yes | One receipt per mandate. |
posted |
integer | yes | How many are posted. |
pending_approval |
integer | yes | How many wait for approval. |
DirectDebitExportInput
| Field | Type | Required | Description |
|---|---|---|---|
entity |
string | yes | Code (or id) of the entity collecting, e.g. DE01. |
collections |
array of string (uuid) | yes | Ids of the receipts to collect (GET /v1/entities/{entity}/direct-debits): posted, not yet sent, each listed once. (min items 1; max items 5000) |
MandateAccountInput
| Field | Type | Required | Description |
|---|---|---|---|
debtor_name |
string or null | The account holder's name. (min length 1; max length 140) | |
iban |
string | yes | The customer's new (or same) IBAN. (max length 42) |
bic |
string or null | BIC of the customer's bank. (pattern ^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$) |
MandateChange
| Field | Type | Required | Description |
|---|---|---|---|
approval_id |
string (uuid) | yes | The approval request a second person decides. |
kind |
"account" | "new" |
yes | new: the mandate itself waits; account: a new IBAN of the debtor. |
iban |
string or null | The proposed IBAN of an account change. | |
bic |
string or null | The proposed BIC. | |
debtor_name |
string or null | The proposed account holder. | |
requested_by |
object | yes | Who asked. |
MandateInput
| Field | Type | Required | Description |
|---|---|---|---|
reference |
string | yes | The mandate reference (Mandatsreferenz) the customer signed, unique for the company in any case: 1 to 35 letters, digits or / - ? : ( ) . , ' +, no space. (pattern ^[A-Za-z0-9/?:().,'+\-]{1,35}$) |
signed_on |
string (date) | yes | The day the customer signed the mandate. |
debtor_name |
string or null | The account holder who signed; default the customer's name. (min length 1; max length 140) | |
iban |
string | yes | The IBAN the customer is debited from (SEPA). (max length 42) |
bic |
string or null | BIC of the customer's bank; optional (SEPA). (pattern ^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$) |
|
scheme |
"B2B" | "CORE" |
CORE (SEPA Core, any debtor; 8 weeks' refund right) or B2B (SEPA Business to Business: businesses only, no refund, the debtor's bank must hold the mandate too). (default "CORE") |
|
recurring |
boolean | true: recurring collections (RCUR); false: one collection only (OOFF), after which the mandate is used. (default true) |
|
prenotification_days |
integer | Calendar days the customer is told of a collection before its date (the invoice is the pre-notification). Default 14 (the rulebook); shorter only as agreed with the customer. (min 1; max 60; default 14) |
MandateOut
| Field | Type | Required | Description |
|---|---|---|---|
id |
string (uuid) | yes | Id of the mandate. |
entity |
string | yes | Code of the entity collecting. |
customer |
string | yes | Code of the customer. |
customer_name |
string | yes | Name of the customer. |
reference |
string | yes | The mandate reference. |
signed_on |
string (date) | yes | Date of signature. |
debtor_name |
string | yes | The account holder who signed. |
iban |
string | yes | The IBAN debited. |
bic |
string or null | yes | BIC of the debtor's bank. |
scheme |
"B2B" | "CORE" |
yes | CORE or B2B. |
recurring |
boolean | yes | Recurring (RCUR) or one-off (OOFF). |
prenotification_days |
integer | yes | Days of pre-notification. |
status |
"active" | "expired" | "pending_approval" | "rejected" | "revoked" | "used" |
yes | pending_approval (a second person decides), active, rejected, revoked, expired (no collection for 36 months, the rulebook) or used (a one-off mandate collected once). |
first_collected_on |
string (date) or null | yes | Date of the first collection sent. |
last_collected_on |
string (date) or null | yes | Date of the last collection sent. |
expires_on |
string (date) or null | yes | The day it expires unless collected from before: 36 months after the last collection, or the signature when it was never used; null when it ended otherwise. |
next_sequence |
"FNAL" | "FRST" | "OOFF" | "RCUR" or null |
yes | The sequence type of its next collection (RCUR or OOFF); null when it cannot be collected from. |
amendment |
boolean | yes | true when the debtor's account changed after a collection: the next collection tells the bank (AmdmntInd). |
pending_change |
MandateChange or null |
yes | What waits for a second person's approval, if anything. |
revoked_on |
string (date) or null | yes | When it was revoked. |
created_by |
object | yes | Who recorded it. |
created_at |
string (date-time) | yes | When it was recorded (UTC). |
RunCollection
| Field | Type | Required | Description |
|---|---|---|---|
payment_id |
string (uuid) | yes | Id of the receipt created. |
customer |
string | yes | Customer code. |
customer_name |
string | yes | Customer name. |
mandate_reference |
string | yes | The mandate collected under. |
sequence_type |
"FNAL" | "FRST" | "OOFF" | "RCUR" |
yes | RCUR or OOFF. |
amount |
string | yes | Amount collected. |
documents |
array of string | yes | Invoice numbers settled. |
status |
string | yes | posted or pending_approval. |
approval_id |
string (uuid) or null | When it waits for approval. |
SkippedInvoice
| Field | Type | Required | Description |
|---|---|---|---|
document_id |
string (uuid) | yes | Id of the invoice. |
number |
string | yes | Invoice number. |
customer |
string | yes | Customer code. |
customer_name |
string | yes | Customer name. |
open |
string | yes | Open amount. |
code |
string | yes | Why it is not proposed, as an error code. |
reason |
string | yes | Why, in plain English. |
details |
object | The values named. |