> ## Documentation Index
> Fetch the complete documentation index at: https://docs.openfiskal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Limits and platform guarantees

> Availability targets, rate limits, idempotency, and concurrency rules. For the error catalog, see Errors.

For the full error catalog and per-code retry guidance, see [Errors](/errors).

## Platform guarantees

OpenFiskal publishes these current platform targets for the fiscalization API:

| Area                        | Guidance                                                                       |
| --------------------------- | ------------------------------------------------------------------------------ |
| Availability target         | `99.9%` monthly for production                                                 |
| Typical synchronous latency | `p50 < 300 ms`, `p95 < 1200 ms` for standard operation mutations               |
| Client timeout guidance     | `10s` request timeout, `30s` total retry budget for synchronous calls          |
| Rate limiting               | `500 requests/second` per API key                                              |
| `429` behavior              | Returns `Retry-After` in seconds and a stable `rate_limit_exceeded` error code |

## Idempotency and concurrency per endpoint

The table below shows which endpoints require `Idempotency-Key` and `If-Match` (ETag). Endpoints not listed here (all `GET`, `DELETE`, and `POST /registers/{id}/fiscalize`) require neither header.

| Endpoint                         | `Idempotency-Key` | `If-Match` (ETag) |
| -------------------------------- | ----------------- | ----------------- |
| `POST /operations`               | **Required**      | Not used          |
| `POST /operations/{id}/complete` | **Required**      | **Required**      |
| `POST /operations/{id}/void`     | **Required**      | **Required**      |
| `PATCH /merchants/{id}`          | Not used          | Not used          |
| `PATCH /registers/{id}`          | Not used          | Not used          |
| `PATCH /locations/{id}`          | Not used          | Not used          |

`PATCH` endpoints for merchants, registers, and locations do not require `If-Match` or `Idempotency-Key`. These endpoints apply a last-writer-wins strategy — concurrency control is not enforced on resource metadata updates.

## Idempotency rules

Send `Idempotency-Key` on every mutating operation request (`POST /operations`, `POST /operations/{id}/complete`, `POST /operations/{id}/void`).

The following are **Forward-looking platform rules**. Clients should code against them, but server-side enforcement is not yet live (see [Reserved codes](/errors#reserved-codes-not-yet-emitted)):

* retention window is at least 24 hours
* uniqueness scope is endpoint plus merchant plus authenticated tenant
* reusing a key with the same payload will return the original response
* reusing a key with a different payload will return `409 idempotency_key_conflict`

## Concurrency rules

Operation mutation endpoints (`POST /operations/{id}/complete`, `POST /operations/{id}/void`) require `If-Match` with the latest operation `ETag`. Omit it and the API returns `428 precondition_required`. Send a stale value and the API returns `412 precondition_failed`; the expected and current versions are included in `message` (e.g. `"Resource version mismatch. Expected 1, current is 2."`). The `If-Match` header value must be a quoted positive integer (e.g. `"1"`); a malformed value returns `400 invalid_request`.

`PATCH` endpoints on merchants, registers, and locations accept updates without `If-Match`. These are metadata-only mutations where last-writer-wins is acceptable.

## Request tracing

Every response includes an `X-Request-Id` header (e.g. `req_a1b2c3d4e5f60718293a`). Persist it in your logs and attach it to support cases.

## Next steps

* [Errors](/errors)
* [Authentication](/auth)
* [Transaction lifecycle](/pos-operation-ingestion)
