← All documentation

API reference · 2026-10-15-github-archives-release

Accounting

Buchhaltung mit organisationsgebundener Aktivierung, fachlichen Mandantenrechten, signierten Ereignissen und einer getrennten synthetischen Testumgebung.

Availability: Limited

Current service status ↗

Versioned guides and examples

Published local documents for revision 2026-10-15-github-archives-release. SDK guidance describes integration options; no external SDK download is implied.

Overview · overview.md
Download overview.md
# Accounting — Produktion

Maschinenzugriffe sind zusätzlich an einen fachlichen Mandanten gebunden. Beträge werden als exakte Dezimalstrings in Minor Units behandelt; Buchungsentwürfe bleiben bis zum expliziten Buchen ungebucht.

Quelle: devacc-api Commit 9725d58f26c058ae422b48b86be9029e61fe6bae, api/openapi.yaml. Diese Dokumentation und der gefilterte OpenAPI-Vertrag sind unveränderliche Snapshots. Quellqualifikation bedeutet keine bestätigte Live-Verfügbarkeit.

Die jeweils andere Umgebung benötigt eigene Clients, Grants, Daten und Signaturschlüssel. OAuth-Issuer: https://auth.d0.eu; Ressource: https://api.d0.eu/accounting. Maschine: Client Credentials mit private_key_jwt und DPoP. Signaturschlüssel bleiben ausschließlich im Serverprozess.

Lokale Mitgliedschaftsrechte umfassen `audit.read`; eine Berechtigungsmenge kann bis zu neun eindeutige Grants enthalten. Die Maschinen-OAuth-Scopes bleiben getrennt von diesen fachlichen Mandantenrechten.
Quickstart · quickstart.md
Download quickstart.md
# Accounting: Produktion in vier Schritten

1. Produkt und Organisationsberechtigung in der Console prüfen. Für Produktion einen eigenen Maschinenclient in d0-auth registrieren; nur die unten genannten Scopes freigeben.
2. Über `https://auth.d0.eu` ein Access Token für `https://api.d0.eu/accounting` mit `private_key_jwt` und DPoP beziehen. Den DPoP-Proof an genau den Ziel-Request binden; Nonce-Antworten gemäß Auth-Transport behandeln.
3. Mit accounting.access.manage einen Mandanten anlegen oder auswählen. Dessen ten_-Kennung als X-Accounting-Tenant binden, mit accounting.read GET /accounting/v1/accounts prüfen und für Änderungen accounting.write sowie einen stabilen Idempotency-Key verwenden. Mit If-Match nur gegen den zuletzt gelesenen ETag ändern.
4. Nur die im `public-openapi.json` dieser Revision gelisteten Operationen verwenden. Bei 429 die veröffentlichten technischen Limits beachten.

Verfügbare Produktions-Scopes: `accounting.read`, `accounting.write`, `accounting.documents.read`, `accounting.documents.write`, `accounting.periods.close`, `accounting.webhooks.manage`, `accounting.access.manage`, `accounting.exports.read`. Pro Client nur den tatsächlich benötigten Teil beantragen.

Go v0.1.1 ist über den öffentlichen Go-Modul-Proxy installierbar. TypeScript und Python v0.1.1 samt gemeinsamem Auth-Transport sind als geprüfte Archive im [GitHub-Release](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) verfügbar; die genauen Installationsschritte stehen in den SDK-Guides. Die drei Beispiele sind Offline-Fixtures ohne Live-Credentials oder Live-Requests.
Examples · examples/typescript.mjs
Download 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
Download 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
Download 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
Download errors.md
# Accounting — Fehler und Wiederholung

Der genaue Fehlerkörper und die operationellen Antworten stehen in `public-openapi.json`. In den öffentlichen Operationen dieser Revision sind die Statuscodes `200`, `201`, `202`, `204`, `400`, `401`, `403`, `404`, `409`, `410`, `412`, `413`, `422`, `428`, `502`, `503`, `default` deklariert. Nicht jeder Code gilt für jede Operation.

- `400`/`422`: Eingabe und geforderte Header gegen die konkrete Operation prüfen; keinen veränderten Request unter demselben Idempotency-Key wiederholen.
- `401`: Token, DPoP-Proof, Nonce, Audience und Clientprofil prüfen.
- `403`: Scope, Organisationsrolle und fachliche Zuordnung prüfen; keine breiteren Scopes erraten.
- `404`: Pfad, Ressource und Tenant-Kontext prüfen; keine Existenz fremder Ressourcen ableiten.
- `409`/`412`: Konflikt bzw. ETag-Vorbedingung durch erneutes Lesen und fachliche Entscheidung auflösen.
- `429`: technische Limitantwort und Reset-/Retry-Hinweis beachten.
- `5xx` oder Transportabbruch: Bei Mutationen denselben vom Aufrufer vergebenen Idempotency-Key verwenden, sofern die Operation ihn vorsieht; sonst erst den serverseitigen Zustand lesen. Keine blinde Wiederholung einer nicht-idempotenten Operation.

Problemantworten und Request-ID helfen bei der Diagnose. Keine Tokens, Schlüssel, Dokumentinhalte oder personenbezogenen Daten in Support-Logs kopieren.
Changelog · CHANGELOG.md
Download CHANGELOG.md
# Accounting 2026-10-15-github-archives-release

- Neue unveränderliche Dokumentationsrevision. Die vorige Revision `2026-10-15-go-011-release` bleibt bytegleich verfügbar; Quell-OpenAPI, öffentlicher Vertrag und klassifizierte Operationen sind unverändert.
- Das [GitHub-Release](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) stellt die geprüften TypeScript-Tarballs und Python-Wheels für accounting v0.1.1 sowie den Auth-Transport v0.1.0 bereit. Der ZIP-Hash ist `6c11b63a5ce5f24dff79d1f3d33c7879ff48831d66dd9029b37abf073152dd93`; der innere `SHA256SUMS`-Katalog wird vor Installation geprüft. Go v0.1.1 bleibt über den öffentlichen Modul-Proxy verfügbar.
- npm und PyPI sind keine Voraussetzungen für diese Distribution. Die installierten Offline-Beispiele wurden im Release-Build geprüft; Service-Rollout und SDK-Download sind getrennte Nachweise.
SDK guidance · sdk-typescript.md
Download sdk-typescript.md
# Accounting typescript SDK

Paket: `@dev-null-gmbh/accounting` v0.1.1, Auth-Transport `@dev-null-gmbh/auth-machine` v0.1.0. MIT-Lizenz; Node.js 24.21 bis unter 27.

Die [qualifizierte GitHub-Release-Datei](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) ist die direkte Distribution. Archiv und Prüfsumme herunterladen, dann äußere und innere SHA-256-Werte prüfen (unter Linux kann `sha256sum -c` statt `shasum -a 256 -c` verwendet werden):

```sh
curl -fLO https://github.com/dev-null-GmbH/d0-sdk/releases/download/sdk-2026-10-15/d0-sdk-2026-10-15.zip
curl -fLO https://github.com/dev-null-GmbH/d0-sdk/releases/download/sdk-2026-10-15/d0-sdk-2026-10-15.sha256
shasum -a 256 -c d0-sdk-2026-10-15.sha256
unzip d0-sdk-2026-10-15.zip -d d0-sdk-2026-10-15
(cd d0-sdk-2026-10-15 && shasum -a 256 -c SHA256SUMS)
```

Der äußere ZIP-Hash lautet `6c11b63a5ce5f24dff79d1f3d33c7879ff48831d66dd9029b37abf073152dd93`. Die Archive stammen aus [dem erfolgreichen Main-Build](https://github.com/dev-null-GmbH/d0-sdk/actions/runs/38748901791) bei `d0-sdk@6f2c39612a661ec557e96e5caff093a057e6e1de`. Das Release enthält SDKs und Auth-Transport, keine privaten Services oder Zugangsdaten.

Die beiden geprüften Tarballs lokal im Serverprojekt installieren (keine npm-Registry-Veröffentlichung erforderlich):

```sh
npm install --ignore-scripts --no-audit --no-fund ./d0-sdk-2026-10-15/npm/dev-null-gmbh-auth-machine-0.1.0.tgz ./d0-sdk-2026-10-15/npm/dev-null-gmbh-accounting-0.1.1.tgz
```

Das Offline-Beispiel dieser Revision liegt unter `catalog/v1/bundles/accounting/2026-10-15-github-archives-release/examples/typescript.mjs`. Das Paket ist für vertrauenswürdige Serveranwendungen gedacht; private Signaturschlüssel gehören nicht in Browser-Code. Öffentliche Operationen und Scopes stehen in `public-openapi.json`.
SDK guidance · sdk-go.md
Download sdk-go.md
# Accounting Go SDK

Paket: `github.com/dev-null-GmbH/d0-sdk/accounting/go` v0.1.1. Gemeinsamer Maschinen-Auth-Transport: `github.com/dev-null-GmbH/d0-sdk/auth/go` v0.1.0. Beide wurden über den öffentlichen Go-Modul-Proxy mit aktiver Checksum-Datenbank aus frischer, anonymer Umgebung installiert und geprüft. Lizenz: MIT.

```sh
go get github.com/dev-null-GmbH/d0-sdk/accounting/go@v0.1.1
```

Modul-Tag: `accounting/go/v0.1.1` auf `d0-sdk@8a56e28666be2321f5f73b6a9ce328fbac0b2155`; Auth-Tag: `auth/go/v0.1.0` (unverändert). Der API-Quellvertrag ist `devacc-api@9725d58f26c058ae422b48b86be9029e61fe6bae:api/openapi.yaml`. Go v0.1.0 bleibt unter seinem eigenen Tag als historische Version installierbar.

Das unveränderte Offline-Fixture aus `devacc-api@9725d58f26c058ae422b48b86be9029e61fe6bae:sdk/go/examples/fixture/main.go` liegt unter `catalog/v1/bundles/accounting/2026-10-15-github-archives-release/examples/go.go` (SHA-256 `9db5b8cd981728a67d65a3cf315fdff6b875caf5eb2034be0ce317cfe1497bb5`). Es demonstriert den Client mit festem production-Profil ohne Netzaufruf. Öffentliche Operationen und Scopes stehen ausschließlich in public-openapi.json.

Die übrigen Sprachpakete sind über das [geprüfte GitHub-Release](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) verfügbar. Go benötigt nur den oben gezeigten Modulbezug über den öffentlichen Proxy.
SDK guidance · sdk-python.md
Download sdk-python.md
# Accounting python SDK

Paket: `d0-accounting` v0.1.1, Auth-Transport `d0-auth-machine` v0.1.0. MIT-Lizenz; Python 3.14.

Die [qualifizierte GitHub-Release-Datei](https://github.com/dev-null-GmbH/d0-sdk/releases/tag/sdk-2026-10-15) ist die direkte Distribution. Archiv und Prüfsumme herunterladen, dann äußere und innere SHA-256-Werte prüfen (unter Linux kann `sha256sum -c` statt `shasum -a 256 -c` verwendet werden):

```sh
curl -fLO https://github.com/dev-null-GmbH/d0-sdk/releases/download/sdk-2026-10-15/d0-sdk-2026-10-15.zip
curl -fLO https://github.com/dev-null-GmbH/d0-sdk/releases/download/sdk-2026-10-15/d0-sdk-2026-10-15.sha256
shasum -a 256 -c d0-sdk-2026-10-15.sha256
unzip d0-sdk-2026-10-15.zip -d d0-sdk-2026-10-15
(cd d0-sdk-2026-10-15 && shasum -a 256 -c SHA256SUMS)
```

Der äußere ZIP-Hash lautet `6c11b63a5ce5f24dff79d1f3d33c7879ff48831d66dd9029b37abf073152dd93`. Die Archive stammen aus [dem erfolgreichen Main-Build](https://github.com/dev-null-GmbH/d0-sdk/actions/runs/38748901791) bei `d0-sdk@6f2c39612a661ec557e96e5caff093a057e6e1de`. Das Release enthält SDKs und Auth-Transport, keine privaten Services oder Zugangsdaten.

Die beiden geprüften Wheels in einer virtuellen Umgebung installieren (keine PyPI-Veröffentlichung erforderlich):

```sh
python3.14 -m venv .venv
.venv/bin/python -m pip install ./d0-sdk-2026-10-15/python/d0_auth_machine-0.1.0-py3-none-any.whl ./d0-sdk-2026-10-15/python/d0_accounting-0.1.1-py3-none-any.whl
```

Das Offline-Beispiel dieser Revision liegt unter `catalog/v1/bundles/accounting/2026-10-15-github-archives-release/examples/python.py`. Das Paket ist für vertrauenswürdige Serveranwendungen gedacht; private Signaturschlüssel gehören nicht in Browser-Code. Öffentliche Operationen und Scopes stehen in `public-openapi.json`.

Get started

  1. Accounting in der Console mit der eigenen Organisation verbinden und aktivieren.
  2. Die fachliche Mandantenzuordnung und die benötigten Rechte für die Integration vergeben.
  3. Maschinenclient in d0-auth für Accounting registrieren und private_key_jwt mit DPoP verwenden.
  4. Mit X-Accounting-Tenant und GET /accounting/v1/accounts den Zugriff prüfen.
Open Developer Console →

Operations

Implemented rows describe supported contract behavior. Product availability above still controls whether the runtime is open to customers. Declared and blocked rows describe contract intent or a release gate.

MethodPathOperationReadiness
GET/tax-ruleslistTaxRulesImplemented
POST/tax-calculationscalculateTaxImplemented
GET/reports/financial-statementsgetFinancialStatementsImplemented
GET/fiscal-yearslistFiscalYearsImplemented
POST/fiscal-yearscreateFiscalYearImplemented
GET/fiscal-years/{yearId}getFiscalYearImplemented
POST/fiscal-years/{yearId}/finalizefinalizeFiscalYearImplemented
POST/fiscal-years/{yearId}/closecloseFiscalYearImplemented
POST/fiscal-years/{yearId}/carryforwardcarryforwardFiscalYearImplemented
GET/reports/trial-balancegetTrialBalanceImplemented
GET/account-mappingslistAccountMappingsImplemented
POST/account-mappingspublishAccountMappingImplemented
GET/account-mappings/{mappingId}getAccountMappingImplemented
POST/accounts/{accountId}/retireretireAccountImplemented
GET/exports/tenantdownloadTenantExportImplemented
GET/tenantslistTenantsImplemented
POST/tenantscreateTenantImplemented
GET/tenants/{tenantId}/membershipslistMembershipsImplemented
POST/tenants/{tenantId}/membershipscreateMembershipImplemented
PUT/tenants/{tenantId}/memberships/{membershipId}replaceMembershipImplemented
GET/accountslistAccountsImplemented
POST/accountscreateAccountImplemented
GET/accounts/{accountId}getAccountImplemented
GET/accounts/{accountId}/statementgetAccountStatementImplemented
GET/accounts/{accountId}/balancesgetAccountBalancesImplemented
GET/periodslistPeriodsImplemented
POST/periodscreatePeriodImplemented
GET/periods/{periodId}getPeriodImplemented
POST/periods/{periodId}/festschreibenfestschreibenPeriodImplemented
GET/journal-entrieslistJournalEntriesImplemented
POST/journal-entriescreateJournalEntryDraftImplemented
GET/journal-entries/{entryId}getJournalEntryImplemented
PUT/journal-entries/{entryId}replaceJournalEntryDraftImplemented
DELETE/journal-entries/{entryId}discardJournalEntryDraftImplemented
POST/journal-entries/{entryId}/postpostJournalEntryImplemented
POST/journal-entries/{entryId}/reversereverseJournalEntryImplemented
POST/journal-entries/{entryId}/documents/{documentId}linkJournalEntryDocumentImplemented
GET/documentslistDocumentsImplemented
POST/documentscreateDocumentImplemented
GET/documents/{documentId}/sourceslistDocumentSourcesImplemented
GET/documents/{documentId}getDocumentImplemented
GET/documents/{documentId}/contentdownloadDocumentImplemented
POST/documents/{documentId}/upload-requestscreateDocumentUploadRequestImplemented
POST/documents/{documentId}/completecompleteDocumentImplemented
POST/documents/{documentId}/preservation-requestscreateDocumentPreservationImplemented
GET/document-preservation-requests/{preservationId}getDocumentPreservationImplemented
POST/documents/{documentId}/e-invoice-validationscreateEInvoiceValidationImplemented
GET/e-invoice-validations/{validationId}getEInvoiceValidationImplemented
POST/e-invoice-validations/{validationId}/zugferd-pdfscreateZUGFeRDPDFImplemented
GET/zugferd-pdfs/{zugferdPdfId}getZUGFeRDPDFImplemented
GET/webhook-endpointslistWebhookEndpointsImplemented
POST/webhook-endpointscreateWebhookEndpointImplemented
GET/webhook-endpoints/{webhookEndpointId}getWebhookEndpointImplemented
PUT/webhook-endpoints/{webhookEndpointId}replaceWebhookEndpointImplemented
DELETE/webhook-endpoints/{webhookEndpointId}deleteWebhookEndpointImplemented
PUT/webhook-endpoints/{webhookEndpointId}/secretrotateWebhookEndpointSecretImplemented

Operation reference

Parameters, request bodies and responses come from the filtered public OpenAPI contract for this revision. Required fields are marked in each schema’s required array.

56 of 56 operations

GET /account-mappingsList immutable account mapping revisions

Returns published mapping revisions in ascending version order for this tenant.

Parameters

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

Mapping identifier returned as nextCursor by the previous page.

{
  "description": "Opaque tenant-owned account mapping revision identifier.",
  "type": "string",
  "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
}

Responses

200 · application/json

Mapping revisions in version order.

Required fields: data

{
  "description": "Mapping revision identities in ascending version order.",
  "type": "object",
  "required": [
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "description": "Published revision identity and content digest.",
        "type": "object",
        "required": [
          "id",
          "version",
          "digest",
          "createdAt"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "description": "Opaque tenant-owned account mapping revision identifier.",
            "type": "string",
            "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "version": {
            "type": "integer",
            "format": "int64",
            "minimum": 1
          },
          "digest": {
            "type": "string",
            "pattern": "^sha256:[0-9a-f]{64}$"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    "nextCursor": {
      "description": "Opaque tenant-owned account mapping revision identifier.",
      "type": "string",
      "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /account-mappingsPublish an immutable account classification

Freezes explicit consumer classifications and account labels for reproducible reports. Every reportCode must have one classification and name.

Parameters

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: items

{
  "description": "Complete classification revision, subject also to the global mutation body byte limit.",
  "type": "object",
  "required": [
    "items"
  ],
  "additionalProperties": false,
  "properties": {
    "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 10000,
      "items": {
        "description": "Consumer-selected classification and report section for one account.",
        "type": "object",
        "required": [
          "accountId",
          "classification",
          "reportCode",
          "reportName"
        ],
        "additionalProperties": false,
        "properties": {
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "classification": {
            "description": "Explicit consumer classification for financial reporting.",
            "type": "string",
            "enum": [
              "asset",
              "liability",
              "equity",
              "income",
              "expense"
            ]
          },
          "reportCode": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "reportName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          }
        }
      }
    }
  }
}

Responses

201 · application/json

Immutable mapping revision.

Required fields: id, version, digest, createdAt, items

{
  "description": "A complete immutable tenant-owned account mapping.",
  "type": "object",
  "required": [
    "id",
    "version",
    "digest",
    "createdAt",
    "items"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "description": "Opaque tenant-owned account mapping revision identifier.",
      "type": "string",
      "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "version": {
      "type": "integer",
      "format": "int64",
      "minimum": 1
    },
    "digest": {
      "type": "string",
      "pattern": "^sha256:[0-9a-f]{64}$"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "items": {
      "type": "array",
      "items": {
        "description": "Immutable classification and account labels frozen at publication.",
        "type": "object",
        "required": [
          "accountId",
          "accountNo",
          "accountName",
          "classification",
          "reportCode",
          "reportName"
        ],
        "additionalProperties": false,
        "properties": {
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string"
          },
          "accountName": {
            "type": "string"
          },
          "classification": {
            "description": "Explicit consumer classification for financial reporting.",
            "type": "string",
            "enum": [
              "asset",
              "liability",
              "equity",
              "income",
              "expense"
            ]
          },
          "reportCode": {
            "type": "string"
          },
          "reportName": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /account-mappings/{mappingId}Fetch an immutable account mapping

Returns the complete frozen mapping if it belongs to this tenant.

Parameters

mappingId · path · required

Opaque tenant-owned account mapping revision identifier.

{
  "description": "Opaque tenant-owned account mapping revision identifier.",
  "type": "string",
  "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
}

Responses

200 · application/json

Immutable mapping revision with its complete account items.

Required fields: id, version, digest, createdAt, items

{
  "description": "A complete immutable tenant-owned account mapping.",
  "type": "object",
  "required": [
    "id",
    "version",
    "digest",
    "createdAt",
    "items"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "description": "Opaque tenant-owned account mapping revision identifier.",
      "type": "string",
      "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "version": {
      "type": "integer",
      "format": "int64",
      "minimum": 1
    },
    "digest": {
      "type": "string",
      "pattern": "^sha256:[0-9a-f]{64}$"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "items": {
      "type": "array",
      "items": {
        "description": "Immutable classification and account labels frozen at publication.",
        "type": "object",
        "required": [
          "accountId",
          "accountNo",
          "accountName",
          "classification",
          "reportCode",
          "reportName"
        ],
        "additionalProperties": false,
        "properties": {
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string"
          },
          "accountName": {
            "type": "string"
          },
          "classification": {
            "description": "Explicit consumer classification for financial reporting.",
            "type": "string",
            "enum": [
              "asset",
              "liability",
              "equity",
              "income",
              "expense"
            ]
          },
          "reportCode": {
            "type": "string"
          },
          "reportName": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /accountsList accounts

Accounts of the calling tenant, ordered by Kontonummer.

Parameters

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

Return items after this account — the `nextCursor` of the previous page.

{
  "type": "string",
  "description": "Opaque account identifier.",
  "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

A page of accounts.

Required fields: data

{
  "type": "object",
  "description": "One page of accounts, oldest Kontonummer first.",
  "required": [
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "A Konto in the tenant's chart of accounts.",
        "required": [
          "id",
          "accountNo",
          "name",
          "createdAt"
        ],
        "additionalProperties": false,
        "properties": {
          "retiredAt": {
            "description": "Retirement prevents new ordinary postings; historical Storno remains available.",
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "id": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string",
            "description": "Kontonummer within the tenant's chart of accounts.",
            "examples": [
              "1200"
            ]
          },
          "name": {
            "type": "string",
            "examples": [
              "Bank"
            ]
          },
          "accountType": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional account classification supplied by the consumer."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    "nextCursor": {
      "type": "string",
      "description": "Opaque account identifier.",
      "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /accountsCreate an account

Adds a Konto to the tenant's chart of accounts. `accountNo` is unique per tenant; creating a duplicate is `409 account-already-exists`.

Parameters

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: accountNo, name

{
  "type": "object",
  "description": "Fields accepted when adding a Konto.",
  "required": [
    "accountNo",
    "name"
  ],
  "additionalProperties": false,
  "properties": {
    "accountNo": {
      "type": "string",
      "minLength": 1,
      "maxLength": 32,
      "examples": [
        "1200"
      ]
    },
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200,
      "examples": [
        "Bank"
      ]
    },
    "accountType": {
      "type": [
        "string",
        "null"
      ],
      "maxLength": 64
    }
  }
}

Responses

201 · application/json

The created account.

Required fields: id, accountNo, name, createdAt

{
  "type": "object",
  "description": "A Konto in the tenant's chart of accounts.",
  "required": [
    "id",
    "accountNo",
    "name",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "retiredAt": {
      "description": "Retirement prevents new ordinary postings; historical Storno remains available.",
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "id": {
      "type": "string",
      "description": "Opaque account identifier.",
      "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "accountNo": {
      "type": "string",
      "description": "Kontonummer within the tenant's chart of accounts.",
      "examples": [
        "1200"
      ]
    },
    "name": {
      "type": "string",
      "examples": [
        "Bank"
      ]
    },
    "accountType": {
      "type": [
        "string",
        "null"
      ],
      "description": "Optional account classification supplied by the consumer."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /accounts/{accountId}Fetch one account

Returns the account if it belongs to the calling tenant, else 404.

Parameters

accountId · path · required

Identifier of the account, as returned when it was created.

{
  "type": "string",
  "description": "Opaque account identifier.",
  "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

The account.

Required fields: id, accountNo, name, createdAt

{
  "type": "object",
  "description": "A Konto in the tenant's chart of accounts.",
  "required": [
    "id",
    "accountNo",
    "name",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "retiredAt": {
      "description": "Retirement prevents new ordinary postings; historical Storno remains available.",
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "id": {
      "type": "string",
      "description": "Opaque account identifier.",
      "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "accountNo": {
      "type": "string",
      "description": "Kontonummer within the tenant's chart of accounts.",
      "examples": [
        "1200"
      ]
    },
    "name": {
      "type": "string",
      "examples": [
        "Bank"
      ]
    },
    "accountType": {
      "type": [
        "string",
        "null"
      ],
      "description": "Optional account classification supplied by the consumer."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /accounts/{accountId}/balancesRead exact account totals and balances by currency

Requires accounting.read. Only posted lines contribute, including Storno through their normal opposite sides. Uses the same asOf cutoff and inclusive date/currency filters as the account statement. Omitted asOf captures the latest committed tenant-wide posted entry; reuse the returned value to keep subsequent reads fixed. Unknown, foreign or draft snapshots are 400 invalid-snapshot. The literal empty always returns an empty ledger view. openingBalance is debit minus credit strictly before bookingDateFrom, or zero without a lower bound. debitTotal and creditTotal cover the selected date range. closingBalance is openingBalance plus debitTotal minus creditTotal. Positive balances mean debit; negative balances mean credit, independently of account type. This is cumulative posted history, not a fiscal-year opening or carry-forward operation. Currencies are never mixed or converted and results are ordered by currency code. With no currency filter, returns currencies with posted activity through bookingDateTo (including opening history); otherwise an unused currency returns one zero row. A wholly unused account has data: [] without a currency filter. All returned totals must fit signed int64 minor units; any overflow, including gross debit/credit totals with a representable net, fails the whole response with 422 balance-overflow. No rounded or partial totals are returned.

Parameters

accountId · path · required

Identifier of the account, as returned when it was created.

{
  "type": "string",
  "description": "Opaque account identifier.",
  "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

asOf · query

Inclusive posted-entry cutoff; omit for latest, or reuse a prior response's asOf.

{
  "type": "string",
  "description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
  "pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
  "examples": [
    "empty"
  ]
}

currency · query

Restrict to one currency without conversion; omit to include each separately.

{
  "type": "string",
  "description": "ISO-4217 alphabetic currency code.",
  "pattern": "^[A-Z]{3}$",
  "examples": [
    "EUR"
  ]
}

bookingDateFrom · query

Inclusive earliest booking date for movements; earlier history forms openingBalance.

{
  "type": "string",
  "format": "date"
}

bookingDateTo · query

Inclusive latest booking date; must not precede bookingDateFrom.

{
  "type": "string",
  "format": "date"
}

Responses

200 · application/json

Exact totals per currency at the returned posting snapshot.

Required fields: accountId, asOf, data

{
  "type": "object",
  "description": "Per-currency balances at a fixed posting cutoff; no currency conversion.",
  "required": [
    "accountId",
    "asOf",
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "accountId": {
      "type": "string",
      "description": "Opaque account identifier.",
      "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "asOf": {
      "type": "string",
      "description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
      "pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
      "examples": [
        "empty"
      ]
    },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "Exact debit/credit totals and signed balances in one currency.",
        "required": [
          "currency",
          "openingBalance",
          "debitTotal",
          "creditTotal",
          "closingBalance"
        ],
        "additionalProperties": false,
        "properties": {
          "currency": {
            "type": "string",
            "description": "ISO-4217 alphabetic currency code.",
            "pattern": "^[A-Z]{3}$",
            "examples": [
              "EUR"
            ]
          },
          "openingBalance": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "debitTotal": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "creditTotal": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "closingBalance": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          }
        }
      }
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /accounts/{accountId}/retireRetire an account for future ordinary postings

Retirement is irreversible and serializes with posting. Historical reads and exact Storno remain available; fresh-key retirement retries preserve the original timestamp.

Parameters

accountId · path · required

Identifier of the account, as returned when it was created.

{
  "type": "string",
  "description": "Opaque account identifier.",
  "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Responses

200 · application/json

Retired account (stable on repeated retirement).

Required fields: id, accountNo, name, createdAt

{
  "type": "object",
  "description": "A Konto in the tenant's chart of accounts.",
  "required": [
    "id",
    "accountNo",
    "name",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "retiredAt": {
      "description": "Retirement prevents new ordinary postings; historical Storno remains available.",
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "id": {
      "type": "string",
      "description": "Opaque account identifier.",
      "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "accountNo": {
      "type": "string",
      "description": "Kontonummer within the tenant's chart of accounts.",
      "examples": [
        "1200"
      ]
    },
    "name": {
      "type": "string",
      "examples": [
        "Bank"
      ]
    },
    "accountType": {
      "type": [
        "string",
        "null"
      ],
      "description": "Optional account classification supplied by the consumer."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /accounts/{accountId}/statementRead a posted Kontoblatt at a fixed booking state

Requires accounting.read. Returns individual posted lines for this account in ascending Buchungsnummer (seq), then lineNo order. Drafts are excluded. Multiple lines in the same Buchung remain distinct. Date bounds are inclusive; currency filters never convert amounts. accountNo is the frozen number as booked, not current chart metadata. Follow entryId to the journal entry or GET /documents?journalEntryId={entryId} for its immutable Beleg links; document reads require documents.read separately. Without asOf, captures the latest committed tenant-wide posted entry. The response's asOf can be reused across statements and balances. Later posts, including backdated entries, newly posted old drafts and later Storno, are excluded. This freezes posted evidence, not mutable chart data or a complete tenant export. The literal empty fixes an empty ledger even after later posts. Pass nextCursor as after and keep date/currency filters unchanged. The cursor carries the original snapshot, so asOf may be omitted on subsequent pages. An explicit conflicting asOf or a malformed, foreign or nonmatching cursor is 400 invalid-cursor. Unknown, foreign or draft asOf entries are 400 invalid-snapshot. Any committed posted entry can define a historical cutoff, even if it belongs to another account or currency in this tenant.

Parameters

accountId · path · required

Identifier of the account, as returned when it was created.

{
  "type": "string",
  "description": "Opaque account identifier.",
  "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

asOf · query

Inclusive posted-entry cutoff; omit for latest, or reuse a prior response's asOf.

{
  "type": "string",
  "description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
  "pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
  "examples": [
    "empty"
  ]
}

currency · query

Restrict to one currency without conversion; omit to include each separately.

{
  "type": "string",
  "description": "ISO-4217 alphabetic currency code.",
  "pattern": "^[A-Z]{3}$",
  "examples": [
    "EUR"
  ]
}

bookingDateFrom · query

Inclusive earliest booking date for movements; earlier history forms openingBalance.

{
  "type": "string",
  "format": "date"
}

bookingDateTo · query

Inclusive latest booking date; must not precede bookingDateFrom.

{
  "type": "string",
  "format": "date"
}

after · query

Opaque nextCursor from this account and the same date/currency filters.

{
  "type": "string",
  "description": "Opaque position including the posting snapshot; pass unchanged as after.",
  "maxLength": 73,
  "examples": [
    "v1:je_9GXQ8W5V4R3P2N1M0KJHGF7ED6:je_9GXQ8W5V4R3P2N1M0KJHGF7ED6:1"
  ]
}

Responses

200 · application/json

A page of immutable posted account movements.

Required fields: accountId, asOf, data

{
  "type": "object",
  "description": "A bounded page of posted lines at one stable booking cutoff.",
  "required": [
    "accountId",
    "asOf",
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "accountId": {
      "type": "string",
      "description": "Opaque account identifier.",
      "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "asOf": {
      "type": "string",
      "description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
      "pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
      "examples": [
        "empty"
      ]
    },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "One immutable posted line for the requested account.",
        "required": [
          "entryId",
          "seq",
          "lineNo",
          "bookingDate",
          "periodId",
          "accountNo",
          "side",
          "amount",
          "taxKey"
        ],
        "additionalProperties": false,
        "properties": {
          "taxRuleId": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
          },
          "bookingText": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 500,
            "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
          },
          "externalReference": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 255,
            "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
          },
          "entryId": {
            "type": "string",
            "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
            "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "seq": {
            "type": "integer",
            "format": "int64",
            "minimum": 1,
            "description": "The Buchungsnummer shared by every line in this entry."
          },
          "lineNo": {
            "type": "integer",
            "minimum": 1,
            "description": "Original position in the journal entry, not a page offset."
          },
          "bookingDate": {
            "type": "string",
            "format": "date"
          },
          "periodId": {
            "type": "string",
            "description": "Opaque period identifier.",
            "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string",
            "description": "Frozen Kontonummer as booked."
          },
          "side": {
            "type": "string",
            "description": "Buchungsseite — Soll (debit) or Haben (credit).",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "taxKey": {
            "type": [
              "string",
              "null"
            ]
          },
          "reversalOf": {
            "type": "string",
            "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
            "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          }
        }
      }
    },
    "nextCursor": {
      "type": "string",
      "description": "Opaque position including the posting snapshot; pass unchanged as after.",
      "maxLength": 73,
      "examples": [
        "v1:je_9GXQ8W5V4R3P2N1M0KJHGF7ED6:je_9GXQ8W5V4R3P2N1M0KJHGF7ED6:1"
      ]
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /document-preservation-requests/{preservationId}Fetch a preservation decision and its confirmed application state

Requires documents.read. The request and actor attribution are immutable. appliedAt and observed protection are present only after exact-version storage verification. A completed observation is historical evidence, not a live storage availability probe. Storage coordinates and credentials are not exposed.

Parameters

preservationId · path · required

Identifier of the durable document preservation request.

{
  "type": "string",
  "description": "Opaque durable preservation-request identifier.",
  "pattern": "^prsv_[0-9A-HJKMNP-TV-Z]{26}$"
}

Responses

200 · application/json

The tenant-visible request and its application state.

Required fields: id, documentId, requestedBy, requestedAt, reason, legalHold, status

{
  "description": "An immutable preservation decision and its durable execution status.",
  "type": "object",
  "required": [
    "id",
    "documentId",
    "requestedBy",
    "requestedAt",
    "reason",
    "legalHold",
    "status"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque durable preservation-request identifier.",
      "pattern": "^prsv_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "documentId": {
      "type": "string",
      "description": "Opaque Beleg identifier. It does not encode storage identity.",
      "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "requestedBy": {
      "type": "string",
      "description": "Opaque public membership identifier.",
      "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "requestedAt": {
      "type": "string",
      "format": "date-time"
    },
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 1000
    },
    "retainUntil": {
      "type": "string",
      "format": "date-time",
      "description": "Requested exclusive retention deadline, absent for a hold-only request."
    },
    "legalHold": {
      "type": "boolean",
      "description": "True requests a legal hold ON. False does not request any hold change."
    },
    "status": {
      "type": "string",
      "enum": [
        "pending",
        "applied"
      ],
      "x-enum-varnames": [
        "DocumentPreservationStatusPending",
        "DocumentPreservationStatusApplied"
      ]
    },
    "nextAttemptAt": {
      "type": "string",
      "format": "date-time",
      "description": "Earliest scheduled retry after a storage or verification failure."
    },
    "failureCode": {
      "type": "string",
      "enum": [
        "archive-unavailable",
        "source-integrity-mismatch",
        "protection-unconfirmed"
      ],
      "description": "Last retry reason. No provider errors or storage coordinates are exposed."
    },
    "appliedAt": {
      "type": "string",
      "format": "date-time",
      "description": "Time confirmed protection was committed to the audit record."
    },
    "observedRetainUntil": {
      "type": "string",
      "format": "date-time",
      "description": "Confirmed COMPLIANCE deadline, at least the requested protection."
    },
    "observedLegalHold": {
      "type": "boolean",
      "description": "Legal hold observed when the request was applied."
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /documentsList Belege and generated documents

Requires documents.read. Returns public metadata in ascending immutable document-ID order, independent of Belegdatum. Omitted filters include all documents; provided filters combine with AND. Date bounds are inclusive. journalEntryId selects direct links to a Buchung (including inherited Storno links), without exposing journal data. sourceDocumentId selects direct generated outputs, never transitive descendants. Unknown or foreign relationship IDs are 404; an existing resource with no matches gives an empty page. Read each output's sources to inspect source roles. Pass nextCursor as after with unchanged filters. The cursor must name a document in this tenant, even if it no longer matches the filters; malformed, unknown and foreign cursors are 400 invalid-cursor. Pagination is not a snapshot: concurrent commits and pending-to-archived transitions may change membership. Documents that become eligible before the cursor are not revisited; restart traversal to discover them. Unchanged data is traversed without skips or duplicates.

Parameters

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

The nextCursor from the previous page.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

status · query

Restrict to pending or archived documents.

{
  "type": "string",
  "description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
  "enum": [
    "pending",
    "archived"
  ]
}

origin · query

Restrict to uploaded originals or generated derivatives.

{
  "type": "string",
  "description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
  "enum": [
    "uploaded",
    "derived"
  ]
}

documentDateFrom · query

Inclusive earliest Belegdatum.

{
  "type": "string",
  "format": "date"
}

documentDateTo · query

Inclusive latest Belegdatum; must not precede documentDateFrom.

{
  "type": "string",
  "format": "date"
}

journalEntryId · query

Only documents directly linked to this tenant's Buchung.

{
  "type": "string",
  "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
  "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

sourceDocumentId · query

Only direct derivatives of this tenant's source document.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

A page of public document metadata.

Required fields: data

{
  "type": "object",
  "description": "One page in immutable document-ID order; not a snapshot across requests.",
  "required": [
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "Public metadata for an immutable Beleg declaration.",
        "required": [
          "id",
          "origin",
          "status",
          "originalFilename",
          "mediaType",
          "sizeBytes",
          "contentSha256",
          "documentDate",
          "classification",
          "retentionUntil",
          "createdAt",
          "archivedAt"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "description": "Opaque Beleg identifier. It does not encode storage identity.",
            "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "origin": {
            "type": "string",
            "description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
            "enum": [
              "uploaded",
              "derived"
            ]
          },
          "status": {
            "type": "string",
            "description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
            "enum": [
              "pending",
              "archived"
            ]
          },
          "originalFilename": {
            "type": "string"
          },
          "mediaType": {
            "type": "string"
          },
          "sizeBytes": {
            "type": "integer",
            "format": "int64",
            "minimum": 1
          },
          "contentSha256": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$"
          },
          "documentDate": {
            "type": "string",
            "format": "date"
          },
          "classification": {
            "type": "string",
            "description": "Trusted server-assigned Beleg class; never caller-selected."
          },
          "retentionUntil": {
            "type": "string",
            "format": "date",
            "description": "Inclusive legal retention date selected by the server."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "archivedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      }
    },
    "nextCursor": {
      "type": "string",
      "description": "Opaque Beleg identifier. It does not encode storage identity.",
      "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /documentsDeclare an immutable Buchungsbeleg upload

Creates a pending Buchungsbeleg and returns a short-lived, create-only PUT request for a direct upload. The checksum, exact byte length, media type, and COMPLIANCE Object Lock retention are all covered by the signature. `classification`, storage identity, retention policy, and retention horizon are server-owned. This public workflow always creates `buchungsbeleg`.

Parameters

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: originalFilename, mediaType, sizeBytes, contentSha256, documentDate

{
  "type": "object",
  "description": "Caller-known immutable metadata for a Buchungsbeleg upload.",
  "required": [
    "originalFilename",
    "mediaType",
    "sizeBytes",
    "contentSha256",
    "documentDate"
  ],
  "additionalProperties": false,
  "properties": {
    "originalFilename": {
      "type": "string",
      "minLength": 1,
      "description": "A UTF-8 basename of at most 255 bytes, never a path.",
      "examples": [
        "rechnung-2026-0042.pdf"
      ]
    },
    "mediaType": {
      "type": "string",
      "minLength": 3,
      "description": "Canonical media type covered by the upload signature, at most 255\nUTF-8 bytes.\n",
      "examples": [
        "application/pdf"
      ]
    },
    "sizeBytes": {
      "type": "integer",
      "format": "int64",
      "minimum": 1,
      "description": "Exact content length in bytes.",
      "examples": [
        48192
      ]
    },
    "contentSha256": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$",
      "description": "Exact SHA-256 digest in canonical lowercase hexadecimal.",
      "examples": [
        "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
      ]
    },
    "documentDate": {
      "type": "string",
      "format": "date",
      "description": "Belegdatum used to select the versioned retention policy."
    }
  }
}

Responses

201 · application/json

The pending Beleg and its first direct-upload request.

Required fields: document, upload

{
  "type": "object",
  "description": "A pending Beleg plus its first direct-upload request.",
  "required": [
    "document",
    "upload"
  ],
  "additionalProperties": false,
  "properties": {
    "document": {
      "type": "object",
      "description": "Public metadata for an immutable Beleg declaration.",
      "required": [
        "id",
        "origin",
        "status",
        "originalFilename",
        "mediaType",
        "sizeBytes",
        "contentSha256",
        "documentDate",
        "classification",
        "retentionUntil",
        "createdAt",
        "archivedAt"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "origin": {
          "type": "string",
          "description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
          "enum": [
            "uploaded",
            "derived"
          ]
        },
        "status": {
          "type": "string",
          "description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
          "enum": [
            "pending",
            "archived"
          ]
        },
        "originalFilename": {
          "type": "string"
        },
        "mediaType": {
          "type": "string"
        },
        "sizeBytes": {
          "type": "integer",
          "format": "int64",
          "minimum": 1
        },
        "contentSha256": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        },
        "documentDate": {
          "type": "string",
          "format": "date"
        },
        "classification": {
          "type": "string",
          "description": "Trusted server-assigned Beleg class; never caller-selected."
        },
        "retentionUntil": {
          "type": "string",
          "format": "date",
          "description": "Inclusive legal retention date selected by the server."
        },
        "createdAt": {
          "type": "string",
          "format": "date-time"
        },
        "archivedAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        }
      }
    },
    "upload": {
      "type": "object",
      "description": "Short-lived exact HTTP request for a direct immutable upload.",
      "required": [
        "url",
        "method",
        "headers",
        "expiresAt"
      ],
      "additionalProperties": false,
      "properties": {
        "url": {
          "type": "string",
          "format": "uri",
          "description": "Signed destination. Treat it as a secret until it expires."
        },
        "method": {
          "type": "string",
          "const": "PUT"
        },
        "headers": {
          "type": "object",
          "description": "Every header must be sent with the exact returned value.",
          "additionalProperties": {
            "type": "string"
          }
        },
        "expiresAt": {
          "type": "string",
          "format": "date-time"
        }
      }
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /documents/{documentId}Fetch one Beleg

Returns public lifecycle and declaration metadata. Storage keys, immutable object version ids, actor ids, and internal database ids are never exposed.

Parameters

documentId · path · required

Identifier of the Beleg.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

The Beleg.

Required fields: id, origin, status, originalFilename, mediaType, sizeBytes, contentSha256, documentDate, classification, retentionUntil, createdAt, archivedAt

{
  "type": "object",
  "description": "Public metadata for an immutable Beleg declaration.",
  "required": [
    "id",
    "origin",
    "status",
    "originalFilename",
    "mediaType",
    "sizeBytes",
    "contentSha256",
    "documentDate",
    "classification",
    "retentionUntil",
    "createdAt",
    "archivedAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque Beleg identifier. It does not encode storage identity.",
      "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "origin": {
      "type": "string",
      "description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
      "enum": [
        "uploaded",
        "derived"
      ]
    },
    "status": {
      "type": "string",
      "description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
      "enum": [
        "pending",
        "archived"
      ]
    },
    "originalFilename": {
      "type": "string"
    },
    "mediaType": {
      "type": "string"
    },
    "sizeBytes": {
      "type": "integer",
      "format": "int64",
      "minimum": 1
    },
    "contentSha256": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "documentDate": {
      "type": "string",
      "format": "date"
    },
    "classification": {
      "type": "string",
      "description": "Trusted server-assigned Beleg class; never caller-selected."
    },
    "retentionUntil": {
      "type": "string",
      "format": "date",
      "description": "Inclusive legal retention date selected by the server."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "archivedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /documents/{documentId}/completeVerify and archive an uploaded Beleg

Verifies the exact immutable object version, checksum, length, media type, and COMPLIANCE retention before atomically sealing the Beleg. Retrying the same completed upload is safe.

Parameters

documentId · path · required

Identifier of the Beleg.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Responses

200 · application/json

The archived Beleg.

Required fields: id, origin, status, originalFilename, mediaType, sizeBytes, contentSha256, documentDate, classification, retentionUntil, createdAt, archivedAt

{
  "type": "object",
  "description": "Public metadata for an immutable Beleg declaration.",
  "required": [
    "id",
    "origin",
    "status",
    "originalFilename",
    "mediaType",
    "sizeBytes",
    "contentSha256",
    "documentDate",
    "classification",
    "retentionUntil",
    "createdAt",
    "archivedAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque Beleg identifier. It does not encode storage identity.",
      "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "origin": {
      "type": "string",
      "description": "`uploaded` is an original caller-provided Beleg. `derived` is a new immutable\nserver-produced Beleg whose exact source lineage is retained independently.\n",
      "enum": [
        "uploaded",
        "derived"
      ]
    },
    "status": {
      "type": "string",
      "description": "`pending` awaits a verified direct or server-owned write; `archived` names\nan immutable, Object-Locked version whose evidence is sealed in the archive.\n",
      "enum": [
        "pending",
        "archived"
      ]
    },
    "originalFilename": {
      "type": "string"
    },
    "mediaType": {
      "type": "string"
    },
    "sizeBytes": {
      "type": "integer",
      "format": "int64",
      "minimum": 1
    },
    "contentSha256": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "documentDate": {
      "type": "string",
      "format": "date"
    },
    "classification": {
      "type": "string",
      "description": "Trusted server-assigned Beleg class; never caller-selected."
    },
    "retentionUntil": {
      "type": "string",
      "format": "date",
      "description": "Inclusive legal retention date selected by the server."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "archivedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /documents/{documentId}/contentDownload the original archived Beleg

Requires documents.read and an archived Beleg visible to the tenant. Returns the complete original bytes from the recorded immutable object version after verifying length and SHA-256. No storage coordinates or download credentials are disclosed. Partial and conditional requests are not supported; Range and conditional headers do not select another result. Pending documents and a deletion in progress return 409. A confirmed original deletion returns 410; document metadata and the disposition receipt remain available. Missing or unavailable archive objects return 503; inconsistent archive bytes or metadata return 502 before any file bytes are sent. Clients should verify Content-Digest and Content-Length as well.

Parameters

documentId · path · required

Identifier of the Beleg.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/octet-stream

The verified original bytes, downloaded as an attachment.

{
  "type": "string",
  "format": "binary"
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

410 · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

502 · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

503 · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /documents/{documentId}/e-invoice-validationsQueue validation of an archived XML e-invoice

Creates one durable validation request for the exact immutable object version sealed into the archived Beleg. The service submits those bytes to the standalone compliance platform under a deployment-pinned validation policy, then copies the verified exact result into its own immutable GoBD archive before publishing completion. Processing is asynchronous; poll the resource named by `Location` until its status is `completed` or `failed`. A completed validation with `result.valid: false` is a successful validation outcome, not a processing failure. Only archived `application/xml` Belege up to 20 MiB (20,971,520 bytes) are accepted. The source bytes and storage identity are never exposed by this operation.

Parameters

documentId · path · required

Identifier of the Beleg.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Responses

202 · application/json

The validation was durably queued, or an exact idempotent replay.

{
  "description": "Durable validation state. Branch on `status` before reading terminal\nfields: `pending` has neither result nor failure, `completed` has exactly\none result, and `failed` has exactly one public failure code.\n",
  "oneOf": [
    {
      "type": "object",
      "description": "A durable validation waiting for processing or a retry.",
      "required": [
        "id",
        "documentId",
        "status",
        "requestedAt"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "documentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "status": {
          "type": "string",
          "const": "pending",
          "x-enum-varnames": [
            "EInvoiceValidationPendingStatusPending"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        }
      }
    },
    {
      "type": "object",
      "description": "A terminal validation, whether the invoice is valid or invalid.",
      "required": [
        "id",
        "documentId",
        "status",
        "requestedAt",
        "completedAt",
        "result"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "documentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "status": {
          "type": "string",
          "const": "completed",
          "x-enum-varnames": [
            "EInvoiceValidationCompletedStatusCompleted"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        },
        "completedAt": {
          "type": "string",
          "format": "date-time"
        },
        "result": {
          "type": "object",
          "description": "Terminal result for the exact archived source. Validator and ruleset\nversions are opaque identities reported under the pinned standalone-platform\npolicy, never guessed by this service.\n",
          "required": [
            "schema",
            "sourceSha256",
            "valid",
            "syntax",
            "validator",
            "ruleset",
            "issues"
          ],
          "additionalProperties": false,
          "properties": {
            "schema": {
              "type": "string",
              "const": "devacc.einvoice.validation.v1",
              "x-enum-varnames": [
                "EInvoiceValidationResultSchemaV1"
              ]
            },
            "sourceSha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "SHA-256 of the exact immutable source version that was validated."
            },
            "valid": {
              "type": "boolean",
              "description": "False is a completed validation outcome, not a processing error."
            },
            "syntax": {
              "type": "string",
              "enum": [
                "ubl",
                "cii",
                "unknown"
              ],
              "x-enum-varnames": [
                "EInvoiceValidationSyntaxUBL",
                "EInvoiceValidationSyntaxCII",
                "EInvoiceValidationSyntaxUnknown"
              ],
              "description": "Canonical syntax classification. `valid: true` is only possible for\n`ubl` or `cii`; `unknown` is retained only for invalid outcomes.\n"
            },
            "profile": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2048,
              "description": "Optional non-empty profile identity of at most 2,048 UTF-8 bytes."
            },
            "validator": {
              "type": "object",
              "description": "Opaque processor runtime or versioned compliance-artifact identity.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Non-empty identity of at most 256 UTF-8 bytes."
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Non-empty opaque version of at most 256 UTF-8 bytes."
                }
              }
            },
            "ruleset": {
              "type": "object",
              "description": "Opaque processor runtime or versioned compliance-artifact identity.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Non-empty identity of at most 256 UTF-8 bytes."
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Non-empty opaque version of at most 256 UTF-8 bytes."
                }
              }
            },
            "issues": {
              "type": "array",
              "maxItems": 1000,
              "items": {
                "type": "object",
                "description": "One structured validator finding.",
                "required": [
                  "severity",
                  "code",
                  "message"
                ],
                "additionalProperties": false,
                "properties": {
                  "severity": {
                    "type": "string",
                    "enum": [
                      "error",
                      "warning",
                      "information"
                    ],
                    "x-enum-varnames": [
                      "EInvoiceValidationIssueSeverityError",
                      "EInvoiceValidationIssueSeverityWarning",
                      "EInvoiceValidationIssueSeverityInformation"
                    ]
                  },
                  "code": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256,
                    "description": "Non-empty stable finding code of at most 256 UTF-8 bytes."
                  },
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8192,
                    "description": "Non-empty finding text of at most 8,192 UTF-8 bytes."
                  },
                  "location": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8192,
                    "description": "Optional non-empty source location of at most 8,192 UTF-8 bytes."
                  }
                }
              }
            }
          }
        }
      }
    },
    {
      "type": "object",
      "description": "A terminal validation processing failure without sensitive diagnostics.",
      "required": [
        "id",
        "documentId",
        "status",
        "requestedAt",
        "completedAt",
        "failure"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "documentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "status": {
          "type": "string",
          "const": "failed",
          "x-enum-varnames": [
            "EInvoiceValidationFailedStatusFailed"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        },
        "completedAt": {
          "type": "string",
          "format": "date-time"
        },
        "failure": {
          "type": "object",
          "description": "Stable public failure classification; internal diagnostics are private.",
          "required": [
            "code"
          ],
          "additionalProperties": false,
          "properties": {
            "code": {
              "type": "string",
              "const": "validation-processing-failed",
              "x-enum-varnames": [
                "EInvoiceValidationFailureCodeValidationProcessingFailed"
              ]
            }
          }
        }
      }
    }
  ],
  "discriminator": {
    "propertyName": "status",
    "mapping": {
      "pending": "#/components/schemas/EInvoiceValidationPending",
      "completed": "#/components/schemas/EInvoiceValidationCompleted",
      "failed": "#/components/schemas/EInvoiceValidationFailed"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /documents/{documentId}/preservation-requestsRequest stronger preservation of an archived Beleg

Requires documents.write. Records the requesting actor, reason and requested protection without changing the original Beleg evidence. Requests may extend COMPLIANCE retention, set a legal hold ON, or both. Shortening, hold release and deletion are not supported. An extension must exceed the original storage deadline and every previously accepted extension for this Beleg. A 202 response confirms durable acceptance only. Poll the returned resource; applied means the worker has verified the requested protection on the original immutable object version. Storage outages leave the request pending for retry. Replaying the same Idempotency-Key returns the original acceptance response; use GET for current state. The retentionUntil on the original Document remains its initial, immutable policy evidence.

Parameters

documentId · path · required

Identifier of the Beleg.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: reason

{
  "type": "object",
  "required": [
    "reason"
  ],
  "minProperties": 2,
  "additionalProperties": false,
  "description": "Supply retainUntil, legalHold=true, or both, with a nonblank reason without\nleading or trailing whitespace. retainUntil is an exclusive whole-second\nUTC deadline, in the future and later than all accepted retention decisions.\nTo preserve through a calendar day, use the following day's UTC midnight.\n",
  "properties": {
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 1000
    },
    "retainUntil": {
      "type": "string",
      "format": "date-time",
      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(Z|[+-]00:00)$"
    },
    "legalHold": {
      "type": "boolean",
      "const": true
    }
  }
}

Responses

202 · application/json

The durable preservation request, awaiting storage confirmation.

Required fields: id, documentId, requestedBy, requestedAt, reason, legalHold, status

{
  "description": "An immutable preservation decision and its durable execution status.",
  "type": "object",
  "required": [
    "id",
    "documentId",
    "requestedBy",
    "requestedAt",
    "reason",
    "legalHold",
    "status"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque durable preservation-request identifier.",
      "pattern": "^prsv_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "documentId": {
      "type": "string",
      "description": "Opaque Beleg identifier. It does not encode storage identity.",
      "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "requestedBy": {
      "type": "string",
      "description": "Opaque public membership identifier.",
      "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "requestedAt": {
      "type": "string",
      "format": "date-time"
    },
    "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 1000
    },
    "retainUntil": {
      "type": "string",
      "format": "date-time",
      "description": "Requested exclusive retention deadline, absent for a hold-only request."
    },
    "legalHold": {
      "type": "boolean",
      "description": "True requests a legal hold ON. False does not request any hold change."
    },
    "status": {
      "type": "string",
      "enum": [
        "pending",
        "applied"
      ],
      "x-enum-varnames": [
        "DocumentPreservationStatusPending",
        "DocumentPreservationStatusApplied"
      ]
    },
    "nextAttemptAt": {
      "type": "string",
      "format": "date-time",
      "description": "Earliest scheduled retry after a storage or verification failure."
    },
    "failureCode": {
      "type": "string",
      "enum": [
        "archive-unavailable",
        "source-integrity-mismatch",
        "protection-unconfirmed"
      ],
      "description": "Last retry reason. No provider errors or storage coordinates are exposed."
    },
    "appliedAt": {
      "type": "string",
      "format": "date-time",
      "description": "Time confirmed protection was committed to the audit record."
    },
    "observedRetainUntil": {
      "type": "string",
      "format": "date-time",
      "description": "Confirmed COMPLIANCE deadline, at least the requested protection."
    },
    "observedLegalHold": {
      "type": "boolean",
      "description": "Legal hold observed when the request was applied."
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /documents/{documentId}/sourcesRead the direct sources of a generated Beleg

Requires documents.read. Returns the immutable direct source references, ordered by role. Uploaded originals return an empty data array. Currently the only derivation kind is zugferd-pdf, with exactly one invoice source and one visual source; this bounded set needs no pagination. Sources are visible as soon as a derived document is declared, including while it is pending. Each documentId can be resolved through GET /documents/{documentId}. Storage keys, object versions and internal identifiers stay private.

Parameters

documentId · path · required

Identifier of the Beleg.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

The complete, bounded set of direct source references.

Required fields: data

{
  "type": "object",
  "description": "All direct sources; empty for an uploaded original.",
  "required": [
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "data": {
      "type": "array",
      "maxItems": 2,
      "items": {
        "type": "object",
        "description": "One immutable edge from a generated Beleg to its direct source.",
        "required": [
          "documentId",
          "role",
          "kind"
        ],
        "additionalProperties": false,
        "properties": {
          "documentId": {
            "type": "string",
            "description": "Opaque Beleg identifier. It does not encode storage identity.",
            "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "role": {
            "type": "string",
            "description": "The source's role in generating the output.",
            "enum": [
              "invoice",
              "visual"
            ]
          },
          "kind": {
            "type": "string",
            "description": "The transformation which produced the requested output.",
            "enum": [
              "zugferd-pdf"
            ]
          }
        }
      }
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /documents/{documentId}/upload-requestsCreate a fresh upload request for a pending Beleg

Re-signs the pending document's original immutable declaration. Use a fresh `Idempotency-Key` after an earlier signed request expires. An archived Beleg can never receive another upload URL.

Parameters

documentId · path · required

Identifier of the Beleg.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Responses

200 · application/json

A fresh short-lived direct-upload request.

Required fields: url, method, headers, expiresAt

{
  "type": "object",
  "description": "Short-lived exact HTTP request for a direct immutable upload.",
  "required": [
    "url",
    "method",
    "headers",
    "expiresAt"
  ],
  "additionalProperties": false,
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "description": "Signed destination. Treat it as a secret until it expires."
    },
    "method": {
      "type": "string",
      "const": "PUT"
    },
    "headers": {
      "type": "object",
      "description": "Every header must be sent with the exact returned value.",
      "additionalProperties": {
        "type": "string"
      }
    },
    "expiresAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /e-invoice-validations/{validationId}Fetch one e-invoice validation

Returns the durable validation state if it belongs to the calling tenant, else 404. Terminal validation results include the exact validator and ruleset identities frozen by the standalone compliance platform. A processing failure exposes only a stable public code; internal diagnostics never cross this boundary.

Parameters

validationId · path · required

Identifier of the durable e-invoice validation request.

{
  "type": "string",
  "description": "Opaque durable e-invoice validation identifier.",
  "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

The validation request and its current state.

{
  "description": "Durable validation state. Branch on `status` before reading terminal\nfields: `pending` has neither result nor failure, `completed` has exactly\none result, and `failed` has exactly one public failure code.\n",
  "oneOf": [
    {
      "type": "object",
      "description": "A durable validation waiting for processing or a retry.",
      "required": [
        "id",
        "documentId",
        "status",
        "requestedAt"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "documentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "status": {
          "type": "string",
          "const": "pending",
          "x-enum-varnames": [
            "EInvoiceValidationPendingStatusPending"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        }
      }
    },
    {
      "type": "object",
      "description": "A terminal validation, whether the invoice is valid or invalid.",
      "required": [
        "id",
        "documentId",
        "status",
        "requestedAt",
        "completedAt",
        "result"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "documentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "status": {
          "type": "string",
          "const": "completed",
          "x-enum-varnames": [
            "EInvoiceValidationCompletedStatusCompleted"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        },
        "completedAt": {
          "type": "string",
          "format": "date-time"
        },
        "result": {
          "type": "object",
          "description": "Terminal result for the exact archived source. Validator and ruleset\nversions are opaque identities reported under the pinned standalone-platform\npolicy, never guessed by this service.\n",
          "required": [
            "schema",
            "sourceSha256",
            "valid",
            "syntax",
            "validator",
            "ruleset",
            "issues"
          ],
          "additionalProperties": false,
          "properties": {
            "schema": {
              "type": "string",
              "const": "devacc.einvoice.validation.v1",
              "x-enum-varnames": [
                "EInvoiceValidationResultSchemaV1"
              ]
            },
            "sourceSha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$",
              "description": "SHA-256 of the exact immutable source version that was validated."
            },
            "valid": {
              "type": "boolean",
              "description": "False is a completed validation outcome, not a processing error."
            },
            "syntax": {
              "type": "string",
              "enum": [
                "ubl",
                "cii",
                "unknown"
              ],
              "x-enum-varnames": [
                "EInvoiceValidationSyntaxUBL",
                "EInvoiceValidationSyntaxCII",
                "EInvoiceValidationSyntaxUnknown"
              ],
              "description": "Canonical syntax classification. `valid: true` is only possible for\n`ubl` or `cii`; `unknown` is retained only for invalid outcomes.\n"
            },
            "profile": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2048,
              "description": "Optional non-empty profile identity of at most 2,048 UTF-8 bytes."
            },
            "validator": {
              "type": "object",
              "description": "Opaque processor runtime or versioned compliance-artifact identity.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Non-empty identity of at most 256 UTF-8 bytes."
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Non-empty opaque version of at most 256 UTF-8 bytes."
                }
              }
            },
            "ruleset": {
              "type": "object",
              "description": "Opaque processor runtime or versioned compliance-artifact identity.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Non-empty identity of at most 256 UTF-8 bytes."
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Non-empty opaque version of at most 256 UTF-8 bytes."
                }
              }
            },
            "issues": {
              "type": "array",
              "maxItems": 1000,
              "items": {
                "type": "object",
                "description": "One structured validator finding.",
                "required": [
                  "severity",
                  "code",
                  "message"
                ],
                "additionalProperties": false,
                "properties": {
                  "severity": {
                    "type": "string",
                    "enum": [
                      "error",
                      "warning",
                      "information"
                    ],
                    "x-enum-varnames": [
                      "EInvoiceValidationIssueSeverityError",
                      "EInvoiceValidationIssueSeverityWarning",
                      "EInvoiceValidationIssueSeverityInformation"
                    ]
                  },
                  "code": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256,
                    "description": "Non-empty stable finding code of at most 256 UTF-8 bytes."
                  },
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8192,
                    "description": "Non-empty finding text of at most 8,192 UTF-8 bytes."
                  },
                  "location": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 8192,
                    "description": "Optional non-empty source location of at most 8,192 UTF-8 bytes."
                  }
                }
              }
            }
          }
        }
      }
    },
    {
      "type": "object",
      "description": "A terminal validation processing failure without sensitive diagnostics.",
      "required": [
        "id",
        "documentId",
        "status",
        "requestedAt",
        "completedAt",
        "failure"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "documentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "status": {
          "type": "string",
          "const": "failed",
          "x-enum-varnames": [
            "EInvoiceValidationFailedStatusFailed"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        },
        "completedAt": {
          "type": "string",
          "format": "date-time"
        },
        "failure": {
          "type": "object",
          "description": "Stable public failure classification; internal diagnostics are private.",
          "required": [
            "code"
          ],
          "additionalProperties": false,
          "properties": {
            "code": {
              "type": "string",
              "const": "validation-processing-failed",
              "x-enum-varnames": [
                "EInvoiceValidationFailureCodeValidationProcessingFailed"
              ]
            }
          }
        }
      }
    }
  ],
  "discriminator": {
    "propertyName": "status",
    "mapping": {
      "pending": "#/components/schemas/EInvoiceValidationPending",
      "completed": "#/components/schemas/EInvoiceValidationCompleted",
      "failed": "#/components/schemas/EInvoiceValidationFailed"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /e-invoice-validations/{validationId}/zugferd-pdfsQueue creation of an immutable ZUGFeRD PDF

Combines the exact CII XML from a completed, valid e-invoice validation with one immutable archived PDF visual source. Processing is durable and asynchronous; poll the resource named by `Location` until it is terminal. The server selects and freezes the ZUGFeRD standard, EN 16931 profile, and generation recipe. The original XML and visual Belege remain independently archived; the output is a new immutable derived Beleg with explicit lineage. UBL-to-CII conversion and visual rendering are deliberately not implicit.

Parameters

validationId · path · required

Identifier of the durable e-invoice validation request.

{
  "type": "string",
  "description": "Opaque durable e-invoice validation identifier.",
  "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: visualDocumentId

{
  "type": "object",
  "description": "The immutable PDF visual source to combine with validated CII XML.",
  "required": [
    "visualDocumentId"
  ],
  "additionalProperties": false,
  "properties": {
    "visualDocumentId": {
      "type": "string",
      "description": "Opaque Beleg identifier. It does not encode storage identity.",
      "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    }
  }
}

Responses

202 · application/json

The generation was durably queued. An exact Idempotency-Key replay returns its originally stored response; the same semantic request under a new key returns the already existing durable resource in its current state, which may already be terminal.

{
  "description": "Durable ZUGFeRD PDF state. Pending has neither result nor failure;\ncompleted has the new immutable output Beleg and exact generation evidence;\nfailed exposes only a stable public failure code.\n",
  "oneOf": [
    {
      "type": "object",
      "description": "A durable generation waiting for processing or a retry.",
      "required": [
        "id",
        "validationId",
        "invoiceDocumentId",
        "visualDocumentId",
        "target",
        "recipe",
        "status",
        "requestedAt"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable ZUGFeRD PDF generation identifier.",
          "pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "validationId": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "invoiceDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "visualDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "target": {
          "type": "object",
          "description": "Frozen standard and profile selected by trusted server configuration.",
          "required": [
            "name",
            "version",
            "profile"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "profile": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "recipe": {
          "type": "object",
          "description": "Frozen versioned generation recipe selected by trusted server configuration.",
          "required": [
            "name",
            "version"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "status": {
          "type": "string",
          "const": "pending",
          "x-enum-varnames": [
            "ZUGFeRDPDFPendingStatusPending"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        }
      }
    },
    {
      "type": "object",
      "description": "A terminal generation with immutable output and provenance evidence.",
      "required": [
        "id",
        "validationId",
        "invoiceDocumentId",
        "visualDocumentId",
        "target",
        "recipe",
        "status",
        "requestedAt",
        "completedAt",
        "outputDocument",
        "result"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable ZUGFeRD PDF generation identifier.",
          "pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "validationId": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "invoiceDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "visualDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "target": {
          "type": "object",
          "description": "Frozen standard and profile selected by trusted server configuration.",
          "required": [
            "name",
            "version",
            "profile"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "profile": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "recipe": {
          "type": "object",
          "description": "Frozen versioned generation recipe selected by trusted server configuration.",
          "required": [
            "name",
            "version"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "status": {
          "type": "string",
          "const": "completed",
          "x-enum-varnames": [
            "ZUGFeRDPDFCompletedStatusCompleted"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        },
        "completedAt": {
          "type": "string",
          "format": "date-time"
        },
        "outputDocument": {
          "type": "object",
          "description": "Public metadata for the completed generation output. This Beleg is always\na newly derived, immutable archived PDF; its exact two-source lineage is\nretained server-side.\n",
          "required": [
            "id",
            "origin",
            "status",
            "originalFilename",
            "mediaType",
            "sizeBytes",
            "contentSha256",
            "documentDate",
            "classification",
            "retentionUntil",
            "createdAt",
            "archivedAt"
          ],
          "additionalProperties": false,
          "properties": {
            "id": {
              "type": "string",
              "description": "Opaque Beleg identifier. It does not encode storage identity.",
              "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
              "examples": [
                "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
              ]
            },
            "origin": {
              "type": "string",
              "const": "derived",
              "x-enum-varnames": [
                "ZUGFeRDPDFDocumentOriginDerived"
              ]
            },
            "status": {
              "type": "string",
              "const": "archived",
              "x-enum-varnames": [
                "ZUGFeRDPDFDocumentStatusArchived"
              ]
            },
            "originalFilename": {
              "type": "string"
            },
            "mediaType": {
              "type": "string",
              "const": "application/pdf",
              "x-enum-varnames": [
                "ZUGFeRDPDFDocumentMediaTypeApplicationPDF"
              ]
            },
            "sizeBytes": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "contentSha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "documentDate": {
              "type": "string",
              "format": "date"
            },
            "classification": {
              "type": "string",
              "description": "Trusted server-assigned Beleg class."
            },
            "retentionUntil": {
              "type": "string",
              "format": "date"
            },
            "createdAt": {
              "type": "string",
              "format": "date-time"
            },
            "archivedAt": {
              "type": "string",
              "format": "date-time"
            }
          }
        },
        "result": {
          "type": "object",
          "description": "Exact immutable generation evidence reported by the sidecar.",
          "required": [
            "schema",
            "invoiceSha256",
            "visualSha256",
            "output",
            "standard",
            "recipe",
            "processor",
            "ruleset"
          ],
          "additionalProperties": false,
          "properties": {
            "schema": {
              "type": "string",
              "const": "devacc.einvoice.zugferd-pdf.v1",
              "x-enum-varnames": [
                "ZUGFeRDPDFResultSchemaV1"
              ]
            },
            "invoiceSha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "visualSha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "output": {
              "type": "object",
              "description": "Exact output facts verified before the derived Beleg was archived.",
              "required": [
                "contentId",
                "mediaType",
                "sizeBytes",
                "sha256",
                "pdfConformance",
                "embeddedFilename"
              ],
              "additionalProperties": false,
              "properties": {
                "contentId": {
                  "type": "string",
                  "const": "output",
                  "x-enum-varnames": [
                    "ZUGFeRDPDFOutputContentIdOutput"
                  ]
                },
                "mediaType": {
                  "type": "string",
                  "const": "application/pdf",
                  "x-enum-varnames": [
                    "ZUGFeRDPDFOutputMediaTypeApplicationPDF"
                  ]
                },
                "sizeBytes": {
                  "type": "integer",
                  "format": "int64",
                  "minimum": 1
                },
                "sha256": {
                  "type": "string",
                  "pattern": "^[0-9a-f]{64}$"
                },
                "pdfConformance": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Conformance identity reported by the configured production sidecar.\nThis API records the evidence but does not independently certify it.\n"
                },
                "embeddedFilename": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 255
                }
              }
            },
            "standard": {
              "type": "object",
              "description": "Frozen standard and profile selected by trusted server configuration.",
              "required": [
                "name",
                "version",
                "profile"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "profile": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                }
              }
            },
            "recipe": {
              "type": "object",
              "description": "Frozen versioned generation recipe selected by trusted server configuration.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                }
              }
            },
            "processor": {
              "type": "object",
              "description": "Opaque ZUGFeRD sidecar runtime or versioned artifact identity.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                }
              }
            },
            "ruleset": {
              "type": "object",
              "description": "Opaque ZUGFeRD sidecar runtime or versioned artifact identity.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                }
              }
            }
          }
        }
      }
    },
    {
      "type": "object",
      "description": "A terminal PDF-generation failure without sensitive diagnostics.",
      "required": [
        "id",
        "validationId",
        "invoiceDocumentId",
        "visualDocumentId",
        "target",
        "recipe",
        "status",
        "requestedAt",
        "completedAt",
        "failure"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable ZUGFeRD PDF generation identifier.",
          "pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "validationId": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "invoiceDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "visualDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "target": {
          "type": "object",
          "description": "Frozen standard and profile selected by trusted server configuration.",
          "required": [
            "name",
            "version",
            "profile"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "profile": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "recipe": {
          "type": "object",
          "description": "Frozen versioned generation recipe selected by trusted server configuration.",
          "required": [
            "name",
            "version"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "status": {
          "type": "string",
          "const": "failed",
          "x-enum-varnames": [
            "ZUGFeRDPDFFailedStatusFailed"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        },
        "completedAt": {
          "type": "string",
          "format": "date-time"
        },
        "failure": {
          "type": "object",
          "description": "Stable public failure classification without internal diagnostics.",
          "required": [
            "code"
          ],
          "additionalProperties": false,
          "properties": {
            "code": {
              "type": "string",
              "enum": [
                "unsupported-source",
                "generation-capacity-exceeded"
              ],
              "x-enum-varnames": [
                "ZUGFeRDPDFFailureCodeUnsupportedSource",
                "ZUGFeRDPDFFailureCodeGenerationCapacityExceeded"
              ]
            }
          }
        }
      }
    }
  ],
  "discriminator": {
    "propertyName": "status",
    "mapping": {
      "pending": "#/components/schemas/ZUGFeRDPDFPending",
      "completed": "#/components/schemas/ZUGFeRDPDFCompleted",
      "failed": "#/components/schemas/ZUGFeRDPDFFailed"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /exports/tenantDownload a complete tenant accounting snapshot

Requires explicit exports.read permission and accounting.exports.read machine scope. Returns a devacc.tenant-export.v1 ZIP containing versioned JSON datasets, a manifest with SHA-256 checksums, and available archived document originals verified against their immutable evidence. Includes discarded drafts, pending declarations, and public archive disposition receipts. A confirmed original deletion retains its document metadata and receipt but excludes its bytes. A deletion in progress returns retryable 409 before ZIP bytes are sent. All metadata comes from one tenant-scoped database snapshot. Original versions are pinned by that snapshot and verified before any ZIP bytes are sent. Stored journal hashes and sequence links are evidence; the public projection does not contain the private canonical hashing payload. The synchronous export is limited to 100000 records, 32 MiB of metadata, 512 MiB of original bytes and two minutes of preparation (the authorization lease may expire sooner). Exceeding a size limit returns 413 export-too-large; no successful truncated export is returned. Unavailable originals return 503 and integrity mismatches return 502. Range and conditional headers do not select a partial result. Verify Content-Length and Content-Digest after download; interruption or authorization expiry may truncate transport.

Responses

200 · application/zip

The complete verified ZIP, downloaded as an attachment.

{
  "type": "string",
  "format": "binary"
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

413 · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

502 · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

503 · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /fiscal-yearsList fiscal years

Returns fiscal years in start-date order for the calling tenant.

Parameters

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

Fiscal-year ID returned as nextCursor by the preceding page.

{
  "type": "string",
  "description": "Opaque fiscal-year identifier.",
  "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}

Responses

200 · application/json

One page of fiscal years.

Required fields: data

{
  "type": "object",
  "description": "One page of fiscal years.",
  "required": [
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "Tenant fiscal year and its finalization state.",
        "required": [
          "id",
          "label",
          "startsOn",
          "endsOn",
          "status",
          "createdAt"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "description": "Opaque fiscal-year identifier.",
            "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "label": {
            "type": "string"
          },
          "startsOn": {
            "type": "string",
            "format": "date"
          },
          "endsOn": {
            "type": "string",
            "format": "date"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "finalized"
            ],
            "x-enum-varnames": [
              "FiscalYearStatusOpen",
              "FiscalYearStatusFinalized"
            ],
            "description": "Finalized years cannot be changed."
          },
          "finalizedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    "nextCursor": {
      "type": "string",
      "description": "Opaque fiscal-year identifier.",
      "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /fiscal-yearsCreate a fiscal year

Creates an open fiscal year with inclusive dates; tenant years cannot overlap.

Parameters

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: label, startsOn, endsOn

{
  "type": "object",
  "description": "Inclusive fiscal-year date range chosen by the consumer.",
  "required": [
    "label",
    "startsOn",
    "endsOn"
  ],
  "additionalProperties": false,
  "properties": {
    "label": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64
    },
    "startsOn": {
      "type": "string",
      "format": "date"
    },
    "endsOn": {
      "type": "string",
      "format": "date"
    }
  }
}

Responses

201 · application/json

The created fiscal year.

Required fields: id, label, startsOn, endsOn, status, createdAt

{
  "type": "object",
  "description": "Tenant fiscal year and its finalization state.",
  "required": [
    "id",
    "label",
    "startsOn",
    "endsOn",
    "status",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque fiscal-year identifier.",
      "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "label": {
      "type": "string"
    },
    "startsOn": {
      "type": "string",
      "format": "date"
    },
    "endsOn": {
      "type": "string",
      "format": "date"
    },
    "status": {
      "type": "string",
      "enum": [
        "open",
        "finalized"
      ],
      "x-enum-varnames": [
        "FiscalYearStatusOpen",
        "FiscalYearStatusFinalized"
      ],
      "description": "Finalized years cannot be changed."
    },
    "finalizedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /fiscal-years/{yearId}Fetch one fiscal year

Returns one year of the calling tenant.

Parameters

yearId · path · required

Opaque fiscal-year identifier.

{
  "type": "string",
  "description": "Opaque fiscal-year identifier.",
  "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}

Responses

200 · application/json

The fiscal year.

Required fields: id, label, startsOn, endsOn, status, createdAt

{
  "type": "object",
  "description": "Tenant fiscal year and its finalization state.",
  "required": [
    "id",
    "label",
    "startsOn",
    "endsOn",
    "status",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque fiscal-year identifier.",
      "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "label": {
      "type": "string"
    },
    "startsOn": {
      "type": "string",
      "format": "date"
    },
    "endsOn": {
      "type": "string",
      "format": "date"
    },
    "status": {
      "type": "string",
      "enum": [
        "open",
        "finalized"
      ],
      "x-enum-varnames": [
        "FiscalYearStatusOpen",
        "FiscalYearStatusFinalized"
      ],
      "description": "Finalized years cannot be changed."
    },
    "finalizedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /fiscal-years/{yearId}/carryforwardPost an opening balance into the next fiscal year

Source year must be finalized; target starts on the following day. For one currency, derives source-year posted balances under the selected immutable mapping. Asset, liability and equity balances carry to the same accounts; remaining income and expense net goes to the explicit equity result account. The target year must have no earlier posted entries in that currency. One archived Beleg is attached to the ordinary journal post. A fresh-key retry with identical inputs returns the existing entry; a different transfer for either source or target year conflicts.

Parameters

yearId · path · required

Opaque fiscal-year identifier.

{
  "type": "string",
  "description": "Opaque fiscal-year identifier.",
  "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: targetYearId, targetPeriodId, mappingRevisionId, resultAccountId, documentId, currency

{
  "type": "object",
  "description": "Consumer-selected target and evidence for one-currency opening.",
  "required": [
    "targetYearId",
    "targetPeriodId",
    "mappingRevisionId",
    "resultAccountId",
    "documentId",
    "currency"
  ],
  "additionalProperties": false,
  "properties": {
    "targetYearId": {
      "type": "string",
      "description": "Opaque fiscal-year identifier.",
      "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "targetPeriodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "mappingRevisionId": {
      "description": "Opaque tenant-owned account mapping revision identifier.",
      "type": "string",
      "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "resultAccountId": {
      "type": "string",
      "description": "Opaque account identifier.",
      "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "documentId": {
      "type": "string",
      "description": "Opaque Beleg identifier. It does not encode storage identity.",
      "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "currency": {
      "type": "string",
      "pattern": "^[A-Z]{3}$"
    }
  }
}

Responses

200 · application/json

Posted opening entry or its existing representation.

Required fields: id, periodId, status, bookingDate, currency, lines, createdAt

{
  "type": "object",
  "description": "A Buchung — a draft, or a posted entry in the hash chain.",
  "required": [
    "id",
    "periodId",
    "status",
    "bookingDate",
    "currency",
    "lines",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "bookingText": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 500,
      "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
    },
    "externalReference": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255,
      "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
    },
    "id": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "status": {
      "type": "string",
      "description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
      "enum": [
        "draft",
        "posted"
      ]
    },
    "bookingDate": {
      "type": "string",
      "format": "date"
    },
    "currency": {
      "type": "string",
      "description": "ISO-4217 alphabetic currency code.",
      "pattern": "^[A-Z]{3}$",
      "examples": [
        "EUR"
      ]
    },
    "seq": {
      "type": [
        "integer",
        "null"
      ],
      "format": "int64",
      "description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
    },
    "entryHash": {
      "type": [
        "string",
        "null"
      ],
      "description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
      "pattern": "^[0-9a-f]{64}$"
    },
    "reversalOf": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "lines": {
      "type": "array",
      "minItems": 2,
      "items": {
        "type": "object",
        "description": "One line of a Buchung as booked.",
        "required": [
          "lineNo",
          "accountId",
          "accountNo",
          "side",
          "amount"
        ],
        "additionalProperties": false,
        "properties": {
          "taxRuleId": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
          },
          "lineNo": {
            "type": "integer",
            "description": "Position within the Buchung, starting at 1.",
            "minimum": 1
          },
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string",
            "description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
          },
          "side": {
            "type": "string",
            "description": "Buchungsseite — Soll (debit) or Haben (credit).",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "taxKey": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "postedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /fiscal-years/{yearId}/closeClose income and expense accounts

Derives every currency's income and expense balance from posted entries inside this year using an immutable caller-selected mapping. Posts inverse lines against an explicit equity result account with one archived Beleg, then seals the closing period in the same transaction. All other periods must already be sealed. If all P&L balances are zero, the period is sealed and entries is empty. A repeat with identical inputs returns the prior result.

Parameters

yearId · path · required

Opaque fiscal-year identifier.

{
  "type": "string",
  "description": "Opaque fiscal-year identifier.",
  "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: periodId, mappingRevisionId, resultAccountId, documentId

{
  "type": "object",
  "description": "Consumer-selected closing classification and evidence.",
  "required": [
    "periodId",
    "mappingRevisionId",
    "resultAccountId",
    "documentId"
  ],
  "additionalProperties": false,
  "properties": {
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "mappingRevisionId": {
      "description": "Opaque tenant-owned account mapping revision identifier.",
      "type": "string",
      "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "resultAccountId": {
      "type": "string",
      "description": "Opaque account identifier.",
      "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "documentId": {
      "type": "string",
      "description": "Opaque Beleg identifier. It does not encode storage identity.",
      "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    }
  }
}

Responses

200 · application/json

Posted closing entries and sealed period.

Required fields: entries, period

{
  "type": "object",
  "description": "Closing entries and the sealed period.",
  "required": [
    "entries",
    "period"
  ],
  "additionalProperties": false,
  "properties": {
    "entries": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "A Buchung — a draft, or a posted entry in the hash chain.",
        "required": [
          "id",
          "periodId",
          "status",
          "bookingDate",
          "currency",
          "lines",
          "createdAt"
        ],
        "additionalProperties": false,
        "properties": {
          "bookingText": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 500,
            "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
          },
          "externalReference": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 255,
            "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
          },
          "id": {
            "type": "string",
            "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
            "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "periodId": {
            "type": "string",
            "description": "Opaque period identifier.",
            "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "status": {
            "type": "string",
            "description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
            "enum": [
              "draft",
              "posted"
            ]
          },
          "bookingDate": {
            "type": "string",
            "format": "date"
          },
          "currency": {
            "type": "string",
            "description": "ISO-4217 alphabetic currency code.",
            "pattern": "^[A-Z]{3}$",
            "examples": [
              "EUR"
            ]
          },
          "seq": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
          },
          "entryHash": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
            "pattern": "^[0-9a-f]{64}$"
          },
          "reversalOf": {
            "type": "string",
            "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
            "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "lines": {
            "type": "array",
            "minItems": 2,
            "items": {
              "type": "object",
              "description": "One line of a Buchung as booked.",
              "required": [
                "lineNo",
                "accountId",
                "accountNo",
                "side",
                "amount"
              ],
              "additionalProperties": false,
              "properties": {
                "taxRuleId": {
                  "type": "string",
                  "maxLength": 128,
                  "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
                },
                "lineNo": {
                  "type": "integer",
                  "description": "Position within the Buchung, starting at 1.",
                  "minimum": 1
                },
                "accountId": {
                  "type": "string",
                  "description": "Opaque account identifier.",
                  "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
                  "examples": [
                    "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
                  ]
                },
                "accountNo": {
                  "type": "string",
                  "description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
                },
                "side": {
                  "type": "string",
                  "description": "Buchungsseite — Soll (debit) or Haben (credit).",
                  "enum": [
                    "debit",
                    "credit"
                  ]
                },
                "amount": {
                  "type": "object",
                  "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
                  "required": [
                    "amount",
                    "currency"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "amount": {
                      "type": "string",
                      "description": "Signed integer count of minor units, no separators, no exponent.",
                      "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                      "examples": [
                        "150000"
                      ]
                    },
                    "currency": {
                      "type": "string",
                      "description": "ISO-4217 alphabetic currency code.",
                      "pattern": "^[A-Z]{3}$",
                      "examples": [
                        "EUR"
                      ]
                    }
                  }
                },
                "taxKey": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "postedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      }
    },
    "period": {
      "type": "object",
      "description": "An accounting period and its Festschreibung state.",
      "required": [
        "id",
        "label",
        "startsOn",
        "endsOn",
        "status",
        "createdAt"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque period identifier.",
          "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "label": {
          "type": "string",
          "examples": [
            "2026-01"
          ]
        },
        "startsOn": {
          "type": "string",
          "format": "date"
        },
        "endsOn": {
          "type": "string",
          "format": "date",
          "description": "Inclusive last day of the period."
        },
        "status": {
          "type": "string",
          "description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
          "enum": [
            "open",
            "festgeschrieben"
          ]
        },
        "festgeschriebenAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "When the period was sealed; null while it is open."
        },
        "createdAt": {
          "type": "string",
          "format": "date-time"
        }
      }
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /fiscal-years/{yearId}/finalizeFinalize a fiscal year

Requires exact coverage by contained, festgeschrieben periods and no unposted drafts in the year. Finalization is irreversible. A fresh-key replay returns the original finalization time. P&L closing is optional; carryforward incorporates any remaining income or expense balance.

Parameters

yearId · path · required

Opaque fiscal-year identifier.

{
  "type": "string",
  "description": "Opaque fiscal-year identifier.",
  "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Responses

200 · application/json

The finalized fiscal year.

Required fields: id, label, startsOn, endsOn, status, createdAt

{
  "type": "object",
  "description": "Tenant fiscal year and its finalization state.",
  "required": [
    "id",
    "label",
    "startsOn",
    "endsOn",
    "status",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque fiscal-year identifier.",
      "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "label": {
      "type": "string"
    },
    "startsOn": {
      "type": "string",
      "format": "date"
    },
    "endsOn": {
      "type": "string",
      "format": "date"
    },
    "status": {
      "type": "string",
      "enum": [
        "open",
        "finalized"
      ],
      "x-enum-varnames": [
        "FiscalYearStatusOpen",
        "FiscalYearStatusFinalized"
      ],
      "description": "Finalized years cannot be changed."
    },
    "finalizedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /journal-entriesList journal entries and drafts

Entries of the calling tenant in ascending immutable entry-ID order, independent of booking date and posting sequence. Select `draft` or `posted` explicitly. Date bounds are inclusive and combine with periodId. Optional documentId restricts results to entries directly linked to that Beleg, including Storno entries with inherited links. Requires accounting.read; it returns journal data, not document metadata. Unknown or foreign documentId is 404 document-not-found. The optional externalReference filter uses an exact, case-sensitive match (no wildcards, trimming or Unicode normalization). References are not unique: an original and its Storno share the reference. Keep filters unchanged when passing nextCursor as after. The cursor must identify an entry visible to this tenant, even if it no longer matches the filters; malformed, unknown or foreign cursors are 400 invalid-cursor. Pagination is not a snapshot: concurrent commits and mutable drafts or status transitions can change membership between requests. Entries that become eligible before the cursor are not revisited; restart traversal to rediscover them. Unchanged data is traversed without skips or duplicates.

Parameters

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

The nextCursor from the previous page.

{
  "type": "string",
  "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
  "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

status · query · required

Select drafts or posted entries.

{
  "type": "string",
  "description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
  "enum": [
    "draft",
    "posted"
  ]
}

periodId · query

Restrict to this tenant's accounting period.

{
  "type": "string",
  "description": "Opaque period identifier.",
  "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

documentId · query

Only entries directly linked to this tenant's Beleg.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

bookingDateFrom · query

Inclusive earliest booking date.

{
  "type": "string",
  "format": "date"
}

bookingDateTo · query

Inclusive latest booking date; must not precede bookingDateFrom.

{
  "type": "string",
  "format": "date"
}

externalReference · query

Exact business reference; combines with all other filters. U+0000 is forbidden.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Responses

200 · application/json

A page of journal entries with their lines.

Required fields: data

{
  "type": "object",
  "description": "One page in immutable entry-ID order; not a snapshot across requests.",
  "required": [
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "A Buchung — a draft, or a posted entry in the hash chain.",
        "required": [
          "id",
          "periodId",
          "status",
          "bookingDate",
          "currency",
          "lines",
          "createdAt"
        ],
        "additionalProperties": false,
        "properties": {
          "bookingText": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 500,
            "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
          },
          "externalReference": {
            "type": [
              "string",
              "null"
            ],
            "minLength": 1,
            "maxLength": 255,
            "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
          },
          "id": {
            "type": "string",
            "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
            "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "periodId": {
            "type": "string",
            "description": "Opaque period identifier.",
            "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "status": {
            "type": "string",
            "description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
            "enum": [
              "draft",
              "posted"
            ]
          },
          "bookingDate": {
            "type": "string",
            "format": "date"
          },
          "currency": {
            "type": "string",
            "description": "ISO-4217 alphabetic currency code.",
            "pattern": "^[A-Z]{3}$",
            "examples": [
              "EUR"
            ]
          },
          "seq": {
            "type": [
              "integer",
              "null"
            ],
            "format": "int64",
            "description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
          },
          "entryHash": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
            "pattern": "^[0-9a-f]{64}$"
          },
          "reversalOf": {
            "type": "string",
            "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
            "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "lines": {
            "type": "array",
            "minItems": 2,
            "items": {
              "type": "object",
              "description": "One line of a Buchung as booked.",
              "required": [
                "lineNo",
                "accountId",
                "accountNo",
                "side",
                "amount"
              ],
              "additionalProperties": false,
              "properties": {
                "taxRuleId": {
                  "type": "string",
                  "maxLength": 128,
                  "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
                },
                "lineNo": {
                  "type": "integer",
                  "description": "Position within the Buchung, starting at 1.",
                  "minimum": 1
                },
                "accountId": {
                  "type": "string",
                  "description": "Opaque account identifier.",
                  "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
                  "examples": [
                    "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
                  ]
                },
                "accountNo": {
                  "type": "string",
                  "description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
                },
                "side": {
                  "type": "string",
                  "description": "Buchungsseite — Soll (debit) or Haben (credit).",
                  "enum": [
                    "debit",
                    "credit"
                  ]
                },
                "amount": {
                  "type": "object",
                  "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
                  "required": [
                    "amount",
                    "currency"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "amount": {
                      "type": "string",
                      "description": "Signed integer count of minor units, no separators, no exponent.",
                      "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                      "examples": [
                        "150000"
                      ]
                    },
                    "currency": {
                      "type": "string",
                      "description": "ISO-4217 alphabetic currency code.",
                      "pattern": "^[A-Z]{3}$",
                      "examples": [
                        "EUR"
                      ]
                    }
                  }
                },
                "taxKey": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "postedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      }
    },
    "nextCursor": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /journal-entriesCreate a draft Buchung

Creates an unposted (draft) Buchung and its lines. The draft is validated immediately — at least two lines, every amount positive, Soll and Haben equal, one currency throughout — but it takes no `seq` and enters no hash chain until it is posted. A draft in a period that is already festgeschrieben is rejected at post time, not here.

Parameters

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: periodId, bookingDate, currency, lines

{
  "type": "object",
  "description": "A balanced Buchung to draft.",
  "required": [
    "periodId",
    "bookingDate",
    "currency",
    "lines"
  ],
  "additionalProperties": false,
  "properties": {
    "bookingText": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 500,
      "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
    },
    "externalReference": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255,
      "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
    },
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "bookingDate": {
      "type": "string",
      "format": "date",
      "description": "Buchungsdatum; must fall inside the period."
    },
    "currency": {
      "type": "string",
      "description": "ISO-4217 alphabetic currency code.",
      "pattern": "^[A-Z]{3}$",
      "examples": [
        "EUR"
      ]
    },
    "lines": {
      "type": "array",
      "description": "At least two lines. Every line's currency must equal the entry's, and\nthe debit total must equal the credit total.\n",
      "minItems": 2,
      "items": {
        "type": "object",
        "description": "One line of a Buchung to create — a Konto, a side, and an amount.",
        "required": [
          "accountId",
          "side",
          "amount"
        ],
        "additionalProperties": false,
        "properties": {
          "taxRuleId": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
          },
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "side": {
            "type": "string",
            "description": "Buchungsseite — Soll (debit) or Haben (credit).",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "taxKey": {
            "type": [
              "string",
              "null"
            ],
            "description": "Steuerschlüssel.",
            "maxLength": 32
          }
        }
      }
    }
  }
}

Responses

201 · application/json

The created draft.

Required fields: id, periodId, status, bookingDate, currency, lines, createdAt

{
  "type": "object",
  "description": "A Buchung — a draft, or a posted entry in the hash chain.",
  "required": [
    "id",
    "periodId",
    "status",
    "bookingDate",
    "currency",
    "lines",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "bookingText": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 500,
      "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
    },
    "externalReference": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255,
      "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
    },
    "id": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "status": {
      "type": "string",
      "description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
      "enum": [
        "draft",
        "posted"
      ]
    },
    "bookingDate": {
      "type": "string",
      "format": "date"
    },
    "currency": {
      "type": "string",
      "description": "ISO-4217 alphabetic currency code.",
      "pattern": "^[A-Z]{3}$",
      "examples": [
        "EUR"
      ]
    },
    "seq": {
      "type": [
        "integer",
        "null"
      ],
      "format": "int64",
      "description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
    },
    "entryHash": {
      "type": [
        "string",
        "null"
      ],
      "description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
      "pattern": "^[0-9a-f]{64}$"
    },
    "reversalOf": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "lines": {
      "type": "array",
      "minItems": 2,
      "items": {
        "type": "object",
        "description": "One line of a Buchung as booked.",
        "required": [
          "lineNo",
          "accountId",
          "accountNo",
          "side",
          "amount"
        ],
        "additionalProperties": false,
        "properties": {
          "taxRuleId": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
          },
          "lineNo": {
            "type": "integer",
            "description": "Position within the Buchung, starting at 1.",
            "minimum": 1
          },
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string",
            "description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
          },
          "side": {
            "type": "string",
            "description": "Buchungsseite — Soll (debit) or Haben (credit).",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "taxKey": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "postedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
DELETE /journal-entries/{entryId}Discard a draft Buchung

Discards an unposted draft from item and list reads. Linked archived Buchungsbelege remain preserved. Posted entries reject discard with `409 entry-not-draft`. Requires the latest item ETag.

Parameters

entryId · path · required

Identifier of the Buchung.

{
  "type": "string",
  "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
  "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

If-Match · header · required

Exactly one strong item ETag observed from create, GET or replacement. Weak tags, wildcards and lists are rejected with 400. Missing tags return 428; stale tags return 412. Fetch again and retry with a fresh Idempotency-Key after a stale version.

{
  "type": "string",
  "pattern": "^\"je-v1-[A-Za-z0-9_-]{32}\"$"
}

Responses

204

The draft was discarded.

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

412 · application/problem+json

The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

428 · application/problem+json

This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /journal-entries/{entryId}Fetch one Buchung with its lines

Returns the Buchung and its lines in line order. A draft carries no `seq`, `entryHash` or `postedAt`; a posted one carries all three.

Parameters

entryId · path · required

Identifier of the Buchung.

{
  "type": "string",
  "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
  "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

The Buchung.

Required fields: id, periodId, status, bookingDate, currency, lines, createdAt

{
  "type": "object",
  "description": "A Buchung — a draft, or a posted entry in the hash chain.",
  "required": [
    "id",
    "periodId",
    "status",
    "bookingDate",
    "currency",
    "lines",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "bookingText": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 500,
      "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
    },
    "externalReference": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255,
      "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
    },
    "id": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "status": {
      "type": "string",
      "description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
      "enum": [
        "draft",
        "posted"
      ]
    },
    "bookingDate": {
      "type": "string",
      "format": "date"
    },
    "currency": {
      "type": "string",
      "description": "ISO-4217 alphabetic currency code.",
      "pattern": "^[A-Z]{3}$",
      "examples": [
        "EUR"
      ]
    },
    "seq": {
      "type": [
        "integer",
        "null"
      ],
      "format": "int64",
      "description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
    },
    "entryHash": {
      "type": [
        "string",
        "null"
      ],
      "description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
      "pattern": "^[0-9a-f]{64}$"
    },
    "reversalOf": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "lines": {
      "type": "array",
      "minItems": 2,
      "items": {
        "type": "object",
        "description": "One line of a Buchung as booked.",
        "required": [
          "lineNo",
          "accountId",
          "accountNo",
          "side",
          "amount"
        ],
        "additionalProperties": false,
        "properties": {
          "taxRuleId": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
          },
          "lineNo": {
            "type": "integer",
            "description": "Position within the Buchung, starting at 1.",
            "minimum": 1
          },
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string",
            "description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
          },
          "side": {
            "type": "string",
            "description": "Buchungsseite — Soll (debit) or Haben (credit).",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "taxKey": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "postedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
PUT /journal-entries/{entryId}Replace a draft Buchung

Replaces all draft accounting fields and lines. Omitted optional metadata is cleared. Identity, creation evidence and linked Buchungsbelege remain. Posted entries reject changes with `409 entry-not-draft`. Requires the latest item ETag; stale versions return `412 precondition-failed`.

Parameters

entryId · path · required

Identifier of the Buchung.

{
  "type": "string",
  "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
  "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

If-Match · header · required

Exactly one strong item ETag observed from create, GET or replacement. Weak tags, wildcards and lists are rejected with 400. Missing tags return 428; stale tags return 412. Fetch again and retry with a fresh Idempotency-Key after a stale version.

{
  "type": "string",
  "pattern": "^\"je-v1-[A-Za-z0-9_-]{32}\"$"
}

Request body

application/json · required

Required fields: periodId, bookingDate, currency, lines

{
  "type": "object",
  "description": "A balanced Buchung to draft.",
  "required": [
    "periodId",
    "bookingDate",
    "currency",
    "lines"
  ],
  "additionalProperties": false,
  "properties": {
    "bookingText": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 500,
      "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
    },
    "externalReference": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255,
      "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
    },
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "bookingDate": {
      "type": "string",
      "format": "date",
      "description": "Buchungsdatum; must fall inside the period."
    },
    "currency": {
      "type": "string",
      "description": "ISO-4217 alphabetic currency code.",
      "pattern": "^[A-Z]{3}$",
      "examples": [
        "EUR"
      ]
    },
    "lines": {
      "type": "array",
      "description": "At least two lines. Every line's currency must equal the entry's, and\nthe debit total must equal the credit total.\n",
      "minItems": 2,
      "items": {
        "type": "object",
        "description": "One line of a Buchung to create — a Konto, a side, and an amount.",
        "required": [
          "accountId",
          "side",
          "amount"
        ],
        "additionalProperties": false,
        "properties": {
          "taxRuleId": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
          },
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "side": {
            "type": "string",
            "description": "Buchungsseite — Soll (debit) or Haben (credit).",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "taxKey": {
            "type": [
              "string",
              "null"
            ],
            "description": "Steuerschlüssel.",
            "maxLength": 32
          }
        }
      }
    }
  }
}

Responses

200 · application/json

The replaced draft.

Required fields: id, periodId, status, bookingDate, currency, lines, createdAt

{
  "type": "object",
  "description": "A Buchung — a draft, or a posted entry in the hash chain.",
  "required": [
    "id",
    "periodId",
    "status",
    "bookingDate",
    "currency",
    "lines",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "bookingText": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 500,
      "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
    },
    "externalReference": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255,
      "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
    },
    "id": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "status": {
      "type": "string",
      "description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
      "enum": [
        "draft",
        "posted"
      ]
    },
    "bookingDate": {
      "type": "string",
      "format": "date"
    },
    "currency": {
      "type": "string",
      "description": "ISO-4217 alphabetic currency code.",
      "pattern": "^[A-Z]{3}$",
      "examples": [
        "EUR"
      ]
    },
    "seq": {
      "type": [
        "integer",
        "null"
      ],
      "format": "int64",
      "description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
    },
    "entryHash": {
      "type": [
        "string",
        "null"
      ],
      "description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
      "pattern": "^[0-9a-f]{64}$"
    },
    "reversalOf": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "lines": {
      "type": "array",
      "minItems": 2,
      "items": {
        "type": "object",
        "description": "One line of a Buchung as booked.",
        "required": [
          "lineNo",
          "accountId",
          "accountNo",
          "side",
          "amount"
        ],
        "additionalProperties": false,
        "properties": {
          "taxRuleId": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
          },
          "lineNo": {
            "type": "integer",
            "description": "Position within the Buchung, starting at 1.",
            "minimum": 1
          },
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string",
            "description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
          },
          "side": {
            "type": "string",
            "description": "Buchungsseite — Soll (debit) or Haben (credit).",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "taxKey": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "postedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

412 · application/problem+json

The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

428 · application/problem+json

This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /journal-entries/{entryId}/documents/{documentId}Link an archived Beleg to a draft Buchung

Links an archived Buchungsbeleg to a draft. The link is append-only and is included in the entry's audit hash when the Buchung is posted. Pending documents and entries that are already posted are rejected.

Parameters

entryId · path · required

Identifier of the Buchung.

{
  "type": "string",
  "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
  "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

documentId · path · required

Identifier of the Beleg.

{
  "type": "string",
  "description": "Opaque Beleg identifier. It does not encode storage identity.",
  "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Responses

204

The document is linked. Repeating the link is a no-op.

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /journal-entries/{entryId}/postPost a draft Buchung

Finalizes a draft: it is assigned the tenant's next `seq` (the legal Buchungsnummer), linked into the append-only hash chain, and becomes immutable. A `journal_entry.posted` event is emitted in the same transaction — the entry and its event commit together or not at all. Posting is terminal. Corrections are new reversal entries (Storno), never edits. Posting an entry that is not a draft is `409 entry-not-draft`; posting into a period that is festgeschrieben is `409 period-sealed`. At least one archived Buchungsbeleg must already be linked to the draft; otherwise posting is rejected with `422 beleg-required`. Optional If-Match binds posting to the reviewed draft revision under the posting lock. A stale version returns 412 without posting; omission preserves unconditional posting for existing clients.

Parameters

entryId · path · required

Identifier of the Buchung.

{
  "type": "string",
  "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
  "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

If-Match · header

Optional strong item ETag of the reviewed draft. Checked under the same lock as posting. A stale revision returns 412; omission preserves the existing unconditional posting behavior. Weak tags, wildcards, duplicate values and lists return 400. A failed request rolls back its key and can reuse it after reviewing the current draft. Use a new Idempotency-Key for a new intent after a previously successful request.

{
  "type": "string",
  "pattern": "^\"je-v1-[A-Za-z0-9_-]{32}\"$"
}

Responses

200 · application/json

The posted Buchung.

Required fields: id, periodId, status, bookingDate, currency, lines, createdAt

{
  "type": "object",
  "description": "A Buchung — a draft, or a posted entry in the hash chain.",
  "required": [
    "id",
    "periodId",
    "status",
    "bookingDate",
    "currency",
    "lines",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "bookingText": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 500,
      "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
    },
    "externalReference": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255,
      "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
    },
    "id": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "status": {
      "type": "string",
      "description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
      "enum": [
        "draft",
        "posted"
      ]
    },
    "bookingDate": {
      "type": "string",
      "format": "date"
    },
    "currency": {
      "type": "string",
      "description": "ISO-4217 alphabetic currency code.",
      "pattern": "^[A-Z]{3}$",
      "examples": [
        "EUR"
      ]
    },
    "seq": {
      "type": [
        "integer",
        "null"
      ],
      "format": "int64",
      "description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
    },
    "entryHash": {
      "type": [
        "string",
        "null"
      ],
      "description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
      "pattern": "^[0-9a-f]{64}$"
    },
    "reversalOf": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "lines": {
      "type": "array",
      "minItems": 2,
      "items": {
        "type": "object",
        "description": "One line of a Buchung as booked.",
        "required": [
          "lineNo",
          "accountId",
          "accountNo",
          "side",
          "amount"
        ],
        "additionalProperties": false,
        "properties": {
          "taxRuleId": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
          },
          "lineNo": {
            "type": "integer",
            "description": "Position within the Buchung, starting at 1.",
            "minimum": 1
          },
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string",
            "description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
          },
          "side": {
            "type": "string",
            "description": "Buchungsseite — Soll (debit) or Haben (credit).",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "taxKey": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "postedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

412 · application/problem+json

The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /journal-entries/{entryId}/reverseReverse a posted Buchung (Storno)

Creates and immediately posts a new immutable Storno. The server copies the original currency, lines, frozen Kontonummer snapshots and immutable Beleg evidence, swaps Soll and Haben, and sets `reversalOf` to the target. A `journal_entry.posted` event is emitted in the same transaction. The caller selects an open destination period and a booking date within that period because the original period may already be festgeschrieben. Only posted entries can be reversed. A second direct reversal is rejected with `409 entry-already-reversed`; reverse the Storno itself to undo it. Retry an uncertain response with the original `Idempotency-Key` for an exact replay; a fresh key represents a new write intent.

Parameters

entryId · path · required

Identifier of the Buchung.

{
  "type": "string",
  "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
  "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: periodId, bookingDate

{
  "type": "object",
  "description": "Posting coordinates for a new Storno; economic data, bookingText and externalReference are inherited unchanged from the original.",
  "required": [
    "periodId",
    "bookingDate"
  ],
  "additionalProperties": false,
  "properties": {
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "bookingDate": {
      "type": "string",
      "format": "date",
      "description": "Buchungsdatum; must fall inside the destination period."
    }
  }
}

Responses

201 · application/json

The newly created and posted Storno.

Required fields: id, periodId, status, bookingDate, currency, lines, createdAt

{
  "type": "object",
  "description": "A Buchung — a draft, or a posted entry in the hash chain.",
  "required": [
    "id",
    "periodId",
    "status",
    "bookingDate",
    "currency",
    "lines",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "bookingText": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 500,
      "description": "Buchungstext, preserved exactly and immutable once posted. Null or omitted means absent; U+0000 is forbidden."
    },
    "externalReference": {
      "type": [
        "string",
        "null"
      ],
      "minLength": 1,
      "maxLength": 255,
      "description": "Caller business reference, preserved exactly and immutable once posted. Not unique; use Idempotency-Key for retries. Null or omitted means absent; U+0000 is forbidden."
    },
    "id": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "periodId": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "status": {
      "type": "string",
      "description": "`draft` is mutable and carries no `seq`; `posted` is in the hash chain and\nimmutable — corrections are new reversal entries (Storno).\n",
      "enum": [
        "draft",
        "posted"
      ]
    },
    "bookingDate": {
      "type": "string",
      "format": "date"
    },
    "currency": {
      "type": "string",
      "description": "ISO-4217 alphabetic currency code.",
      "pattern": "^[A-Z]{3}$",
      "examples": [
        "EUR"
      ]
    },
    "seq": {
      "type": [
        "integer",
        "null"
      ],
      "format": "int64",
      "description": "The legal Buchungsnummer — gapless and strictly increasing per tenant.\nAssigned at posting; null on a draft.\n"
    },
    "entryHash": {
      "type": [
        "string",
        "null"
      ],
      "description": "Opaque server-side audit fingerprint for this chain link. The canonical\npayload intentionally includes private identifiers that are not exposed\nby the public API, so clients must not treat this as a recomputable proof.\nAssigned at posting; null on a draft.\n",
      "pattern": "^[0-9a-f]{64}$"
    },
    "reversalOf": {
      "type": "string",
      "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
      "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "lines": {
      "type": "array",
      "minItems": 2,
      "items": {
        "type": "object",
        "description": "One line of a Buchung as booked.",
        "required": [
          "lineNo",
          "accountId",
          "accountNo",
          "side",
          "amount"
        ],
        "additionalProperties": false,
        "properties": {
          "taxRuleId": {
            "type": "string",
            "maxLength": 128,
            "description": "Optional immutable published rule; requires matching taxKey and effective booking date."
          },
          "lineNo": {
            "type": "integer",
            "description": "Position within the Buchung, starting at 1.",
            "minimum": 1
          },
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string",
            "description": "The Kontonummer as booked — frozen at creation, so it keeps reading\ntrue even if the account is later renumbered (INVARIANT #10).\n"
          },
          "side": {
            "type": "string",
            "description": "Buchungsseite — Soll (debit) or Haben (credit).",
            "enum": [
              "debit",
              "credit"
            ]
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "taxKey": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "postedAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /periodsList accounting periods

Periods of the calling tenant, ordered by start date.

Parameters

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

Return items after this period — the `nextCursor` of the previous page.

{
  "type": "string",
  "description": "Opaque period identifier.",
  "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

A page of periods.

Required fields: data

{
  "type": "object",
  "description": "One page of periods, earliest start date first.",
  "required": [
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "An accounting period and its Festschreibung state.",
        "required": [
          "id",
          "label",
          "startsOn",
          "endsOn",
          "status",
          "createdAt"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "description": "Opaque period identifier.",
            "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "label": {
            "type": "string",
            "examples": [
              "2026-01"
            ]
          },
          "startsOn": {
            "type": "string",
            "format": "date"
          },
          "endsOn": {
            "type": "string",
            "format": "date",
            "description": "Inclusive last day of the period."
          },
          "status": {
            "type": "string",
            "description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
            "enum": [
              "open",
              "festgeschrieben"
            ]
          },
          "festgeschriebenAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the period was sealed; null while it is open."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    "nextCursor": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /periodsCreate an accounting period

Periods of one tenant may not overlap; an overlapping range is `409 period-overlap`. A new period starts `open`.

Parameters

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: label, startsOn, endsOn

{
  "type": "object",
  "description": "Fields accepted when opening a period.",
  "required": [
    "label",
    "startsOn",
    "endsOn"
  ],
  "additionalProperties": false,
  "properties": {
    "label": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "examples": [
        "2026-01"
      ]
    },
    "startsOn": {
      "type": "string",
      "format": "date"
    },
    "endsOn": {
      "type": "string",
      "format": "date",
      "description": "Inclusive last day; must not precede `startsOn`."
    }
  }
}

Responses

201 · application/json

The created period.

Required fields: id, label, startsOn, endsOn, status, createdAt

{
  "type": "object",
  "description": "An accounting period and its Festschreibung state.",
  "required": [
    "id",
    "label",
    "startsOn",
    "endsOn",
    "status",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "label": {
      "type": "string",
      "examples": [
        "2026-01"
      ]
    },
    "startsOn": {
      "type": "string",
      "format": "date"
    },
    "endsOn": {
      "type": "string",
      "format": "date",
      "description": "Inclusive last day of the period."
    },
    "status": {
      "type": "string",
      "description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
      "enum": [
        "open",
        "festgeschrieben"
      ]
    },
    "festgeschriebenAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When the period was sealed; null while it is open."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /periods/{periodId}Fetch one period

Returns the period if it belongs to the calling tenant, else 404.

Parameters

periodId · path · required

Identifier of the accounting period.

{
  "type": "string",
  "description": "Opaque period identifier.",
  "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

The period.

Required fields: id, label, startsOn, endsOn, status, createdAt

{
  "type": "object",
  "description": "An accounting period and its Festschreibung state.",
  "required": [
    "id",
    "label",
    "startsOn",
    "endsOn",
    "status",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "label": {
      "type": "string",
      "examples": [
        "2026-01"
      ]
    },
    "startsOn": {
      "type": "string",
      "format": "date"
    },
    "endsOn": {
      "type": "string",
      "format": "date",
      "description": "Inclusive last day of the period."
    },
    "status": {
      "type": "string",
      "description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
      "enum": [
        "open",
        "festgeschrieben"
      ]
    },
    "festgeschriebenAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When the period was sealed; null while it is open."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /periods/{periodId}/festschreibenFinalize an accounting period (Festschreibung)

Permanently seals the period. The database records the authoritative transition time and actor; neither value is caller-controlled. A fresh-key retry after an uncertain response is domain-idempotent and returns the existing terminal Period with its original `festgeschriebenAt`. Draft Buchungen may remain in the period, but they can no longer be posted. Festschreibung is irreversible; corrections remain new Storno entries.

Parameters

periodId · path · required

Identifier of the accounting period.

{
  "type": "string",
  "description": "Opaque period identifier.",
  "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Responses

200 · application/json

The sealed period, or its unchanged terminal representation.

Required fields: id, label, startsOn, endsOn, status, createdAt

{
  "type": "object",
  "description": "An accounting period and its Festschreibung state.",
  "required": [
    "id",
    "label",
    "startsOn",
    "endsOn",
    "status",
    "createdAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque period identifier.",
      "pattern": "^per_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "per_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "label": {
      "type": "string",
      "examples": [
        "2026-01"
      ]
    },
    "startsOn": {
      "type": "string",
      "format": "date"
    },
    "endsOn": {
      "type": "string",
      "format": "date",
      "description": "Inclusive last day of the period."
    },
    "status": {
      "type": "string",
      "description": "`open` accepts postings; `festgeschrieben` is sealed and immutable\n(Festschreibung, §146 AO).\n",
      "enum": [
        "open",
        "festgeschrieben"
      ]
    },
    "festgeschriebenAt": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "When the period was sealed; null while it is open."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /reports/financial-statementsRead mapped Bilanz and GuV for one fiscal year

Requires accounting.read. An explicit immutable mapping classifies every account with posted activity in the selected fiscal-year/currency/asOf view. Unknown or foreign year and mapping IDs return 404; missing account classification returns 422 incomplete-account-mapping, including accounts with zero net activity. Amounts use only booking dates inside the year and the inclusive asOf posting cutoff. Earlier years are excluded: opening balances must be ordinary evidence-backed entries or carryforward in this year. Automated fiscal-year closing entries are excluded so they cannot erase GuV movements or count the result twice in equity. Other posted entries, including opening and Storno, contribute normally. A stale asOf yields a historical report, not an assertion that finalization has occurred. Mappings and labels are supplied by the integrator, never inferred from account numbers or tax keys. Asset and expense amounts are debit minus credit; liability, equity and income use the opposite sign. result is income minus expense; balanceDifference is assets minus liabilities, equity and result. Each currency is separate. This is an accounting report under the chosen mapping, not statutory filing validation. Data sorts by classification, reportCode and currency; account drilldowns sort by the mapping's frozen accountNo then accountId. Follow accountId to its statement with the response dates and asOf. That statement also contains closing entries; use closingEntryIds to reconcile their exclusion. Empty views return empty arrays. More than 10000 account/currency rows returns 413 report-too-large; any signed-int64 amount overflow fails the whole response with 422 balance-overflow.

Parameters

fiscalYearId · query · required

Fiscal year whose inclusive dates delimit posted activity.

{
  "type": "string",
  "description": "Opaque fiscal-year identifier.",
  "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
}

mappingRevisionId · query · required

Immutable consumer-owned account classification.

{
  "description": "Opaque tenant-owned account mapping revision identifier.",
  "type": "string",
  "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
}

asOf · query

Inclusive posted-entry cutoff; omit for latest, or reuse a prior response's asOf.

{
  "type": "string",
  "description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
  "pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
  "examples": [
    "empty"
  ]
}

currency · query

Restrict to one currency without conversion; omit to include each separately.

{
  "type": "string",
  "description": "ISO-4217 alphabetic currency code.",
  "pattern": "^[A-Z]{3}$",
  "examples": [
    "EUR"
  ]
}

Responses

200 · application/json

Bilanz and GuV sections with account drilldowns and currency totals.

Required fields: asOf, fiscalYearId, mappingRevisionId, mappingDigest, bookingDateFrom, bookingDateTo, closingEntryIds, data, totals

{
  "type": "object",
  "description": "Reproducible year-scoped reports under an explicit immutable mapping.",
  "required": [
    "asOf",
    "fiscalYearId",
    "mappingRevisionId",
    "mappingDigest",
    "bookingDateFrom",
    "bookingDateTo",
    "closingEntryIds",
    "data",
    "totals"
  ],
  "additionalProperties": false,
  "properties": {
    "asOf": {
      "type": "string",
      "description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
      "pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
      "examples": [
        "empty"
      ]
    },
    "fiscalYearId": {
      "type": "string",
      "description": "Opaque fiscal-year identifier.",
      "pattern": "^fy_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "mappingRevisionId": {
      "description": "Opaque tenant-owned account mapping revision identifier.",
      "type": "string",
      "pattern": "^map_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "mappingDigest": {
      "type": "string",
      "pattern": "^sha256:[0-9a-f]{64}$"
    },
    "bookingDateFrom": {
      "type": "string",
      "format": "date"
    },
    "bookingDateTo": {
      "type": "string",
      "format": "date"
    },
    "closingEntryIds": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "Opaque Buchung identifier. Not the Buchungsnummer — that is `seq`.",
        "pattern": "^je_[0-9A-HJKMNP-TV-Z]{26}$",
        "examples": [
          "je_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
        ]
      }
    },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "One consumer-defined report section and its underlying accounts.",
        "required": [
          "classification",
          "reportCode",
          "reportName",
          "amount",
          "accounts"
        ],
        "additionalProperties": false,
        "properties": {
          "classification": {
            "description": "Explicit consumer classification for financial reporting.",
            "type": "string",
            "enum": [
              "asset",
              "liability",
              "equity",
              "income",
              "expense"
            ]
          },
          "reportCode": {
            "type": "string"
          },
          "reportName": {
            "type": "string"
          },
          "amount": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "accounts": {
            "type": "array",
            "items": {
              "type": "object",
              "description": "One account's year-scoped net in its classification's sign convention.",
              "required": [
                "accountId",
                "accountNo",
                "accountName",
                "amount"
              ],
              "additionalProperties": false,
              "properties": {
                "accountId": {
                  "type": "string",
                  "description": "Opaque account identifier.",
                  "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
                  "examples": [
                    "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
                  ]
                },
                "accountNo": {
                  "type": "string"
                },
                "accountName": {
                  "type": "string"
                },
                "amount": {
                  "type": "object",
                  "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
                  "required": [
                    "amount",
                    "currency"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "amount": {
                      "type": "string",
                      "description": "Signed integer count of minor units, no separators, no exponent.",
                      "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                      "examples": [
                        "150000"
                      ]
                    },
                    "currency": {
                      "type": "string",
                      "description": "ISO-4217 alphabetic currency code.",
                      "pattern": "^[A-Z]{3}$",
                      "examples": [
                        "EUR"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "totals": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "Separate balance sheet and profit/loss control totals in one currency.",
        "required": [
          "currency",
          "assets",
          "liabilities",
          "equity",
          "income",
          "expense",
          "result",
          "balanceDifference"
        ],
        "additionalProperties": false,
        "properties": {
          "currency": {
            "type": "string",
            "description": "ISO-4217 alphabetic currency code.",
            "pattern": "^[A-Z]{3}$",
            "examples": [
              "EUR"
            ]
          },
          "assets": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "liabilities": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "equity": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "income": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "expense": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "result": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "balanceDifference": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          }
        }
      }
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /reports/trial-balanceRead a complete Summen- und Saldenliste at one posting cutoff

Requires accounting.read. Returns posted opening, debit, credit and closing amounts per account and currency, plus currency totals. Uses the same asOf and inclusive date filters as account balances. Drafts never contribute; Storno contributes its ordinary opposite lines. accountNo comes from the latest participating posted line by seq/lineNo, including opening history. Renumbering without a new posting cannot alter a report, and all numbers of one account aggregate together. Rows sort by accountNo, accountId and currency; totals sort by currency. Unused accounts/currencies are omitted, including with a currency filter; empty views use empty arrays. Positive balances are debit, negative credit. This is cumulative history, not a fiscal-year report; use financial-statements for year-scoped reporting. A maximum of 10000 rows including totals is returned atomically; exceeding the bound is 413 report-too-large. Every amount must fit signed int64 minor units, including gross currency totals; otherwise 422 balance-overflow. No partial or rounded report is returned.

Parameters

asOf · query

Inclusive posted-entry cutoff; omit for latest, or reuse a prior response's asOf.

{
  "type": "string",
  "description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
  "pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
  "examples": [
    "empty"
  ]
}

currency · query

Restrict to one currency without conversion; omit to include each separately.

{
  "type": "string",
  "description": "ISO-4217 alphabetic currency code.",
  "pattern": "^[A-Z]{3}$",
  "examples": [
    "EUR"
  ]
}

bookingDateFrom · query

Inclusive earliest booking date for movements; earlier history forms openingBalance.

{
  "type": "string",
  "format": "date"
}

bookingDateTo · query

Inclusive latest booking date; must not precede bookingDateFrom.

{
  "type": "string",
  "format": "date"
}

Responses

200 · application/json

Complete account rows and per-currency control totals.

Required fields: asOf, data, totals

{
  "type": "object",
  "description": "Summen- und Saldenliste with exact currency control totals.",
  "required": [
    "asOf",
    "data",
    "totals"
  ],
  "additionalProperties": false,
  "properties": {
    "asOf": {
      "type": "string",
      "description": "A posted tenant entry's public ID, or empty for the permanent zero cutoff.",
      "pattern": "^(empty|je_[0-9A-HJKMNP-TV-Z]{26})$",
      "examples": [
        "empty"
      ]
    },
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "Exact totals for one account and currency.",
        "required": [
          "accountId",
          "accountNo",
          "currency",
          "openingBalance",
          "debitTotal",
          "creditTotal",
          "closingBalance"
        ],
        "additionalProperties": false,
        "properties": {
          "accountId": {
            "type": "string",
            "description": "Opaque account identifier.",
            "pattern": "^acct_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "acct_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "accountNo": {
            "type": "string",
            "description": "Account number from the latest participating posted line."
          },
          "currency": {
            "type": "string",
            "description": "ISO-4217 alphabetic currency code.",
            "pattern": "^[A-Z]{3}$",
            "examples": [
              "EUR"
            ]
          },
          "openingBalance": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "debitTotal": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "creditTotal": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "closingBalance": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          }
        }
      }
    },
    "totals": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "Exact debit/credit totals and signed balances in one currency.",
        "required": [
          "currency",
          "openingBalance",
          "debitTotal",
          "creditTotal",
          "closingBalance"
        ],
        "additionalProperties": false,
        "properties": {
          "currency": {
            "type": "string",
            "description": "ISO-4217 alphabetic currency code.",
            "pattern": "^[A-Z]{3}$",
            "examples": [
              "EUR"
            ]
          },
          "openingBalance": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "debitTotal": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "creditTotal": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          },
          "closingBalance": {
            "type": "object",
            "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
            "required": [
              "amount",
              "currency"
            ],
            "additionalProperties": false,
            "properties": {
              "amount": {
                "type": "string",
                "description": "Signed integer count of minor units, no separators, no exponent.",
                "pattern": "^-?(0|[1-9][0-9]{0,18})$",
                "examples": [
                  "150000"
                ]
              },
              "currency": {
                "type": "string",
                "description": "ISO-4217 alphabetic currency code.",
                "pattern": "^[A-Z]{3}$",
                "examples": [
                  "EUR"
                ]
              }
            }
          }
        }
      }
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /tax-calculationsCalculate tax from an explicitly selected published rule

Calculates an exact amount using the selected rule and its effective dates. It makes no posting or legal classification decision.

Parameters

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: taxRuleId, bookingDate, net

{
  "description": "Explicit net amount, booking date and qualified rule.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "taxRuleId",
    "bookingDate",
    "net"
  ],
  "properties": {
    "taxRuleId": {
      "type": "string",
      "maxLength": 128
    },
    "bookingDate": {
      "type": "string",
      "format": "date"
    },
    "net": {
      "type": "object",
      "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
      "required": [
        "amount",
        "currency"
      ],
      "additionalProperties": false,
      "properties": {
        "amount": {
          "type": "string",
          "description": "Signed integer count of minor units, no separators, no exponent.",
          "pattern": "^-?(0|[1-9][0-9]{0,18})$",
          "examples": [
            "150000"
          ]
        },
        "currency": {
          "type": "string",
          "description": "ISO-4217 alphabetic currency code.",
          "pattern": "^[A-Z]{3}$",
          "examples": [
            "EUR"
          ]
        }
      }
    }
  }
}

Responses

200 · application/json

Exact calculation and immutable rule evidence.

Required fields: tax, evidence

{
  "description": "Exact rounded tax with the selected rule provenance.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "tax",
    "evidence"
  ],
  "properties": {
    "tax": {
      "type": "object",
      "description": "An exact monetary amount. `amount` is an integer string in the currency's\nMINOR units (cents for EUR) — never a JSON number, so it cannot be rounded\nthrough a binary float. `\"150000\"` with currency `EUR` is 1500,00 €.\n",
      "required": [
        "amount",
        "currency"
      ],
      "additionalProperties": false,
      "properties": {
        "amount": {
          "type": "string",
          "description": "Signed integer count of minor units, no separators, no exponent.",
          "pattern": "^-?(0|[1-9][0-9]{0,18})$",
          "examples": [
            "150000"
          ]
        },
        "currency": {
          "type": "string",
          "description": "ISO-4217 alphabetic currency code.",
          "pattern": "^[A-Z]{3}$",
          "examples": [
            "EUR"
          ]
        }
      }
    },
    "evidence": {
      "description": "An immutable rule from a digest-verified published artifact.",
      "type": "object",
      "additionalProperties": false,
      "required": [
        "id",
        "taxKey",
        "effectiveFrom",
        "effectiveUntil",
        "rateNumerator",
        "rateDenominator",
        "sourceVersion",
        "artifactSha256"
      ],
      "properties": {
        "id": {
          "type": "string",
          "maxLength": 128
        },
        "taxKey": {
          "type": "string",
          "maxLength": 32
        },
        "effectiveFrom": {
          "type": "string",
          "format": "date"
        },
        "effectiveUntil": {
          "type": [
            "string",
            "null"
          ],
          "format": "date"
        },
        "rateNumerator": {
          "type": "string",
          "pattern": "^[0-9]+$"
        },
        "rateDenominator": {
          "type": "string",
          "pattern": "^[1-9][0-9]*$"
        },
        "sourceVersion": {
          "type": "string",
          "maxLength": 64
        },
        "artifactSha256": {
          "type": "string",
          "pattern": "^[0-9a-f]{64}$"
        }
      }
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /tax-rulesList published optional tax rules

Returns immutable global reference rules. An empty list means no qualified rules are published; ordinary consumer-owned taxKey remains valid.

Parameters

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

Rule ID returned as nextCursor by the previous page.

{
  "type": "string",
  "maxLength": 128
}

Responses

200 · application/json

Bounded page of rules, ordered by ID.

Required fields: data, nextCursor

{
  "description": "A bounded page of published reference rules.",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "data",
    "nextCursor"
  ],
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "description": "An immutable rule from a digest-verified published artifact.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "taxKey",
          "effectiveFrom",
          "effectiveUntil",
          "rateNumerator",
          "rateDenominator",
          "sourceVersion",
          "artifactSha256"
        ],
        "properties": {
          "id": {
            "type": "string",
            "maxLength": 128
          },
          "taxKey": {
            "type": "string",
            "maxLength": 32
          },
          "effectiveFrom": {
            "type": "string",
            "format": "date"
          },
          "effectiveUntil": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "rateNumerator": {
            "type": "string",
            "pattern": "^[0-9]+$"
          },
          "rateDenominator": {
            "type": "string",
            "pattern": "^[1-9][0-9]*$"
          },
          "sourceVersion": {
            "type": "string",
            "maxLength": 64
          },
          "artifactSha256": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$"
          }
        }
      },
      "maxItems": 200
    },
    "nextCursor": {
      "type": [
        "string",
        "null"
      ]
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /tenantsList partner tenants

Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. Ordered by public identifier; after is an exclusive public identifier boundary, not a snapshot.

Parameters

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

Exclusive public identifier boundary from nextCursor.

{
  "type": "string",
  "description": "Opaque public tenant identifier.",
  "pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
}

Responses

200 · application/json

The requested access resource.

Required fields: data

{
  "type": "object",
  "description": "One page ordered by public identifier.",
  "additionalProperties": false,
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "An isolated accounting tenant within the caller's partner.",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Opaque public tenant identifier.",
            "pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "name": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    "nextCursor": {
      "type": "string",
      "description": "Opaque public tenant identifier.",
      "pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /tenantsCreate an isolated tenant

Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. Creates a tenant and inherits the administrator membership's explicit permissions for the same identity.

Parameters

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: name

{
  "type": "object",
  "description": "A new isolated tenant.",
  "additionalProperties": false,
  "required": [
    "name"
  ],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    }
  }
}

Responses

201 · application/json

The requested access resource.

Required fields: id, name, createdAt

{
  "type": "object",
  "description": "An isolated accounting tenant within the caller's partner.",
  "additionalProperties": false,
  "required": [
    "id",
    "name",
    "createdAt"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque public tenant identifier.",
      "pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "name": {
      "type": "string"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /tenants/{tenantId}/membershipsList tenant memberships

Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. Ordered by public identifier; after is an exclusive public identifier boundary, not a snapshot.

Parameters

tenantId · path · required

Opaque public tenant identifier.

{
  "type": "string",
  "description": "Opaque public tenant identifier.",
  "pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
}

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

Exclusive public identifier boundary from nextCursor.

{
  "type": "string",
  "description": "Opaque public membership identifier.",
  "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
}

Responses

200 · application/json

The requested access resource.

Required fields: data

{
  "type": "object",
  "description": "One page ordered by public identifier.",
  "additionalProperties": false,
  "required": [
    "data"
  ],
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "An external subject's explicit grants in a tenant.",
        "additionalProperties": false,
        "required": [
          "id",
          "subject",
          "permissions",
          "status",
          "revision",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Opaque public membership identifier.",
            "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "subject": {
            "type": "string"
          },
          "permissions": {
            "type": "array",
            "description": "Explicit unique grants; an empty array grants no operations.",
            "maxItems": 9,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "description": "A local membership grant. access.manage is explicit partner-wide administration.",
              "enum": [
                "accounting.read",
                "accounting.write",
                "documents.read",
                "documents.write",
                "periods.close",
                "webhooks.manage",
                "access.manage",
                "exports.read",
                "audit.read"
              ]
            }
          },
          "status": {
            "type": "string",
            "description": "An inactive membership cannot bind to an API request.",
            "enum": [
              "active",
              "inactive"
            ]
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "maximum": 2147483647
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      }
    },
    "nextCursor": {
      "type": "string",
      "description": "Opaque public membership identifier.",
      "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /tenants/{tenantId}/membershipsGrant an external identity tenant access

Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. The subject belongs to the configured trusted issuer; permissions must be supplied explicitly.

Parameters

tenantId · path · required

Opaque public tenant identifier.

{
  "type": "string",
  "description": "Opaque public tenant identifier.",
  "pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: subject, permissions

{
  "type": "object",
  "description": "Explicit grants for a subject in the administrator's trusted issuer.",
  "additionalProperties": false,
  "required": [
    "subject",
    "permissions"
  ],
  "properties": {
    "subject": {
      "type": "string",
      "minLength": 1,
      "maxLength": 512
    },
    "permissions": {
      "type": "array",
      "description": "Explicit unique grants; an empty array grants no operations.",
      "maxItems": 9,
      "uniqueItems": true,
      "items": {
        "type": "string",
        "description": "A local membership grant. access.manage is explicit partner-wide administration.",
        "enum": [
          "accounting.read",
          "accounting.write",
          "documents.read",
          "documents.write",
          "periods.close",
          "webhooks.manage",
          "access.manage",
          "exports.read",
          "audit.read"
        ]
      }
    }
  }
}

Responses

201 · application/json

The requested access resource.

Required fields: id, subject, permissions, status, revision, createdAt

{
  "type": "object",
  "description": "An external subject's explicit grants in a tenant.",
  "additionalProperties": false,
  "required": [
    "id",
    "subject",
    "permissions",
    "status",
    "revision",
    "createdAt"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque public membership identifier.",
      "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "subject": {
      "type": "string"
    },
    "permissions": {
      "type": "array",
      "description": "Explicit unique grants; an empty array grants no operations.",
      "maxItems": 9,
      "uniqueItems": true,
      "items": {
        "type": "string",
        "description": "A local membership grant. access.manage is explicit partner-wide administration.",
        "enum": [
          "accounting.read",
          "accounting.write",
          "documents.read",
          "documents.write",
          "periods.close",
          "webhooks.manage",
          "access.manage",
          "exports.read",
          "audit.read"
        ]
      }
    },
    "status": {
      "type": "string",
      "description": "An inactive membership cannot bind to an API request.",
      "enum": [
        "active",
        "inactive"
      ]
    },
    "revision": {
      "type": "integer",
      "minimum": 1,
      "maximum": 2147483647
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
PUT /tenants/{tenantId}/memberships/{membershipId}Replace or revoke tenant access

Requires explicit access.manage in the bound tenant. This grants administration across that tenant's authoritative partner. Uses expectedRevision to prevent lost updates; inactive memberships cannot access the tenant.

Parameters

tenantId · path · required

Opaque public tenant identifier.

{
  "type": "string",
  "description": "Opaque public tenant identifier.",
  "pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$"
}

membershipId · path · required

Opaque public membership identifier.

{
  "type": "string",
  "description": "Opaque public membership identifier.",
  "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: permissions, status, expectedRevision

{
  "type": "object",
  "description": "Complete grant replacement or revocation guarded by the current revision.",
  "additionalProperties": false,
  "required": [
    "permissions",
    "status",
    "expectedRevision"
  ],
  "properties": {
    "permissions": {
      "type": "array",
      "description": "Explicit unique grants; an empty array grants no operations.",
      "maxItems": 9,
      "uniqueItems": true,
      "items": {
        "type": "string",
        "description": "A local membership grant. access.manage is explicit partner-wide administration.",
        "enum": [
          "accounting.read",
          "accounting.write",
          "documents.read",
          "documents.write",
          "periods.close",
          "webhooks.manage",
          "access.manage",
          "exports.read",
          "audit.read"
        ]
      }
    },
    "status": {
      "type": "string",
      "description": "An inactive membership cannot bind to an API request.",
      "enum": [
        "active",
        "inactive"
      ]
    },
    "expectedRevision": {
      "type": "integer",
      "minimum": 1,
      "maximum": 2147483647
    }
  }
}

Responses

200 · application/json

The requested access resource.

Required fields: id, subject, permissions, status, revision, createdAt

{
  "type": "object",
  "description": "An external subject's explicit grants in a tenant.",
  "additionalProperties": false,
  "required": [
    "id",
    "subject",
    "permissions",
    "status",
    "revision",
    "createdAt"
  ],
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque public membership identifier.",
      "pattern": "^mem_[0-9A-HJKMNP-TV-Z]{26}$"
    },
    "subject": {
      "type": "string"
    },
    "permissions": {
      "type": "array",
      "description": "Explicit unique grants; an empty array grants no operations.",
      "maxItems": 9,
      "uniqueItems": true,
      "items": {
        "type": "string",
        "description": "A local membership grant. access.manage is explicit partner-wide administration.",
        "enum": [
          "accounting.read",
          "accounting.write",
          "documents.read",
          "documents.write",
          "periods.close",
          "webhooks.manage",
          "access.manage",
          "exports.read",
          "audit.read"
        ]
      }
    },
    "status": {
      "type": "string",
      "description": "An inactive membership cannot bind to an API request.",
      "enum": [
        "active",
        "inactive"
      ]
    },
    "revision": {
      "type": "integer",
      "minimum": 1,
      "maximum": 2147483647
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /webhook-endpointsList webhook endpoints

Requires explicit webhook endpoint management permission in the calling tenant. Returns every endpoint of that tenant, including inactive endpoints, ordered by creation time. Inactive metadata remains visible so an endpoint can be audited or reactivated without losing its identity or delivery history.

Parameters

limit · query

Maximum number of items to return.

{
  "type": "integer",
  "minimum": 1,
  "maximum": 200,
  "default": 50
}

after · query

Return items after this webhook endpoint — the `nextCursor` of the previous page.

{
  "type": "string",
  "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
  "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

A page of webhook endpoint metadata. Collection responses do not carry per-item HTTP validators; fetch an item before mutating it to obtain its current `ETag`.

Required fields: data

{
  "type": "object",
  "description": "One page of webhook endpoints, oldest creation time first.",
  "required": [
    "data"
  ],
  "additionalProperties": false,
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "object",
        "description": "Safe webhook endpoint metadata. Signing-secret material is never present.",
        "required": [
          "id",
          "url",
          "eventTypes",
          "active",
          "createdAt",
          "updatedAt"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
            "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
            "examples": [
              "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri",
            "pattern": "^[hH][tT][tT][pP][sS]://",
            "maxLength": 2048,
            "description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
            "examples": [
              "https://hooks.example.com/accounting"
            ]
          },
          "eventTypes": {
            "type": "array",
            "maxItems": 16,
            "uniqueItems": true,
            "description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
            "items": {
              "type": "string",
              "description": "A domain event type currently available for endpoint subscriptions.",
              "enum": [
                "journal_entry.posted"
              ],
              "x-enum-varnames": [
                "WebhookEventTypeJournalEntryPosted"
              ]
            }
          },
          "active": {
            "type": "boolean",
            "description": "Whether this endpoint is eligible for newly committed event snapshots.\nDeactivation also permanently suppresses its older-snapshot recipients\nthat a worker has not already loaded; later reactivation does not revive\nthose recipients.\n"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last metadata, active-state, or secret change. A secret rotation changes\nthis timestamp but never exposes either secret.\n"
          }
        }
      }
    },
    "nextCursor": {
      "type": "string",
      "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
      "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
POST /webhook-endpointsCreate a webhook endpoint

Requires explicit webhook endpoint management permission in the calling tenant. Registers an active HTTPS destination. The caller supplies the signing secret once; it is write-only and is never included in this or any later response. A tenant may retain at most 256 endpoints in total, including inactive endpoints, and at most 64 of them may be active. Deactivation does not free retained-endpoint capacity.

Parameters

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

Request body

application/json · required

Required fields: url, eventTypes, secret

{
  "type": "object",
  "description": "Fields accepted when registering an active webhook endpoint.",
  "required": [
    "url",
    "eventTypes",
    "secret"
  ],
  "additionalProperties": false,
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "pattern": "^[hH][tT][tT][pP][sS]://",
      "maxLength": 2048,
      "description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
      "examples": [
        "https://hooks.example.com/accounting"
      ]
    },
    "eventTypes": {
      "type": "array",
      "maxItems": 16,
      "uniqueItems": true,
      "description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
      "items": {
        "type": "string",
        "description": "A domain event type currently available for endpoint subscriptions.",
        "enum": [
          "journal_entry.posted"
        ],
        "x-enum-varnames": [
          "WebhookEventTypeJournalEntryPosted"
        ]
      }
    },
    "secret": {
      "type": "string",
      "minLength": 43,
      "maxLength": 43,
      "pattern": "^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$",
      "writeOnly": true,
      "x-go-type-skip-optional-pointer": true,
      "description": "Exactly 32 bytes encoded as canonical, unpadded base64url (43 characters).\nFor every create or rotation, the caller MUST generate a unique, independent,\nunpredictable 32-byte value with a cryptographically secure random-number\ngenerator and MUST NOT reuse it for another endpoint or secret version. The\ncaller retains this HMAC-SHA256 signing secret. It is accepted only on create\nor rotation and is never returned by the API. The final-character restriction\nrejects non-canonical encodings with non-zero unused bits.\n"
    }
  }
}

Responses

201 · application/json

The created endpoint metadata. The signing secret is never returned.

Required fields: id, url, eventTypes, active, createdAt, updatedAt

{
  "type": "object",
  "description": "Safe webhook endpoint metadata. Signing-secret material is never present.",
  "required": [
    "id",
    "url",
    "eventTypes",
    "active",
    "createdAt",
    "updatedAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
      "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "url": {
      "type": "string",
      "format": "uri",
      "pattern": "^[hH][tT][tT][pP][sS]://",
      "maxLength": 2048,
      "description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
      "examples": [
        "https://hooks.example.com/accounting"
      ]
    },
    "eventTypes": {
      "type": "array",
      "maxItems": 16,
      "uniqueItems": true,
      "description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
      "items": {
        "type": "string",
        "description": "A domain event type currently available for endpoint subscriptions.",
        "enum": [
          "journal_entry.posted"
        ],
        "x-enum-varnames": [
          "WebhookEventTypeJournalEntryPosted"
        ]
      }
    },
    "active": {
      "type": "boolean",
      "description": "Whether this endpoint is eligible for newly committed event snapshots.\nDeactivation also permanently suppresses its older-snapshot recipients\nthat a worker has not already loaded; later reactivation does not revive\nthose recipients.\n"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "updatedAt": {
      "type": "string",
      "format": "date-time",
      "description": "Last metadata, active-state, or secret change. A secret rotation changes\nthis timestamp but never exposes either secret.\n"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
DELETE /webhook-endpoints/{webhookEndpointId}Deactivate a webhook endpoint

Requires explicit webhook endpoint management permission in the calling tenant. Soft-deactivates the endpoint. No endpoint or delivery-attempt row is deleted: its stable identity, lifecycle attribution, and delivery audit history are preserved. After deactivation commits, the endpoint is excluded from new event snapshots and every older-snapshot recipient for it that a worker has not already loaded is permanently suppressed. Reactivating the same endpoint identity later does not revive those suppressed recipients. Deleting an already inactive endpoint is a no-op. An attempt loaded before deactivation commits may still complete with its pinned URL after this operation returns.

Parameters

webhookEndpointId · path · required

Identifier of the tenant-managed webhook endpoint.

{
  "type": "string",
  "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
  "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

If-Match · header · required

The exact strong `ETag` returned by the latest item response. Weak tags, wildcard matching, and validator lists are not accepted because every mutation must name one observed endpoint version. A missing precondition is `428 precondition-required`; a well-formed but stale validator is `412 precondition-failed`. After a 412, fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.

{
  "type": "string",
  "pattern": "^\"whep-v1-[A-Za-z0-9_-]{32}\"$"
}

Example

"\"whep-v1-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""

Responses

204

The endpoint is inactive and its audit history is preserved.

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

412 · application/problem+json

The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

428 · application/problem+json

This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /webhook-endpoints/{webhookEndpointId}Fetch one webhook endpoint

Requires explicit webhook endpoint management permission in the calling tenant. Returns safe metadata if the endpoint belongs to that tenant, else 404. The signing secret is never readable through the API.

Parameters

webhookEndpointId · path · required

Identifier of the tenant-managed webhook endpoint.

{
  "type": "string",
  "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
  "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

The webhook endpoint metadata.

Required fields: id, url, eventTypes, active, createdAt, updatedAt

{
  "type": "object",
  "description": "Safe webhook endpoint metadata. Signing-secret material is never present.",
  "required": [
    "id",
    "url",
    "eventTypes",
    "active",
    "createdAt",
    "updatedAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
      "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "url": {
      "type": "string",
      "format": "uri",
      "pattern": "^[hH][tT][tT][pP][sS]://",
      "maxLength": 2048,
      "description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
      "examples": [
        "https://hooks.example.com/accounting"
      ]
    },
    "eventTypes": {
      "type": "array",
      "maxItems": 16,
      "uniqueItems": true,
      "description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
      "items": {
        "type": "string",
        "description": "A domain event type currently available for endpoint subscriptions.",
        "enum": [
          "journal_entry.posted"
        ],
        "x-enum-varnames": [
          "WebhookEventTypeJournalEntryPosted"
        ]
      }
    },
    "active": {
      "type": "boolean",
      "description": "Whether this endpoint is eligible for newly committed event snapshots.\nDeactivation also permanently suppresses its older-snapshot recipients\nthat a worker has not already loaded; later reactivation does not revive\nthose recipients.\n"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "updatedAt": {
      "type": "string",
      "format": "date-time",
      "description": "Last metadata, active-state, or secret change. A secret rotation changes\nthis timestamp but never exposes either secret.\n"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
PUT /webhook-endpoints/{webhookEndpointId}Replace webhook endpoint metadata

Requires explicit webhook endpoint management permission in the calling tenant. Fully replaces the destination URL, event subscription, and active state; the existing signing secret is unchanged. All three metadata fields are required. The active state and event subscription select recipients only for events committed after this replacement commits. Each previously selected recipient keeps the routing URL snapshotted with its event, even if this replacement changes the URL. Setting `active` to false also permanently suppresses every older-snapshot recipient for this endpoint that a worker has not already loaded. Reactivating the endpoint later does not revive those suppressed recipients; it only makes the endpoint eligible for new event snapshots. An attempt loaded before deactivation commits may still complete with its pinned URL after this operation returns.

Parameters

webhookEndpointId · path · required

Identifier of the tenant-managed webhook endpoint.

{
  "type": "string",
  "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
  "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

If-Match · header · required

The exact strong `ETag` returned by the latest item response. Weak tags, wildcard matching, and validator lists are not accepted because every mutation must name one observed endpoint version. A missing precondition is `428 precondition-required`; a well-formed but stale validator is `412 precondition-failed`. After a 412, fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.

{
  "type": "string",
  "pattern": "^\"whep-v1-[A-Za-z0-9_-]{32}\"$"
}

Example

"\"whep-v1-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""

Request body

application/json · required

Required fields: url, eventTypes, active

{
  "type": "object",
  "description": "Complete replacement of mutable endpoint metadata. The signing secret is\ndeliberately not metadata and remains unchanged.\n",
  "required": [
    "url",
    "eventTypes",
    "active"
  ],
  "additionalProperties": false,
  "properties": {
    "url": {
      "type": "string",
      "format": "uri",
      "pattern": "^[hH][tT][tT][pP][sS]://",
      "maxLength": 2048,
      "description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
      "examples": [
        "https://hooks.example.com/accounting"
      ]
    },
    "eventTypes": {
      "type": "array",
      "maxItems": 16,
      "uniqueItems": true,
      "description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
      "items": {
        "type": "string",
        "description": "A domain event type currently available for endpoint subscriptions.",
        "enum": [
          "journal_entry.posted"
        ],
        "x-enum-varnames": [
          "WebhookEventTypeJournalEntryPosted"
        ]
      }
    },
    "active": {
      "type": "boolean"
    }
  }
}

Responses

200 · application/json

The replaced webhook endpoint metadata.

Required fields: id, url, eventTypes, active, createdAt, updatedAt

{
  "type": "object",
  "description": "Safe webhook endpoint metadata. Signing-secret material is never present.",
  "required": [
    "id",
    "url",
    "eventTypes",
    "active",
    "createdAt",
    "updatedAt"
  ],
  "additionalProperties": false,
  "properties": {
    "id": {
      "type": "string",
      "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
      "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
      "examples": [
        "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
      ]
    },
    "url": {
      "type": "string",
      "format": "uri",
      "pattern": "^[hH][tT][tT][pP][sS]://",
      "maxLength": 2048,
      "description": "Absolute HTTPS delivery URL of at most 2,048 UTF-8 bytes. Userinfo and\nfragments are forbidden, and an IP-literal host must be globally routable;\nloopback, private, link-local, carrier-grade NAT, multicast, documentation,\nunspecified, and other special-use addresses are rejected. On create and\nreplacement, the service canonicalizes an accepted URL before storing and\nreturning it: the scheme and ASCII host are lowercased, the default HTTPS\nport is removed, and a non-default port is normalized to decimal. The caller\ndoes not need to perform that canonicalization first.\n\nDNS names are resolved only when delivery is attempted: the complete answer\nset is validated and the selected public address pinned before every connection\nto prevent rebinding. Redirects are not followed. URL syntax and IP-literal\nrestrictions are rechecked whenever metadata is replaced and again at delivery\ntime. Query strings are retained in immutable routing history for audit and\nretries; they must not contain credentials or capability tokens. Authenticate\ndelivery with the signing secret instead.\n",
      "examples": [
        "https://hooks.example.com/accounting"
      ]
    },
    "eventTypes": {
      "type": "array",
      "maxItems": 16,
      "uniqueItems": true,
      "description": "Unique event types delivered to this endpoint, with at most 16 entries.\nAn empty array subscribes the endpoint to all current and future webhook\nevent types; list explicit values to opt in only to those event types. The\nsubscription is evaluated when each event's recipients are snapshotted;\nchanging it does not add or remove recipients from an existing snapshot.\n",
      "items": {
        "type": "string",
        "description": "A domain event type currently available for endpoint subscriptions.",
        "enum": [
          "journal_entry.posted"
        ],
        "x-enum-varnames": [
          "WebhookEventTypeJournalEntryPosted"
        ]
      }
    },
    "active": {
      "type": "boolean",
      "description": "Whether this endpoint is eligible for newly committed event snapshots.\nDeactivation also permanently suppresses its older-snapshot recipients\nthat a worker has not already loaded; later reactivation does not revive\nthose recipients.\n"
    },
    "createdAt": {
      "type": "string",
      "format": "date-time"
    },
    "updatedAt": {
      "type": "string",
      "format": "date-time",
      "description": "Last metadata, active-state, or secret change. A secret rotation changes\nthis timestamp but never exposes either secret.\n"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

412 · application/problem+json

The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

428 · application/problem+json

This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
PUT /webhook-endpoints/{webhookEndpointId}/secretRotate a webhook endpoint signing secret

Requires explicit webhook endpoint management permission in the calling tenant. Replaces only the signing secret; metadata and active state are unchanged. Configure the receiver to accept both secrets before rotating. Once this operation returns 204, every newly loaded attempt uses the current secret version, including a retry for an event snapshotted before rotation. A request already loaded or in flight may still arrive with a signature made by the old secret. Keep the overlap until those attempts have drained. The old and new secrets are both write-only and are never returned.

Parameters

webhookEndpointId · path · required

Identifier of the tenant-managed webhook endpoint.

{
  "type": "string",
  "description": "Opaque webhook endpoint identifier. It encodes neither the tenant nor the\nendpoint's internal database identity.\n",
  "pattern": "^whep_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "whep_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Idempotency-Key · header · required

Client-generated key that makes this mutation replay-safe. Send exactly one field value. Use a fresh value (a UUID or equivalent) per logical operation and reuse it verbatim when retrying that operation. One layer of surrounding double quotes is stripped before the key is compared, so the RFC 8941 structured-field form (`"k"`) and the bare form (`k`) name the same key.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 255
}

Example

"2f1c7f6e-5f0b-4a3a-8f8f-2b8f6c1f9a11"

X-Accounting-Acting-User-Issuer · header

Optional partner-attested human attribution, machine authentication only. Send exactly one value together with X-Accounting-Acting-User-Subject. Absolute HTTPS issuer URI without credentials, query or fragment; ASCII without whitespace or commas. The authenticated partner asserts this identity; Accounting does not independently verify a human login token. This metadata grants no tenant access or permissions and never replaces the authenticated machine membership. Retained as immutable same-transaction evidence with the write and included in the idempotency fingerprint. Successful attributed writes and their replays return X-Accounting-Acting-User-Recorded: v1. Deploy this API before enabling attributed writes; a missing acknowledgment leaves the outcome unqualified.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^https://[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"https://auth.d0.eu"

X-Accounting-Acting-User-Subject · header

Stable opaque person reference in the issuer namespace, asserted by the authenticated partner. Send exactly one value together with X-Accounting-Acting-User-Issuer; 1–200 ASCII bytes without whitespace or commas. Use technical references, not names or email addresses. A different attributed human or asserting machine under the same Idempotency-Key is a different request (422). Neither header is an Accounting membership ID.

{
  "type": "string",
  "minLength": 1,
  "maxLength": 200,
  "pattern": "^[\\x21-\\x2B\\x2D-\\x7E]+$"
}

Example

"person-42"

If-Match · header · required

The exact strong `ETag` returned by the latest item response. Weak tags, wildcard matching, and validator lists are not accepted because every mutation must name one observed endpoint version. A missing precondition is `428 precondition-required`; a well-formed but stale validator is `412 precondition-failed`. After a 412, fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.

{
  "type": "string",
  "pattern": "^\"whep-v1-[A-Za-z0-9_-]{32}\"$"
}

Example

"\"whep-v1-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\""

Request body

application/json · required

Required fields: secret

{
  "type": "object",
  "description": "Write-only replacement signing material for one endpoint.",
  "required": [
    "secret"
  ],
  "additionalProperties": false,
  "properties": {
    "secret": {
      "type": "string",
      "minLength": 43,
      "maxLength": 43,
      "pattern": "^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$",
      "writeOnly": true,
      "x-go-type-skip-optional-pointer": true,
      "description": "Exactly 32 bytes encoded as canonical, unpadded base64url (43 characters).\nFor every create or rotation, the caller MUST generate a unique, independent,\nunpredictable 32-byte value with a cryptographically secure random-number\ngenerator and MUST NOT reuse it for another endpoint or secret version. The\ncaller retains this HMAC-SHA256 signing secret. It is accepted only on create\nor rotation and is never returned by the API. The final-character restriction\nrejects non-canonical encodings with non-zero unused bits.\n"
    }
  }
}

Responses

204

Future delivery attempts use the replacement secret.

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

403 · application/problem+json

The caller is authenticated for the tenant but lacks the explicit permission required for this operation. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

409 · application/problem+json

The request conflicts with current state — a duplicate, a sealed period, an entry that is no longer a draft, or an in-flight request with this `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

412 · application/problem+json

The supplied `If-Match` validator is well-formed but stale. No resource state or audit evidence was changed. Fetch the item and retry the intended change with its new `ETag` and a fresh `Idempotency-Key`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

422 · application/problem+json

The request is well-formed but cannot be carried out — an unbalanced Buchung, or an `Idempotency-Key` reused with a different request (including a different `Content-Type` or `If-Match` validator).

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

428 · application/problem+json

This mutation requires the latest item `ETag` in `If-Match`; no resource state or audit evidence was changed.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}
GET /zugferd-pdfs/{zugferdPdfId}Fetch one ZUGFeRD PDF generation

Returns tenant-visible durable generation state. A completed resource includes the immutable output Beleg and exact processor/ruleset evidence; failures expose no internal diagnostic or storage identity.

Parameters

zugferdPdfId · path · required

Identifier of the durable ZUGFeRD PDF generation.

{
  "type": "string",
  "description": "Opaque durable ZUGFeRD PDF generation identifier.",
  "pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
  "examples": [
    "eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
  ]
}

Responses

200 · application/json

The generation and its current state.

{
  "description": "Durable ZUGFeRD PDF state. Pending has neither result nor failure;\ncompleted has the new immutable output Beleg and exact generation evidence;\nfailed exposes only a stable public failure code.\n",
  "oneOf": [
    {
      "type": "object",
      "description": "A durable generation waiting for processing or a retry.",
      "required": [
        "id",
        "validationId",
        "invoiceDocumentId",
        "visualDocumentId",
        "target",
        "recipe",
        "status",
        "requestedAt"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable ZUGFeRD PDF generation identifier.",
          "pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "validationId": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "invoiceDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "visualDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "target": {
          "type": "object",
          "description": "Frozen standard and profile selected by trusted server configuration.",
          "required": [
            "name",
            "version",
            "profile"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "profile": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "recipe": {
          "type": "object",
          "description": "Frozen versioned generation recipe selected by trusted server configuration.",
          "required": [
            "name",
            "version"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "status": {
          "type": "string",
          "const": "pending",
          "x-enum-varnames": [
            "ZUGFeRDPDFPendingStatusPending"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        }
      }
    },
    {
      "type": "object",
      "description": "A terminal generation with immutable output and provenance evidence.",
      "required": [
        "id",
        "validationId",
        "invoiceDocumentId",
        "visualDocumentId",
        "target",
        "recipe",
        "status",
        "requestedAt",
        "completedAt",
        "outputDocument",
        "result"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable ZUGFeRD PDF generation identifier.",
          "pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "validationId": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "invoiceDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "visualDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "target": {
          "type": "object",
          "description": "Frozen standard and profile selected by trusted server configuration.",
          "required": [
            "name",
            "version",
            "profile"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "profile": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "recipe": {
          "type": "object",
          "description": "Frozen versioned generation recipe selected by trusted server configuration.",
          "required": [
            "name",
            "version"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "status": {
          "type": "string",
          "const": "completed",
          "x-enum-varnames": [
            "ZUGFeRDPDFCompletedStatusCompleted"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        },
        "completedAt": {
          "type": "string",
          "format": "date-time"
        },
        "outputDocument": {
          "type": "object",
          "description": "Public metadata for the completed generation output. This Beleg is always\na newly derived, immutable archived PDF; its exact two-source lineage is\nretained server-side.\n",
          "required": [
            "id",
            "origin",
            "status",
            "originalFilename",
            "mediaType",
            "sizeBytes",
            "contentSha256",
            "documentDate",
            "classification",
            "retentionUntil",
            "createdAt",
            "archivedAt"
          ],
          "additionalProperties": false,
          "properties": {
            "id": {
              "type": "string",
              "description": "Opaque Beleg identifier. It does not encode storage identity.",
              "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
              "examples": [
                "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
              ]
            },
            "origin": {
              "type": "string",
              "const": "derived",
              "x-enum-varnames": [
                "ZUGFeRDPDFDocumentOriginDerived"
              ]
            },
            "status": {
              "type": "string",
              "const": "archived",
              "x-enum-varnames": [
                "ZUGFeRDPDFDocumentStatusArchived"
              ]
            },
            "originalFilename": {
              "type": "string"
            },
            "mediaType": {
              "type": "string",
              "const": "application/pdf",
              "x-enum-varnames": [
                "ZUGFeRDPDFDocumentMediaTypeApplicationPDF"
              ]
            },
            "sizeBytes": {
              "type": "integer",
              "format": "int64",
              "minimum": 1
            },
            "contentSha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "documentDate": {
              "type": "string",
              "format": "date"
            },
            "classification": {
              "type": "string",
              "description": "Trusted server-assigned Beleg class."
            },
            "retentionUntil": {
              "type": "string",
              "format": "date"
            },
            "createdAt": {
              "type": "string",
              "format": "date-time"
            },
            "archivedAt": {
              "type": "string",
              "format": "date-time"
            }
          }
        },
        "result": {
          "type": "object",
          "description": "Exact immutable generation evidence reported by the sidecar.",
          "required": [
            "schema",
            "invoiceSha256",
            "visualSha256",
            "output",
            "standard",
            "recipe",
            "processor",
            "ruleset"
          ],
          "additionalProperties": false,
          "properties": {
            "schema": {
              "type": "string",
              "const": "devacc.einvoice.zugferd-pdf.v1",
              "x-enum-varnames": [
                "ZUGFeRDPDFResultSchemaV1"
              ]
            },
            "invoiceSha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "visualSha256": {
              "type": "string",
              "pattern": "^[0-9a-f]{64}$"
            },
            "output": {
              "type": "object",
              "description": "Exact output facts verified before the derived Beleg was archived.",
              "required": [
                "contentId",
                "mediaType",
                "sizeBytes",
                "sha256",
                "pdfConformance",
                "embeddedFilename"
              ],
              "additionalProperties": false,
              "properties": {
                "contentId": {
                  "type": "string",
                  "const": "output",
                  "x-enum-varnames": [
                    "ZUGFeRDPDFOutputContentIdOutput"
                  ]
                },
                "mediaType": {
                  "type": "string",
                  "const": "application/pdf",
                  "x-enum-varnames": [
                    "ZUGFeRDPDFOutputMediaTypeApplicationPDF"
                  ]
                },
                "sizeBytes": {
                  "type": "integer",
                  "format": "int64",
                  "minimum": 1
                },
                "sha256": {
                  "type": "string",
                  "pattern": "^[0-9a-f]{64}$"
                },
                "pdfConformance": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256,
                  "description": "Conformance identity reported by the configured production sidecar.\nThis API records the evidence but does not independently certify it.\n"
                },
                "embeddedFilename": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 255
                }
              }
            },
            "standard": {
              "type": "object",
              "description": "Frozen standard and profile selected by trusted server configuration.",
              "required": [
                "name",
                "version",
                "profile"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "profile": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                }
              }
            },
            "recipe": {
              "type": "object",
              "description": "Frozen versioned generation recipe selected by trusted server configuration.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                }
              }
            },
            "processor": {
              "type": "object",
              "description": "Opaque ZUGFeRD sidecar runtime or versioned artifact identity.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                }
              }
            },
            "ruleset": {
              "type": "object",
              "description": "Opaque ZUGFeRD sidecar runtime or versioned artifact identity.",
              "required": [
                "name",
                "version"
              ],
              "additionalProperties": false,
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "version": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                }
              }
            }
          }
        }
      }
    },
    {
      "type": "object",
      "description": "A terminal PDF-generation failure without sensitive diagnostics.",
      "required": [
        "id",
        "validationId",
        "invoiceDocumentId",
        "visualDocumentId",
        "target",
        "recipe",
        "status",
        "requestedAt",
        "completedAt",
        "failure"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": "string",
          "description": "Opaque durable ZUGFeRD PDF generation identifier.",
          "pattern": "^eip_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eip_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "validationId": {
          "type": "string",
          "description": "Opaque durable e-invoice validation identifier.",
          "pattern": "^eiv_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "eiv_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "invoiceDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "visualDocumentId": {
          "type": "string",
          "description": "Opaque Beleg identifier. It does not encode storage identity.",
          "pattern": "^doc_[0-9A-HJKMNP-TV-Z]{26}$",
          "examples": [
            "doc_9GXQ8W5V4R3P2N1M0KJHGF7ED6"
          ]
        },
        "target": {
          "type": "object",
          "description": "Frozen standard and profile selected by trusted server configuration.",
          "required": [
            "name",
            "version",
            "profile"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "profile": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "recipe": {
          "type": "object",
          "description": "Frozen versioned generation recipe selected by trusted server configuration.",
          "required": [
            "name",
            "version"
          ],
          "additionalProperties": false,
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "version": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          }
        },
        "status": {
          "type": "string",
          "const": "failed",
          "x-enum-varnames": [
            "ZUGFeRDPDFFailedStatusFailed"
          ]
        },
        "requestedAt": {
          "type": "string",
          "format": "date-time"
        },
        "completedAt": {
          "type": "string",
          "format": "date-time"
        },
        "failure": {
          "type": "object",
          "description": "Stable public failure classification without internal diagnostics.",
          "required": [
            "code"
          ],
          "additionalProperties": false,
          "properties": {
            "code": {
              "type": "string",
              "enum": [
                "unsupported-source",
                "generation-capacity-exceeded"
              ],
              "x-enum-varnames": [
                "ZUGFeRDPDFFailureCodeUnsupportedSource",
                "ZUGFeRDPDFFailureCodeGenerationCapacityExceeded"
              ]
            }
          }
        }
      }
    }
  ],
  "discriminator": {
    "propertyName": "status",
    "mapping": {
      "pending": "#/components/schemas/ZUGFeRDPDFPending",
      "completed": "#/components/schemas/ZUGFeRDPDFCompleted",
      "failed": "#/components/schemas/ZUGFeRDPDFFailed"
    }
  }
}

400 · application/problem+json

The request is malformed or violates the contract.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

401 · application/problem+json

No valid tenant assertion. No data is read or written.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

404 · application/problem+json

No such resource in the calling tenant.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}

default · application/problem+json

An error. Branch on `type`.

Required fields: type, title, status

{
  "type": "object",
  "description": "RFC 9457 problem detail.",
  "required": [
    "type",
    "title",
    "status"
  ],
  "properties": {
    "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable, machine-readable problem identifier. This is the field to\nbranch on; `title` and `detail` are prose and may be reworded.\n",
      "examples": [
        "https://api.d0.eu/accounting/problems/period-sealed"
      ]
    },
    "title": {
      "type": "string",
      "description": "Short human-readable summary of the problem type."
    },
    "status": {
      "type": "integer",
      "minimum": 400,
      "maximum": 599
    },
    "detail": {
      "type": "string",
      "description": "Human-readable explanation specific to this occurrence."
    },
    "instance": {
      "type": "string",
      "format": "uri-reference",
      "description": "The request path this problem occurred on."
    },
    "errors": {
      "type": "array",
      "description": "Field-level detail, when the problem is a validation failure.",
      "items": {
        "type": "object",
        "required": [
          "detail"
        ],
        "properties": {
          "pointer": {
            "type": "string",
            "description": "JSON Pointer (RFC 6901) into the request body.",
            "examples": [
              "/lines/0/amount"
            ]
          },
          "detail": {
            "type": "string"
          }
        }
      }
    }
  }
}