Isolated test contract · 2026-10-15-test-github-archives-release
Accounting test API
Isolierte synthetische Konten, Perioden und Buchungsentwürfe. Keine Buchung, Archivierung, Exporte, Webhooks oder Provideraufrufe.
Current service status ↗Versioned guides and examples
Published local documents for revision 2026-10-15-test-github-archives-release. SDK guidance describes
integration options; no external SDK download is implied.
Overview · overview.md
# Accounting — isolierter Test
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.test.d0.eu/accounting. Maschine: Client Credentials mit private_key_jwt und DPoP. Signaturschlüssel bleiben ausschließlich im Serverprozess.
Quickstart · quickstart.md
# Accounting: Test in vier Schritten
1. Produkt und Organisationsberechtigung in der Console prüfen. Für Test 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.test.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. Einen synthetischen Mandanten mit getrennter Testberechtigung auswählen. Zwei Konten und eine Periode anlegen, dann einen ausgeglichenen Buchungsentwurf erzeugen. Keine Buchung, Archivierung, Exporte, Webhooks oder Provideraufrufe im Testprofil.
4. Nur die im `public-openapi.json` dieser Revision gelisteten Operationen verwenden. Testdaten und Test-Clients nie mit Produktion mischen.
Verfügbare Test-Scopes: `accounting.read`, `accounting.write`. 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`, `204`, `400`, `401`, `403`, `404`, `409`, `412`, `422`, `428`, `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-test-github-archives-release
- Neue unveränderliche Dokumentationsrevision. Die vorige Revision `2026-10-15-test-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-test-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-test-github-archives-release/examples/go.go` (SHA-256 `9db5b8cd981728a67d65a3cf315fdff6b875caf5eb2034be0ce317cfe1497bb5`). Es demonstriert den Client mit festem test-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-test-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`.
Test workflow
Use a dedicated test machine client for published API operations or a dedicated human session for the browser Explorer. Production credentials are not accepted.
Open Test Explorer →Published operations
Only public, implemented operations in this pinned bundle are actionable. Machine DPoP and human Bearer requirements remain separate.
| Method | Path | Operation | Readiness |
|---|---|---|---|
| GET | /reports/trial-balance | getTrialBalance | implemented |
| GET | /accounts | listAccounts | implemented |
| POST | /accounts | createAccount | implemented |
| GET | /accounts/{accountId} | getAccount | implemented |
| GET | /periods | listPeriods | implemented |
| POST | /periods | createPeriod | implemented |
| GET | /periods/{periodId} | getPeriod | 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 |
Operation reference
12 of 12 operations
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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"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.test.d0.eu/accounting/problems/period-sealed"
]
},
"title": {
"type": "string",
"description": "Short human-readable summary of the problem type."
},
"status": {
"type": "integer",
"minimum": 400,
"maximum": 599
},
"detail": {
"type": "string",
"description": "Human-readable explanation specific to this occurrence."
},
"instance": {
"type": "string",
"format": "uri-reference",
"description": "The request path this problem occurred on."
},
"errors": {
"type": "array",
"description": "Field-level detail, when the problem is a validation failure.",
"items": {
"type": "object",
"required": [
"detail"
],
"properties": {
"pointer": {
"type": "string",
"description": "JSON Pointer (RFC 6901) into the request body.",
"examples": [
"/lines/0/amount"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}