This guide walks theDocumentation Index
Fetch the complete documentation index at: https://dev.openfiskal.com/llms.txt
Use this file to discover all available pages before exploring further.
v1 integration contract for Germany. You create a deu API key, onboard a merchant with a German fiscal_identity, register a location and terminal, fiscalize the register under KassenSichV, start an operation, and complete it with the typed payment contract.
Examples use
https://sandbox.api.openfiskal.com/v1. Replace with https://api.openfiskal.com/v1 when you go live.Prerequisites
- An OpenFiskal tenant
- A tenant-scoped, country-scoped API key (
of_test_deu_โฆorof_live_deu_โฆ) curlor an HTTP client- A backend service / database to store your API key, entity IDs and ETags
Authentication model
Use the standard bearer header on every request. The key encodes the environment and country โof_test_deu_โฆ for the German sandbox, of_live_deu_โฆ for German production. A deu key rejects payloads for any other country.
POST /merchants, not your API key.
Create resources
Create these resources in order. The register cannot fiscalize until the merchant has aDEU fiscal_identity.
Create your API key
Start in the OpenFiskal tenant dashboard. Create a
deu key. Store it in your secrets manager. Format: of_{env}_deu_{random}, e.g. of_test_deu_abcdefgh12345678.Create a merchant
country_code and every address.country_code must be DEU (ISO 3166-1 alpha-3). The German fiscal_identity requires both tax_number (Steuernummer) and vat_id (USt-IdNr).id becomes the X-OpenFiskal-Merchant header on every merchant-scoped request that follows.Create a location
A location is a physical point of sale.
timezone is a required IANA zone string โ KassenSichV embeds local time into signed records.Fiscalize the register
Before the register can accept operations, call
POST /registers/{id}/fiscalize. This provisions the KassenSichV components โ the TSS and POS client โ using the merchantโs German fiscal_identity and the locationโs country. The response is 202 Accepted; poll GET /registers/{id} until fiscalizedAt is populated.Perform a fiscalized sale
Once your register is fiscalized, you can create and complete sale operations.Start an operation
POST /operations is a single-shot create. All monetary fields are decimal strings, not integers. pretax_amount + tax_amount + tip_amount must equal total_amount. line_items is required with at least one entry.Complete the operation
Completion includes typed payment legs. Use one entry per tender leg and include processor references where available. Send the latest Response:
ETag in If-Match. The completed operation returns fiscal_information with the KassenSichV regime.The current API has no generic
PATCH /operations/{id} endpoint. Build the full line-item and amount set before calling POST /operations; you cannot amend the body after creation. Open operations only accept /complete and /void.Void an open operation
If the sale is abandoned before completion, void the open operation:return operation instead.
Next steps
- Transaction lifecycle โ operation lifecycle in detail
- Payment lifecycle โ split tender, asynchronous settlement