Documentation Index
Fetch the complete documentation index at: https://dev.openfiskal.com/llms.txt
Use this file to discover all available pages before exploring further.
This guide walks the v1 integration contract for Austria. You create an aut API key, onboard a merchant with an Austrian fiscal_identity, register a location and terminal, fiscalize the register under RKSV, 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.
Register fiscalization on the public API today exercises the DE / KassenSichV regime. Austrian RKSV fiscalization is rolling out โ contact support@openfiskal.com for current AT enablement status before scheduling go-live. The merchant, location, and register data shapes shown here are stable and safe to integrate against now.
Prerequisites
- An OpenFiskal tenant
- A tenant-scoped, country-scoped API key (
of_test_aut_โฆ or of_live_aut_โฆ)
curl or 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_aut_โฆ for the Austrian sandbox, of_live_aut_โฆ for Austrian production. An aut key rejects payloads for any other country.
-H "Authorization: Bearer of_live_aut_abc123..."
Every merchant-scoped request must also include:
-H "X-OpenFiskal-Merchant: merchant_01HXYZ"
This header value is the merchant ID returned by POST /merchants, not your API key.
Create resources
Create these resources in order. The register cannot fiscalize until the merchant has an AUT fiscal_identity.
Create your API key
Start in the OpenFiskal tenant dashboard. Create an aut key. Store it in your secrets manager. Format: of_{env}_aut_{random}, e.g. of_test_aut_abcdefgh12345678.
Create a merchant
country_code and every address.country_code must be AUT (ISO 3166-1 alpha-3). The Austrian fiscal_identity requires legal_entity_id_type (one of VAT_ID, TAX_ID, GLN). Provide the corresponding identifier โ vat_id (UID, e.g. ATU12345678), tax_number (Steuernummer), or gln (13-digit Global Location Number).curl -X POST https://sandbox.api.openfiskal.com/v1/merchants \
-H "Authorization: Bearer of_test_aut_abc123..." \
-H "Content-Type: application/json" \
-d '{
"legal_name": "Alpenblick Handels GmbH",
"country_code": "AUT",
"address": {
"line1": "Mariahilfer Straรe 24",
"city": "Wien",
"postal_code": "1070",
"country_code": "AUT"
},
"fiscal_identities": [
{
"country_code": "AUT",
"legal_entity_id_type": "VAT_ID",
"vat_id": "ATU12345678"
}
]
}'
The returned 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 โ RKSV embeds local time into signed records.curl -X POST https://sandbox.api.openfiskal.com/v1/locations \
-H "Authorization: Bearer of_test_aut_abc123..." \
-H "X-OpenFiskal-Merchant: merchant_01HXYZ" \
-H "Content-Type: application/json" \
-d '{
"name": "Wien Neubau",
"address": {
"line1": "Mariahilfer Straรe 24",
"city": "Wien",
"postal_code": "1070",
"country_code": "AUT"
},
"timezone": "Europe/Vienna"
}'
Create a register
A register is the logical checkout (Registrierkasse) that creates operations.curl -X POST https://sandbox.api.openfiskal.com/v1/registers \
-H "Authorization: Bearer of_test_aut_abc123..." \
-H "X-OpenFiskal-Merchant: merchant_01HXYZ" \
-H "Content-Type: application/json" \
-d '{
"location_id": "loc_01HXYZ",
"name": "Kassa 1",
"external_id": "pos-register-1"
}'
Fiscalize the register (rolling out)
Once enabled for AT, POST /registers/{id}/fiscalize provisions the RKSV components โ the SCU and Registrierkasse โ using the merchantโs AUT fiscal_identity and the locationโs country. The response is 202 Accepted; poll GET /registers/{id} until fiscalizedAt is populated.curl -X POST https://sandbox.api.openfiskal.com/v1/registers/reg_01HXYZ/fiscalize \
-H "Authorization: Bearer of_test_aut_abc123..." \
-H "X-OpenFiskal-Merchant: merchant_01HXYZ"
Verify your saved IDs
Persist the returned merchant, location, and register IDs. You will use them for every later operation request.
Once your register is fiscalized, you can create and complete sale operations. The request body is identical to other countries; the responseโs fiscal_information carries the RKSV-specific shape.
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.curl -X POST https://sandbox.api.openfiskal.com/v1/operations \
-H "Authorization: Bearer of_test_aut_abc123..." \
-H "X-OpenFiskal-Merchant: merchant_01HXYZ" \
-H "Idempotency-Key: op-order-1001-start" \
-H "Content-Type: application/json" \
-d '{
"register_id": "reg_01HXYZ",
"source": "POS",
"type": "sale",
"currency": "EUR",
"external_id": "order-1001",
"pretax_amount": "39.72",
"tax_amount": "2.78",
"tip_amount": "0.00",
"total_amount": "42.50",
"line_items": [
{
"title": "Mittagsmenรผ",
"quantity": 1,
"unit_price": "42.50",
"total_amount": "42.50",
"taxes": [
{ "name": "USt. 10%", "rate": "0.10", "tax_amount": "2.78" }
]
}
]
}'
Always send line_items[].taxes[]. RKSV requires per-rate VAT breakdown on the signed record (the AT rate buckets โ Normal, Ermรครigt-1, Ermรครigt-2, Null, Besonders โ are derived from the per-line rate).
Complete the operation
Completion includes typed payment legs. Use one entry per tender leg and include processor references where available. Send the latest ETag in If-Match. The completed operation returns fiscal_information with the RKSV regime.curl -X PATCH https://sandbox.api.openfiskal.com/v1/operations/op_01HXYZ/complete \
-H "Authorization: Bearer of_test_aut_abc123..." \
-H "X-OpenFiskal-Merchant: merchant_01HXYZ" \
-H "Idempotency-Key: op-order-1001-complete" \
-H 'If-Match: "1"' \
-H "Content-Type: application/json" \
-d '{
"payments": [
{
"payment_id": "pay_1001_card",
"method": "card",
"amount": "42.50",
"currency": "EUR",
"status": "captured",
"processor": "sumup",
"card_brand": "visa",
"processor_reference": "ch_123",
"processed_at": "2026-02-26T12:05:00Z"
}
]
}'
Response:HTTP/1.1 200 OK
ETag: "2"
X-Request-Id: req_01JCOMPLETE
{
"id": "op_01HXYZ",
"resource_version": 2,
"status": "completed",
"payments": [
{
"payment_id": "pay_1001_card",
"method": "card",
"amount": "42.50",
"currency": "EUR",
"status": "captured",
"processor": "sumup",
"processor_reference": "ch_123",
"card_brand": "visa",
"processed_at": "2026-02-26T12:05:00Z"
}
],
"fiscal_information": {
"regime": "RKSV",
"document_number": "2026-000123",
"document_type": "Beleg",
"transmitted_at": "2026-02-26T12:05:01Z",
"cashbox_id": "cashbox-01HXYZ",
"certificate_serial": "1A2B3C4D5E6F",
"signature": {
"signed_at": "2026-02-26T12:05:00Z",
"transaction_counter": 4822,
"turnover_counter": "12345.67",
"signature": "base64encodedSignature==",
"certificate_serial": "1A2B3C4D5E6F"
},
"verification": {
"qr_data": "_R1-AT0_cashbox-01HXYZ_4822_2026-02-26T12:05:00_42.50_0.00_0.00_0.00_0.00_..."
}
}
}
Void an open operation
If the sale is abandoned before completion, void the open operation:
curl -X PATCH https://sandbox.api.openfiskal.com/v1/operations/op_01HXYZ/void \
-H "Authorization: Bearer of_test_aut_abc123..." \
-H "X-OpenFiskal-Merchant: merchant_01HXYZ" \
-H "Idempotency-Key: op-order-1001-void" \
-H 'If-Match: "1"' \
-H "Content-Type: application/json" \
-d '{ "reason": "void_before_completion" }'
Completed operations cannot be voided โ use a return operation instead. Under RKSV a return produces a separately-signed Stornobeleg.
Next steps