Skip to main content

API scope

The OpenFiskal API currently supports server-to-server communication only. Do not embed API keys in POS devices, mobile apps, browsers, or other client-side surfaces.

API key creation

Create API keys at console.openfiskal.com. Each key is tenant-scoped and country-scoped.
Store the key in your secrets manager. Treat it like any other production secret.

Key format

Keys follow the pattern of_{environment}_{country}_{random} where:
  • environment is test (sandbox) or live (production)
  • country is the lowercase ISO 3166-1 alpha-3 country code (e.g. deu, aut)
  • random is the opaque secret portion
Examples:
  • of_test_deu_abcdefgh12345678 — sandbox key for Germany
  • of_live_deu_… — production key for Germany
  • of_test_aut_… — sandbox key for Austria
The embedded country scopes every request. A deu key cannot create merchants in Austria.

Use the standard authorization header

Although the credential is an API key, the API uses the standard HTTP bearer pattern:
-H "Authorization: Bearer of_live_deu_abc123..."
This keeps the API compatible with standard API tooling, gateways, proxies, and security middleware.

Merchant scoping

For every merchant-scoped request, also send:
-H "X-OpenFiskal-Merchant: merchant_01HXYZ"
This header must contain the OpenFiskal merchant ID, not the API key. Together, a typical merchant-scoped request looks like this:
curl https://api.openfiskal.com/v1/operations \
  -H "Authorization: Bearer of_live_deu_abc123..." \
  -H "X-OpenFiskal-Merchant: merchant_01HXYZ"
Merchant-scoped resources include:
  • Locations
  • Registers
  • Operations
You do not need X-OpenFiskal-Merchant when you create, update, delete, or read the merchant itself.

Response envelope

Single-resource endpoints return the resource object directly. List endpoints wrap the array in a data field:
{
  "data": [
    { "id": "merchant_01HXYZ", "legal_name": "Mustermann GmbH", "..." : "..." },
    { "id": "merchant_01HABC", "legal_name": "Beispiel AG", "..." : "..." }
  ]
}
This applies to GET /merchants, GET /registers, and GET /locations. Single-resource responses (GET /merchants/{id}, POST /operations, etc.) return the object at the top level without a data wrapper. Error responses always use the error envelope, regardless of the endpoint.

Idempotency

For mutating requests that create or finalize state, send an Idempotency-Key header so retries remain safe:
curl -X POST https://api.openfiskal.com/v1/operations \
  -H "Authorization: Bearer of_live_deu_abc123..." \
  -H "X-OpenFiskal-Merchant: merchant_01HXYZ" \
  -H "Idempotency-Key: op-order-1001-start" \
  -H "Content-Type: application/json" \
  -d '{ "...": "..." }'
Use idempotency keys on every POST /operations, POST /operations/{id}/complete, and POST /operations/{id}/void request. The platform retains keys for at least 24 hours. Reusing the same key with a different payload returns 409 idempotency_key_conflict.
  • Return 401 when authentication is missing or invalid.
  • Return 403 when the API key is valid but not allowed to access the requested tenant, country, or merchant.
  • Return 412 Precondition Failed when an operation update, completion, or cancellation uses a stale If-Match value.
  • Return 429 Too Many Requests with Retry-After when the caller exceeds 500 requests/second per API key.

Next step

Continue with Getting started for the full onboarding and operation flow.