GoBD for developers
GoBD-compliant bookkeeping API: what it means for your integration
For an API or AI agent integration, GoBD — the German tax authority's principles for keeping books electronically — means four things: a booking can be reversed but never edited or deleted, a locked (festgeschrieben) period accepts no further postings, every entry balances and stays traceable to its receipt, and the books can be handed to a tax auditor in machine-readable form. At jahresabschluss.io the REST API and the MCP server cannot switch any of this off, because every write runs through the same posting core and database checks as the app. What remains your part is choosing the right key, confirming writes and documenting how the agent works.
Last reviewed: 2026-10-19
GoBD in brief, for developers new to Germany
GoBD stands for Grundsätze zur ordnungsmäßigen Führung und Aufbewahrung von Büchern, Aufzeichnungen und Unterlagen in elektronischer Form sowie zum Datenzugriff — an administrative letter of the Federal Ministry of Finance dated 28 November 2019 and amended since. It interprets statutory rules: bookings must be made individually, completely, correctly, promptly and in order (§ 146 Abs. 1 AO); a record may not be changed in a way that its original content can no longer be determined (§ 146 Abs. 4 AO, mirrored in § 239 Abs. 3 HGB); books and vouchers must be retained and made available to the tax audit (§ 147 AO).
For software this means immutability with reversals, a period lock, traceability from voucher to booking, a procedure documentation (Verfahrensdokumentation) and an export the auditor can read. Software alone does not make a business compliant — the tax authority looks at the whole procedure, including how the software is used.
How the rules map onto the API
Reversal instead of delete
No route edits or deletes a booking. storno_journal_entry (POST /v1/journal-entries/{id}/storno) books the counter-entry and requires a reason. storno_payment reverses a payment, cancel_incoming_invoice a supplier invoice, cancel_outgoing_invoice issues a cancellation invoice with its own number, storno_journal_batch reverses a whole import in one transaction.
Period lock
finalize_bookkeeping_period (POST /v1/periods/finalize) locks the books up to a date. A database trigger enforces the lock on every write path — app, API and internal functions alike. There is no unlock; corrections are booked in an open period.
Balanced entries
Every write passes the posting core: debit equals credit, a manual booking forms its net and VAT lines from the tax key, and import_journal_batch books a batch completely or not at all.
Voucher reference
belegfeld1 and attachment_receipt_ids tie a booking to its receipt; confirm_receipt books a receipt with all checks. A discarded receipt keeps its file (§ 147 AO); delete_receipt only removes a misdirected document that was never reviewed, booked or linked.
A correction, the GoBD way
A booking on the wrong expense account is reversed and booked again; each call carries its own idempotency key:
export JAB_API_KEY="jab_live_…" # key with read + write
BASE="https://api.jahresabschluss.io/functions/v1/bookkeeping-api/v1"
# 1. Reverse the wrong booking (a reason is mandatory)
curl -X POST "$BASE/journal-entries/<id of the wrong entry>/storno" \
-H "Authorization: Bearer $JAB_API_KEY" -H "Content-Type: application/json" \
-d '{"reason":"Wrong expense account","idempotency_key":"<new UUID>"}'
# 2. Book it again on the right account, with the receipt number
curl -X POST "$BASE/journal-entries" \
-H "Authorization: Bearer $JAB_API_KEY" -H "Content-Type: application/json" \
-d '{"fiscal_year_id":"<id>","idempotency_key":"<new UUID>","booking_date":"2026-10-14",
"debit_account":"4930","credit_account":"1200","amount":119.00,"tax_key":"V19",
"description":"Office supplies","belegfeld1":"RE-2026-311"}'The reversal carries the date of the original booking unless you pass a later booking_date in the same fiscal year. Both entries stay in the journal with their numbers, so an auditor sees what was booked, when, and why it was corrected. Once a period is locked, nothing can be dated inside it any more; a correction then goes into an open period. Through MCP the same steps are storno_journal_entry and create_journal_entry.
The finalize right
Locking is irreversible, so it is a right of its own. A key without finalize does not even see finalize_bookkeeping_period. With the right, the call needs confirm=true, and our server instructs the agent to name the cut-off date and wait for your explicit yes; repeating the same date changes nothing.
list_bookkeeping_periods shows each month as open, partially_finalized or finalized. Agree the rhythm with your tax adviser: you can lock month by month after each VAT return, or only once the adviser has reviewed the year. Book, review, then lock: that order keeps corrections cheap.
Traceability: what is recorded
- The journal itself: ascending entry numbers, a source_type for each booking (bank_tx, receipt, manual, csv_import, opening_balance and others) and the import batch a booking came from (list_journal_batches).
- A hash chain links each booking to the one before it. The app shows the check result on its lock page; a later change to booked values would appear as a break in the chain.
- Master data history: get_business_partner returns every change to a partner — which field, when, from which value to which.
- API usage per key: the area “KI-Agent & API” in the app shows each key's calls of the last 30 days — how many, how many of them wrote or failed, the last call and the most used endpoints — so unexpected writes or failures stand out.
- That usage log is a convenience written alongside each request. The record that counts under the GoBD is the journal.
Retention and the tax audit
§ 147 Abs. 3 AO sets ten years for books, records and annual accounts and eight years for accounting vouchers. § 147 Abs. 6 AO lets the tax audit access the data directly, have it evaluated, or receive it on a machine-readable data carrier.
export_bookkeeping with format gobd (GET /v1/export?format=gobd) delivers that data-carrier package as a ZIP with an index.xml description; get_receipt_archive delivers the original receipts of a fiscal year in parts. Both are files that must stay byte-exact, so the tools return a download path instead of passing the content through the model.
What the API deliberately does not offer
- No editing or deleting of bookings and no unlocking of a locked period.
- No free database queries — only documented operations, each bound to the company of the key.
- No change of company settings (chart of accounts, profit method, VAT method), no bank connection and no change to partners' IBAN/BIC.
- No ELSTER submission by the agent; filings are released in the app through an approval link.
- No procedure documentation on your behalf: the GoBD expect you to describe your own process, including the agent.
Your part: key, confirmations, documentation
Give each integration its own key with only the rights it needs, an expiry and a recognisable name, and revoke it when the integration ends. Require a confirmation in your AI program for every write. Describe the agent in your Verfahrensdokumentation: which program, which key and rights, which steps run automatically and who approves the rest.
The managing directors remain responsible for proper bookkeeping (§ 41 GmbHG). Work alone or together with your tax adviser, who can review in the same software before a period is locked.
Frequently asked questions
Does a GoBD-compliant API make my bookkeeping compliant?
Not on its own. The API enforces the technical rules — reversal instead of delete, period lock, balanced entries — but the tax authority assesses the whole procedure, including your process and its documentation.
Can I delete a wrong booking through the API?
No. You reverse it with storno_journal_entry and book it again. Both entries stay in the journal.
Can a locked period be reopened?
No. There is no unlock route. Corrections are booked in an open period.
What happens if my agent retries a booking after a timeout?
With the same idempotency_key and the same data, the API does not book a second time. A new UUID would create a second booking.
Does an AI agent belong in the Verfahrensdokumentation?
Yes, if it takes part in the bookkeeping. Describe the program, key, rights, automatic steps and approvals.
Which right does locking need?
finalize — a separate right chosen when the key is created — plus confirm=true in the call.