API reference · 2026-10-15-github-archives-release
Accounting
Buchhaltung mit organisationsgebundener Aktivierung, fachlichen Mandantenrechten, signierten Ereignissen und einer getrennten synthetischen Testumgebung.
Availability: Limited
Current service status ↗Versioned guides and examples
Published local documents for revision 2026-10-15-github-archives-release. SDK guidance describes
integration options; no external SDK download is implied.
Overview · overview.md
# Accounting — Produktion
Maschinenzugriffe sind zusätzlich an einen fachlichen Mandanten gebunden. Beträge werden als exakte Dezimalstrings in Minor Units behandelt; Buchungsentwürfe bleiben bis zum expliziten Buchen ungebucht.
Quelle: devacc-api Commit 9725d58f26c058ae422b48b86be9029e61fe6bae, api/openapi.yaml. Diese Dokumentation und der gefilterte OpenAPI-Vertrag sind unveränderliche Snapshots. Quellqualifikation bedeutet keine bestätigte Live-Verfügbarkeit.
Die jeweils andere Umgebung benötigt eigene Clients, Grants, Daten und Signaturschlüssel. OAuth-Issuer: https://auth.d0.eu; Ressource: https://api.d0.eu/accounting. Maschine: Client Credentials mit private_key_jwt und DPoP. Signaturschlüssel bleiben ausschließlich im Serverprozess.
Lokale Mitgliedschaftsrechte umfassen `audit.read`; eine Berechtigungsmenge kann bis zu neun eindeutige Grants enthalten. Die Maschinen-OAuth-Scopes bleiben getrennt von diesen fachlichen Mandantenrechten.
Quickstart · quickstart.md
# Accounting: Produktion in vier Schritten
1. Produkt und Organisationsberechtigung in der Console prüfen. Für Produktion einen eigenen Maschinenclient in d0-auth registrieren; nur die unten genannten Scopes freigeben.
2. Über `https://auth.d0.eu` ein Access Token für `https://api.d0.eu/accounting` mit `private_key_jwt` und DPoP beziehen. Den DPoP-Proof an genau den Ziel-Request binden; Nonce-Antworten gemäß Auth-Transport behandeln.
3. Mit accounting.access.manage einen Mandanten anlegen oder auswählen. Dessen ten_-Kennung als X-Accounting-Tenant binden, mit accounting.read GET /accounting/v1/accounts prüfen und für Änderungen accounting.write sowie einen stabilen Idempotency-Key verwenden. Mit If-Match nur gegen den zuletzt gelesenen ETag ändern.
4. Nur die im `public-openapi.json` dieser Revision gelisteten Operationen verwenden. Bei 429 die veröffentlichten technischen Limits beachten.
Verfügbare Produktions-Scopes: `accounting.read`, `accounting.write`, `accounting.documents.read`, `accounting.documents.write`, `accounting.periods.close`, `accounting.webhooks.manage`, `accounting.access.manage`, `accounting.exports.read`. Pro Client nur den tatsächlich benötigten Teil beantragen.
Go v0.1.1 ist über den öffentlichen Go-Modul-Proxy installierbar. TypeScript und Python v0.1.1 samt gemeinsamem Auth-Transport sind als geprüfte Archive im [GitHub-Release](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) verfügbar; die genauen Installationsschritte stehen in den SDK-Guides. Die drei Beispiele sind Offline-Fixtures ohne Live-Credentials oder Live-Requests.
Examples · examples/typescript.mjs
import { AccountingClient, resourceFor } from "../dist/index.js";
const suffix = "9GXQ8W5V4R3P2N1M0KJHGF7ED6";
for (const profile of ["production", "test"]) {
const transport = { async request(target, options) {
if (!String(target).startsWith(resourceFor(profile) + "/v1/")) throw new Error("profile crossover");
const path = new URL(target).pathname;
const input = JSON.parse(options.body);
let response;
if (path.endsWith("/accounts")) response = { id: "acct_" + suffix, accountNo: input.accountNo, name: input.name, createdAt: "2026-01-01T00:00:00Z" };
else if (path.endsWith("/periods")) response = { id: "per_" + suffix, ...input, status: "open", createdAt: "2026-01-01T00:00:00Z" };
else if (path.endsWith("/journal-entries")) {
if (input.lines.length !== 2 || input.lines[0].amount.amount !== input.lines[1].amount.amount || input.lines[0].side !== "debit" || input.lines[1].side !== "credit") throw new Error("unbalanced fixture");
response = { id: "je_" + suffix, status: "draft", ...input, createdAt: "2026-01-01T00:00:00Z" };
} else throw new Error("unexpected fixture operation");
return new Response(JSON.stringify(response), { status: 201, headers: { "Content-Type": "application/json" } });
} };
const sdk = new AccountingClient(profile, "ten_" + suffix, transport);
const debit = await sdk.createAccount({ idempotencyKey: "fixture-account-00001", body: { accountNo: "1200", name: "Bank" } });
const credit = await sdk.createAccount({ idempotencyKey: "fixture-account-00002", body: { accountNo: "4000", name: "Revenue" } });
const period = await sdk.createPeriod({ idempotencyKey: "fixture-period-00001", body: { label: "2026-01", startsOn: "2026-01-01", endsOn: "2026-01-31" } });
const draft = await sdk.createJournalEntryDraft({ idempotencyKey: "fixture-draft-000001", body: { periodId: period.id, bookingDate: "2026-01-15", currency: "EUR", lines: [
{ accountId: debit.id, side: "debit", amount: { amount: "150000", currency: "EUR" } },
{ accountId: credit.id, side: "credit", amount: { amount: "150000", currency: "EUR" } },
] } });
process.stdout.write(`${profile}: balanced unposted draft ${draft.id}\n`);
}
Examples · examples/go.go
package main
import (
"fmt"
"log"
accounting "github.com/dev-null-GmbH/d0-sdk/accounting/go"
"github.com/dev-null-GmbH/d0-sdk/accounting/go/fixture"
)
func main() {
for _, profile := range []accounting.Profile{accounting.Production, accounting.Test} {
id, err := fixture.Run(profile)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s: balanced unposted draft %s\n", profile, id)
}
}
Examples · examples/python.py
"""Standalone offline balanced draft example; never sends a network request."""
import io
import json
from email.message import Message
from typing import Any
from d0_auth_machine import MachineClient
from d0_accounting import AccountingClient, resource_for
SUFFIX = "9GXQ8W5V4R3P2N1M0KJHGF7ED6"
TENANT = "ten_" + SUFFIX
class Response(io.BytesIO):
def __init__(self, status: int, body: dict[str, Any]):
super().__init__(json.dumps(body).encode())
self.status = status
self.headers = Message()
self.headers["Content-Type"] = "application/json"
self.headers["ETag"] = '"fixture-v1"'
class FakeMachine(MachineClient):
def __init__(self, profile: str):
self.resource = resource_for(profile) # type: ignore[arg-type]
def request(self, url: str, *, method: str = "GET", headers: Any = None, body: Any = None, cancel: Any = None, timeout: float = 45.0) -> Any:
assert url.startswith(self.resource + "/v1/")
headers = dict(headers or {})
assert headers["X-Accounting-Tenant"] == TENANT
payload = json.loads(body) if body else {}
if url.endswith("/accounts") and method == "POST":
return Response(201, {"id": "acct_" + SUFFIX[:-1] + ("6" if payload["accountNo"] == "1200" else "7"), "accountNo": payload["accountNo"], "name": payload["name"], "createdAt": "2026-01-01T00:00:00Z"})
if url.endswith("/periods") and method == "POST":
return Response(201, {"id": "per_" + SUFFIX, **payload, "status": "open", "createdAt": "2026-01-01T00:00:00Z"})
if url.endswith("/journal-entries") and method == "POST":
lines = payload["lines"]
assert [line["amount"]["amount"] for line in lines] == ["150000", "150000"]
assert [line["side"] for line in lines] == ["debit", "credit"]
return Response(201, {"id": "je_" + SUFFIX, "status": "draft", **payload, "createdAt": "2026-01-01T00:00:00Z"})
raise AssertionError("unexpected fixture route")
for profile in ("production", "test"):
client = AccountingClient(profile, TENANT, FakeMachine(profile)) # type: ignore[arg-type]
debit = client.create_account({"idempotencyKey": "fixture-account-00001", "body": {"accountNo": "1200", "name": "Bank"}})
credit = client.create_account({"idempotencyKey": "fixture-account-00002", "body": {"accountNo": "4000", "name": "Revenue"}})
period = client.create_period({"idempotencyKey": "fixture-period-00001", "body": {"label": "2026-01", "startsOn": "2026-01-01", "endsOn": "2026-01-31"}})
draft = client.create_journal_entry_draft({"idempotencyKey": "fixture-draft-000001", "body": {"periodId": period["id"], "bookingDate": "2026-01-15", "currency": "EUR", "lines": [
{"accountId": debit["id"], "side": "debit", "amount": {"amount": "150000", "currency": "EUR"}},
{"accountId": credit["id"], "side": "credit", "amount": {"amount": "150000", "currency": "EUR"}},
]}})
assert draft["id"] == "je_" + SUFFIX and draft["status"] == "draft"
print(f"{profile}: balanced unposted draft {draft['id']}")
Error catalog · errors.md
# Accounting — Fehler und Wiederholung
Der genaue Fehlerkörper und die operationellen Antworten stehen in `public-openapi.json`. In den öffentlichen Operationen dieser Revision sind die Statuscodes `200`, `201`, `202`, `204`, `400`, `401`, `403`, `404`, `409`, `410`, `412`, `413`, `422`, `428`, `502`, `503`, `default` deklariert. Nicht jeder Code gilt für jede Operation.
- `400`/`422`: Eingabe und geforderte Header gegen die konkrete Operation prüfen; keinen veränderten Request unter demselben Idempotency-Key wiederholen.
- `401`: Token, DPoP-Proof, Nonce, Audience und Clientprofil prüfen.
- `403`: Scope, Organisationsrolle und fachliche Zuordnung prüfen; keine breiteren Scopes erraten.
- `404`: Pfad, Ressource und Tenant-Kontext prüfen; keine Existenz fremder Ressourcen ableiten.
- `409`/`412`: Konflikt bzw. ETag-Vorbedingung durch erneutes Lesen und fachliche Entscheidung auflösen.
- `429`: technische Limitantwort und Reset-/Retry-Hinweis beachten.
- `5xx` oder Transportabbruch: Bei Mutationen denselben vom Aufrufer vergebenen Idempotency-Key verwenden, sofern die Operation ihn vorsieht; sonst erst den serverseitigen Zustand lesen. Keine blinde Wiederholung einer nicht-idempotenten Operation.
Problemantworten und Request-ID helfen bei der Diagnose. Keine Tokens, Schlüssel, Dokumentinhalte oder personenbezogenen Daten in Support-Logs kopieren.
Changelog · CHANGELOG.md
# Accounting 2026-10-15-github-archives-release
- Neue unveränderliche Dokumentationsrevision. Die vorige Revision `2026-10-15-go-011-release` bleibt bytegleich verfügbar; Quell-OpenAPI, öffentlicher Vertrag und klassifizierte Operationen sind unverändert.
- Das [GitHub-Release](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) stellt die geprüften TypeScript-Tarballs und Python-Wheels für accounting v0.1.1 sowie den Auth-Transport v0.1.0 bereit. Der ZIP-Hash ist `6c11b63a5ce5f24dff79d1f3d33c7879ff48831d66dd9029b37abf073152dd93`; der innere `SHA256SUMS`-Katalog wird vor Installation geprüft. Go v0.1.1 bleibt über den öffentlichen Modul-Proxy verfügbar.
- npm und PyPI sind keine Voraussetzungen für diese Distribution. Die installierten Offline-Beispiele wurden im Release-Build geprüft; Service-Rollout und SDK-Download sind getrennte Nachweise.
SDK guidance · sdk-typescript.md
# Accounting typescript SDK
Paket: `@dev-null-gmbh/accounting` v0.1.1, Auth-Transport `@dev-null-gmbh/auth-machine` v0.1.0. MIT-Lizenz; Node.js 24.21 bis unter 27.
Die [qualifizierte GitHub-Release-Datei](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) ist die direkte Distribution. Archiv und Prüfsumme herunterladen, dann äußere und innere SHA-256-Werte prüfen (unter Linux kann `sha256sum -c` statt `shasum -a 256 -c` verwendet werden):
```sh
curl -fLO https://github.com/dev-null-GmbH/d0-sdk/releases/download/sdk-2026-10-15/d0-sdk-2026-10-15.zip
curl -fLO https://github.com/dev-null-GmbH/d0-sdk/releases/download/sdk-2026-10-15/d0-sdk-2026-10-15.sha256
shasum -a 256 -c d0-sdk-2026-10-15.sha256
unzip d0-sdk-2026-10-15.zip -d d0-sdk-2026-10-15
(cd d0-sdk-2026-10-15 && shasum -a 256 -c SHA256SUMS)
```
Der äußere ZIP-Hash lautet `6c11b63a5ce5f24dff79d1f3d33c7879ff48831d66dd9029b37abf073152dd93`. Die Archive stammen aus [dem erfolgreichen Main-Build](https://github.com/dev-null-GmbH/d0-sdk/actions/runs/38748901791) bei `d0-sdk@6f2c39612a661ec557e96e5caff093a057e6e1de`. Das Release enthält SDKs und Auth-Transport, keine privaten Services oder Zugangsdaten.
Die beiden geprüften Tarballs lokal im Serverprojekt installieren (keine npm-Registry-Veröffentlichung erforderlich):
```sh
npm install --ignore-scripts --no-audit --no-fund ./d0-sdk-2026-10-15/npm/dev-null-gmbh-auth-machine-0.1.0.tgz ./d0-sdk-2026-10-15/npm/dev-null-gmbh-accounting-0.1.1.tgz
```
Das Offline-Beispiel dieser Revision liegt unter `catalog/v1/bundles/accounting/2026-10-15-github-archives-release/examples/typescript.mjs`. Das Paket ist für vertrauenswürdige Serveranwendungen gedacht; private Signaturschlüssel gehören nicht in Browser-Code. Öffentliche Operationen und Scopes stehen in `public-openapi.json`.
SDK guidance · sdk-go.md
# Accounting Go SDK
Paket: `github.com/dev-null-GmbH/d0-sdk/accounting/go` v0.1.1. Gemeinsamer Maschinen-Auth-Transport: `github.com/dev-null-GmbH/d0-sdk/auth/go` v0.1.0. Beide wurden über den öffentlichen Go-Modul-Proxy mit aktiver Checksum-Datenbank aus frischer, anonymer Umgebung installiert und geprüft. Lizenz: MIT.
```sh
go get github.com/dev-null-GmbH/d0-sdk/accounting/go@v0.1.1
```
Modul-Tag: `accounting/go/v0.1.1` auf `d0-sdk@8a56e28666be2321f5f73b6a9ce328fbac0b2155`; Auth-Tag: `auth/go/v0.1.0` (unverändert). Der API-Quellvertrag ist `devacc-api@9725d58f26c058ae422b48b86be9029e61fe6bae:api/openapi.yaml`. Go v0.1.0 bleibt unter seinem eigenen Tag als historische Version installierbar.
Das unveränderte Offline-Fixture aus `devacc-api@9725d58f26c058ae422b48b86be9029e61fe6bae:sdk/go/examples/fixture/main.go` liegt unter `catalog/v1/bundles/accounting/2026-10-15-github-archives-release/examples/go.go` (SHA-256 `9db5b8cd981728a67d65a3cf315fdff6b875caf5eb2034be0ce317cfe1497bb5`). Es demonstriert den Client mit festem production-Profil ohne Netzaufruf. Öffentliche Operationen und Scopes stehen ausschließlich in public-openapi.json.
Die übrigen Sprachpakete sind über das [geprüfte GitHub-Release](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) verfügbar. Go benötigt nur den oben gezeigten Modulbezug über den öffentlichen Proxy.
SDK guidance · sdk-python.md
# Accounting python SDK
Paket: `d0-accounting` v0.1.1, Auth-Transport `d0-auth-machine` v0.1.0. MIT-Lizenz; Python 3.14.
Die [qualifizierte GitHub-Release-Datei](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) ist die direkte Distribution. Archiv und Prüfsumme herunterladen, dann äußere und innere SHA-256-Werte prüfen (unter Linux kann `sha256sum -c` statt `shasum -a 256 -c` verwendet werden):
```sh
curl -fLO https://github.com/dev-null-GmbH/d0-sdk/releases/download/sdk-2026-10-15/d0-sdk-2026-10-15.zip
curl -fLO https://github.com/dev-null-GmbH/d0-sdk/releases/download/sdk-2026-10-15/d0-sdk-2026-10-15.sha256
shasum -a 256 -c d0-sdk-2026-10-15.sha256
unzip d0-sdk-2026-10-15.zip -d d0-sdk-2026-10-15
(cd d0-sdk-2026-10-15 && shasum -a 256 -c SHA256SUMS)
```
Der äußere ZIP-Hash lautet `6c11b63a5ce5f24dff79d1f3d33c7879ff48831d66dd9029b37abf073152dd93`. Die Archive stammen aus [dem erfolgreichen Main-Build](https://github.com/dev-null-GmbH/d0-sdk/actions/runs/38748901791) bei `d0-sdk@6f2c39612a661ec557e96e5caff093a057e6e1de`. Das Release enthält SDKs und Auth-Transport, keine privaten Services oder Zugangsdaten.
Die beiden geprüften Wheels in einer virtuellen Umgebung installieren (keine PyPI-Veröffentlichung erforderlich):
```sh
python3.14 -m venv .venv
.venv/bin/python -m pip install ./d0-sdk-2026-10-15/python/d0_auth_machine-0.1.0-py3-none-any.whl ./d0-sdk-2026-10-15/python/d0_accounting-0.1.1-py3-none-any.whl
```
Das Offline-Beispiel dieser Revision liegt unter `catalog/v1/bundles/accounting/2026-10-15-github-archives-release/examples/python.py`. Das Paket ist für vertrauenswürdige Serveranwendungen gedacht; private Signaturschlüssel gehören nicht in Browser-Code. Öffentliche Operationen und Scopes stehen in `public-openapi.json`.
Get started
- Accounting in der Console mit der eigenen Organisation verbinden und aktivieren.
- Die fachliche Mandantenzuordnung und die benötigten Rechte für die Integration vergeben.
- Maschinenclient in d0-auth für Accounting registrieren und private_key_jwt mit DPoP verwenden.
- Mit X-Accounting-Tenant und GET /accounting/v1/accounts den Zugriff prüfen.
Operations
Implemented rows describe supported contract behavior. Product availability above still controls whether the runtime is open to customers. Declared and blocked rows describe contract intent or a release gate.
| Method | Path | Operation | Readiness |
|---|---|---|---|
| GET | /tax-rules | listTaxRules | Implemented |
| POST | /tax-calculations | calculateTax | Implemented |
| GET | /reports/financial-statements | getFinancialStatements | Implemented |
| GET | /fiscal-years | listFiscalYears | Implemented |
| POST | /fiscal-years | createFiscalYear | Implemented |
| GET | /fiscal-years/{yearId} | getFiscalYear | Implemented |
| POST | /fiscal-years/{yearId}/finalize | finalizeFiscalYear | Implemented |
| POST | /fiscal-years/{yearId}/close | closeFiscalYear | Implemented |
| POST | /fiscal-years/{yearId}/carryforward | carryforwardFiscalYear | Implemented |
| GET | /reports/trial-balance | getTrialBalance | Implemented |
| GET | /account-mappings | listAccountMappings | Implemented |
| POST | /account-mappings | publishAccountMapping | Implemented |
| GET | /account-mappings/{mappingId} | getAccountMapping | Implemented |
| POST | /accounts/{accountId}/retire | retireAccount | Implemented |
| GET | /exports/tenant | downloadTenantExport | Implemented |
| GET | /tenants | listTenants | Implemented |
| POST | /tenants | createTenant | Implemented |
| GET | /tenants/{tenantId}/memberships | listMemberships | Implemented |
| POST | /tenants/{tenantId}/memberships | createMembership | Implemented |
| PUT | /tenants/{tenantId}/memberships/{membershipId} | replaceMembership | Implemented |
| GET | /accounts | listAccounts | Implemented |
| POST | /accounts | createAccount | Implemented |
| GET | /accounts/{accountId} | getAccount | Implemented |
| GET | /accounts/{accountId}/statement | getAccountStatement | Implemented |
| GET | /accounts/{accountId}/balances | getAccountBalances | Implemented |
| GET | /periods | listPeriods | Implemented |
| POST | /periods | createPeriod | Implemented |
| GET | /periods/{periodId} | getPeriod | Implemented |
| POST | /periods/{periodId}/festschreiben | festschreibenPeriod | Implemented |
| GET | /journal-entries | listJournalEntries | Implemented |
| POST | /journal-entries | createJournalEntryDraft | Implemented |
| GET | /journal-entries/{entryId} | getJournalEntry | Implemented |
| PUT | /journal-entries/{entryId} | replaceJournalEntryDraft | Implemented |
| DELETE | /journal-entries/{entryId} | discardJournalEntryDraft | Implemented |
| POST | /journal-entries/{entryId}/post | postJournalEntry | Implemented |
| POST | /journal-entries/{entryId}/reverse | reverseJournalEntry | Implemented |
| POST | /journal-entries/{entryId}/documents/{documentId} | linkJournalEntryDocument | Implemented |
| GET | /documents | listDocuments | Implemented |
| POST | /documents | createDocument | Implemented |
| GET | /documents/{documentId}/sources | listDocumentSources | Implemented |
| GET | /documents/{documentId} | getDocument | Implemented |
| GET | /documents/{documentId}/content | downloadDocument | Implemented |
| POST | /documents/{documentId}/upload-requests | createDocumentUploadRequest | Implemented |
| POST | /documents/{documentId}/complete | completeDocument | Implemented |
| POST | /documents/{documentId}/preservation-requests | createDocumentPreservation | Implemented |
| GET | /document-preservation-requests/{preservationId} | getDocumentPreservation | Implemented |
| POST | /documents/{documentId}/e-invoice-validations | createEInvoiceValidation | Implemented |
| GET | /e-invoice-validations/{validationId} | getEInvoiceValidation | Implemented |
| POST | /e-invoice-validations/{validationId}/zugferd-pdfs | createZUGFeRDPDF | Implemented |
| GET | /zugferd-pdfs/{zugferdPdfId} | getZUGFeRDPDF | Implemented |
| GET | /webhook-endpoints | listWebhookEndpoints | Implemented |
| POST | /webhook-endpoints | createWebhookEndpoint | Implemented |
| GET | /webhook-endpoints/{webhookEndpointId} | getWebhookEndpoint | Implemented |
| PUT | /webhook-endpoints/{webhookEndpointId} | replaceWebhookEndpoint | Implemented |
| DELETE | /webhook-endpoints/{webhookEndpointId} | deleteWebhookEndpoint | Implemented |
| PUT | /webhook-endpoints/{webhookEndpointId}/secret | rotateWebhookEndpointSecret | Implemented |
Operation reference
Parameters, request bodies and responses come from the filtered public OpenAPI contract
for this revision. Required fields are marked in each schema’s required array.
56 of 56 operations
GET /account-mappingsList immutable account mapping revisions
Returns published mapping revisions in ascending version order for this tenant.
Parameters
limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
Mapping identifier returned as nextCursor by the previous page.
{
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
}Responses
200 · application/json
Mapping revisions in version order.
Required fields: data
{
"description": "Mapping revision identities in ascending version order.",
"type": "object",
"required": [
"data"
],
"additionalProperties": false,
"properties": {
"data": {
"type": "array",
"items": {
"description": "Published revision identity and content digest.",
"type": "object",
"required": [
"id",
"version",
"digest",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
},
"version": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"digest": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}
},
"nextCursor": {
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /account-mappingsPublish an immutable account classification
Freezes explicit consumer classifications and account labels for reproducible reports. Every reportCode must have one classification and name.
Parameters
Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: items
{
"description": "Complete classification revision, subject also to the global mutation body byte limit.",
"type": "object",
"required": [
"items"
],
"additionalProperties": false,
"properties": {
"items": {
"type": "array",
"minItems": 1,
"maxItems": 10000,
"items": {
"description": "Consumer-selected classification and report section for one account.",
"type": "object",
"required": [
"accountId",
"classification",
"reportCode",
"reportName"
],
"additionalProperties": false,
"properties": {
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"classification": {
"description": "Explicit consumer classification for financial reporting.",
"type": "string",
"enum": [
"asset",
"liability",
"equity",
"income",
"expense"
]
},
"reportCode": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"reportName": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
}
}
}
}
} Responses
201 · application/json
Immutable mapping revision.
Required fields: id, version, digest, createdAt, items
{
"description": "A complete immutable tenant-owned account mapping.",
"type": "object",
"required": [
"id",
"version",
"digest",
"createdAt",
"items"
],
"additionalProperties": false,
"properties": {
"id": {
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
},
"version": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"digest": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"items": {
"type": "array",
"items": {
"description": "Immutable classification and account labels frozen at publication.",
"type": "object",
"required": [
"accountId",
"accountNo",
"accountName",
"classification",
"reportCode",
"reportName"
],
"additionalProperties": false,
"properties": {
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string"
},
"accountName": {
"type": "string"
},
"classification": {
"description": "Explicit consumer classification for financial reporting.",
"type": "string",
"enum": [
"asset",
"liability",
"equity",
"income",
"expense"
]
},
"reportCode": {
"type": "string"
},
"reportName": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /account-mappings/{mappingId}Fetch an immutable account mapping
Returns the complete frozen mapping if it belongs to this tenant.
Parameters
mappingId · path · required
Opaque tenant-owned account mapping revision identifier.
{
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
}Responses
200 · application/json
Immutable mapping revision with its complete account items.
Required fields: id, version, digest, createdAt, items
{
"description": "A complete immutable tenant-owned account mapping.",
"type": "object",
"required": [
"id",
"version",
"digest",
"createdAt",
"items"
],
"additionalProperties": false,
"properties": {
"id": {
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
},
"version": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"digest": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"items": {
"type": "array",
"items": {
"description": "Immutable classification and account labels frozen at publication.",
"type": "object",
"required": [
"accountId",
"accountNo",
"accountName",
"classification",
"reportCode",
"reportName"
],
"additionalProperties": false,
"properties": {
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string"
},
"accountName": {
"type": "string"
},
"classification": {
"description": "Explicit consumer classification for financial reporting.",
"type": "string",
"enum": [
"asset",
"liability",
"equity",
"income",
"expense"
]
},
"reportCode": {
"type": "string"
},
"reportName": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /accountsList accounts
Accounts of the calling tenant, ordered by Kontonummer.
Parameters
limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
Return items after this account — the `nextCursor` of the previous page.
{
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
A page of accounts.
Required fields: data
{
"type": "object",
"description": "One page of accounts, oldest Kontonummer first.",
"required": [
"data"
],
"additionalProperties": false,
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"description": "A Konto in the tenant's chart of accounts.",
"required": [
"id",
"accountNo",
"name",
"createdAt"
],
"additionalProperties": false,
"properties": {
"retiredAt": {
"description": "Retirement prevents new ordinary postings; historical Storno remains available.",
"type": [
"string",
"null"
],
"format": "date-time"
},
"id": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "Kontonummer within the tenant's chart of accounts.",
"examples": [
"1200"
]
},
"name": {
"type": "string",
"examples": [
"Bank"
]
},
"accountType": {
"type": [
"string",
"null"
],
"description": "Optional account classification supplied by the consumer."
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}
},
"nextCursor": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /accountsCreate an account
Adds a Konto to the tenant's chart of accounts. `accountNo` is unique per tenant; creating a duplicate is `409 account-already-exists`.
Parameters
Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: accountNo, name
{
"type": "object",
"description": "Fields accepted when adding a Konto.",
"required": [
"accountNo",
"name"
],
"additionalProperties": false,
"properties": {
"accountNo": {
"type": "string",
"minLength": 1,
"maxLength": 32,
"examples": [
"1200"
]
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"examples": [
"Bank"
]
},
"accountType": {
"type": [
"string",
"null"
],
"maxLength": 64
}
}
} Responses
201 · application/json
The created account.
Required fields: id, accountNo, name, createdAt
{
"type": "object",
"description": "A Konto in the tenant's chart of accounts.",
"required": [
"id",
"accountNo",
"name",
"createdAt"
],
"additionalProperties": false,
"properties": {
"retiredAt": {
"description": "Retirement prevents new ordinary postings; historical Storno remains available.",
"type": [
"string",
"null"
],
"format": "date-time"
},
"id": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "Kontonummer within the tenant's chart of accounts.",
"examples": [
"1200"
]
},
"name": {
"type": "string",
"examples": [
"Bank"
]
},
"accountType": {
"type": [
"string",
"null"
],
"description": "Optional account classification supplied by the consumer."
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /accounts/{accountId}Fetch one account
Returns the account if it belongs to the calling tenant, else 404.
Parameters
accountId · path · required
Identifier of the account, as returned when it was created.
{
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
The account.
Required fields: id, accountNo, name, createdAt
{
"type": "object",
"description": "A Konto in the tenant's chart of accounts.",
"required": [
"id",
"accountNo",
"name",
"createdAt"
],
"additionalProperties": false,
"properties": {
"retiredAt": {
"description": "Retirement prevents new ordinary postings; historical Storno remains available.",
"type": [
"string",
"null"
],
"format": "date-time"
},
"id": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "Kontonummer within the tenant's chart of accounts.",
"examples": [
"1200"
]
},
"name": {
"type": "string",
"examples": [
"Bank"
]
},
"accountType": {
"type": [
"string",
"null"
],
"description": "Optional account classification supplied by the consumer."
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /accounts/{accountId}/balancesRead exact account totals and balances by currency
Requires accounting.read. Only posted lines contribute, including Storno through their normal opposite sides. Uses the same asOf cutoff and inclusive date/currency filters as the account statement. Omitted asOf captures the latest committed tenant-wide posted entry; reuse the returned value to keep subsequent reads fixed. Unknown, foreign or draft snapshots are 400 invalid-snapshot. The literal empty always returns an empty ledger view. openingBalance is debit minus credit strictly before bookingDateFrom, or zero without a lower bound. debitTotal and creditTotal cover the selected date range. closingBalance is openingBalance plus debitTotal minus creditTotal. Positive balances mean debit; negative balances mean credit, independently of account type. This is cumulative posted history, not a fiscal-year opening or carry-forward operation. Currencies are never mixed or converted and results are ordered by currency code. With no currency filter, returns currencies with posted activity through bookingDateTo (including opening history); otherwise an unused currency returns one zero row. A wholly unused account has data: [] without a currency filter. All returned totals must fit signed int64 minor units; any overflow, including gross debit/credit totals with a representable net, fails the whole response with 422 balance-overflow. No rounded or partial totals are returned.
Parameters
accountId · path · required
Identifier of the account, as returned when it was created.
{
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}asOf · query
Inclusive posted-entry cutoff; omit for latest, or reuse a prior response's asOf.
{
"type": "string",
"description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
"pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
"examples": [
"empty"
]
}currency · query
Restrict to one currency without conversion; omit to include each separately.
{
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}bookingDateFrom · query
Inclusive earliest booking date for movements; earlier history forms openingBalance.
{
"type": "string",
"format": "date"
}bookingDateTo · query
Inclusive latest booking date; must not precede bookingDateFrom.
{
"type": "string",
"format": "date"
}Responses
200 · application/json
Exact totals per currency at the returned posting snapshot.
Required fields: accountId, asOf, data
{
"type": "object",
"description": "Per-currency balances at a fixed posting cutoff; no currency conversion.",
"required": [
"accountId",
"asOf",
"data"
],
"additionalProperties": false,
"properties": {
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"asOf": {
"type": "string",
"description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
"pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
"examples": [
"empty"
]
},
"data": {
"type": "array",
"items": {
"type": "object",
"description": "Exact debit/credit totals and signed balances in one currency.",
"required": [
"currency",
"openingBalance",
"debitTotal",
"creditTotal",
"closingBalance"
],
"additionalProperties": false,
"properties": {
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"openingBalance": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"debitTotal": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"creditTotal": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"closingBalance": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
}
}
}
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /accounts/{accountId}/retireRetire an account for future ordinary postings
Retirement is irreversible and serializes with posting. Historical reads and exact Storno remain available; fresh-key retirement retries preserve the original timestamp.
Parameters
accountId · path · required
Identifier of the account, as returned when it was created.
{
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Responses
200 · application/json
Retired account (stable on repeated retirement).
Required fields: id, accountNo, name, createdAt
{
"type": "object",
"description": "A Konto in the tenant's chart of accounts.",
"required": [
"id",
"accountNo",
"name",
"createdAt"
],
"additionalProperties": false,
"properties": {
"retiredAt": {
"description": "Retirement prevents new ordinary postings; historical Storno remains available.",
"type": [
"string",
"null"
],
"format": "date-time"
},
"id": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "Kontonummer within the tenant's chart of accounts.",
"examples": [
"1200"
]
},
"name": {
"type": "string",
"examples": [
"Bank"
]
},
"accountType": {
"type": [
"string",
"null"
],
"description": "Optional account classification supplied by the consumer."
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /accounts/{accountId}/statementRead a posted Kontoblatt at a fixed booking state
Requires accounting.read. Returns individual posted lines for this account in ascending Buchungsnummer (seq), then lineNo order. Drafts are excluded. Multiple lines in the same Buchung remain distinct. Date bounds are inclusive; currency filters never convert amounts. accountNo is the frozen number as booked, not current chart metadata. Follow entryId to the journal entry or GET /documents?journalEntryId={entryId} for its immutable Beleg links; document reads require documents.read separately. Without asOf, captures the latest committed tenant-wide posted entry. The response's asOf can be reused across statements and balances. Later posts, including backdated entries, newly posted old drafts and later Storno, are excluded. This freezes posted evidence, not mutable chart data or a complete tenant export. The literal empty fixes an empty ledger even after later posts. Pass nextCursor as after and keep date/currency filters unchanged. The cursor carries the original snapshot, so asOf may be omitted on subsequent pages. An explicit conflicting asOf or a malformed, foreign or nonmatching cursor is 400 invalid-cursor. Unknown, foreign or draft asOf entries are 400 invalid-snapshot. Any committed posted entry can define a historical cutoff, even if it belongs to another account or currency in this tenant.
Parameters
accountId · path · required
Identifier of the account, as returned when it was created.
{
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}asOf · query
Inclusive posted-entry cutoff; omit for latest, or reuse a prior response's asOf.
{
"type": "string",
"description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
"pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
"examples": [
"empty"
]
}currency · query
Restrict to one currency without conversion; omit to include each separately.
{
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}bookingDateFrom · query
Inclusive earliest booking date for movements; earlier history forms openingBalance.
{
"type": "string",
"format": "date"
}bookingDateTo · query
Inclusive latest booking date; must not precede bookingDateFrom.
{
"type": "string",
"format": "date"
}after · query
Opaque nextCursor from this account and the same date/currency filters.
{
"type": "string",
"description": "Opaque position including the posting snapshot; pass unchanged as after.",
"maxLength": 73,
"examples": [
"v1:je_9GXQ8W5V4R3P2N1M0KJHGF7ED6:je_9GXQ8W5V4R3P2N1M0KJHGF7ED6:1"
]
}Responses
200 · application/json
A page of immutable posted account movements.
Required fields: accountId, asOf, data
{
"type": "object",
"description": "A bounded page of posted lines at one stable booking cutoff.",
"required": [
"accountId",
"asOf",
"data"
],
"additionalProperties": false,
"properties": {
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"asOf": {
"type": "string",
"description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
"pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
"examples": [
"empty"
]
},
"data": {
"type": "array",
"items": {
"type": "object",
"description": "One immutable posted line for the requested account.",
"required": [
"entryId",
"seq",
"lineNo",
"bookingDate",
"periodId",
"accountNo",
"side",
"amount",
"taxKey"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"entryId": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"seq": {
"type": "integer",
"format": "int64",
"minimum": 1,
"description": "The Buchungsnummer shared by every line in this entry."
},
"lineNo": {
"type": "integer",
"minimum": 1,
"description": "Original position in the journal entry, not a page offset."
},
"bookingDate": {
"type": "string",
"format": "date"
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "Frozen Kontonummer as booked."
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
]
},
"reversalOf": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}
}
}
},
"nextCursor": {
"type": "string",
"description": "Opaque position including the posting snapshot; pass unchanged as after.",
"maxLength": 73,
"examples": [
"v1:je_9GXQ8W5V4R3P2N1M0KJHGF7ED6:je_9GXQ8W5V4R3P2N1M0KJHGF7ED6:1"
]
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /document-preservation-requests/{preservationId}Fetch a preservation decision and its confirmed application state
Requires documents.read. The request and actor attribution are immutable. appliedAt and observed protection are present only after exact-version storage verification. A completed observation is historical evidence, not a live storage availability probe. Storage coordinates and credentials are not exposed.
Parameters
preservationId · path · required
Identifier of the durable document preservation request.
{
"type": "string",
"description": "Opaque durable preservation-request identifier.",
"pattern": "^prsv_[0-9A-HJKMNP-TV-Z]{26}$"
}Responses
200 · application/json
The tenant-visible request and its application state.
Required fields: id, documentId, requestedBy, requestedAt, reason, legalHold, status
{
"description": "An immutable preservation decision and its durable execution status.",
"type": "object",
"required": [
"id",
"documentId",
"requestedBy",
"requestedAt",
"reason",
"legalHold",
"status"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable preservation-request identifier.",
"pattern": "^prsv_[0-9A-HJKMNP-TV-Z]{26}$"
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"requestedBy": {
"type": "string",
"description": "Opaque public membership identifier.",
"pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"reason": {
"type": "string",
"minLength": 1,
"maxLength": 1000
},
"retainUntil": {
"type": "string",
"format": "date-time",
"description": "Requested exclusive retention deadline, absent for a hold-only request."
},
"legalHold": {
"type": "boolean",
"description": "True requests a legal hold ON. False does not request any hold change."
},
"status": {
"type": "string",
"enum": [
"pending",
"applied"
],
"x-enum-varnames": [
"DocumentPreservationStatusPending",
"DocumentPreservationStatusApplied"
]
},
"nextAttemptAt": {
"type": "string",
"format": "date-time",
"description": "Earliest scheduled retry after a storage or verification failure."
},
"failureCode": {
"type": "string",
"enum": [
"archive-unavailable",
"source-integrity-mismatch",
"protection-unconfirmed"
],
"description": "Last retry reason. No provider errors or storage coordinates are exposed."
},
"appliedAt": {
"type": "string",
"format": "date-time",
"description": "Time confirmed protection was committed to the audit record."
},
"observedRetainUntil": {
"type": "string",
"format": "date-time",
"description": "Confirmed COMPLIANCE deadline, at least the requested protection."
},
"observedLegalHold": {
"type": "boolean",
"description": "Legal hold observed when the request was applied."
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /documentsList Belege and generated documents
Requires documents.read. Returns public metadata in ascending immutable document-ID order, independent of Belegdatum. Omitted filters include all documents; provided filters combine with AND. Date bounds are inclusive. journalEntryId selects direct links to a Buchung (including inherited Storno links), without exposing journal data. sourceDocumentId selects direct generated outputs, never transitive descendants. Unknown or foreign relationship IDs are 404; an existing resource with no matches gives an empty page. Read each output's sources to inspect source roles. Pass nextCursor as after with unchanged filters. The cursor must name a document in this tenant, even if it no longer matches the filters; malformed, unknown and foreign cursors are 400 invalid-cursor. Pagination is not a snapshot: concurrent commits and pending-to-archived transitions may change membership. Documents that become eligible before the cursor are not revisited; restart traversal to discover them. Unchanged data is traversed without skips or duplicates.
Parameters
limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
The nextCursor from the previous page.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}status · query
Restrict to pending or archived documents.
{
"type": "string",
"description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
"enum": [
"pending",
"archived"
]
}origin · query
Restrict to uploaded originals or generated derivatives.
{
"type": "string",
"description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
"enum": [
"uploaded",
"derived"
]
}documentDateFrom · query
Inclusive earliest Belegdatum.
{
"type": "string",
"format": "date"
}documentDateTo · query
Inclusive latest Belegdatum; must not precede documentDateFrom.
{
"type": "string",
"format": "date"
}journalEntryId · query
Only documents directly linked to this tenant's Buchung.
{
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}sourceDocumentId · query
Only direct derivatives of this tenant's source document.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
A page of public document metadata.
Required fields: data
{
"type": "object",
"description": "One page in immutable document-ID order; not a snapshot across requests.",
"required": [
"data"
],
"additionalProperties": false,
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"description": "Public metadata for an immutable Beleg declaration.",
"required": [
"id",
"origin",
"status",
"originalFilename",
"mediaType",
"sizeBytes",
"contentSha256",
"documentDate",
"classification",
"retentionUntil",
"createdAt",
"archivedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"origin": {
"type": "string",
"description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
"enum": [
"uploaded",
"derived"
]
},
"status": {
"type": "string",
"description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
"enum": [
"pending",
"archived"
]
},
"originalFilename": {
"type": "string"
},
"mediaType": {
"type": "string"
},
"sizeBytes": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"contentSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"documentDate": {
"type": "string",
"format": "date"
},
"classification": {
"type": "string",
"description": "Trusted server-assigned Beleg class; never caller-selected."
},
"retentionUntil": {
"type": "string",
"format": "date",
"description": "Inclusive legal retention date selected by the server."
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"archivedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}
},
"nextCursor": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /documentsDeclare an immutable Buchungsbeleg upload
Creates a pending Buchungsbeleg and returns a short-lived, create-only PUT request for a direct upload. The checksum, exact byte length, media type, and COMPLIANCE Object Lock retention are all covered by the signature. `classification`, storage identity, retention policy, and retention horizon are server-owned. This public workflow always creates `buchungsbeleg`.
Parameters
Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: originalFilename, mediaType, sizeBytes, contentSha256, documentDate
{
"type": "object",
"description": "Caller-known immutable metadata for a Buchungsbeleg upload.",
"required": [
"originalFilename",
"mediaType",
"sizeBytes",
"contentSha256",
"documentDate"
],
"additionalProperties": false,
"properties": {
"originalFilename": {
"type": "string",
"minLength": 1,
"description": "A UTF-8 basename of at most 255 bytes, never a path.",
"examples": [
"rechnung-2026-0042.pdf"
]
},
"mediaType": {
"type": "string",
"minLength": 3,
"description": "Canonical media type covered by the upload signature, at most 255\nUTF-8 bytes.\n",
"examples": [
"application/pdf"
]
},
"sizeBytes": {
"type": "integer",
"format": "int64",
"minimum": 1,
"description": "Exact content length in bytes.",
"examples": [
48192
]
},
"contentSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$",
"description": "Exact SHA-256 digest in canonical lowercase hexadecimal.",
"examples": [
"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
]
},
"documentDate": {
"type": "string",
"format": "date",
"description": "Belegdatum used to select the versioned retention policy."
}
}
} Responses
201 · application/json
The pending Beleg and its first direct-upload request.
Required fields: document, upload
{
"type": "object",
"description": "A pending Beleg plus its first direct-upload request.",
"required": [
"document",
"upload"
],
"additionalProperties": false,
"properties": {
"document": {
"type": "object",
"description": "Public metadata for an immutable Beleg declaration.",
"required": [
"id",
"origin",
"status",
"originalFilename",
"mediaType",
"sizeBytes",
"contentSha256",
"documentDate",
"classification",
"retentionUntil",
"createdAt",
"archivedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"origin": {
"type": "string",
"description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
"enum": [
"uploaded",
"derived"
]
},
"status": {
"type": "string",
"description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
"enum": [
"pending",
"archived"
]
},
"originalFilename": {
"type": "string"
},
"mediaType": {
"type": "string"
},
"sizeBytes": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"contentSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"documentDate": {
"type": "string",
"format": "date"
},
"classification": {
"type": "string",
"description": "Trusted server-assigned Beleg class; never caller-selected."
},
"retentionUntil": {
"type": "string",
"format": "date",
"description": "Inclusive legal retention date selected by the server."
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"archivedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
"upload": {
"type": "object",
"description": "Short-lived exact HTTP request for a direct immutable upload.",
"required": [
"url",
"method",
"headers",
"expiresAt"
],
"additionalProperties": false,
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "Signed destination. Treat it as a secret until it expires."
},
"method": {
"type": "string",
"const": "PUT"
},
"headers": {
"type": "object",
"description": "Every header must be sent with the exact returned value.",
"additionalProperties": {
"type": "string"
}
},
"expiresAt": {
"type": "string",
"format": "date-time"
}
}
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /documents/{documentId}Fetch one Beleg
Returns public lifecycle and declaration metadata. Storage keys, immutable object version ids, actor ids, and internal database ids are never exposed.
Parameters
documentId · path · required
Identifier of the Beleg.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
The Beleg.
Required fields: id, origin, status, originalFilename, mediaType, sizeBytes, contentSha256, documentDate, classification, retentionUntil, createdAt, archivedAt
{
"type": "object",
"description": "Public metadata for an immutable Beleg declaration.",
"required": [
"id",
"origin",
"status",
"originalFilename",
"mediaType",
"sizeBytes",
"contentSha256",
"documentDate",
"classification",
"retentionUntil",
"createdAt",
"archivedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"origin": {
"type": "string",
"description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
"enum": [
"uploaded",
"derived"
]
},
"status": {
"type": "string",
"description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
"enum": [
"pending",
"archived"
]
},
"originalFilename": {
"type": "string"
},
"mediaType": {
"type": "string"
},
"sizeBytes": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"contentSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"documentDate": {
"type": "string",
"format": "date"
},
"classification": {
"type": "string",
"description": "Trusted server-assigned Beleg class; never caller-selected."
},
"retentionUntil": {
"type": "string",
"format": "date",
"description": "Inclusive legal retention date selected by the server."
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"archivedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /documents/{documentId}/completeVerify and archive an uploaded Beleg
Verifies the exact immutable object version, checksum, length, media type, and COMPLIANCE retention before atomically sealing the Beleg. Retrying the same completed upload is safe.
Parameters
documentId · path · required
Identifier of the Beleg.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Responses
200 · application/json
The archived Beleg.
Required fields: id, origin, status, originalFilename, mediaType, sizeBytes, contentSha256, documentDate, classification, retentionUntil, createdAt, archivedAt
{
"type": "object",
"description": "Public metadata for an immutable Beleg declaration.",
"required": [
"id",
"origin",
"status",
"originalFilename",
"mediaType",
"sizeBytes",
"contentSha256",
"documentDate",
"classification",
"retentionUntil",
"createdAt",
"archivedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"origin": {
"type": "string",
"description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
"enum": [
"uploaded",
"derived"
]
},
"status": {
"type": "string",
"description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
"enum": [
"pending",
"archived"
]
},
"originalFilename": {
"type": "string"
},
"mediaType": {
"type": "string"
},
"sizeBytes": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"contentSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"documentDate": {
"type": "string",
"format": "date"
},
"classification": {
"type": "string",
"description": "Trusted server-assigned Beleg class; never caller-selected."
},
"retentionUntil": {
"type": "string",
"format": "date",
"description": "Inclusive legal retention date selected by the server."
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"archivedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /documents/{documentId}/contentDownload the original archived Beleg
Requires documents.read and an archived Beleg visible to the tenant. Returns the complete original bytes from the recorded immutable object version after verifying length and SHA-256. No storage coordinates or download credentials are disclosed. Partial and conditional requests are not supported; Range and conditional headers do not select another result. Pending documents and a deletion in progress return 409. A confirmed original deletion returns 410; document metadata and the disposition receipt remain available. Missing or unavailable archive objects return 503; inconsistent archive bytes or metadata return 502 before any file bytes are sent. Clients should verify Content-Digest and Content-Length as well.
Parameters
documentId · path · required
Identifier of the Beleg.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/octet-stream
The verified original bytes, downloaded as an attachment.
{
"type": "string",
"format": "binary"
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}410 · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}502 · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}503 · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /documents/{documentId}/e-invoice-validationsQueue validation of an archived XML e-invoice
Creates one durable validation request for the exact immutable object version sealed into the archived Beleg. The service submits those bytes to the standalone compliance platform under a deployment-pinned validation policy, then copies the verified exact result into its own immutable GoBD archive before publishing completion. Processing is asynchronous; poll the resource named by `Location` until its status is `completed` or `failed`. A completed validation with `result.valid: false` is a successful validation outcome, not a processing failure. Only archived `application/xml` Belege up to 20 MiB (20,971,520 bytes) are accepted. The source bytes and storage identity are never exposed by this operation.
Parameters
documentId · path · required
Identifier of the Beleg.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Responses
202 · application/json
The validation was durably queued, or an exact idempotent replay.
{
"description": "Durable validation state. Branch on `status` before reading terminal\nfields: `pending` has neither result nor failure, `completed` has exactly\none result, and `failed` has exactly one public failure code.\n",
"oneOf": [
{
"type": "object",
"description": "A durable validation waiting for processing or a retry.",
"required": [
"id",
"documentId",
"status",
"requestedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"const": "pending",
"x-enum-varnames": [
"EInvoiceValidationPendingStatusPending"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
}
}
},
{
"type": "object",
"description": "A terminal validation, whether the invoice is valid or invalid.",
"required": [
"id",
"documentId",
"status",
"requestedAt",
"completedAt",
"result"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"const": "completed",
"x-enum-varnames": [
"EInvoiceValidationCompletedStatusCompleted"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"result": {
"type": "object",
"description": "Terminal result for the exact archived source. Validator and ruleset\nversions are opaque identities reported under the pinned standalone-platform\npolicy, never guessed by this service.\n",
"required": [
"schema",
"sourceSha256",
"valid",
"syntax",
"validator",
"ruleset",
"issues"
],
"additionalProperties": false,
"properties": {
"schema": {
"type": "string",
"const": "devacc.einvoice.validation.v1",
"x-enum-varnames": [
"EInvoiceValidationResultSchemaV1"
]
},
"sourceSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$",
"description": "SHA-256 of the exact immutable source version that was validated."
},
"valid": {
"type": "boolean",
"description": "False is a completed validation outcome, not a processing error."
},
"syntax": {
"type": "string",
"enum": [
"ubl",
"cii",
"unknown"
],
"x-enum-varnames": [
"EInvoiceValidationSyntaxUBL",
"EInvoiceValidationSyntaxCII",
"EInvoiceValidationSyntaxUnknown"
],
"description": "Canonical syntax classification. `valid: true` is only possible for\n`ubl` or `cii`; `unknown` is retained only for invalid outcomes.\n"
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 2048,
"description": "Optional non-empty profile identity of at most 2,048 UTF-8 bytes."
},
"validator": {
"type": "object",
"description": "Opaque processor runtime or versioned compliance-artifact identity.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty identity of at most 256 UTF-8 bytes."
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty opaque version of at most 256 UTF-8 bytes."
}
}
},
"ruleset": {
"type": "object",
"description": "Opaque processor runtime or versioned compliance-artifact identity.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty identity of at most 256 UTF-8 bytes."
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty opaque version of at most 256 UTF-8 bytes."
}
}
},
"issues": {
"type": "array",
"maxItems": 1000,
"items": {
"type": "object",
"description": "One structured validator finding.",
"required": [
"severity",
"code",
"message"
],
"additionalProperties": false,
"properties": {
"severity": {
"type": "string",
"enum": [
"error",
"warning",
"information"
],
"x-enum-varnames": [
"EInvoiceValidationIssueSeverityError",
"EInvoiceValidationIssueSeverityWarning",
"EInvoiceValidationIssueSeverityInformation"
]
},
"code": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty stable finding code of at most 256 UTF-8 bytes."
},
"message": {
"type": "string",
"minLength": 1,
"maxLength": 8192,
"description": "Non-empty finding text of at most 8,192 UTF-8 bytes."
},
"location": {
"type": "string",
"minLength": 1,
"maxLength": 8192,
"description": "Optional non-empty source location of at most 8,192 UTF-8 bytes."
}
}
}
}
}
}
}
},
{
"type": "object",
"description": "A terminal validation processing failure without sensitive diagnostics.",
"required": [
"id",
"documentId",
"status",
"requestedAt",
"completedAt",
"failure"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"const": "failed",
"x-enum-varnames": [
"EInvoiceValidationFailedStatusFailed"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"failure": {
"type": "object",
"description": "Stable public failure classification; internal diagnostics are private.",
"required": [
"code"
],
"additionalProperties": false,
"properties": {
"code": {
"type": "string",
"const": "validation-processing-failed",
"x-enum-varnames": [
"EInvoiceValidationFailureCodeValidationProcessingFailed"
]
}
}
}
}
}
],
"discriminator": {
"propertyName": "status",
"mapping": {
"pending": "#/components/schemas/EInvoiceValidationPending",
"completed": "#/components/schemas/EInvoiceValidationCompleted",
"failed": "#/components/schemas/EInvoiceValidationFailed"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /documents/{documentId}/preservation-requestsRequest stronger preservation of an archived Beleg
Requires documents.write. Records the requesting actor, reason and requested protection without changing the original Beleg evidence. Requests may extend COMPLIANCE retention, set a legal hold ON, or both. Shortening, hold release and deletion are not supported. An extension must exceed the original storage deadline and every previously accepted extension for this Beleg. A 202 response confirms durable acceptance only. Poll the returned resource; applied means the worker has verified the requested protection on the original immutable object version. Storage outages leave the request pending for retry. Replaying the same Idempotency-Key returns the original acceptance response; use GET for current state. The retentionUntil on the original Document remains its initial, immutable policy evidence.
Parameters
documentId · path · required
Identifier of the Beleg.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: reason
{
"type": "object",
"required": [
"reason"
],
"minProperties": 2,
"additionalProperties": false,
"description": "Supply retainUntil, legalHold=true, or both, with a nonblank reason without\nleading or trailing whitespace. retainUntil is an exclusive whole-second\nUTC deadline, in the future and later than all accepted retention decisions.\nTo preserve through a calendar day, use the following day's UTC midnight.\n",
"properties": {
"reason": {
"type": "string",
"minLength": 1,
"maxLength": 1000
},
"retainUntil": {
"type": "string",
"format": "date-time",
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-]00:00)$"
},
"legalHold": {
"type": "boolean",
"const": true
}
}
} Responses
202 · application/json
The durable preservation request, awaiting storage confirmation.
Required fields: id, documentId, requestedBy, requestedAt, reason, legalHold, status
{
"description": "An immutable preservation decision and its durable execution status.",
"type": "object",
"required": [
"id",
"documentId",
"requestedBy",
"requestedAt",
"reason",
"legalHold",
"status"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable preservation-request identifier.",
"pattern": "^prsv_[0-9A-HJKMNP-TV-Z]{26}$"
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"requestedBy": {
"type": "string",
"description": "Opaque public membership identifier.",
"pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"reason": {
"type": "string",
"minLength": 1,
"maxLength": 1000
},
"retainUntil": {
"type": "string",
"format": "date-time",
"description": "Requested exclusive retention deadline, absent for a hold-only request."
},
"legalHold": {
"type": "boolean",
"description": "True requests a legal hold ON. False does not request any hold change."
},
"status": {
"type": "string",
"enum": [
"pending",
"applied"
],
"x-enum-varnames": [
"DocumentPreservationStatusPending",
"DocumentPreservationStatusApplied"
]
},
"nextAttemptAt": {
"type": "string",
"format": "date-time",
"description": "Earliest scheduled retry after a storage or verification failure."
},
"failureCode": {
"type": "string",
"enum": [
"archive-unavailable",
"source-integrity-mismatch",
"protection-unconfirmed"
],
"description": "Last retry reason. No provider errors or storage coordinates are exposed."
},
"appliedAt": {
"type": "string",
"format": "date-time",
"description": "Time confirmed protection was committed to the audit record."
},
"observedRetainUntil": {
"type": "string",
"format": "date-time",
"description": "Confirmed COMPLIANCE deadline, at least the requested protection."
},
"observedLegalHold": {
"type": "boolean",
"description": "Legal hold observed when the request was applied."
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /documents/{documentId}/sourcesRead the direct sources of a generated Beleg
Requires documents.read. Returns the immutable direct source references, ordered by role. Uploaded originals return an empty data array. Currently the only derivation kind is zugferd-pdf, with exactly one invoice source and one visual source; this bounded set needs no pagination. Sources are visible as soon as a derived document is declared, including while it is pending. Each documentId can be resolved through GET /documents/{documentId}. Storage keys, object versions and internal identifiers stay private.
Parameters
documentId · path · required
Identifier of the Beleg.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
The complete, bounded set of direct source references.
Required fields: data
{
"type": "object",
"description": "All direct sources; empty for an uploaded original.",
"required": [
"data"
],
"additionalProperties": false,
"properties": {
"data": {
"type": "array",
"maxItems": 2,
"items": {
"type": "object",
"description": "One immutable edge from a generated Beleg to its direct source.",
"required": [
"documentId",
"role",
"kind"
],
"additionalProperties": false,
"properties": {
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"role": {
"type": "string",
"description": "The source's role in generating the output.",
"enum": [
"invoice",
"visual"
]
},
"kind": {
"type": "string",
"description": "The transformation which produced the requested output.",
"enum": [
"zugferd-pdf"
]
}
}
}
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /documents/{documentId}/upload-requestsCreate a fresh upload request for a pending Beleg
Re-signs the pending document's original immutable declaration. Use a fresh `Idempotency-Key` after an earlier signed request expires. An archived Beleg can never receive another upload URL.
Parameters
documentId · path · required
Identifier of the Beleg.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Responses
200 · application/json
A fresh short-lived direct-upload request.
Required fields: url, method, headers, expiresAt
{
"type": "object",
"description": "Short-lived exact HTTP request for a direct immutable upload.",
"required": [
"url",
"method",
"headers",
"expiresAt"
],
"additionalProperties": false,
"properties": {
"url": {
"type": "string",
"format": "uri",
"description": "Signed destination. Treat it as a secret until it expires."
},
"method": {
"type": "string",
"const": "PUT"
},
"headers": {
"type": "object",
"description": "Every header must be sent with the exact returned value.",
"additionalProperties": {
"type": "string"
}
},
"expiresAt": {
"type": "string",
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /e-invoice-validations/{validationId}Fetch one e-invoice validation
Returns the durable validation state if it belongs to the calling tenant, else 404. Terminal validation results include the exact validator and ruleset identities frozen by the standalone compliance platform. A processing failure exposes only a stable public code; internal diagnostics never cross this boundary.
Parameters
validationId · path · required
Identifier of the durable e-invoice validation request.
{
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
The validation request and its current state.
{
"description": "Durable validation state. Branch on `status` before reading terminal\nfields: `pending` has neither result nor failure, `completed` has exactly\none result, and `failed` has exactly one public failure code.\n",
"oneOf": [
{
"type": "object",
"description": "A durable validation waiting for processing or a retry.",
"required": [
"id",
"documentId",
"status",
"requestedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"const": "pending",
"x-enum-varnames": [
"EInvoiceValidationPendingStatusPending"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
}
}
},
{
"type": "object",
"description": "A terminal validation, whether the invoice is valid or invalid.",
"required": [
"id",
"documentId",
"status",
"requestedAt",
"completedAt",
"result"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"const": "completed",
"x-enum-varnames": [
"EInvoiceValidationCompletedStatusCompleted"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"result": {
"type": "object",
"description": "Terminal result for the exact archived source. Validator and ruleset\nversions are opaque identities reported under the pinned standalone-platform\npolicy, never guessed by this service.\n",
"required": [
"schema",
"sourceSha256",
"valid",
"syntax",
"validator",
"ruleset",
"issues"
],
"additionalProperties": false,
"properties": {
"schema": {
"type": "string",
"const": "devacc.einvoice.validation.v1",
"x-enum-varnames": [
"EInvoiceValidationResultSchemaV1"
]
},
"sourceSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$",
"description": "SHA-256 of the exact immutable source version that was validated."
},
"valid": {
"type": "boolean",
"description": "False is a completed validation outcome, not a processing error."
},
"syntax": {
"type": "string",
"enum": [
"ubl",
"cii",
"unknown"
],
"x-enum-varnames": [
"EInvoiceValidationSyntaxUBL",
"EInvoiceValidationSyntaxCII",
"EInvoiceValidationSyntaxUnknown"
],
"description": "Canonical syntax classification. `valid: true` is only possible for\n`ubl` or `cii`; `unknown` is retained only for invalid outcomes.\n"
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 2048,
"description": "Optional non-empty profile identity of at most 2,048 UTF-8 bytes."
},
"validator": {
"type": "object",
"description": "Opaque processor runtime or versioned compliance-artifact identity.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty identity of at most 256 UTF-8 bytes."
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty opaque version of at most 256 UTF-8 bytes."
}
}
},
"ruleset": {
"type": "object",
"description": "Opaque processor runtime or versioned compliance-artifact identity.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty identity of at most 256 UTF-8 bytes."
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty opaque version of at most 256 UTF-8 bytes."
}
}
},
"issues": {
"type": "array",
"maxItems": 1000,
"items": {
"type": "object",
"description": "One structured validator finding.",
"required": [
"severity",
"code",
"message"
],
"additionalProperties": false,
"properties": {
"severity": {
"type": "string",
"enum": [
"error",
"warning",
"information"
],
"x-enum-varnames": [
"EInvoiceValidationIssueSeverityError",
"EInvoiceValidationIssueSeverityWarning",
"EInvoiceValidationIssueSeverityInformation"
]
},
"code": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Non-empty stable finding code of at most 256 UTF-8 bytes."
},
"message": {
"type": "string",
"minLength": 1,
"maxLength": 8192,
"description": "Non-empty finding text of at most 8,192 UTF-8 bytes."
},
"location": {
"type": "string",
"minLength": 1,
"maxLength": 8192,
"description": "Optional non-empty source location of at most 8,192 UTF-8 bytes."
}
}
}
}
}
}
}
},
{
"type": "object",
"description": "A terminal validation processing failure without sensitive diagnostics.",
"required": [
"id",
"documentId",
"status",
"requestedAt",
"completedAt",
"failure"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"const": "failed",
"x-enum-varnames": [
"EInvoiceValidationFailedStatusFailed"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"failure": {
"type": "object",
"description": "Stable public failure classification; internal diagnostics are private.",
"required": [
"code"
],
"additionalProperties": false,
"properties": {
"code": {
"type": "string",
"const": "validation-processing-failed",
"x-enum-varnames": [
"EInvoiceValidationFailureCodeValidationProcessingFailed"
]
}
}
}
}
}
],
"discriminator": {
"propertyName": "status",
"mapping": {
"pending": "#/components/schemas/EInvoiceValidationPending",
"completed": "#/components/schemas/EInvoiceValidationCompleted",
"failed": "#/components/schemas/EInvoiceValidationFailed"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /e-invoice-validations/{validationId}/zugferd-pdfsQueue creation of an immutable ZUGFeRD PDF
Combines the exact CII XML from a completed, valid e-invoice validation with one immutable archived PDF visual source. Processing is durable and asynchronous; poll the resource named by `Location` until it is terminal. The server selects and freezes the ZUGFeRD standard, EN 16931 profile, and generation recipe. The original XML and visual Belege remain independently archived; the output is a new immutable derived Beleg with explicit lineage. UBL-to-CII conversion and visual rendering are deliberately not implicit.
Parameters
validationId · path · required
Identifier of the durable e-invoice validation request.
{
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: visualDocumentId
{
"type": "object",
"description": "The immutable PDF visual source to combine with validated CII XML.",
"required": [
"visualDocumentId"
],
"additionalProperties": false,
"properties": {
"visualDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}
}
} Responses
202 · application/json
The generation was durably queued. An exact Idempotency-Key replay returns its originally stored response; the same semantic request under a new key returns the already existing durable resource in its current state, which may already be terminal.
{
"description": "Durable ZUGFeRD PDF state. Pending has neither result nor failure;\ncompleted has the new immutable output Beleg and exact generation evidence;\nfailed exposes only a stable public failure code.\n",
"oneOf": [
{
"type": "object",
"description": "A durable generation waiting for processing or a retry.",
"required": [
"id",
"validationId",
"invoiceDocumentId",
"visualDocumentId",
"target",
"recipe",
"status",
"requestedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable ZUGFeRD PDF generation identifier.",
"pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"validationId": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"invoiceDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"visualDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"target": {
"type": "object",
"description": "Frozen standard and profile selected by trusted server configuration.",
"required": [
"name",
"version",
"profile"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"recipe": {
"type": "object",
"description": "Frozen versioned generation recipe selected by trusted server configuration.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"status": {
"type": "string",
"const": "pending",
"x-enum-varnames": [
"ZUGFeRDPDFPendingStatusPending"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
}
}
},
{
"type": "object",
"description": "A terminal generation with immutable output and provenance evidence.",
"required": [
"id",
"validationId",
"invoiceDocumentId",
"visualDocumentId",
"target",
"recipe",
"status",
"requestedAt",
"completedAt",
"outputDocument",
"result"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable ZUGFeRD PDF generation identifier.",
"pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"validationId": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"invoiceDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"visualDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"target": {
"type": "object",
"description": "Frozen standard and profile selected by trusted server configuration.",
"required": [
"name",
"version",
"profile"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"recipe": {
"type": "object",
"description": "Frozen versioned generation recipe selected by trusted server configuration.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"status": {
"type": "string",
"const": "completed",
"x-enum-varnames": [
"ZUGFeRDPDFCompletedStatusCompleted"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"outputDocument": {
"type": "object",
"description": "Public metadata for the completed generation output. This Beleg is always\na newly derived, immutable archived PDF; its exact two-source lineage is\nretained server-side.\n",
"required": [
"id",
"origin",
"status",
"originalFilename",
"mediaType",
"sizeBytes",
"contentSha256",
"documentDate",
"classification",
"retentionUntil",
"createdAt",
"archivedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"origin": {
"type": "string",
"const": "derived",
"x-enum-varnames": [
"ZUGFeRDPDFDocumentOriginDerived"
]
},
"status": {
"type": "string",
"const": "archived",
"x-enum-varnames": [
"ZUGFeRDPDFDocumentStatusArchived"
]
},
"originalFilename": {
"type": "string"
},
"mediaType": {
"type": "string",
"const": "application/pdf",
"x-enum-varnames": [
"ZUGFeRDPDFDocumentMediaTypeApplicationPDF"
]
},
"sizeBytes": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"contentSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"documentDate": {
"type": "string",
"format": "date"
},
"classification": {
"type": "string",
"description": "Trusted server-assigned Beleg class."
},
"retentionUntil": {
"type": "string",
"format": "date"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"archivedAt": {
"type": "string",
"format": "date-time"
}
}
},
"result": {
"type": "object",
"description": "Exact immutable generation evidence reported by the sidecar.",
"required": [
"schema",
"invoiceSha256",
"visualSha256",
"output",
"standard",
"recipe",
"processor",
"ruleset"
],
"additionalProperties": false,
"properties": {
"schema": {
"type": "string",
"const": "devacc.einvoice.zugferd-pdf.v1",
"x-enum-varnames": [
"ZUGFeRDPDFResultSchemaV1"
]
},
"invoiceSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"visualSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"output": {
"type": "object",
"description": "Exact output facts verified before the derived Beleg was archived.",
"required": [
"contentId",
"mediaType",
"sizeBytes",
"sha256",
"pdfConformance",
"embeddedFilename"
],
"additionalProperties": false,
"properties": {
"contentId": {
"type": "string",
"const": "output",
"x-enum-varnames": [
"ZUGFeRDPDFOutputContentIdOutput"
]
},
"mediaType": {
"type": "string",
"const": "application/pdf",
"x-enum-varnames": [
"ZUGFeRDPDFOutputMediaTypeApplicationPDF"
]
},
"sizeBytes": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"pdfConformance": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Conformance identity reported by the configured production sidecar.\nThis API records the evidence but does not independently certify it.\n"
},
"embeddedFilename": {
"type": "string",
"minLength": 1,
"maxLength": 255
}
}
},
"standard": {
"type": "object",
"description": "Frozen standard and profile selected by trusted server configuration.",
"required": [
"name",
"version",
"profile"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"recipe": {
"type": "object",
"description": "Frozen versioned generation recipe selected by trusted server configuration.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"processor": {
"type": "object",
"description": "Opaque ZUGFeRD sidecar runtime or versioned artifact identity.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"ruleset": {
"type": "object",
"description": "Opaque ZUGFeRD sidecar runtime or versioned artifact identity.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
}
}
}
}
},
{
"type": "object",
"description": "A terminal PDF-generation failure without sensitive diagnostics.",
"required": [
"id",
"validationId",
"invoiceDocumentId",
"visualDocumentId",
"target",
"recipe",
"status",
"requestedAt",
"completedAt",
"failure"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable ZUGFeRD PDF generation identifier.",
"pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"validationId": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"invoiceDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"visualDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"target": {
"type": "object",
"description": "Frozen standard and profile selected by trusted server configuration.",
"required": [
"name",
"version",
"profile"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"recipe": {
"type": "object",
"description": "Frozen versioned generation recipe selected by trusted server configuration.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"status": {
"type": "string",
"const": "failed",
"x-enum-varnames": [
"ZUGFeRDPDFFailedStatusFailed"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"failure": {
"type": "object",
"description": "Stable public failure classification without internal diagnostics.",
"required": [
"code"
],
"additionalProperties": false,
"properties": {
"code": {
"type": "string",
"enum": [
"unsupported-source",
"generation-capacity-exceeded"
],
"x-enum-varnames": [
"ZUGFeRDPDFFailureCodeUnsupportedSource",
"ZUGFeRDPDFFailureCodeGenerationCapacityExceeded"
]
}
}
}
}
}
],
"discriminator": {
"propertyName": "status",
"mapping": {
"pending": "#/components/schemas/ZUGFeRDPDFPending",
"completed": "#/components/schemas/ZUGFeRDPDFCompleted",
"failed": "#/components/schemas/ZUGFeRDPDFFailed"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /exports/tenantDownload a complete tenant accounting snapshot
Requires explicit exports.read permission and accounting.exports.read machine scope. Returns a devacc.tenant-export.v1 ZIP containing versioned JSON datasets, a manifest with SHA-256 checksums, and available archived document originals verified against their immutable evidence. Includes discarded drafts, pending declarations, and public archive disposition receipts. A confirmed original deletion retains its document metadata and receipt but excludes its bytes. A deletion in progress returns retryable 409 before ZIP bytes are sent. All metadata comes from one tenant-scoped database snapshot. Original versions are pinned by that snapshot and verified before any ZIP bytes are sent. Stored journal hashes and sequence links are evidence; the public projection does not contain the private canonical hashing payload. The synchronous export is limited to 100000 records, 32 MiB of metadata, 512 MiB of original bytes and two minutes of preparation (the authorization lease may expire sooner). Exceeding a size limit returns 413 export-too-large; no successful truncated export is returned. Unavailable originals return 503 and integrity mismatches return 502. Range and conditional headers do not select a partial result. Verify Content-Length and Content-Digest after download; interruption or authorization expiry may truncate transport.
Responses
200 · application/zip
The complete verified ZIP, downloaded as an attachment.
{
"type": "string",
"format": "binary"
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}413 · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}502 · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}503 · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /fiscal-yearsList fiscal years
Returns fiscal years in start-date order for the calling tenant.
Parameters
limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
Fiscal-year ID returned as nextCursor by the preceding page.
{
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}Responses
200 · application/json
One page of fiscal years.
Required fields: data
{
"type": "object",
"description": "One page of fiscal years.",
"required": [
"data"
],
"additionalProperties": false,
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"description": "Tenant fiscal year and its finalization state.",
"required": [
"id",
"label",
"startsOn",
"endsOn",
"status",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
},
"label": {
"type": "string"
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date"
},
"status": {
"type": "string",
"enum": [
"open",
"finalized"
],
"x-enum-varnames": [
"FiscalYearStatusOpen",
"FiscalYearStatusFinalized"
],
"description": "Finalized years cannot be changed."
},
"finalizedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}
},
"nextCursor": {
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /fiscal-yearsCreate a fiscal year
Creates an open fiscal year with inclusive dates; tenant years cannot overlap.
Parameters
Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: label, startsOn, endsOn
{
"type": "object",
"description": "Inclusive fiscal-year date range chosen by the consumer.",
"required": [
"label",
"startsOn",
"endsOn"
],
"additionalProperties": false,
"properties": {
"label": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date"
}
}
} Responses
201 · application/json
The created fiscal year.
Required fields: id, label, startsOn, endsOn, status, createdAt
{
"type": "object",
"description": "Tenant fiscal year and its finalization state.",
"required": [
"id",
"label",
"startsOn",
"endsOn",
"status",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
},
"label": {
"type": "string"
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date"
},
"status": {
"type": "string",
"enum": [
"open",
"finalized"
],
"x-enum-varnames": [
"FiscalYearStatusOpen",
"FiscalYearStatusFinalized"
],
"description": "Finalized years cannot be changed."
},
"finalizedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /fiscal-years/{yearId}Fetch one fiscal year
Returns one year of the calling tenant.
Parameters
yearId · path · required
Opaque fiscal-year identifier.
{
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}Responses
200 · application/json
The fiscal year.
Required fields: id, label, startsOn, endsOn, status, createdAt
{
"type": "object",
"description": "Tenant fiscal year and its finalization state.",
"required": [
"id",
"label",
"startsOn",
"endsOn",
"status",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
},
"label": {
"type": "string"
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date"
},
"status": {
"type": "string",
"enum": [
"open",
"finalized"
],
"x-enum-varnames": [
"FiscalYearStatusOpen",
"FiscalYearStatusFinalized"
],
"description": "Finalized years cannot be changed."
},
"finalizedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /fiscal-years/{yearId}/carryforwardPost an opening balance into the next fiscal year
Source year must be finalized; target starts on the following day. For one currency, derives source-year posted balances under the selected immutable mapping. Asset, liability and equity balances carry to the same accounts; remaining income and expense net goes to the explicit equity result account. The target year must have no earlier posted entries in that currency. One archived Beleg is attached to the ordinary journal post. A fresh-key retry with identical inputs returns the existing entry; a different transfer for either source or target year conflicts.
Parameters
yearId · path · required
Opaque fiscal-year identifier.
{
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: targetYearId, targetPeriodId, mappingRevisionId, resultAccountId, documentId, currency
{
"type": "object",
"description": "Consumer-selected target and evidence for one-currency opening.",
"required": [
"targetYearId",
"targetPeriodId",
"mappingRevisionId",
"resultAccountId",
"documentId",
"currency"
],
"additionalProperties": false,
"properties": {
"targetYearId": {
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
},
"targetPeriodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"mappingRevisionId": {
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
},
"resultAccountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"currency": {
"type": "string",
"pattern": "^[A-Z]{3}$"
}
}
} Responses
200 · application/json
Posted opening entry or its existing representation.
Required fields: id, periodId, status, bookingDate, currency, lines, createdAt
{
"type": "object",
"description": "A Buchung — a draft, or a posted entry in the hash chain.",
"required": [
"id",
"periodId",
"status",
"bookingDate",
"currency",
"lines",
"createdAt"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"id": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
"enum": [
"draft",
"posted"
]
},
"bookingDate": {
"type": "string",
"format": "date"
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"seq": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
},
"entryHash": {
"type": [
"string",
"null"
],
"description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
"pattern": "^[0-9a-f]{64}$"
},
"reversalOf": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"lines": {
"type": "array",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung as booked.",
"required": [
"lineNo",
"accountId",
"accountNo",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"lineNo": {
"type": "integer",
"description": "Position within the Buchung, starting at 1.",
"minimum": 1
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
]
}
}
}
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"postedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /fiscal-years/{yearId}/closeClose income and expense accounts
Derives every currency's income and expense balance from posted entries inside this year using an immutable caller-selected mapping. Posts inverse lines against an explicit equity result account with one archived Beleg, then seals the closing period in the same transaction. All other periods must already be sealed. If all P&L balances are zero, the period is sealed and entries is empty. A repeat with identical inputs returns the prior result.
Parameters
yearId · path · required
Opaque fiscal-year identifier.
{
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: periodId, mappingRevisionId, resultAccountId, documentId
{
"type": "object",
"description": "Consumer-selected closing classification and evidence.",
"required": [
"periodId",
"mappingRevisionId",
"resultAccountId",
"documentId"
],
"additionalProperties": false,
"properties": {
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"mappingRevisionId": {
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
},
"resultAccountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"documentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}
}
} Responses
200 · application/json
Posted closing entries and sealed period.
Required fields: entries, period
{
"type": "object",
"description": "Closing entries and the sealed period.",
"required": [
"entries",
"period"
],
"additionalProperties": false,
"properties": {
"entries": {
"type": "array",
"items": {
"type": "object",
"description": "A Buchung — a draft, or a posted entry in the hash chain.",
"required": [
"id",
"periodId",
"status",
"bookingDate",
"currency",
"lines",
"createdAt"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"id": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
"enum": [
"draft",
"posted"
]
},
"bookingDate": {
"type": "string",
"format": "date"
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"seq": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
},
"entryHash": {
"type": [
"string",
"null"
],
"description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
"pattern": "^[0-9a-f]{64}$"
},
"reversalOf": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"lines": {
"type": "array",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung as booked.",
"required": [
"lineNo",
"accountId",
"accountNo",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"lineNo": {
"type": "integer",
"description": "Position within the Buchung, starting at 1.",
"minimum": 1
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
]
}
}
}
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"postedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}
},
"period": {
"type": "object",
"description": "An accounting period and its Festschreibung state.",
"required": [
"id",
"label",
"startsOn",
"endsOn",
"status",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"label": {
"type": "string",
"examples": [
"2026-01"
]
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date",
"description": "Inclusive last day of the period."
},
"status": {
"type": "string",
"description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
"enum": [
"open",
"festgeschrieben"
]
},
"festgeschriebenAt": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the period was sealed; null while it is open."
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /fiscal-years/{yearId}/finalizeFinalize a fiscal year
Requires exact coverage by contained, festgeschrieben periods and no unposted drafts in the year. Finalization is irreversible. A fresh-key replay returns the original finalization time. P&L closing is optional; carryforward incorporates any remaining income or expense balance.
Parameters
yearId · path · required
Opaque fiscal-year identifier.
{
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Responses
200 · application/json
The finalized fiscal year.
Required fields: id, label, startsOn, endsOn, status, createdAt
{
"type": "object",
"description": "Tenant fiscal year and its finalization state.",
"required": [
"id",
"label",
"startsOn",
"endsOn",
"status",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
},
"label": {
"type": "string"
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date"
},
"status": {
"type": "string",
"enum": [
"open",
"finalized"
],
"x-enum-varnames": [
"FiscalYearStatusOpen",
"FiscalYearStatusFinalized"
],
"description": "Finalized years cannot be changed."
},
"finalizedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /journal-entriesList journal entries and drafts
Entries of the calling tenant in ascending immutable entry-ID order, independent of booking date and posting sequence. Select `draft` or `posted` explicitly. Date bounds are inclusive and combine with periodId. Optional documentId restricts results to entries directly linked to that Beleg, including Storno entries with inherited links. Requires accounting.read; it returns journal data, not document metadata. Unknown or foreign documentId is 404 document-not-found. The optional externalReference filter uses an exact, case-sensitive match (no wildcards, trimming or Unicode normalization). References are not unique: an original and its Storno share the reference. Keep filters unchanged when passing nextCursor as after. The cursor must identify an entry visible to this tenant, even if it no longer matches the filters; malformed, unknown or foreign cursors are 400 invalid-cursor. Pagination is not a snapshot: concurrent commits and mutable drafts or status transitions can change membership between requests. Entries that become eligible before the cursor are not revisited; restart traversal to rediscover them. Unchanged data is traversed without skips or duplicates.
Parameters
limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
The nextCursor from the previous page.
{
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}status · query · required
Select drafts or posted entries.
{
"type": "string",
"description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
"enum": [
"draft",
"posted"
]
}periodId · query
Restrict to this tenant's accounting period.
{
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}documentId · query
Only entries directly linked to this tenant's Beleg.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}bookingDateFrom · query
Inclusive earliest booking date.
{
"type": "string",
"format": "date"
}bookingDateTo · query
Inclusive latest booking date; must not precede bookingDateFrom.
{
"type": "string",
"format": "date"
}externalReference · query
Exact business reference; combines with all other filters. U+0000 is forbidden.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Responses
200 · application/json
A page of journal entries with their lines.
Required fields: data
{
"type": "object",
"description": "One page in immutable entry-ID order; not a snapshot across requests.",
"required": [
"data"
],
"additionalProperties": false,
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"description": "A Buchung — a draft, or a posted entry in the hash chain.",
"required": [
"id",
"periodId",
"status",
"bookingDate",
"currency",
"lines",
"createdAt"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"id": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
"enum": [
"draft",
"posted"
]
},
"bookingDate": {
"type": "string",
"format": "date"
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"seq": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
},
"entryHash": {
"type": [
"string",
"null"
],
"description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
"pattern": "^[0-9a-f]{64}$"
},
"reversalOf": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"lines": {
"type": "array",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung as booked.",
"required": [
"lineNo",
"accountId",
"accountNo",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"lineNo": {
"type": "integer",
"description": "Position within the Buchung, starting at 1.",
"minimum": 1
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
]
}
}
}
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"postedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}
},
"nextCursor": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /journal-entriesCreate a draft Buchung
Creates an unposted (draft) Buchung and its lines. The draft is validated immediately — at least two lines, every amount positive, Soll and Haben equal, one currency throughout — but it takes no `seq` and enters no hash chain until it is posted. A draft in a period that is already festgeschrieben is rejected at post time, not here.
Parameters
Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: periodId, bookingDate, currency, lines
{
"type": "object",
"description": "A balanced Buchung to draft.",
"required": [
"periodId",
"bookingDate",
"currency",
"lines"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"bookingDate": {
"type": "string",
"format": "date",
"description": "Buchungsdatum; must fall inside the period."
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"lines": {
"type": "array",
"description": "At least two lines. Every line's currency must equal the entry's, and\nthe debit total must equal the credit total.\n",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung to create — a Konto, a side, and an amount.",
"required": [
"accountId",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
],
"description": "Steuerschlüssel.",
"maxLength": 32
}
}
}
}
}
} Responses
201 · application/json
The created draft.
Required fields: id, periodId, status, bookingDate, currency, lines, createdAt
{
"type": "object",
"description": "A Buchung — a draft, or a posted entry in the hash chain.",
"required": [
"id",
"periodId",
"status",
"bookingDate",
"currency",
"lines",
"createdAt"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"id": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
"enum": [
"draft",
"posted"
]
},
"bookingDate": {
"type": "string",
"format": "date"
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"seq": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
},
"entryHash": {
"type": [
"string",
"null"
],
"description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
"pattern": "^[0-9a-f]{64}$"
},
"reversalOf": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"lines": {
"type": "array",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung as booked.",
"required": [
"lineNo",
"accountId",
"accountNo",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"lineNo": {
"type": "integer",
"description": "Position within the Buchung, starting at 1.",
"minimum": 1
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
]
}
}
}
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"postedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}DELETE /journal-entries/{entryId}Discard a draft Buchung
Discards an unposted draft from item and list reads. Linked archived Buchungsbelege remain preserved. Posted entries reject discard with `409 entry-not-draft`. Requires the latest item ETag.
Parameters
entryId · path · required
Identifier of the Buchung.
{
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"If-Match · header · required
Exactly one strong item ETag observed from create, GET or replacement. Weak tags, wildcards and lists are rejected with 400. Missing tags return 428; stale tags return 412. Fetch again and retry with a fresh Idempotency-Key after a stale version.
{
"type": "string",
"pattern": "^\"je-v1-[A-Za-z0-9_-]{32}\"$"
}Responses
204
The draft was discarded.
400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}412 · application/problem+json
The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}428 · application/problem+json
This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /journal-entries/{entryId}Fetch one Buchung with its lines
Returns the Buchung and its lines in line order. A draft carries no `seq`, `entryHash` or `postedAt`; a posted one carries all three.
Parameters
entryId · path · required
Identifier of the Buchung.
{
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
The Buchung.
Required fields: id, periodId, status, bookingDate, currency, lines, createdAt
{
"type": "object",
"description": "A Buchung — a draft, or a posted entry in the hash chain.",
"required": [
"id",
"periodId",
"status",
"bookingDate",
"currency",
"lines",
"createdAt"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"id": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
"enum": [
"draft",
"posted"
]
},
"bookingDate": {
"type": "string",
"format": "date"
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"seq": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
},
"entryHash": {
"type": [
"string",
"null"
],
"description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
"pattern": "^[0-9a-f]{64}$"
},
"reversalOf": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"lines": {
"type": "array",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung as booked.",
"required": [
"lineNo",
"accountId",
"accountNo",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"lineNo": {
"type": "integer",
"description": "Position within the Buchung, starting at 1.",
"minimum": 1
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
]
}
}
}
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"postedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}PUT /journal-entries/{entryId}Replace a draft Buchung
Replaces all draft accounting fields and lines. Omitted optional metadata is cleared. Identity, creation evidence and linked Buchungsbelege remain. Posted entries reject changes with `409 entry-not-draft`. Requires the latest item ETag; stale versions return `412 precondition-failed`.
Parameters
entryId · path · required
Identifier of the Buchung.
{
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"If-Match · header · required
Exactly one strong item ETag observed from create, GET or replacement. Weak tags, wildcards and lists are rejected with 400. Missing tags return 428; stale tags return 412. Fetch again and retry with a fresh Idempotency-Key after a stale version.
{
"type": "string",
"pattern": "^\"je-v1-[A-Za-z0-9_-]{32}\"$"
}Request body
application/json · required
Required fields: periodId, bookingDate, currency, lines
{
"type": "object",
"description": "A balanced Buchung to draft.",
"required": [
"periodId",
"bookingDate",
"currency",
"lines"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"bookingDate": {
"type": "string",
"format": "date",
"description": "Buchungsdatum; must fall inside the period."
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"lines": {
"type": "array",
"description": "At least two lines. Every line's currency must equal the entry's, and\nthe debit total must equal the credit total.\n",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung to create — a Konto, a side, and an amount.",
"required": [
"accountId",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
],
"description": "Steuerschlüssel.",
"maxLength": 32
}
}
}
}
}
} Responses
200 · application/json
The replaced draft.
Required fields: id, periodId, status, bookingDate, currency, lines, createdAt
{
"type": "object",
"description": "A Buchung — a draft, or a posted entry in the hash chain.",
"required": [
"id",
"periodId",
"status",
"bookingDate",
"currency",
"lines",
"createdAt"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"id": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
"enum": [
"draft",
"posted"
]
},
"bookingDate": {
"type": "string",
"format": "date"
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"seq": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
},
"entryHash": {
"type": [
"string",
"null"
],
"description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
"pattern": "^[0-9a-f]{64}$"
},
"reversalOf": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"lines": {
"type": "array",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung as booked.",
"required": [
"lineNo",
"accountId",
"accountNo",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"lineNo": {
"type": "integer",
"description": "Position within the Buchung, starting at 1.",
"minimum": 1
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
]
}
}
}
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"postedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}412 · application/problem+json
The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}428 · application/problem+json
This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /journal-entries/{entryId}/documents/{documentId}Link an archived Beleg to a draft Buchung
Links an archived Buchungsbeleg to a draft. The link is append-only and is included in the entry's audit hash when the Buchung is posted. Pending documents and entries that are already posted are rejected.
Parameters
entryId · path · required
Identifier of the Buchung.
{
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}documentId · path · required
Identifier of the Beleg.
{
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Responses
204
The document is linked. Repeating the link is a no-op.
400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /journal-entries/{entryId}/postPost a draft Buchung
Finalizes a draft: it is assigned the tenant's next `seq` (the legal Buchungsnummer), linked into the append-only hash chain, and becomes immutable. A `journal_entry.posted` event is emitted in the same transaction — the entry and its event commit together or not at all. Posting is terminal. Corrections are new reversal entries (Storno), never edits. Posting an entry that is not a draft is `409 entry-not-draft`; posting into a period that is festgeschrieben is `409 period-sealed`. At least one archived Buchungsbeleg must already be linked to the draft; otherwise posting is rejected with `422 beleg-required`. Optional If-Match binds posting to the reviewed draft revision under the posting lock. A stale version returns 412 without posting; omission preserves unconditional posting for existing clients.
Parameters
entryId · path · required
Identifier of the Buchung.
{
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"If-Match · header
Optional strong item ETag of the reviewed draft. Checked under the same lock as posting. A stale revision returns 412; omission preserves the existing unconditional posting behavior. Weak tags, wildcards, duplicate values and lists return 400. A failed request rolls back its key and can reuse it after reviewing the current draft. Use a new Idempotency-Key for a new intent after a previously successful request.
{
"type": "string",
"pattern": "^\"je-v1-[A-Za-z0-9_-]{32}\"$"
}Responses
200 · application/json
The posted Buchung.
Required fields: id, periodId, status, bookingDate, currency, lines, createdAt
{
"type": "object",
"description": "A Buchung — a draft, or a posted entry in the hash chain.",
"required": [
"id",
"periodId",
"status",
"bookingDate",
"currency",
"lines",
"createdAt"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"id": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
"enum": [
"draft",
"posted"
]
},
"bookingDate": {
"type": "string",
"format": "date"
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"seq": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
},
"entryHash": {
"type": [
"string",
"null"
],
"description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
"pattern": "^[0-9a-f]{64}$"
},
"reversalOf": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"lines": {
"type": "array",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung as booked.",
"required": [
"lineNo",
"accountId",
"accountNo",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"lineNo": {
"type": "integer",
"description": "Position within the Buchung, starting at 1.",
"minimum": 1
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
]
}
}
}
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"postedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}412 · application/problem+json
The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /journal-entries/{entryId}/reverseReverse a posted Buchung (Storno)
Creates and immediately posts a new immutable Storno. The server copies the original currency, lines, frozen Kontonummer snapshots and immutable Beleg evidence, swaps Soll and Haben, and sets `reversalOf` to the target. A `journal_entry.posted` event is emitted in the same transaction. The caller selects an open destination period and a booking date within that period because the original period may already be festgeschrieben. Only posted entries can be reversed. A second direct reversal is rejected with `409 entry-already-reversed`; reverse the Storno itself to undo it. Retry an uncertain response with the original `Idempotency-Key` for an exact replay; a fresh key represents a new write intent.
Parameters
entryId · path · required
Identifier of the Buchung.
{
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: periodId, bookingDate
{
"type": "object",
"description": "Posting coordinates for a new Storno; economic data, bookingText and externalReference are inherited unchanged from the original.",
"required": [
"periodId",
"bookingDate"
],
"additionalProperties": false,
"properties": {
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"bookingDate": {
"type": "string",
"format": "date",
"description": "Buchungsdatum; must fall inside the destination period."
}
}
} Responses
201 · application/json
The newly created and posted Storno.
Required fields: id, periodId, status, bookingDate, currency, lines, createdAt
{
"type": "object",
"description": "A Buchung — a draft, or a posted entry in the hash chain.",
"required": [
"id",
"periodId",
"status",
"bookingDate",
"currency",
"lines",
"createdAt"
],
"additionalProperties": false,
"properties": {
"bookingText": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 500,
"description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
},
"externalReference": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 255,
"description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
},
"id": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"periodId": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"status": {
"type": "string",
"description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
"enum": [
"draft",
"posted"
]
},
"bookingDate": {
"type": "string",
"format": "date"
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"seq": {
"type": [
"integer",
"null"
],
"format": "int64",
"description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
},
"entryHash": {
"type": [
"string",
"null"
],
"description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
"pattern": "^[0-9a-f]{64}$"
},
"reversalOf": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"lines": {
"type": "array",
"minItems": 2,
"items": {
"type": "object",
"description": "One line of a Buchung as booked.",
"required": [
"lineNo",
"accountId",
"accountNo",
"side",
"amount"
],
"additionalProperties": false,
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128,
"description": "Optional immutable published rule; requires matching taxKey and effective booking date."
},
"lineNo": {
"type": "integer",
"description": "Position within the Buchung, starting at 1.",
"minimum": 1
},
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
},
"side": {
"type": "string",
"description": "Buchungsseite — Soll (debit) or Haben (credit).",
"enum": [
"debit",
"credit"
]
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"taxKey": {
"type": [
"string",
"null"
]
}
}
}
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"postedAt": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /periodsList accounting periods
Periods of the calling tenant, ordered by start date.
Parameters
limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
Return items after this period — the `nextCursor` of the previous page.
{
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
A page of periods.
Required fields: data
{
"type": "object",
"description": "One page of periods, earliest start date first.",
"required": [
"data"
],
"additionalProperties": false,
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"description": "An accounting period and its Festschreibung state.",
"required": [
"id",
"label",
"startsOn",
"endsOn",
"status",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"label": {
"type": "string",
"examples": [
"2026-01"
]
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date",
"description": "Inclusive last day of the period."
},
"status": {
"type": "string",
"description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
"enum": [
"open",
"festgeschrieben"
]
},
"festgeschriebenAt": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the period was sealed; null while it is open."
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}
},
"nextCursor": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /periodsCreate an accounting period
Periods of one tenant may not overlap; an overlapping range is `409 period-overlap`. A new period starts `open`.
Parameters
Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: label, startsOn, endsOn
{
"type": "object",
"description": "Fields accepted when opening a period.",
"required": [
"label",
"startsOn",
"endsOn"
],
"additionalProperties": false,
"properties": {
"label": {
"type": "string",
"minLength": 1,
"maxLength": 64,
"examples": [
"2026-01"
]
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date",
"description": "Inclusive last day; must not precede `startsOn`."
}
}
} Responses
201 · application/json
The created period.
Required fields: id, label, startsOn, endsOn, status, createdAt
{
"type": "object",
"description": "An accounting period and its Festschreibung state.",
"required": [
"id",
"label",
"startsOn",
"endsOn",
"status",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"label": {
"type": "string",
"examples": [
"2026-01"
]
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date",
"description": "Inclusive last day of the period."
},
"status": {
"type": "string",
"description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
"enum": [
"open",
"festgeschrieben"
]
},
"festgeschriebenAt": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the period was sealed; null while it is open."
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /periods/{periodId}Fetch one period
Returns the period if it belongs to the calling tenant, else 404.
Parameters
periodId · path · required
Identifier of the accounting period.
{
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
The period.
Required fields: id, label, startsOn, endsOn, status, createdAt
{
"type": "object",
"description": "An accounting period and its Festschreibung state.",
"required": [
"id",
"label",
"startsOn",
"endsOn",
"status",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"label": {
"type": "string",
"examples": [
"2026-01"
]
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date",
"description": "Inclusive last day of the period."
},
"status": {
"type": "string",
"description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
"enum": [
"open",
"festgeschrieben"
]
},
"festgeschriebenAt": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the period was sealed; null while it is open."
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /periods/{periodId}/festschreibenFinalize an accounting period (Festschreibung)
Permanently seals the period. The database records the authoritative transition time and actor; neither value is caller-controlled. A fresh-key retry after an uncertain response is domain-idempotent and returns the existing terminal Period with its original `festgeschriebenAt`. Draft Buchungen may remain in the period, but they can no longer be posted. Festschreibung is irreversible; corrections remain new Storno entries.
Parameters
periodId · path · required
Identifier of the accounting period.
{
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Responses
200 · application/json
The sealed period, or its unchanged terminal representation.
Required fields: id, label, startsOn, endsOn, status, createdAt
{
"type": "object",
"description": "An accounting period and its Festschreibung state.",
"required": [
"id",
"label",
"startsOn",
"endsOn",
"status",
"createdAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque period identifier.",
"pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"label": {
"type": "string",
"examples": [
"2026-01"
]
},
"startsOn": {
"type": "string",
"format": "date"
},
"endsOn": {
"type": "string",
"format": "date",
"description": "Inclusive last day of the period."
},
"status": {
"type": "string",
"description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
"enum": [
"open",
"festgeschrieben"
]
},
"festgeschriebenAt": {
"type": [
"string",
"null"
],
"format": "date-time",
"description": "When the period was sealed; null while it is open."
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /reports/financial-statementsRead mapped Bilanz and GuV for one fiscal year
Requires accounting.read. An explicit immutable mapping classifies every account with posted activity in the selected fiscal-year/currency/asOf view. Unknown or foreign year and mapping IDs return 404; missing account classification returns 422 incomplete-account-mapping, including accounts with zero net activity. Amounts use only booking dates inside the year and the inclusive asOf posting cutoff. Earlier years are excluded: opening balances must be ordinary evidence-backed entries or carryforward in this year. Automated fiscal-year closing entries are excluded so they cannot erase GuV movements or count the result twice in equity. Other posted entries, including opening and Storno, contribute normally. A stale asOf yields a historical report, not an assertion that finalization has occurred. Mappings and labels are supplied by the integrator, never inferred from account numbers or tax keys. Asset and expense amounts are debit minus credit; liability, equity and income use the opposite sign. result is income minus expense; balanceDifference is assets minus liabilities, equity and result. Each currency is separate. This is an accounting report under the chosen mapping, not statutory filing validation. Data sorts by classification, reportCode and currency; account drilldowns sort by the mapping's frozen accountNo then accountId. Follow accountId to its statement with the response dates and asOf. That statement also contains closing entries; use closingEntryIds to reconcile their exclusion. Empty views return empty arrays. More than 10000 account/currency rows returns 413 report-too-large; any signed-int64 amount overflow fails the whole response with 422 balance-overflow.
Parameters
fiscalYearId · query · required
Fiscal year whose inclusive dates delimit posted activity.
{
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}mappingRevisionId · query · required
Immutable consumer-owned account classification.
{
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
}asOf · query
Inclusive posted-entry cutoff; omit for latest, or reuse a prior response's asOf.
{
"type": "string",
"description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
"pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
"examples": [
"empty"
]
}currency · query
Restrict to one currency without conversion; omit to include each separately.
{
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}Responses
200 · application/json
Bilanz and GuV sections with account drilldowns and currency totals.
Required fields: asOf, fiscalYearId, mappingRevisionId, mappingDigest, bookingDateFrom, bookingDateTo, closingEntryIds, data, totals
{
"type": "object",
"description": "Reproducible year-scoped reports under an explicit immutable mapping.",
"required": [
"asOf",
"fiscalYearId",
"mappingRevisionId",
"mappingDigest",
"bookingDateFrom",
"bookingDateTo",
"closingEntryIds",
"data",
"totals"
],
"additionalProperties": false,
"properties": {
"asOf": {
"type": "string",
"description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
"pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
"examples": [
"empty"
]
},
"fiscalYearId": {
"type": "string",
"description": "Opaque fiscal-year identifier.",
"pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
},
"mappingRevisionId": {
"description": "Opaque tenant-owned account mapping revision identifier.",
"type": "string",
"pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
},
"mappingDigest": {
"type": "string",
"pattern": "^sha256:[0-9a-f]{64}$"
},
"bookingDateFrom": {
"type": "string",
"format": "date"
},
"bookingDateTo": {
"type": "string",
"format": "date"
},
"closingEntryIds": {
"type": "array",
"items": {
"type": "string",
"description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
"pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}
},
"data": {
"type": "array",
"items": {
"type": "object",
"description": "One consumer-defined report section and its underlying accounts.",
"required": [
"classification",
"reportCode",
"reportName",
"amount",
"accounts"
],
"additionalProperties": false,
"properties": {
"classification": {
"description": "Explicit consumer classification for financial reporting.",
"type": "string",
"enum": [
"asset",
"liability",
"equity",
"income",
"expense"
]
},
"reportCode": {
"type": "string"
},
"reportName": {
"type": "string"
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"accounts": {
"type": "array",
"items": {
"type": "object",
"description": "One account's year-scoped net in its classification's sign convention.",
"required": [
"accountId",
"accountNo",
"accountName",
"amount"
],
"additionalProperties": false,
"properties": {
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string"
},
"accountName": {
"type": "string"
},
"amount": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
}
}
}
}
}
}
},
"totals": {
"type": "array",
"items": {
"type": "object",
"description": "Separate balance sheet and profit/loss control totals in one currency.",
"required": [
"currency",
"assets",
"liabilities",
"equity",
"income",
"expense",
"result",
"balanceDifference"
],
"additionalProperties": false,
"properties": {
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"assets": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"liabilities": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"equity": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"income": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"expense": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"result": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"balanceDifference": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
}
}
}
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /reports/trial-balanceRead a complete Summen- und Saldenliste at one posting cutoff
Requires accounting.read. Returns posted opening, debit, credit and closing amounts per account and currency, plus currency totals. Uses the same asOf and inclusive date filters as account balances. Drafts never contribute; Storno contributes its ordinary opposite lines. accountNo comes from the latest participating posted line by seq/lineNo, including opening history. Renumbering without a new posting cannot alter a report, and all numbers of one account aggregate together. Rows sort by accountNo, accountId and currency; totals sort by currency. Unused accounts/currencies are omitted, including with a currency filter; empty views use empty arrays. Positive balances are debit, negative credit. This is cumulative history, not a fiscal-year report; use financial-statements for year-scoped reporting. A maximum of 10000 rows including totals is returned atomically; exceeding the bound is 413 report-too-large. Every amount must fit signed int64 minor units, including gross currency totals; otherwise 422 balance-overflow. No partial or rounded report is returned.
Parameters
asOf · query
Inclusive posted-entry cutoff; omit for latest, or reuse a prior response's asOf.
{
"type": "string",
"description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
"pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
"examples": [
"empty"
]
}currency · query
Restrict to one currency without conversion; omit to include each separately.
{
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}bookingDateFrom · query
Inclusive earliest booking date for movements; earlier history forms openingBalance.
{
"type": "string",
"format": "date"
}bookingDateTo · query
Inclusive latest booking date; must not precede bookingDateFrom.
{
"type": "string",
"format": "date"
}Responses
200 · application/json
Complete account rows and per-currency control totals.
Required fields: asOf, data, totals
{
"type": "object",
"description": "Summen- und Saldenliste with exact currency control totals.",
"required": [
"asOf",
"data",
"totals"
],
"additionalProperties": false,
"properties": {
"asOf": {
"type": "string",
"description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
"pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
"examples": [
"empty"
]
},
"data": {
"type": "array",
"items": {
"type": "object",
"description": "Exact totals for one account and currency.",
"required": [
"accountId",
"accountNo",
"currency",
"openingBalance",
"debitTotal",
"creditTotal",
"closingBalance"
],
"additionalProperties": false,
"properties": {
"accountId": {
"type": "string",
"description": "Opaque account identifier.",
"pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"accountNo": {
"type": "string",
"description": "Account number from the latest participating posted line."
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"openingBalance": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"debitTotal": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"creditTotal": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"closingBalance": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
}
}
}
},
"totals": {
"type": "array",
"items": {
"type": "object",
"description": "Exact debit/credit totals and signed balances in one currency.",
"required": [
"currency",
"openingBalance",
"debitTotal",
"creditTotal",
"closingBalance"
],
"additionalProperties": false,
"properties": {
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
},
"openingBalance": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"debitTotal": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"creditTotal": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"closingBalance": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
}
}
}
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /tax-calculationsCalculate tax from an explicitly selected published rule
Calculates an exact amount using the selected rule and its effective dates. It makes no posting or legal classification decision.
Parameters
Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: taxRuleId, bookingDate, net
{
"description": "Explicit net amount, booking date and qualified rule.",
"type": "object",
"additionalProperties": false,
"required": [
"taxRuleId",
"bookingDate",
"net"
],
"properties": {
"taxRuleId": {
"type": "string",
"maxLength": 128
},
"bookingDate": {
"type": "string",
"format": "date"
},
"net": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
}
}
} Responses
200 · application/json
Exact calculation and immutable rule evidence.
Required fields: tax, evidence
{
"description": "Exact rounded tax with the selected rule provenance.",
"type": "object",
"additionalProperties": false,
"required": [
"tax",
"evidence"
],
"properties": {
"tax": {
"type": "object",
"description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
"required": [
"amount",
"currency"
],
"additionalProperties": false,
"properties": {
"amount": {
"type": "string",
"description": "Signed integer count of minor units, no separators, no exponent.",
"pattern": "^-?(0|[1-9][0-9]{0,18})$",
"examples": [
"150000"
]
},
"currency": {
"type": "string",
"description": "ISO-4217 alphabetic currency code.",
"pattern": "^[A-Z]{3}$",
"examples": [
"EUR"
]
}
}
},
"evidence": {
"description": "An immutable rule from a digest-verified published artifact.",
"type": "object",
"additionalProperties": false,
"required": [
"id",
"taxKey",
"effectiveFrom",
"effectiveUntil",
"rateNumerator",
"rateDenominator",
"sourceVersion",
"artifactSha256"
],
"properties": {
"id": {
"type": "string",
"maxLength": 128
},
"taxKey": {
"type": "string",
"maxLength": 32
},
"effectiveFrom": {
"type": "string",
"format": "date"
},
"effectiveUntil": {
"type": [
"string",
"null"
],
"format": "date"
},
"rateNumerator": {
"type": "string",
"pattern": "^[0-9]+$"
},
"rateDenominator": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"sourceVersion": {
"type": "string",
"maxLength": 64
},
"artifactSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
}
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /tax-rulesList published optional tax rules
Returns immutable global reference rules. An empty list means no qualified rules are published; ordinary consumer-owned taxKey remains valid.
Parameters
limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
Rule ID returned as nextCursor by the previous page.
{
"type": "string",
"maxLength": 128
}Responses
200 · application/json
Bounded page of rules, ordered by ID.
Required fields: data, nextCursor
{
"description": "A bounded page of published reference rules.",
"type": "object",
"additionalProperties": false,
"required": [
"data",
"nextCursor"
],
"properties": {
"data": {
"type": "array",
"items": {
"description": "An immutable rule from a digest-verified published artifact.",
"type": "object",
"additionalProperties": false,
"required": [
"id",
"taxKey",
"effectiveFrom",
"effectiveUntil",
"rateNumerator",
"rateDenominator",
"sourceVersion",
"artifactSha256"
],
"properties": {
"id": {
"type": "string",
"maxLength": 128
},
"taxKey": {
"type": "string",
"maxLength": 32
},
"effectiveFrom": {
"type": "string",
"format": "date"
},
"effectiveUntil": {
"type": [
"string",
"null"
],
"format": "date"
},
"rateNumerator": {
"type": "string",
"pattern": "^[0-9]+$"
},
"rateDenominator": {
"type": "string",
"pattern": "^[1-9][0-9]*$"
},
"sourceVersion": {
"type": "string",
"maxLength": 64
},
"artifactSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
}
}
},
"maxItems": 200
},
"nextCursor": {
"type": [
"string",
"null"
]
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /tenantsList partner tenants
Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. Ordered by public identifier; after is an exclusive public identifier boundary, not a snapshot.
Parameters
limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
Exclusive public identifier boundary from nextCursor.
{
"type": "string",
"description": "Opaque public tenant identifier.",
"pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
}Responses
200 · application/json
The requested access resource.
Required fields: data
{
"type": "object",
"description": "One page ordered by public identifier.",
"additionalProperties": false,
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"description": "An isolated accounting tenant within the caller's partner.",
"additionalProperties": false,
"required": [
"id",
"name",
"createdAt"
],
"properties": {
"id": {
"type": "string",
"description": "Opaque public tenant identifier.",
"pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
},
"name": {
"type": "string"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}
},
"nextCursor": {
"type": "string",
"description": "Opaque public tenant identifier.",
"pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /tenantsCreate an isolated tenant
Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. Creates a tenant and inherits the administrator membership's explicit permissions for the same identity.
Parameters
Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: name
{
"type": "object",
"description": "A new isolated tenant.",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
}
} Responses
201 · application/json
The requested access resource.
Required fields: id, name, createdAt
{
"type": "object",
"description": "An isolated accounting tenant within the caller's partner.",
"additionalProperties": false,
"required": [
"id",
"name",
"createdAt"
],
"properties": {
"id": {
"type": "string",
"description": "Opaque public tenant identifier.",
"pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
},
"name": {
"type": "string"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /tenants/{tenantId}/membershipsList tenant memberships
Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. Ordered by public identifier; after is an exclusive public identifier boundary, not a snapshot.
Parameters
tenantId · path · required
Opaque public tenant identifier.
{
"type": "string",
"description": "Opaque public tenant identifier.",
"pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
}limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
Exclusive public identifier boundary from nextCursor.
{
"type": "string",
"description": "Opaque public membership identifier.",
"pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
}Responses
200 · application/json
The requested access resource.
Required fields: data
{
"type": "object",
"description": "One page ordered by public identifier.",
"additionalProperties": false,
"required": [
"data"
],
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"description": "An external subject's explicit grants in a tenant.",
"additionalProperties": false,
"required": [
"id",
"subject",
"permissions",
"status",
"revision",
"createdAt"
],
"properties": {
"id": {
"type": "string",
"description": "Opaque public membership identifier.",
"pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
},
"subject": {
"type": "string"
},
"permissions": {
"type": "array",
"description": "Explicit unique grants; an empty array grants no operations.",
"maxItems": 9,
"uniqueItems": true,
"items": {
"type": "string",
"description": "A local membership grant. access.manage is explicit partner-wide administration.",
"enum": [
"accounting.read",
"accounting.write",
"documents.read",
"documents.write",
"periods.close",
"webhooks.manage",
"access.manage",
"exports.read",
"audit.read"
]
}
},
"status": {
"type": "string",
"description": "An inactive membership cannot bind to an API request.",
"enum": [
"active",
"inactive"
]
},
"revision": {
"type": "integer",
"minimum": 1,
"maximum": 2147483647
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}
},
"nextCursor": {
"type": "string",
"description": "Opaque public membership identifier.",
"pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /tenants/{tenantId}/membershipsGrant an external identity tenant access
Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. The subject belongs to the configured trusted issuer; permissions must be supplied explicitly.
Parameters
tenantId · path · required
Opaque public tenant identifier.
{
"type": "string",
"description": "Opaque public tenant identifier.",
"pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: subject, permissions
{
"type": "object",
"description": "Explicit grants for a subject in the administrator's trusted issuer.",
"additionalProperties": false,
"required": [
"subject",
"permissions"
],
"properties": {
"subject": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"permissions": {
"type": "array",
"description": "Explicit unique grants; an empty array grants no operations.",
"maxItems": 9,
"uniqueItems": true,
"items": {
"type": "string",
"description": "A local membership grant. access.manage is explicit partner-wide administration.",
"enum": [
"accounting.read",
"accounting.write",
"documents.read",
"documents.write",
"periods.close",
"webhooks.manage",
"access.manage",
"exports.read",
"audit.read"
]
}
}
}
} Responses
201 · application/json
The requested access resource.
Required fields: id, subject, permissions, status, revision, createdAt
{
"type": "object",
"description": "An external subject's explicit grants in a tenant.",
"additionalProperties": false,
"required": [
"id",
"subject",
"permissions",
"status",
"revision",
"createdAt"
],
"properties": {
"id": {
"type": "string",
"description": "Opaque public membership identifier.",
"pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
},
"subject": {
"type": "string"
},
"permissions": {
"type": "array",
"description": "Explicit unique grants; an empty array grants no operations.",
"maxItems": 9,
"uniqueItems": true,
"items": {
"type": "string",
"description": "A local membership grant. access.manage is explicit partner-wide administration.",
"enum": [
"accounting.read",
"accounting.write",
"documents.read",
"documents.write",
"periods.close",
"webhooks.manage",
"access.manage",
"exports.read",
"audit.read"
]
}
},
"status": {
"type": "string",
"description": "An inactive membership cannot bind to an API request.",
"enum": [
"active",
"inactive"
]
},
"revision": {
"type": "integer",
"minimum": 1,
"maximum": 2147483647
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}PUT /tenants/{tenantId}/memberships/{membershipId}Replace or revoke tenant access
Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. Uses expectedRevision to prevent lost updates; inactive memberships cannot access the tenant.
Parameters
tenantId · path · required
Opaque public tenant identifier.
{
"type": "string",
"description": "Opaque public tenant identifier.",
"pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
}membershipId · path · required
Opaque public membership identifier.
{
"type": "string",
"description": "Opaque public membership identifier.",
"pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: permissions, status, expectedRevision
{
"type": "object",
"description": "Complete grant replacement or revocation guarded by the current revision.",
"additionalProperties": false,
"required": [
"permissions",
"status",
"expectedRevision"
],
"properties": {
"permissions": {
"type": "array",
"description": "Explicit unique grants; an empty array grants no operations.",
"maxItems": 9,
"uniqueItems": true,
"items": {
"type": "string",
"description": "A local membership grant. access.manage is explicit partner-wide administration.",
"enum": [
"accounting.read",
"accounting.write",
"documents.read",
"documents.write",
"periods.close",
"webhooks.manage",
"access.manage",
"exports.read",
"audit.read"
]
}
},
"status": {
"type": "string",
"description": "An inactive membership cannot bind to an API request.",
"enum": [
"active",
"inactive"
]
},
"expectedRevision": {
"type": "integer",
"minimum": 1,
"maximum": 2147483647
}
}
} Responses
200 · application/json
The requested access resource.
Required fields: id, subject, permissions, status, revision, createdAt
{
"type": "object",
"description": "An external subject's explicit grants in a tenant.",
"additionalProperties": false,
"required": [
"id",
"subject",
"permissions",
"status",
"revision",
"createdAt"
],
"properties": {
"id": {
"type": "string",
"description": "Opaque public membership identifier.",
"pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
},
"subject": {
"type": "string"
},
"permissions": {
"type": "array",
"description": "Explicit unique grants; an empty array grants no operations.",
"maxItems": 9,
"uniqueItems": true,
"items": {
"type": "string",
"description": "A local membership grant. access.manage is explicit partner-wide administration.",
"enum": [
"accounting.read",
"accounting.write",
"documents.read",
"documents.write",
"periods.close",
"webhooks.manage",
"access.manage",
"exports.read",
"audit.read"
]
}
},
"status": {
"type": "string",
"description": "An inactive membership cannot bind to an API request.",
"enum": [
"active",
"inactive"
]
},
"revision": {
"type": "integer",
"minimum": 1,
"maximum": 2147483647
},
"createdAt": {
"type": "string",
"format": "date-time"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /webhook-endpointsList webhook endpoints
Requires explicit webhook endpoint management permission in the calling tenant. Returns every endpoint of that tenant, including inactive endpoints, ordered by creation time. Inactive metadata remains visible so an endpoint can be audited or reactivated without losing its identity or delivery history.
Parameters
limit · query
Maximum number of items to return.
{
"type": "integer",
"minimum": 1,
"maximum": 200,
"default": 50
}after · query
Return items after this webhook endpoint — the `nextCursor` of the previous page.
{
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
A page of webhook endpoint metadata. Collection responses do not carry per-item HTTP validators; fetch an item before mutating it to obtain its current `ETag`.
Required fields: data
{
"type": "object",
"description": "One page of webhook endpoints, oldest creation time first.",
"required": [
"data"
],
"additionalProperties": false,
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"description": "Safe webhook endpoint metadata. Signing-secret material is never present.",
"required": [
"id",
"url",
"eventTypes",
"active",
"createdAt",
"updatedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^[hH][tT][tT][pP][sS]://",
"maxLength": 2048,
"description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
"examples": [
"https://hooks.example.com/accounting"
]
},
"eventTypes": {
"type": "array",
"maxItems": 16,
"uniqueItems": true,
"description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
"items": {
"type": "string",
"description": "A domain event type currently available for endpoint subscriptions.",
"enum": [
"journal_entry.posted"
],
"x-enum-varnames": [
"WebhookEventTypeJournalEntryPosted"
]
}
},
"active": {
"type": "boolean",
"description": "Whether this endpoint is eligible for newly committed event snapshots.\nDeactivation also permanently suppresses its older-snapshot recipients\nthat a worker has not already loaded; later reactivation does not revive\nthose recipients.\n"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"updatedAt": {
"type": "string",
"format": "date-time",
"description": "Last metadata, active-state, or secret change. A secret rotation changes\nthis timestamp but never exposes either secret.\n"
}
}
}
},
"nextCursor": {
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}POST /webhook-endpointsCreate a webhook endpoint
Requires explicit webhook endpoint management permission in the calling tenant. Registers an active HTTPS destination. The caller supplies the signing secret once; it is write-only and is never included in this or any later response. A tenant may retain at most 256 endpoints in total, including inactive endpoints, and at most 64 of them may be active. Deactivation does not free retained-endpoint capacity.
Parameters
Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"Request body
application/json · required
Required fields: url, eventTypes, secret
{
"type": "object",
"description": "Fields accepted when registering an active webhook endpoint.",
"required": [
"url",
"eventTypes",
"secret"
],
"additionalProperties": false,
"properties": {
"url": {
"type": "string",
"format": "uri",
"pattern": "^[hH][tT][tT][pP][sS]://",
"maxLength": 2048,
"description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
"examples": [
"https://hooks.example.com/accounting"
]
},
"eventTypes": {
"type": "array",
"maxItems": 16,
"uniqueItems": true,
"description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
"items": {
"type": "string",
"description": "A domain event type currently available for endpoint subscriptions.",
"enum": [
"journal_entry.posted"
],
"x-enum-varnames": [
"WebhookEventTypeJournalEntryPosted"
]
}
},
"secret": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$",
"writeOnly": true,
"x-go-type-skip-optional-pointer": true,
"description": "Exactly 32 bytes encoded as canonical, unpadded base64url (43 characters).\nFor every create or rotation, the caller MUST generate a unique, independent,\nunpredictable 32-byte value with a cryptographically secure random-number\ngenerator and MUST NOT reuse it for another endpoint or secret version. The\ncaller retains this HMAC-SHA256 signing secret. It is accepted only on create\nor rotation and is never returned by the API. The final-character restriction\nrejects non-canonical encodings with non-zero unused bits.\n"
}
}
} Responses
201 · application/json
The created endpoint metadata. The signing secret is never returned.
Required fields: id, url, eventTypes, active, createdAt, updatedAt
{
"type": "object",
"description": "Safe webhook endpoint metadata. Signing-secret material is never present.",
"required": [
"id",
"url",
"eventTypes",
"active",
"createdAt",
"updatedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^[hH][tT][tT][pP][sS]://",
"maxLength": 2048,
"description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
"examples": [
"https://hooks.example.com/accounting"
]
},
"eventTypes": {
"type": "array",
"maxItems": 16,
"uniqueItems": true,
"description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
"items": {
"type": "string",
"description": "A domain event type currently available for endpoint subscriptions.",
"enum": [
"journal_entry.posted"
],
"x-enum-varnames": [
"WebhookEventTypeJournalEntryPosted"
]
}
},
"active": {
"type": "boolean",
"description": "Whether this endpoint is eligible for newly committed event snapshots.\nDeactivation also permanently suppresses its older-snapshot recipients\nthat a worker has not already loaded; later reactivation does not revive\nthose recipients.\n"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"updatedAt": {
"type": "string",
"format": "date-time",
"description": "Last metadata, active-state, or secret change. A secret rotation changes\nthis timestamp but never exposes either secret.\n"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}DELETE /webhook-endpoints/{webhookEndpointId}Deactivate a webhook endpoint
Requires explicit webhook endpoint management permission in the calling tenant. Soft-deactivates the endpoint. No endpoint or delivery-attempt row is deleted: its stable identity, lifecycle attribution, and delivery audit history are preserved. After deactivation commits, the endpoint is excluded from new event snapshots and every older-snapshot recipient for it that a worker has not already loaded is permanently suppressed. Reactivating the same endpoint identity later does not revive those suppressed recipients. Deleting an already inactive endpoint is a no-op. An attempt loaded before deactivation commits may still complete with its pinned URL after this operation returns.
Parameters
webhookEndpointId · path · required
Identifier of the tenant-managed webhook endpoint.
{
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"If-Match · header · required
The exact strong `ETag` returned by the latest item response. Weak tags, wildcard matching, and validator lists are not accepted because every mutation must name one observed endpoint version. A missing precondition is `428 precondition-required`; a well-formed but stale validator is `412 precondition-failed`. After a 412, fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.
{
"type": "string",
"pattern": "^\"whep-v1-[A-Za-z0-9_-]{32}\"$"
}Example
"\"whep-v1-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""Responses
204
The endpoint is inactive and its audit history is preserved.
400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}412 · application/problem+json
The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}428 · application/problem+json
This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /webhook-endpoints/{webhookEndpointId}Fetch one webhook endpoint
Requires explicit webhook endpoint management permission in the calling tenant. Returns safe metadata if the endpoint belongs to that tenant, else 404. The signing secret is never readable through the API.
Parameters
webhookEndpointId · path · required
Identifier of the tenant-managed webhook endpoint.
{
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
The webhook endpoint metadata.
Required fields: id, url, eventTypes, active, createdAt, updatedAt
{
"type": "object",
"description": "Safe webhook endpoint metadata. Signing-secret material is never present.",
"required": [
"id",
"url",
"eventTypes",
"active",
"createdAt",
"updatedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^[hH][tT][tT][pP][sS]://",
"maxLength": 2048,
"description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
"examples": [
"https://hooks.example.com/accounting"
]
},
"eventTypes": {
"type": "array",
"maxItems": 16,
"uniqueItems": true,
"description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
"items": {
"type": "string",
"description": "A domain event type currently available for endpoint subscriptions.",
"enum": [
"journal_entry.posted"
],
"x-enum-varnames": [
"WebhookEventTypeJournalEntryPosted"
]
}
},
"active": {
"type": "boolean",
"description": "Whether this endpoint is eligible for newly committed event snapshots.\nDeactivation also permanently suppresses its older-snapshot recipients\nthat a worker has not already loaded; later reactivation does not revive\nthose recipients.\n"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"updatedAt": {
"type": "string",
"format": "date-time",
"description": "Last metadata, active-state, or secret change. A secret rotation changes\nthis timestamp but never exposes either secret.\n"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}PUT /webhook-endpoints/{webhookEndpointId}Replace webhook endpoint metadata
Requires explicit webhook endpoint management permission in the calling tenant. Fully replaces the destination URL, event subscription, and active state; the existing signing secret is unchanged. All three metadata fields are required. The active state and event subscription select recipients only for events committed after this replacement commits. Each previously selected recipient keeps the routing URL snapshotted with its event, even if this replacement changes the URL. Setting `active` to false also permanently suppresses every older-snapshot recipient for this endpoint that a worker has not already loaded. Reactivating the endpoint later does not revive those suppressed recipients; it only makes the endpoint eligible for new event snapshots. An attempt loaded before deactivation commits may still complete with its pinned URL after this operation returns.
Parameters
webhookEndpointId · path · required
Identifier of the tenant-managed webhook endpoint.
{
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"If-Match · header · required
The exact strong `ETag` returned by the latest item response. Weak tags, wildcard matching, and validator lists are not accepted because every mutation must name one observed endpoint version. A missing precondition is `428 precondition-required`; a well-formed but stale validator is `412 precondition-failed`. After a 412, fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.
{
"type": "string",
"pattern": "^\"whep-v1-[A-Za-z0-9_-]{32}\"$"
}Example
"\"whep-v1-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""Request body
application/json · required
Required fields: url, eventTypes, active
{
"type": "object",
"description": "Complete replacement of mutable endpoint metadata. The signing secret is\ndeliberately not metadata and remains unchanged.\n",
"required": [
"url",
"eventTypes",
"active"
],
"additionalProperties": false,
"properties": {
"url": {
"type": "string",
"format": "uri",
"pattern": "^[hH][tT][tT][pP][sS]://",
"maxLength": 2048,
"description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
"examples": [
"https://hooks.example.com/accounting"
]
},
"eventTypes": {
"type": "array",
"maxItems": 16,
"uniqueItems": true,
"description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
"items": {
"type": "string",
"description": "A domain event type currently available for endpoint subscriptions.",
"enum": [
"journal_entry.posted"
],
"x-enum-varnames": [
"WebhookEventTypeJournalEntryPosted"
]
}
},
"active": {
"type": "boolean"
}
}
} Responses
200 · application/json
The replaced webhook endpoint metadata.
Required fields: id, url, eventTypes, active, createdAt, updatedAt
{
"type": "object",
"description": "Safe webhook endpoint metadata. Signing-secret material is never present.",
"required": [
"id",
"url",
"eventTypes",
"active",
"createdAt",
"updatedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"url": {
"type": "string",
"format": "uri",
"pattern": "^[hH][tT][tT][pP][sS]://",
"maxLength": 2048,
"description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
"examples": [
"https://hooks.example.com/accounting"
]
},
"eventTypes": {
"type": "array",
"maxItems": 16,
"uniqueItems": true,
"description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
"items": {
"type": "string",
"description": "A domain event type currently available for endpoint subscriptions.",
"enum": [
"journal_entry.posted"
],
"x-enum-varnames": [
"WebhookEventTypeJournalEntryPosted"
]
}
},
"active": {
"type": "boolean",
"description": "Whether this endpoint is eligible for newly committed event snapshots.\nDeactivation also permanently suppresses its older-snapshot recipients\nthat a worker has not already loaded; later reactivation does not revive\nthose recipients.\n"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"updatedAt": {
"type": "string",
"format": "date-time",
"description": "Last metadata, active-state, or secret change. A secret rotation changes\nthis timestamp but never exposes either secret.\n"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}412 · application/problem+json
The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}428 · application/problem+json
This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}PUT /webhook-endpoints/{webhookEndpointId}/secretRotate a webhook endpoint signing secret
Requires explicit webhook endpoint management permission in the calling tenant. Replaces only the signing secret; metadata and active state are unchanged. Configure the receiver to accept both secrets before rotating. Once this operation returns 204, every newly loaded attempt uses the current secret version, including a retry for an event snapshotted before rotation. A request already loaded or in flight may still arrive with a signature made by the old secret. Keep the overlap until those attempts have drained. The old and new secrets are both write-only and are never returned.
Parameters
webhookEndpointId · path · required
Identifier of the tenant-managed webhook endpoint.
{
"type": "string",
"description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
"pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Idempotency-Key · header · required
Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.
{
"type": "string",
"minLength": 1,
"maxLength": 255
}Example
"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"X-Accounting-Acting-User-Issuer · header
Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"https://auth.d0.eu"X-Accounting-Acting-User-Subject · header
Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.
{
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}Example
"person-42"If-Match · header · required
The exact strong `ETag` returned by the latest item response. Weak tags, wildcard matching, and validator lists are not accepted because every mutation must name one observed endpoint version. A missing precondition is `428 precondition-required`; a well-formed but stale validator is `412 precondition-failed`. After a 412, fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.
{
"type": "string",
"pattern": "^\"whep-v1-[A-Za-z0-9_-]{32}\"$"
}Example
"\"whep-v1-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""Request body
application/json · required
Required fields: secret
{
"type": "object",
"description": "Write-only replacement signing material for one endpoint.",
"required": [
"secret"
],
"additionalProperties": false,
"properties": {
"secret": {
"type": "string",
"minLength": 43,
"maxLength": 43,
"pattern": "^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$",
"writeOnly": true,
"x-go-type-skip-optional-pointer": true,
"description": "Exactly 32 bytes encoded as canonical, unpadded base64url (43 characters).\nFor every create or rotation, the caller MUST generate a unique, independent,\nunpredictable 32-byte value with a cryptographically secure random-number\ngenerator and MUST NOT reuse it for another endpoint or secret version. The\ncaller retains this HMAC-SHA256 signing secret. It is accepted only on create\nor rotation and is never returned by the API. The final-character restriction\nrejects non-canonical encodings with non-zero unused bits.\n"
}
}
} Responses
204
Future delivery attempts use the replacement secret.
400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}403 · application/problem+json
The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}409 · application/problem+json
The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}412 · application/problem+json
The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}422 · application/problem+json
The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}428 · application/problem+json
This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}GET /zugferd-pdfs/{zugferdPdfId}Fetch one ZUGFeRD PDF generation
Returns tenant-visible durable generation state. A completed resource includes the immutable output Beleg and exact processor/ruleset evidence; failures expose no internal diagnostic or storage identity.
Parameters
zugferdPdfId · path · required
Identifier of the durable ZUGFeRD PDF generation.
{
"type": "string",
"description": "Opaque durable ZUGFeRD PDF generation identifier.",
"pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
}Responses
200 · application/json
The generation and its current state.
{
"description": "Durable ZUGFeRD PDF state. Pending has neither result nor failure;\ncompleted has the new immutable output Beleg and exact generation evidence;\nfailed exposes only a stable public failure code.\n",
"oneOf": [
{
"type": "object",
"description": "A durable generation waiting for processing or a retry.",
"required": [
"id",
"validationId",
"invoiceDocumentId",
"visualDocumentId",
"target",
"recipe",
"status",
"requestedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable ZUGFeRD PDF generation identifier.",
"pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"validationId": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"invoiceDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"visualDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"target": {
"type": "object",
"description": "Frozen standard and profile selected by trusted server configuration.",
"required": [
"name",
"version",
"profile"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"recipe": {
"type": "object",
"description": "Frozen versioned generation recipe selected by trusted server configuration.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"status": {
"type": "string",
"const": "pending",
"x-enum-varnames": [
"ZUGFeRDPDFPendingStatusPending"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
}
}
},
{
"type": "object",
"description": "A terminal generation with immutable output and provenance evidence.",
"required": [
"id",
"validationId",
"invoiceDocumentId",
"visualDocumentId",
"target",
"recipe",
"status",
"requestedAt",
"completedAt",
"outputDocument",
"result"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable ZUGFeRD PDF generation identifier.",
"pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"validationId": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"invoiceDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"visualDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"target": {
"type": "object",
"description": "Frozen standard and profile selected by trusted server configuration.",
"required": [
"name",
"version",
"profile"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"recipe": {
"type": "object",
"description": "Frozen versioned generation recipe selected by trusted server configuration.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"status": {
"type": "string",
"const": "completed",
"x-enum-varnames": [
"ZUGFeRDPDFCompletedStatusCompleted"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"outputDocument": {
"type": "object",
"description": "Public metadata for the completed generation output. This Beleg is always\na newly derived, immutable archived PDF; its exact two-source lineage is\nretained server-side.\n",
"required": [
"id",
"origin",
"status",
"originalFilename",
"mediaType",
"sizeBytes",
"contentSha256",
"documentDate",
"classification",
"retentionUntil",
"createdAt",
"archivedAt"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"origin": {
"type": "string",
"const": "derived",
"x-enum-varnames": [
"ZUGFeRDPDFDocumentOriginDerived"
]
},
"status": {
"type": "string",
"const": "archived",
"x-enum-varnames": [
"ZUGFeRDPDFDocumentStatusArchived"
]
},
"originalFilename": {
"type": "string"
},
"mediaType": {
"type": "string",
"const": "application/pdf",
"x-enum-varnames": [
"ZUGFeRDPDFDocumentMediaTypeApplicationPDF"
]
},
"sizeBytes": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"contentSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"documentDate": {
"type": "string",
"format": "date"
},
"classification": {
"type": "string",
"description": "Trusted server-assigned Beleg class."
},
"retentionUntil": {
"type": "string",
"format": "date"
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"archivedAt": {
"type": "string",
"format": "date-time"
}
}
},
"result": {
"type": "object",
"description": "Exact immutable generation evidence reported by the sidecar.",
"required": [
"schema",
"invoiceSha256",
"visualSha256",
"output",
"standard",
"recipe",
"processor",
"ruleset"
],
"additionalProperties": false,
"properties": {
"schema": {
"type": "string",
"const": "devacc.einvoice.zugferd-pdf.v1",
"x-enum-varnames": [
"ZUGFeRDPDFResultSchemaV1"
]
},
"invoiceSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"visualSha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"output": {
"type": "object",
"description": "Exact output facts verified before the derived Beleg was archived.",
"required": [
"contentId",
"mediaType",
"sizeBytes",
"sha256",
"pdfConformance",
"embeddedFilename"
],
"additionalProperties": false,
"properties": {
"contentId": {
"type": "string",
"const": "output",
"x-enum-varnames": [
"ZUGFeRDPDFOutputContentIdOutput"
]
},
"mediaType": {
"type": "string",
"const": "application/pdf",
"x-enum-varnames": [
"ZUGFeRDPDFOutputMediaTypeApplicationPDF"
]
},
"sizeBytes": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"sha256": {
"type": "string",
"pattern": "^[0-9a-f]{64}$"
},
"pdfConformance": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "Conformance identity reported by the configured production sidecar.\nThis API records the evidence but does not independently certify it.\n"
},
"embeddedFilename": {
"type": "string",
"minLength": 1,
"maxLength": 255
}
}
},
"standard": {
"type": "object",
"description": "Frozen standard and profile selected by trusted server configuration.",
"required": [
"name",
"version",
"profile"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"recipe": {
"type": "object",
"description": "Frozen versioned generation recipe selected by trusted server configuration.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"processor": {
"type": "object",
"description": "Opaque ZUGFeRD sidecar runtime or versioned artifact identity.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"ruleset": {
"type": "object",
"description": "Opaque ZUGFeRD sidecar runtime or versioned artifact identity.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
}
}
}
}
},
{
"type": "object",
"description": "A terminal PDF-generation failure without sensitive diagnostics.",
"required": [
"id",
"validationId",
"invoiceDocumentId",
"visualDocumentId",
"target",
"recipe",
"status",
"requestedAt",
"completedAt",
"failure"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "Opaque durable ZUGFeRD PDF generation identifier.",
"pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"validationId": {
"type": "string",
"description": "Opaque durable e-invoice validation identifier.",
"pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"invoiceDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"visualDocumentId": {
"type": "string",
"description": "Opaque Beleg identifier. It does not encode storage identity.",
"pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
"examples": [
"doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
]
},
"target": {
"type": "object",
"description": "Frozen standard and profile selected by trusted server configuration.",
"required": [
"name",
"version",
"profile"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"profile": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"recipe": {
"type": "object",
"description": "Frozen versioned generation recipe selected by trusted server configuration.",
"required": [
"name",
"version"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"version": {
"type": "string",
"minLength": 1,
"maxLength": 256
}
}
},
"status": {
"type": "string",
"const": "failed",
"x-enum-varnames": [
"ZUGFeRDPDFFailedStatusFailed"
]
},
"requestedAt": {
"type": "string",
"format": "date-time"
},
"completedAt": {
"type": "string",
"format": "date-time"
},
"failure": {
"type": "object",
"description": "Stable public failure classification without internal diagnostics.",
"required": [
"code"
],
"additionalProperties": false,
"properties": {
"code": {
"type": "string",
"enum": [
"unsupported-source",
"generation-capacity-exceeded"
],
"x-enum-varnames": [
"ZUGFeRDPDFFailureCodeUnsupportedSource",
"ZUGFeRDPDFFailureCodeGenerationCapacityExceeded"
]
}
}
}
}
}
],
"discriminator": {
"propertyName": "status",
"mapping": {
"pending": "#/components/schemas/ZUGFeRDPDFPending",
"completed": "#/components/schemas/ZUGFeRDPDFCompleted",
"failed": "#/components/schemas/ZUGFeRDPDFFailed"
}
}
}400 · application/problem+json
The request is malformed or violates the contract.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}401 · application/problem+json
No valid tenant assertion. No data is read or written.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}404 · application/problem+json
No such resource in the calling tenant.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}default · application/problem+json
An error. Branch on `type`.
Required fields: type, title, status
{
"type": "object",
"description": "RFC 9457 problem detail.",
"required": [
"type",
"title",
"status"
],
"properties": {
"type": {
"type": "string",
"format": "uri",
"description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
"examples": [
"https://api.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}