{
 "openapi": "3.1.0",
 "jsonSchemaDialect": "https://spec.openapis.org/oas/3.1/dialect/base",
 "info": {
  "title": "Profirest API",
  "version": "26.11.28",
  "summary": "Public REST API of the Profirest restaurant system.",
  "x-summary-cs": "Veřejné REST API restauračního systému Profirest.",
  "description": "Profirest API v2 connects e-shops, devices and partner systems to restaurants that run on Profirest.\n\n> **EET 2.0 is done by Profirest – your application never records sales.** Every sale that goes through Profirest\n> (an order of your application, a receipt of a register) is recorded in EET 2.0, the Czech electronic registration\n> of sales from 1 January 2027, by the Profirest server: it signs the sale with the restaurant's certificate and sends\n> it when the customer pays on the spot – cash or card to the courier or at pickup, at the moment of the hand-over.\n> Payments over the internet (`online`) are not recorded. Your application sends nothing to the tax administration and\n> needs no certificate. Only when another system of the restaurant (its own register or kiosk) already recorded the\n> sale itself, send the order with `eet` and the confirmation code (POK) – Profirest then never sends it and keeps the\n> confirmation. A sale must never be recorded twice.\n\n## Quick start\n\n### A partner application (an e-shop)\n\n1. Ask Profirest (info@profirest.cz) for a `client_id` – and a `client_secret` for an application with its own\n   server – and register your redirect URI.\n2. Send the restaurant owner to the consent page (PKCE: `code_challenge` = BASE64URL(SHA-256(`code_verifier`))):\n\n   ```\n   https://api.mujprofirest.cz/oauth/authorize?response_type=code&client_id=YOUR_ID\n     &redirect_uri=https%3A%2F%2Fshop.example%2Fcallback&state=RANDOM\n     &scope=restaurants%3Aread+catalog%3Aread+orders%3Awrite+orders%3Aread\n     &code_challenge=CHALLENGE&code_challenge_method=S256\n   ```\n\n3. Your redirect URI gets `code` and `state`. Exchange the code for tokens:\n\n   ```\n   curl https://api.mujprofirest.cz/oauth/token -u YOUR_ID:YOUR_SECRET \\\n     -d grant_type=authorization_code -d code=CODE \\\n     -d redirect_uri=https://shop.example/callback -d code_verifier=VERIFIER\n   ```\n\n   The answer carries `access_token` (30 minutes) and `refresh_token`; refresh with `grant_type=refresh_token`.\n4. Read the restaurants you may see and the catalog of one of them:\n\n   ```\n   curl https://api.mujprofirest.cz/v2/restaurants -H \"Authorization: Bearer ACCESS_TOKEN\"\n   curl https://api.mujprofirest.cz/v2/restaurants/123/catalog -H \"Authorization: Bearer ACCESS_TOKEN\"\n   ```\n\n5. Price the basket – the server computes the prices, delivery and VAT – and create the order from the quote. Every\n   `POST` carries a new `Idempotency-Key`; repeat a failed request with the same key.\n\n   ```\n   curl https://api.mujprofirest.cz/v2/restaurants/123/quotes -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n     -H \"Content-Type: application/json\" -H \"Idempotency-Key: 0f8b4e2c-6d1a-4c3e-9b7f-2a5d8c1e4f60\" \\\n     -d '{\"fulfillment\":{\"type\":\"pickup\"},\"items\":[{\"product_id\":\"4567\",\"quantity\":2}]}'\n\n   curl https://api.mujprofirest.cz/v2/restaurants/123/orders -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n     -H \"Content-Type: application/json\" -H \"Idempotency-Key: 7c3e9a41-2b8d-4f6a-8e1c-5d9b0a7f3e12\" \\\n     -d '{\"quote_id\":\"QUOTE_ID\",\"customer\":{\"name\":\"Jana Nováková\",\"phone\":\"+420777123456\"},\n          \"payments\":[{\"method\":\"cash\",\"status\":\"unpaid\",\"amount\":{\"amount\":39800,\"currency\":\"CZK\"}}]}'\n   ```\n\n   The payments must add up to the quote's `amount_due` (here 398 CZK paid on pickup). An online payment goes as\n   `{\"method\":\"online\",\"status\":\"pending\",…}` and is confirmed by `…/orders/{order_id}/confirm-payment`.\n6. Follow what happens: `GET /v2/events` without a cursor returns `next_cursor` at the current end; ask with it\n   again (every few seconds, or when a webhook arrives) and keep the newest `next_cursor`.\n\n### A Profirest device (a register)\n\n1. The device asks for a code (no secret – a device is a public client):\n\n   ```\n   curl https://api.mujprofirest.cz/oauth/device_authorization -d client_id=profirest-pos \\\n     -d device_name=\"Register at the bar\" \\\n     -d scope=\"restaurants:read catalog:read staff:read staff:authenticate receipts:read receipts:write\"\n   ```\n\n   It shows `user_code` (for example `BCDF-GHJK`) or a QR code of `verification_uri_complete`. A manager confirms it\n   in the administration (*Správa PC / zařízení → Připojit zařízení*) and chooses the restaurant.\n2. Meanwhile the device asks for the token every `interval` seconds; it gets `authorization_pending` until the\n   code is confirmed:\n\n   ```\n   curl https://api.mujprofirest.cz/oauth/token -d client_id=profirest-pos -d device_code=DEVICE_CODE \\\n     -d grant_type=urn:ietf:params:oauth:grant-type:device_code\n   ```\n\n3. An employee signs in with a PIN; the answer carries the staff `token`:\n\n   ```\n   curl https://api.mujprofirest.cz/v2/restaurants/123/staff-sessions -H \"Authorization: Bearer DEVICE_TOKEN\" \\\n     -H \"Content-Type: application/json\" -d '{\"method\":\"pin\",\"secret\":\"4321\"}'\n   ```\n\n4. Price the receipt (`…/receipts/preview` with the same `items` and `discounts`; it returns the totals to pay) and issue it. The\n   receipt is deduplicated by its own `id` (a UUID made on the device), so a repeat never issues it twice:\n\n   ```\n   curl https://api.mujprofirest.cz/v2/restaurants/123/receipts -H \"Authorization: Bearer DEVICE_TOKEN\" \\\n     -H \"Profirest-Staff-Token: STAFF_TOKEN\" -H \"Content-Type: application/json\" \\\n     -d '{\"id\":\"6f1c2a9e-8b7d-4c3e-9f10-2a3b4c5d6e7f\",\"number\":1001,\"issued_at\":\"2027-01-15T12:03:00+01:00\",\n          \"items\":[{\"product_id\":\"4567\",\"quantity\":1}],\n          \"payments\":[{\"method\":\"cash\",\"amount\":{\"amount\":19900,\"currency\":\"CZK\"}}]}'\n   ```\n\n   The server records the sale in EET 2.0 itself; the device needs no certificate.\n\n### Examples in curl, PHP, Kotlin, Java and JavaScript\n\nEvery operation below has a ready example of the request in five languages (the tabs in the right column) and a full\nexample of the request body and the response. Whole scenarios step by step – an e-shop order, a register, a kitchen\ndisplay, an attendance terminal, deliveries, customers – are in the [guides](/v2/docs/guides).\n\n### JavaScript\n\n`https://api.mujprofirest.cz/v2/profirest-api.js` is a client without dependencies for browsers, the WebViews of\ndevices and Node 18+. It does the pairing by code, PKCE, token refresh (once, also across browser tabs), the staff\nsign-in, `Idempotency-Key`, retries after `Retry-After` and the event feed. See the\n[JavaScript client](/v2/docs/js).\n\n### Verifying a webhook\n\n```php\n$key = base64_decode(substr($whsec, 6));             // the secret without \"whsec_\"\n$signed = $_SERVER['HTTP_WEBHOOK_ID'] . '.' . $_SERVER['HTTP_WEBHOOK_TIMESTAMP'] . '.' . $body;\n$expected = base64_encode(hash_hmac('sha256', $signed, $key, true));\n$valid = false;\nforeach (explode(' ', $_SERVER['HTTP_WEBHOOK_SIGNATURE']) as $candidate) {\n    $valid = $valid || hash_equals('v1,' . $expected, $candidate);\n}\n// also reject a webhook-timestamp older than 5 minutes; then answer 2xx quickly and read GET /v2/events\n```\n\n## Glossary\n\n- **Account** – one restaurant owner in Profirest. It can have several restaurants.\n- **Restaurant** – one place with its own kitchen, prices and opening hours.\n- **Client** – your application registered with Profirest (`client_id`).\n- **Connection** – the access one account granted to your client: chosen restaurants and scopes.\n  One client can have connections to many accounts. See `GET /connection`.\n\n## Rules every client must follow\n\n- **Ignore unknown fields.** Responses gain new fields over time. That is not an incompatible change.\n- **Handle unknown enum values.** Values marked `x-extensible-enum` (statuses, types, event types)\n  may get new members. Treat an unknown value as \"other\" and never crash.\n- **Treat IDs as opaque strings.** Do not parse them and do not do arithmetic with them.\n- **Money is an integer in minor units plus an ISO 4217 currency.**\n  `{\"amount\": 1229460, \"currency\": \"CZK\"}` is 12 294.60 CZK.\n- **Branch on the error `code`, not on the HTTP status.** Codes never change. See *Errors*.\n- **Send `Idempotency-Key` with every POST** and reuse the same key when you retry the same request.\n- **Follow `next_cursor`** to page through lists. Never build a cursor yourself.\n- **Respect `Retry-After`** on 429 and 503 responses.\n- **Watch the `Deprecation` and `Sunset` headers.**\n\n## Stability promise\n\nWithin v2 we only add: new endpoints, new optional request fields, new response fields, new enum values,\nnew event types and new error codes. We never remove or rename anything, never change a type or a meaning\nand never add a required request field. A deprecated feature is marked with the `Deprecation` header and keeps\nworking until the end of v2. The end of v2 is announced with the `Sunset` header at least 12 months ahead.\n\nThe version of the contract (`info.version`, `version` of `GET /v2/`) is YY.M.N – the year, the month and the\nrelease within the month: `26.10.7` is the seventh release in October 2026. It says when a release came out,\nnot how compatible it is – that is what v2 in the URL is for. Compare versions part by part as numbers\n(`26.10.1` is newer than `26.9.12`). What each release brought: [changelog](/v2/docs/changelog).\n\n## Responses\n\n- Every documented field is always present in a response. When a value does not apply it is `null`.\n- Single resources are returned as an object. Lists are returned as `{\"data\": [...], \"next_cursor\": \"...\"}`.\n- Instants are RFC 3339 with an offset (`2026-10-05T18:30:00+02:00`), in the time zone of the restaurant.\n  Accept any offset on input.\n- Business dates (a shift, a daily menu, attendance) are plain dates `YYYY-MM-DD` in the time zone of the restaurant.\n- Any operation may also answer `429`, `500` or `503`, and every operation answers `400`, `406` and `422` the same\n  way (the published `openapi.json` lists them): the server rejects query parameters and body fields it does not\n  know (`422` with `unknown_field` – also a cache-busting `?_=123`), a body on an operation without one (`400`) and\n  an `Accept` it cannot give (`406`); operations with a body also `413` and `415`.\n\n## Headers on every response\n\n- `X-Request-Id` – quote it when you contact support.\n- `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` – your current request budget, a number of requests\n  a minute. The budget is per connection, and every paired device has its own. They come on responses of\n  operations with an access token once the token and its scopes are accepted; `/oauth/*`, `GET /v2/` and\n  `GET /v2/app-versions` do not have them, and neither do `401` and `403 insufficient_scope` (such requests do not\n  count). `429 rate_limited` comes with `Retry-After`.\n- `Content-Language` on errors – the language of `title`.\n- `Deprecation` (RFC 9745) and `Sunset` (RFC 8594) when a feature is being retired.\n- `Cache-Control` on authenticated responses: `private, no-store` when the body may hold personal data (orders,\n  customers, staff, delivery addresses, tabs, events), `private, no-cache` for the catalog, availability, daily\n  menu, delivery zones, restaurants and device settings. Send `If-None-Match` yourself where an operation offers it.\n\n## Retries and concurrency\n\n- `POST` requires `Idempotency-Key`. Retrying with the same key never creates a second object.\n  Final results (2xx and 4xx) are stored for 24 hours; a 5xx is not stored, so the retry runs again.\n  Keys are scoped to your connection, the method and the path.\n- `PUT` and `DELETE` are idempotent by themselves.\n- `PATCH` requires `If-Match` with the `ETag` you read. When somebody changed the object meanwhile you get\n  `412 precondition_failed`; read it again and decide.\n- After a network error, `500` or `503`, retry with exponential backoff and the same `Idempotency-Key`.\n- After a crash or a restart of your application the key a library made for you is gone – it lives only in the\n  memory of the process. For writes that must not happen twice (an order), create the key yourself, store it with\n  your record **before** you send the request and after the restart send the same request with the same key and\n  body: you get the original response. An order has two more guards that do not depend on the key: a quote can be\n  used only once (`409 quote_already_used`) and your `external_id` of an order is permanent\n  (`409 external_id_conflict`); both errors carry the ID of the existing order in `existing_id` – read it instead\n  of creating a new one. Receipts and attendance punches carry their own `id` in the body, which works as the key.\n\n## Ordering flow\n\n1. Read the catalog (`GET /restaurants/{restaurant_id}/catalog`) and the times you can offer (`/time-slots`).\n2. Price the basket: `POST /restaurants/{restaurant_id}/quotes`. The prices in a quote are guaranteed until `expires_at`.\n3. Create the order: `POST /restaurants/{restaurant_id}/orders`. With an online payment still to be made, send it\n   as `pending`: the order waits in `awaiting_payment`, portions and vouchers are reserved and the kitchen does not\n   see it yet.\n4. Charge your customer, then confirm: `POST /restaurants/{restaurant_id}/orders/{order_id}/confirm-payment`. Only now\n   the order goes to the kitchen. Without confirmation the order is cancelled when `payment_deadline` passes.\n5. Follow the status through webhooks or `GET /events`.\n\nThis way a customer is never charged for an order that could not be created.\n\n## Money and VAT\n\n- Prices are final prices including VAT.\n- `total = items + charges + discounts + rounding` – `discounts` is negative (or zero), see `Totals`.\n- VAT of one rate is computed from the gross amount: `vat = round(gross × rate / (100 + rate))`, rounded half up to\n  minor units; `base = gross − vat`.\n- Delivery and similar charges are ancillary costs under § 36(3) of Czech Act 235/2004 Coll.: they take the VAT\n  rate of the items. When the items have several rates, a charge is split in proportion to the items' amounts\n  including VAT, exactly like Profirest's receipt and accounting exports; the rounding remainder goes to the rate\n  with the largest amount. The minimum order surcharge is split first, express delivery over the items and the\n  surcharge, delivery then over all of them.\n- Gift vouchers are a means of payment, not a discount: they lower what is left to pay, not the price or the VAT.\n- Discounts come only from promotions the restaurant set up in the administration (`GET …/promotions`); your\n  application sends at most a promo code (`promo_codes` in the quote) and never an amount. A discount lowers the\n  price and the VAT base and is split into the VAT rates like on the receipt. A discount of items\n  (`applies_to: line`) stays in the VAT rate of its line; charges and discounts of the whole order are then split\n  over the items after the discounts of items.\n\n## Your own IDs and metadata\n\nRestaurants, categories, products, orders and customers your connection can see can carry your own `external_id`\n(one per object, unique per object type within your connection, searchable) and `metadata` (up to 20 key–value\npairs). Only your connection sees them. Other objects (receipts, tabs, kitchen tickets, employees, vouchers,\ndelivery routes) cannot carry them yet.\n\n## Texts\n\nTexts are UTF-8. Characters outside the Basic Multilingual Plane (for example emoji) are rejected with\n`422 validation_failed` and the field code `unsupported_characters`.\n\n## Environments\n\nAPI v2 runs at `https://api.mujprofirest.cz` – the default address of the official libraries – with the paths\n`/v2/…` and `/oauth/…`. It is not a sandbox: it works with the live data of restaurants, so test on a test\nrestaurant (see below). The documentation is at `https://api.mujprofirest.cz/v2/docs`, and OAuth returns\n`iss` = `https://api.mujprofirest.cz`.\n\n## Test restaurants\n\nProfirest can add test restaurants to your connection (`Restaurant.is_test`). Orders there appear only on a test\nkitchen display and are never prepared. Use them for development and automated tests.\n\n## Public demo account\n\nProfirest has a public demo account (`profirestdemo`) – a restaurant open around the clock with a catalog,\nemployees with PINs, order history and an e-shop. Its sign-in, the employees' PINs and the pairing of devices are on\nhttps://www.mujprofirest.cz/demo. It is meant for trying Profirest: the demo page pairs devices of any application\nthat pairs with a code with the demo restaurant without a manager, and an application can connect to it through the\nordinary consent page with the public sign-in. Test access for your own application – a client that can connect\nonly to the demo account – is issued straight away, without review, at `/zadost/test` on the API host.\n\n- Requests made on behalf of the demo account never send an SMS or an e-mail, and no sale of the account is ever\n  sent to EET 2.0. The API answers as usual, but order messages and phone verification codes are not delivered\n  (`POST …/phone-verification` still answers `201`, so a customer cannot be verified there) and receipts have\n  `eet: null`. Webhooks are delivered as usual.\n- Every night (around midnight) the account's data is deleted and created again; only the account, its restaurant\n  and its licence stay. Orders, receipts, customers, tabs, paired devices and connections with their tokens\n  disappear, and all IDs except those of the account and its restaurant change. Pair or connect again the next day\n  and never keep anything that depends on it.\n\nFor the development and automated tests of your application ask for a test restaurant instead.\n\n## Browsers\n\nThe API can be called from JavaScript in a browser. CORS is allowed only for the origins registered for your client.\nJavaScript can read `ETag`, `Location`, `Retry-After`, `X-Request-Id`, `RateLimit-*`, `Deprecation` and `Sunset`.\nThe API never uses cookies. Never put a client secret into browser code.\n\n## Errors\n\nErrors use RFC 9457 (`application/problem+json`). The machine-readable `code` is English and never changes.\n`title` is Czech or English according to `Accept-Language` (default Czech). The full list is in `x-error-catalog`\nand in the *Error catalog* section of the documentation.\n\n## Authentication\n\nOAuth 2.0 authorization code flow with PKCE (S256). The OAuth endpoints live outside `/v2`, so a connection keeps\nworking in later API versions. The restaurant owner signs in to Profirest, picks the restaurants and grants the\nscopes your client asked for. Send the access token as `Authorization: Bearer <token>` and never put it in a URL.\n\n- Access tokens live 30 minutes.\n- Refresh tokens live 90 days since their last use. Every refresh returns a new refresh token. For a confidential\n  client (with a secret) the previous refresh token keeps working for 60 seconds and returns the same new pair, so\n  two of your workers refreshing at once do no harm. A paired device may repeat the refresh with the previous token\n  until it has used the new refresh token, at most 24 hours – a device that lost the answer in a network outage\n  simply asks again. The repeat returns the same new refresh token; the access token is the same one with\n  `expires_in` counting only its remaining time, or a fresh one when that has run out. Reusing an old refresh token\n  outside these windows fails with `invalid_grant`. For a public client – a paired device after its window, or an\n  application in a browser at any time – it also ends the token's family (all tokens that come from the same\n  authorization or pairing; a device is unpaired), because the token was most likely stolen. A confidential client\n  keeps its other tokens.\n\n## Profirest's own devices\n\nCash registers, kitchen displays, attendance terminals and courier phones of Profirest use this same API. They\npair with the device authorization grant (RFC 8628, `POST /oauth/device_authorization`): the device shows a code,\na manager confirms it in the Profirest administration and the device picks up its tokens. A paired device works\nfor one restaurant only and the manager can unpair it at any time; its tokens stop working at once.\n\nEmployees sign in on a device with their PIN or card (`POST /restaurants/{restaurant_id}/staff-sessions`). The\ndevice then sends the staff token in the `Profirest-Staff-Token` header next to its own token, so every write\nrecords who did it, on which device and through which application. PINs and card numbers never leave the server.\n\nRecords made without a network (for example punches on an attendance terminal) carry an ID created on the device\nand the time they happened; sending them again never records them twice.\n\nThe scopes `staff:read`, `staff:authenticate`, `attendance:read`, `attendance:punch`, `kitchen:read`,\n`kitchen:write`, `deliveries:read`, `deliveries:write`, `settings:read`, `queue:read`, `directory:read`,\n`calls:write`, `receipts:read`, `receipts:write`, `stock:read`, `stock:write`, `backups:read`, `backups:write`,\n`diagnostics:write`, `table:sync`, `lodging_desk:read` and `lodging_desk:write` are only for Profirest's own applications (`x-first-party-scopes`). Partner applications never\nget them.\n\n## Exceptions to the rules\n\n- The OAuth endpoints follow RFC 6749: form-encoded requests, unknown parameters are ignored, errors use the\n  OAuth format and no `Idempotency-Key` is needed.\n- The catalog is one object (a snapshot), not a paginated list.\n- Customers belong to the whole account, so they are not under `/restaurants/{restaurant_id}`.\n- Signing an employee in (`POST …/staff-sessions`) takes no `Idempotency-Key`: a repeated sign-in only opens another\n  session and the answer carries a secret that is never stored.\n- Attendance punches are deduplicated by their own `id` made on the device, not by `Idempotency-Key`.\n- Operations of Profirest's own devices that carry their own `id` in the body – receipts and their cancellation,\n  kitchen tickets, the shift close, stock taking, POS activity and bug reports – are deduplicated by that `id`;\n  `Idempotency-Key` is ignored there. Keep the same `id` when you repeat such a request, a new `id` is a new\n  document. `reportCall`, `createDeviceLogs` and `previewReceipt` need neither (a repeat does no harm).\n- An `Idempotency-Key` must be random (a UUID): all devices of one application on an account share one connection,\n  so a counter could collide with another device.\n- Guests ordering from the table (`/table/…`) do not use OAuth: `startTableSession` gives a token of the phone at\n  the table (`tableGuest`) that works only for these operations. Requests the main register of the restaurant\n  decides answer `202` – an order or a call in the state `submitted`, or a request to read later.\n\n## Migrating from API v1\n\nAPI v1 (`/api/v1/{token}/…`, and `/api1/kds/…` of the kitchen display) keeps working until its end is announced.\nWhere its calls go in v2:\n\n| API v1 | API v2 |\n|---|---|\n| `POST api/v1` (app key and login), `bartender/pair`, `bartender/check` | pairing by code (`POST /oauth/device_authorization`); the token goes in `Authorization`, never in the URL |\n| `ping`, `versions` | `GET /` gives `server_time`, `GET /app-versions` the latest app versions |\n| `categories`, `products`, `portions`, `daily-menu`, `alergens` | `GET /restaurants/{restaurant_id}/catalog` (channel `pos`, `kitchen` or `web`), `…/availability` |\n| `users/{app}` | `GET …/staff` (without PINs) and `POST …/staff-sessions` (PIN checked by the server) |\n| `users/{app}/{id}` (PIN change) | `POST …/staff-sessions/current/pin` – only the employee's own PIN |\n| `orders/{app}` – a receipt | `POST …/receipts` (prices from the server, split payments, EET 2.0) |\n| `orders/{app}` – a ticket of an open table | `POST …/kitchen/tickets` |\n| `orders/{app}/status` | `GET …/kitchen/tickets/{ticket_id}` |\n| `orders/storno/{app}` | `POST …/receipts/{receipt_id}/storno` – only receipts issued through this API, always the whole receipt |\n| `storno/{app}` (an item taken off a table), `tables/{app}` | `GET`, `PUT` and `DELETE …/tabs/{tab_id}` |\n| `changePayment` | `POST …/receipts/{receipt_id}/payment-change` – cash, meal voucher, company account and invoice payments, until the shift close; card and gift voucher payments stay |\n| `changeNote` | the items and the note of a receipt never change: cancel it and issue a new one |\n| `deadline-shift/{app}` | `GET …/pos-shift`, `POST …/pos-shift/close` (totals computed by the server) – the shift of the calling device only; closed shifts in `GET …/pos-shifts` |\n| `timeline/create` | `POST …/pos-activity` |\n| `warehouse`, `stockTaking` | `GET …/stock-taking/items`, `POST …/stock-takings` |\n| `warehouse/decrease-stock` | the receipt itself takes the items off the stock |\n| `vouchers/{app}/{code}` and its `sell`, `redeem` | `POST …/vouchers/check` (sold vouchers; a paired register sees unsold ones too); selling and paying with a voucher are lines and payments of the receipt |\n| `vouchers/…/sell/cancel`, `…/redeem/cancel` | no separate operation: cancelling the receipt (`…/storno`) takes back its voucher sales and payments |\n| `eet/certificate/{hash}` | EET 2.0 is signed and sent by the server; devices hold no certificate |\n| `mobile/delivery/…` (couriers) | `…/couriers`, `…/delivery-routes`, `…/customer-directory`, `…/calls` |\n| `addr`, `regions`, `info` | `…/address-suggestions` (staff, a paired device only), `…/delivery-zones`, `GET /restaurants/{restaurant_id}` |\n| `clients/login`, `register`, `change-pass` | customers with a verified phone number (`POST /customers`), no passwords |\n| `info/menu` (the daily menu of a week) | `GET …/daily-menu?week=` |\n| `backup/{app}` (upload, list, download) | `POST …/backups` (the ZIP as the body), `GET …/backups`, `GET …/backups/{backup_id}/content` |\n| `log`, `report` | `POST …/device-logs`, `POST …/bug-reports` (signed in by the device token, no longer open to anyone) |\n| `sync` | no equivalent: follow changes with `GET /events` and read with `If-None-Match` |\n| `terminals`, `sms`, `external/sms`, `regions/unique` | no equivalent |\n| `api1/kds/pair`, `check`, `login_data`, `login_chef` | pairing by code (`POST /oauth/device_authorization`), `GET …/staff`, `GET …/device-settings`, `POST …/staff-sessions` |\n| `api1/kds/menu` | `GET …/catalog?channel=kitchen` |\n| `api1/kds/orders`, `history`, `preorders` | `GET …/kitchen/tickets` with `view=active`, `history` or `preorders` |\n| `api1/kds/status_change`, `printed` | `POST …/kitchen/tickets/{ticket_id}/status` (`STORNO`: `…/cancel`), `PUT …/printed` |\n| `api1/kds/create_order`, `update_order` | `POST …/quotes` and `…/orders`; `POST …/kitchen/tickets/{ticket_id}/items` – prices from the catalog, never from the device |\n| `api1/kds/client_lookup`, `clients_search`, `check_call`, `address_suggest`, `delivery_zones` | `GET …/customer-directory`, `…/calls/latest`, `…/address-suggestions`, `…/delivery-zones` |\n| `api1/kds/couriers`, `courier_toggle`, `create_route` | `GET …/couriers`, `PUT` and `DELETE …/couriers/{employee_id}/shift`, `POST …/delivery-routes` |\n| `api1/kds/shift_close`, `shift_close_confirm` | `GET …/kitchen/shift`, `POST …/kitchen/shift/close` |\n| `api1/kds/production_orders`, `production_status`, `production_segment`, `production_history` | `…/kitchen/stations/{station_id}/tickets`, `…/working`, `…/complete`, `…/actions` and `…/undo` |\n\n**Move a whole restaurant at once.** While registers on API v1 and on this API work side by side in one restaurant,\nthe v1 ones get in the way: a v1 register that syncs its tables removes the administration's copies of tabs\nopened through this API, an older v1 register (one that does not send the IDs of its orders) puts receipts issued\nthrough this API into its own shift close, and the backup cleanup of v1 can delete the oldest backups of any device\nof the restaurant. Switch all registers of the restaurant together, best right after a shift close.\n\n## Languages\n\nError titles and this documentation are available in Czech and English. Field names, enum values, event types and\nerror codes are English only and are never translated. Texts entered by the restaurant (product names,\ndescriptions) are returned as entered.\n\n## Support\n\nRegistration of your client, test restaurants and help with the integration: info@profirest.cz,\n+420 777 983 213. Quote `X-Request-Id` when something went wrong.\n",
  "x-description-cs": "Profirest API v2 propojuje e-shopy, zařízení a partnerské systémy s restauracemi, které používají Profirest.\n\n> **EET 2.0 eviduje Profirest – vaše aplikace tržby neeviduje.** Každou tržbu, která jde přes Profirest (objednávku\n> vaší aplikace, účtenku pokladny), zaeviduje do EET 2.0 (elektronická evidence tržeb od 1. 1. 2027) server\n> Profirestu: podepíše ji certifikátem provozovny a odešle, když zákazník zaplatí na místě – hotově nebo kartou\n> kurýrovi či při odběru, v okamžiku předání. Platby přes internet (`online`) se neevidují. Vaše aplikace finanční\n> správě nic neposílá a certifikát nepotřebuje. Jen když tržbu už zaevidoval sám jiný systém provozovny (její vlastní\n> pokladna nebo kiosek), pošlete objednávku s `eet` a potvrzovacím kódem (POK) – Profirest ji pak nikdy neodešle\n> a potvrzení si uloží. Tržba se nesmí zaevidovat dvakrát.\n\n## Rychlý start\n\n### Partnerská aplikace (e-shop)\n\n1. Požádejte Profirest (info@profirest.cz) o `client_id` – u aplikace s vlastním serverem i o `client_secret` – a\n   zaregistrujte adresu pro přesměrování.\n2. Pošlete majitele restaurace na souhlasovou stránku (PKCE: `code_challenge` = BASE64URL(SHA-256(`code_verifier`))):\n\n   ```\n   https://api.mujprofirest.cz/oauth/authorize?response_type=code&client_id=VASE_ID\n     &redirect_uri=https%3A%2F%2Fshop.example%2Fcallback&state=NAHODNE\n     &scope=restaurants%3Aread+catalog%3Aread+orders%3Awrite+orders%3Aread\n     &code_challenge=CHALLENGE&code_challenge_method=S256\n   ```\n\n3. Na adresu pro přesměrování přijde `code` a `state`. Kód vyměňte za tokeny:\n\n   ```\n   curl https://api.mujprofirest.cz/oauth/token -u VASE_ID:VASE_TAJEMSTVI \\\n     -d grant_type=authorization_code -d code=KOD \\\n     -d redirect_uri=https://shop.example/callback -d code_verifier=VERIFIER\n   ```\n\n   Odpověď nese `access_token` (30 minut) a `refresh_token`; obnovuje se přes `grant_type=refresh_token`.\n4. Načtěte provozovny, které smíte vidět, a sortiment jedné z nich:\n\n   ```\n   curl https://api.mujprofirest.cz/v2/restaurants -H \"Authorization: Bearer ACCESS_TOKEN\"\n   curl https://api.mujprofirest.cz/v2/restaurants/123/catalog -H \"Authorization: Bearer ACCESS_TOKEN\"\n   ```\n\n5. Spočítejte košík – ceny, dopravu i DPH počítá server – a z kalkulace založte objednávku. Každý `POST` nese nový\n   `Idempotency-Key`; nepovedený požadavek opakujte se stejným klíčem.\n\n   ```\n   curl https://api.mujprofirest.cz/v2/restaurants/123/quotes -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n     -H \"Content-Type: application/json\" -H \"Idempotency-Key: 0f8b4e2c-6d1a-4c3e-9b7f-2a5d8c1e4f60\" \\\n     -d '{\"fulfillment\":{\"type\":\"pickup\"},\"items\":[{\"product_id\":\"4567\",\"quantity\":2}]}'\n\n   curl https://api.mujprofirest.cz/v2/restaurants/123/orders -H \"Authorization: Bearer ACCESS_TOKEN\" \\\n     -H \"Content-Type: application/json\" -H \"Idempotency-Key: 7c3e9a41-2b8d-4f6a-8e1c-5d9b0a7f3e12\" \\\n     -d '{\"quote_id\":\"QUOTE_ID\",\"customer\":{\"name\":\"Jana Nováková\",\"phone\":\"+420777123456\"},\n          \"payments\":[{\"method\":\"cash\",\"status\":\"unpaid\",\"amount\":{\"amount\":39800,\"currency\":\"CZK\"}}]}'\n   ```\n\n   Platby musí dát dohromady `amount_due` z kalkulace (tady 398 Kč při vyzvednutí). Online platba jde jako\n   `{\"method\":\"online\",\"status\":\"pending\",…}` a potvrdí se přes `…/orders/{order_id}/confirm-payment`.\n6. Sledujte, co se děje: `GET /v2/events` bez kurzoru vrátí `next_cursor` na aktuálním konci; ptejte se s ním znovu\n   (po pár sekundách nebo po webhooku) a schovávejte si nejnovější `next_cursor`.\n\n### Zařízení Profirestu (pokladna)\n\n1. Zařízení si vyžádá kód (bez tajemství – zařízení je veřejný klient):\n\n   ```\n   curl https://api.mujprofirest.cz/oauth/device_authorization -d client_id=profirest-pos \\\n     -d device_name=\"Pokladna u baru\" \\\n     -d scope=\"restaurants:read catalog:read staff:read staff:authenticate receipts:read receipts:write\"\n   ```\n\n   Ukáže `user_code` (třeba `BCDF-GHJK`) nebo QR kód z `verification_uri_complete`. Vedoucí ho potvrdí\n   v administraci (*Správa PC / zařízení → Připojit zařízení*) a vybere provozovnu.\n2. Zařízení se mezitím každých `interval` sekund ptá na token; dokud kód nikdo nepotvrdí, dostává\n   `authorization_pending`:\n\n   ```\n   curl https://api.mujprofirest.cz/oauth/token -d client_id=profirest-pos -d device_code=DEVICE_CODE \\\n     -d grant_type=urn:ietf:params:oauth:grant-type:device_code\n   ```\n\n3. Zaměstnanec se přihlásí PINem; odpověď nese jeho `token`:\n\n   ```\n   curl https://api.mujprofirest.cz/v2/restaurants/123/staff-sessions -H \"Authorization: Bearer DEVICE_TOKEN\" \\\n     -H \"Content-Type: application/json\" -d '{\"method\":\"pin\",\"secret\":\"4321\"}'\n   ```\n\n4. Účtenku nechte spočítat (`…/receipts/preview` se stejnými `items` a `discounts`; vrátí částku k zaplacení) a vystavte. Proti\n   dvojímu zápisu hlídá její vlastní `id` (UUID ze zařízení), opakování ji nikdy nevystaví dvakrát:\n\n   ```\n   curl https://api.mujprofirest.cz/v2/restaurants/123/receipts -H \"Authorization: Bearer DEVICE_TOKEN\" \\\n     -H \"Profirest-Staff-Token: STAFF_TOKEN\" -H \"Content-Type: application/json\" \\\n     -d '{\"id\":\"6f1c2a9e-8b7d-4c3e-9f10-2a3b4c5d6e7f\",\"number\":1001,\"issued_at\":\"2027-01-15T12:03:00+01:00\",\n          \"items\":[{\"product_id\":\"4567\",\"quantity\":1}],\n          \"payments\":[{\"method\":\"cash\",\"amount\":{\"amount\":19900,\"currency\":\"CZK\"}}]}'\n   ```\n\n   Tržbu do EET 2.0 zaeviduje server sám; zařízení certifikát nepotřebuje.\n\n### Příklady v curl, PHP, Kotlinu, Javě a JavaScriptu\n\nKaždá operace níže má hotovou ukázku požadavku v pěti jazycích (záložky v pravém sloupci) a úplný příklad těla\npožadavku i odpovědi. Celé scénáře krok za krokem – objednávka z e-shopu, pokladna, kuchyňský displej, docházkový\nterminál, rozvoz, zákazníci – jsou v [návodech](/v2/docs/guides).\n\n### JavaScript\n\n`https://api.mujprofirest.cz/v2/profirest-api.js` je klient bez závislostí pro prohlížeč, WebView zařízení a Node 18+.\nUdělá párování kódem, PKCE, obnovu tokenů (jednou, i mezi panely prohlížeče), přihlášení zaměstnance,\n`Idempotency-Key`, opakování po `Retry-After` a čtení proudu událostí. Viz [klient pro JavaScript](/v2/docs/js).\n\n### Ověření webhooku\n\n```php\n$key = base64_decode(substr($whsec, 6));             // tajemství bez „whsec_“\n$signed = $_SERVER['HTTP_WEBHOOK_ID'] . '.' . $_SERVER['HTTP_WEBHOOK_TIMESTAMP'] . '.' . $body;\n$expected = base64_encode(hash_hmac('sha256', $signed, $key, true));\n$valid = false;\nforeach (explode(' ', $_SERVER['HTTP_WEBHOOK_SIGNATURE']) as $candidate) {\n    $valid = $valid || hash_equals('v1,' . $expected, $candidate);\n}\n// odmítněte i webhook-timestamp starší než 5 minut; pak rychle odpovězte 2xx a načtěte GET /v2/events\n```\n\n## Pojmy\n\n- **Účet** – jeden majitel restaurace v Profirestu. Může mít víc provozoven.\n- **Provozovna** – jedno místo s vlastní kuchyní, cenami a otevírací dobou.\n- **Klient** – vaše aplikace registrovaná v Profirestu (`client_id`).\n- **Připojení** – přístup, který jeden účet dal vašemu klientovi: vybrané provozovny a oprávnění.\n  Jeden klient může mít připojení k mnoha účtům. Viz `GET /connection`.\n\n## Pravidla pro každého klienta\n\n- **Ignorujte neznámá pole.** Odpovědi časem dostávají nová pole. Není to nekompatibilní změna.\n- **Zvládněte neznámou hodnotu výčtu.** Hodnoty označené `x-extensible-enum` (stavy, typy, typy událostí) mohou\n  dostat nové členy. Neznámou hodnotu berte jako „jiné“ a nikdy kvůli ní nepadejte.\n- **ID jsou neprůhledné řetězce.** Nerozkládejte je a neprovádějte s nimi výpočty.\n- **Peníze jsou celé číslo v nejmenší jednotce a měna podle ISO 4217.**\n  `{\"amount\": 1229460, \"currency\": \"CZK\"}` je 12 294,60 Kč.\n- **Rozhodujte se podle `code` chyby, ne podle HTTP stavu.** Kódy se nikdy nemění. Viz *Chyby*.\n- **Posílejte `Idempotency-Key` u každého POST** a při opakování stejného požadavku použijte stejný klíč.\n- **Stránkujte přes `next_cursor`.** Kurzor nikdy neskládejte sami.\n- **Respektujte `Retry-After`** u odpovědí 429 a 503.\n- **Sledujte hlavičky `Deprecation` a `Sunset`.**\n\n## Slib stability\n\nV rámci v2 jen přidáváme: nové endpointy, nová nepovinná vstupní pole, nová pole v odpovědích, nové hodnoty\nvýčtů, nové typy událostí a nové kódy chyb. Nikdy nic neodebíráme ani nepřejmenováváme, neměníme typ ani význam\na nepřidáváme povinné vstupní pole. Ukončovanou funkci označí hlavička `Deprecation` a funguje až do konce v2.\nKonec v2 oznámí hlavička `Sunset` nejméně 12 měsíců předem.\n\nVerze smlouvy (`info.version`, `version` v `GET /v2/`) má tvar RR.M.N – rok, měsíc a pořadí vydání v měsíci:\n`26.10.7` je sedmé vydání v říjnu 2026. Říká, kdy vydání vyšlo, ne jak je kompatibilní – to říká v2 v adrese.\nVerze porovnávejte číselně po částech (`26.10.1` je novější než `26.9.12`). Co které vydání přineslo:\n[changelog](/v2/docs/changelog).\n\n## Odpovědi\n\n- Každé zdokumentované pole je v odpovědi vždy. Když hodnota nedává smysl, je `null`.\n- Jeden záznam se vrací jako objekt. Seznam jako `{\"data\": [...], \"next_cursor\": \"...\"}`.\n- Okamžiky jsou RFC 3339 s posunem (`2026-10-05T18:30:00+02:00`) v časové zóně provozovny.\n  Na vstupu přijímáme jakýkoli posun.\n- Provozní dny (směna, denní menu, docházka) jsou prostá data `YYYY-MM-DD` v časové zóně provozovny.\n- Každá operace může navíc odpovědět `429`, `500` nebo `503` a každá odpovídá stejně `400`, `406` a `422`\n  (zveřejněný `openapi.json` je uvádí): server odmítne parametry adresy i pole těla, která nezná (`422`\n  s `unknown_field` – i `?_=123` proti mezipaměti), tělo u operace, která žádné nebere (`400`), a `Accept`, který\n  neumí (`406`); operace s tělem i `413` a `415`.\n\n## Hlavičky v každé odpovědi\n\n- `X-Request-Id` – uveďte ho, když píšete podpoře.\n- `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset` – váš aktuální příděl požadavků za minutu. Příděl má\n  každé připojení a vlastní ho má i každé spárované zařízení. Přicházejí u operací s access tokenem, jakmile je\n  token i jeho oprávnění v pořádku; `/oauth/*`, `GET /v2/` a `GET /v2/app-versions` je nemají, stejně jako `401`\n  a `403 insufficient_scope` (takové požadavky se do přídělu nepočítají). `429 rate_limited` přichází\n  s `Retry-After`.\n- `Content-Language` u chyb – jazyk pole `title`.\n- `Deprecation` (RFC 9745) a `Sunset` (RFC 8594), když se funkce ukončuje.\n- `Cache-Control` u odpovědí s tokenem: `private, no-store`, když tělo může nést osobní údaje (objednávky,\n  zákazníci, personál, adresy rozvozu, účty stolů, události), `private, no-cache` u sortimentu, dostupnosti,\n  denního menu, rozvozových zón, provozoven a nastavení zařízení. `If-None-Match` posílejte sami tam, kde ho\n  operace nabízí.\n\n## Opakování a souběh\n\n- `POST` vyžaduje `Idempotency-Key`. Opakování se stejným klíčem nikdy nevytvoří druhý záznam.\n  Konečné výsledky (2xx a 4xx) se drží 24 hodin; 5xx se neukládá, takže opakování proběhne znovu.\n  Klíče platí v rámci vašeho připojení, metody a cesty.\n- `PUT` a `DELETE` jsou idempotentní samy od sebe.\n- `PATCH` vyžaduje `If-Match` s načteným `ETag`. Když záznam mezitím změnil někdo jiný, dostanete\n  `412 precondition_failed`; načtěte ho znovu a rozhodněte se.\n- Po chybě sítě, `500` nebo `503` opakujte s rostoucí prodlevou a se stejným `Idempotency-Key`.\n- Po pádu nebo restartu vaší aplikace klíč, který vám vytvořila knihovna, už nemáte – žije jen v paměti procesu.\n  U zápisů, které se nesmí provést dvakrát (objednávka), klíč vytvořte sami, uložte ho k záznamu **dřív**, než\n  požadavek odešlete, a po restartu pošlete stejný požadavek se stejným klíčem i tělem: dostanete původní odpověď.\n  Objednávka má navíc dvě pojistky nezávislé na klíči: kalkulaci jde použít jen jednou\n  (`409 quote_already_used`) a vaše `external_id` objednávky je trvalé (`409 external_id_conflict`); obě chyby\n  nesou ID existující objednávky v `existing_id` – načtěte ji místo zakládání nové. Účtenky a píchnutí docházky\n  nesou vlastní `id` v těle, které slouží jako klíč.\n\n## Průběh objednávky\n\n1. Načtěte sortiment (`GET /restaurants/{restaurant_id}/catalog`) a časy, které lze nabídnout (`/time-slots`).\n2. Spočítejte košík: `POST /restaurants/{restaurant_id}/quotes`. Ceny v kalkulaci jsou zaručené do `expires_at`.\n3. Vytvořte objednávku: `POST /restaurants/{restaurant_id}/orders`. Když online platba teprve proběhne, pošlete ji\n   jako `pending`: objednávka čeká ve stavu `awaiting_payment`, porce a vouchery jsou rezervované a kuchyně ji\n   ještě nevidí.\n4. Vyberte platbu od zákazníka a potvrďte ji: `POST /restaurants/{restaurant_id}/orders/{order_id}/confirm-payment`.\n   Teprve teď jde objednávka do kuchyně. Bez potvrzení se objednávka po `payment_deadline` zruší.\n5. Stav sledujte přes webhooky nebo `GET /events`.\n\nZákazník tak nikdy nezaplatí za objednávku, kterou nešlo vytvořit.\n\n## Peníze a DPH\n\n- Ceny jsou konečné včetně DPH.\n- `total = items + charges + discounts + rounding` – `discounts` je záporné (nebo nula), viz `Totals`.\n- DPH jedné sazby se počítá z částky s daní: `vat = round(gross × sazba / (100 + sazba))`, zaokrouhleno\n  matematicky na nejmenší jednotky; `base = gross − vat`.\n- Doprava a podobné poplatky jsou vedlejší výdaje podle § 36 odst. 3 zákona č. 235/2004 Sb.: daní se sazbou\n  položek. Když mají položky více sazeb, poplatek se rozdělí v poměru jejich částek s DPH – přesně jako na účtence\n  a v účetních exportech Profirestu; zbytek po zaokrouhlení dostane sazba s nejvyšší částkou. Nejdřív se rozdělí\n  doplatek do minimální objednávky, expresní doručení podle položek i s doplatkem, doprava pak podle všeho.\n- Dárkové vouchery jsou platební prostředek, ne sleva: snižují částku k úhradě, ne cenu ani DPH.\n- Slevy dává jen provozovna akcemi, které nastaví v administraci (`GET …/promotions`); aplikace posílá nejvýš\n  slevový kód (`promo_codes` v kalkulaci), nikdy částku. Sleva snižuje cenu i základ daně a do sazeb DPH se dělí\n  jako na účtence. Sleva na položku (`applies_to: line`) zůstává v sazbě svého řádku; poplatky a slevy celé\n  objednávky se pak dělí podle položek po slevách na položky.\n\n## Vaše vlastní ID a metadata\n\nK provozovnám, kategoriím, produktům, objednávkám a zákazníkům, které vaše připojení vidí, si můžete uložit vlastní\n`external_id` (jedno na objekt, unikátní v rámci typu objektu a vašeho připojení, lze podle něj hledat)\na `metadata` (až 20 dvojic klíč–hodnota). Vidí je jen vaše připojení. Jiné objekty (účtenky, účty stolů,\nkuchyňské bony, zaměstnanci, vouchery, rozvozové trasy) je zatím nést nemohou.\n\n## Texty\n\nTexty jsou v UTF-8. Znaky mimo základní rovinu Unicode (například emoji) API odmítne s `422 validation_failed`\na kódem pole `unsupported_characters`.\n\n## Prostředí\n\nAPI v2 běží na `https://api.mujprofirest.cz` – výchozí adrese oficiálních knihoven – s cestami `/v2/…` a\n`/oauth/…`. Není to pískoviště: pracuje nad ostrými daty restaurací, zkoušejte proto na testovací provozovně\n(viz níže). Dokumentace je na `https://api.mujprofirest.cz/v2/docs` a OAuth vrací\n`iss` = `https://api.mujprofirest.cz`.\n\n## Testovací provozovny\n\nProfirest může k vašemu připojení přidat testovací provozovny (`Restaurant.is_test`). Objednávky z nich se ukážou\njen na testovacím kuchyňském displeji a nikdo je nepřipravuje. Používejte je pro vývoj a automatické testy.\n\n## Veřejný ukázkový účet\n\nProfirest má veřejný ukázkový účet (`profirestdemo`) – provozovnu otevřenou nonstop se sortimentem, zaměstnanci\ns PINy, historií objednávek a e-shopem. Přihlášení, PINy zaměstnanců a párování zařízení jsou na\nhttps://www.mujprofirest.cz/demo. Slouží k vyzkoušení Profirestu: stránka ukázky spáruje s ukázkovou provozovnou\nbez vedoucího zařízení kterékoli aplikace párované kódem a aplikaci k němu jde připojit běžnou souhlasovou stránkou\ns veřejným přihlášením. Testovací přístup pro vlastní aplikaci – klienta, který se připojí jen k ukázkovému účtu –\nvydáme hned a bez posuzování na `/zadost/test` na adrese API.\n\n- Z požadavků za ukázkový účet nikdy neodejde SMS ani e-mail a žádná tržba účtu se nikdy neposílá do EET 2.0. API\n  odpovídá jako obvykle, ale zprávy o objednávkách a ověřovací kódy telefonu se nedoručí\n  (`POST …/phone-verification` přesto odpoví `201`, zákazníka tam tedy ověřit nejde) a účtenky mají `eet: null`.\n  Webhooky se doručují jako obvykle.\n- Každou noc (kolem půlnoci) se data účtu smažou a vytvoří znovu; zůstane jen účet, jeho provozovna a licence.\n  Objednávky, účtenky, zákazníci, účty stolů, spárovaná zařízení i připojení s tokeny zmizí a všechna ID kromě ID\n  účtu a jeho provozovny se změní. Druhý den spárujte nebo připojte znovu a nic, co na něm závisí, si neuchovávejte.\n\nPro vývoj a automatické testy své aplikace si místo toho řekněte o testovací provozovnu.\n\n## Prohlížeče\n\nAPI lze volat z JavaScriptu v prohlížeči. CORS je povolený jen pro adresy registrované u vašeho klienta.\nJavaScript smí číst `ETag`, `Location`, `Retry-After`, `X-Request-Id`, `RateLimit-*`, `Deprecation` a `Sunset`.\nAPI nikdy nepoužívá cookies. Tajemství klienta (client secret) nikdy nedávejte do kódu v prohlížeči.\n\n## Chyby\n\nChyby jsou podle RFC 9457 (`application/problem+json`). Strojový `code` je anglicky a nikdy se nemění. `title` je\nčesky nebo anglicky podle `Accept-Language` (výchozí čeština). Úplný seznam je v `x-error-catalog` a v kapitole\n*Katalog chyb* dokumentace.\n\n## Přihlášení\n\nOAuth 2.0 authorization code s PKCE (S256). OAuth endpointy leží mimo `/v2`, takže připojení bude fungovat i v dalších\nverzích API. Majitel restaurace se přihlásí do Profirestu, vybere provozovny a potvrdí oprávnění, o která váš klient\nžádá. Access token posílejte jako `Authorization: Bearer <token>` a nikdy ho nedávejte do URL.\n\n- Access token platí 30 minut.\n- Refresh token platí 90 dní od posledního použití. Každé obnovení vrátí nový refresh token. U důvěrného klienta\n  (s tajemstvím) předchozí refresh token funguje ještě 60 sekund a vrátí stejnou novou dvojici, takže nevadí\n  souběžné obnovení ze dvou vašich procesů. Spárované zařízení smí obnovu s předchozím tokenem zopakovat, dokud nový\n  refresh token nepoužije, nejdéle 24 hodin – zařízení, kterému se odpověď ztratila ve výpadku sítě, se prostě\n  zeptá znovu. Opakování vrátí stejný nový refresh token; access token stejný s `expires_in` jen na zbývající dobu,\n  nebo nový, když už vypršel. Opětovné použití starého refresh tokenu mimo tato okna skončí `invalid_grant`.\n  U veřejného klienta – spárovaného zařízení po uplynutí jeho okna, nebo aplikace v prohlížeči kdykoli – navíc\n  ukončí řadu tokenů (všechny tokeny ze stejného povolení nebo spárování; zařízení se odpáruje), protože token byl\n  nejspíš ukraden. Důvěrnému klientovi ostatní tokeny zůstanou.\n\n## Vlastní zařízení Profirestu\n\nPokladny, kuchyňské displeje, docházkové terminály a telefony kurýrů Profirestu používají stejné API. Párují se\npřes device authorization grant (RFC 8628, `POST /oauth/device_authorization`): zařízení ukáže kód, vedoucí ho\npotvrdí v administraci Profirestu a zařízení si vyzvedne tokeny. Spárované zařízení pracuje jen pro jednu\nprovozovnu a vedoucí ho může kdykoli odpojit; jeho tokeny pak hned přestanou platit.\n\nZaměstnanci se na zařízení přihlašují PINem nebo čipem (`POST /restaurants/{restaurant_id}/staff-sessions`).\nZařízení pak posílá token zaměstnance v hlavičce `Profirest-Staff-Token` vedle svého tokenu, takže u každého\nzápisu je vidět, kdo ho udělal, na kterém zařízení a přes kterou aplikaci. PINy a čísla čipů server nikdy nevydá.\n\nZáznamy pořízené bez sítě (třeba píchnutí na docházkovém terminálu) nesou ID vytvořené v zařízení a čas, kdy se\nstaly; opakované odeslání je nikdy nezapíše dvakrát.\n\nOprávnění `staff:read`, `staff:authenticate`, `attendance:read`, `attendance:punch`, `kitchen:read`,\n`kitchen:write`, `deliveries:read`, `deliveries:write`, `settings:read`, `queue:read`, `directory:read`,\n`calls:write`, `receipts:read`, `receipts:write`, `stock:read`, `stock:write`, `backups:read`, `backups:write`,\n`diagnostics:write`, `table:sync`, `lodging_desk:read` a `lodging_desk:write` jsou jen pro vlastní aplikace Profirestu (`x-first-party-scopes`). Partnerské aplikace je\nnikdy nedostanou.\n\n## Výjimky z pravidel\n\n- OAuth endpointy se řídí RFC 6749: požadavky jsou formuláře, neznámé parametry se ignorují, chyby mají formát\n  OAuth a `Idempotency-Key` není potřeba.\n- Sortiment je jeden objekt (snímek), ne stránkovaný seznam.\n- Zákazníci patří celému účtu, proto nejsou pod `/restaurants/{restaurant_id}`.\n- Přihlášení zaměstnance (`POST …/staff-sessions`) nebere `Idempotency-Key`: opakované přihlášení jen založí další\n  relaci a odpověď nese tajemství, které se nikam neukládá.\n- Píchnutí v docházce se proti dvojímu zápisu hlídají vlastním `id` ze zařízení, ne `Idempotency-Key`.\n- Operace vlastních zařízení Profirestu, které nesou vlastní `id` v těle – účtenky a jejich storno, kuchyňské bony,\n  uzávěrka, inventura, deník akcí pokladny a hlášení chyb –, se proti dvojímu zápisu hlídají tímto `id`;\n  `Idempotency-Key` se u nich nečte. Při opakování požadavku pošlete stejné `id`, nové `id` je nový doklad.\n  `reportCall`, `createDeviceLogs` a `previewReceipt` nepotřebují nic (opakování neškodí).\n- `Idempotency-Key` musí být náhodný (UUID): všechna zařízení jedné aplikace na účtu sdílejí jedno připojení,\n  takže by se čítač mohl potkat s jiným zařízením.\n- Hosté objednávající od stolu (`/table/…`) nepoužívají OAuth: `startTableSession` dá token telefonu u stolu\n  (`tableGuest`), který funguje jen pro tyto operace. Požadavky, o kterých rozhoduje hlavní kasa podniku, odpovídají\n  `202` – objednávka nebo volání ve stavu `submitted`, nebo žádost, kterou si přečtete později.\n\n## Přechod z API v1\n\nAPI v1 (`/api/v1/{token}/…` a `/api1/kds/…` kuchyňského displeje) funguje dál, dokud nebude oznámen jeho konec.\nKam jeho volání patří ve v2:\n\n| API v1 | API v2 |\n|---|---|\n| `POST api/v1` (klíč aplikace a login), `bartender/pair`, `bartender/check` | párování kódem (`POST /oauth/device_authorization`); token v `Authorization`, nikdy v adrese |\n| `ping`, `versions` | `GET /` vrací `server_time`, `GET /app-versions` nejnovější verze aplikací |\n| `categories`, `products`, `portions`, `daily-menu`, `alergens` | `GET /restaurants/{restaurant_id}/catalog` (kanál `pos`, `kitchen` nebo `web`), `…/availability` |\n| `users/{app}` | `GET …/staff` (bez PINů) a `POST …/staff-sessions` (PIN ověří server) |\n| `users/{app}/{id}` (změna PINu) | `POST …/staff-sessions/current/pin` – jen vlastní PIN zaměstnance |\n| `orders/{app}` – účtenka | `POST …/receipts` (ceny ze serveru, dělená platba, EET 2.0) |\n| `orders/{app}` – bon otevřeného stolu | `POST …/kitchen/tickets` |\n| `orders/{app}/status` | `GET …/kitchen/tickets/{ticket_id}` |\n| `orders/storno/{app}` | `POST …/receipts/{receipt_id}/storno` – jen účtenky vystavené přes toto API, vždy celá účtenka |\n| `storno/{app}` (položka odebraná ze stolu), `tables/{app}` | `GET`, `PUT` a `DELETE …/tabs/{tab_id}` |\n| `changePayment` | `POST …/receipts/{receipt_id}/payment-change` – platby hotově, stravenkami, na firemní účet a fakturou, do uzávěrky směny; platby kartou a dárkovým voucherem zůstávají |\n| `changeNote` | položky ani poznámka účtenky se nemění: stornujte ji a vystavte novou |\n| `deadline-shift/{app}` | `GET …/pos-shift`, `POST …/pos-shift/close` (součty spočítá server) – jen směna volajícího zařízení; uzavřené směny v `GET …/pos-shifts` |\n| `timeline/create` | `POST …/pos-activity` |\n| `warehouse`, `stockTaking` | `GET …/stock-taking/items`, `POST …/stock-takings` |\n| `warehouse/decrease-stock` | ze skladu odepíše sama účtenka |\n| `vouchers/{app}/{code}` a jeho `sell`, `redeem` | `POST …/vouchers/check` (prodané vouchery; spárovaná pokladna vidí i neprodané); prodej a platba voucherem jsou řádky a platby účtenky |\n| `vouchers/…/sell/cancel`, `…/redeem/cancel` | samostatná operace není: storno účtenky (`…/storno`) vezme zpět její prodeje a platby vouchery |\n| `eet/certificate/{hash}` | EET 2.0 podepisuje a odesílá server; zařízení certifikát nemají |\n| `mobile/delivery/…` (kurýři) | `…/couriers`, `…/delivery-routes`, `…/customer-directory`, `…/calls` |\n| `addr`, `regions`, `info` | `…/address-suggestions` (personál, jen spárované zařízení), `…/delivery-zones`, `GET /restaurants/{restaurant_id}` |\n| `clients/login`, `register`, `change-pass` | zákazníci s ověřeným telefonem (`POST /customers`), bez hesel |\n| `info/menu` (denní menu na týden) | `GET …/daily-menu?week=` |\n| `backup/{app}` (nahrání, seznam, stažení) | `POST …/backups` (ZIP jako tělo), `GET …/backups`, `GET …/backups/{backup_id}/content` |\n| `log`, `report` | `POST …/device-logs`, `POST …/bug-reports` (přihlášené tokenem zařízení, už ne otevřené komukoli) |\n| `sync` | obdoba není: změny sledujte přes `GET /events` a čtěte s `If-None-Match` |\n| `terminals`, `sms`, `external/sms`, `regions/unique` | obdoba není |\n| `api1/kds/pair`, `check`, `login_data`, `login_chef` | párování kódem (`POST /oauth/device_authorization`), `GET …/staff`, `GET …/device-settings`, `POST …/staff-sessions` |\n| `api1/kds/menu` | `GET …/catalog?channel=kitchen` |\n| `api1/kds/orders`, `history`, `preorders` | `GET …/kitchen/tickets` s `view=active`, `history` nebo `preorders` |\n| `api1/kds/status_change`, `printed` | `POST …/kitchen/tickets/{ticket_id}/status` (`STORNO`: `…/cancel`), `PUT …/printed` |\n| `api1/kds/create_order`, `update_order` | `POST …/quotes` a `…/orders`; `POST …/kitchen/tickets/{ticket_id}/items` – ceny ze sortimentu, nikdy ze zařízení |\n| `api1/kds/client_lookup`, `clients_search`, `check_call`, `address_suggest`, `delivery_zones` | `GET …/customer-directory`, `…/calls/latest`, `…/address-suggestions`, `…/delivery-zones` |\n| `api1/kds/couriers`, `courier_toggle`, `create_route` | `GET …/couriers`, `PUT` a `DELETE …/couriers/{employee_id}/shift`, `POST …/delivery-routes` |\n| `api1/kds/shift_close`, `shift_close_confirm` | `GET …/kitchen/shift`, `POST …/kitchen/shift/close` |\n| `api1/kds/production_orders`, `production_status`, `production_segment`, `production_history` | `…/kitchen/stations/{station_id}/tickets`, `…/working`, `…/complete`, `…/actions` a `…/undo` |\n\n**Přecházejte celou provozovnou najednou.** Když v jedné provozovně pracují vedle sebe pokladny na API v1 a na\ntomto API, ty na v1 překážejí: pokladna v1 při synchronizaci svých stolů odstraní kopie účtů stolů otevřených přes\ntoto API v administraci, starší pokladna v1 (která neposílá ID svých objednávek) zahrne účtenky vystavené přes toto\nAPI do své uzávěrky a úklid záloh v1 může smazat nejstarší zálohy kteréhokoli zařízení provozovny. Přepněte všechny\npokladny provozovny naráz, nejlépe hned po uzávěrce.\n\n## Jazyky\n\nNázvy chyb a tato dokumentace jsou česky i anglicky. Názvy polí, hodnoty výčtů, typy událostí a kódy chyb jsou jen\nanglicky a nikdy se nepřekládají. Texty zadané restaurací (názvy a popisy produktů) vracíme tak, jak byly zadány.\n\n## Podpora\n\nRegistrace klienta, testovací provozovny a pomoc s napojením: info@profirest.cz, +420 777 983 213.\nKdyž se něco pokazí, uveďte `X-Request-Id`.\n",
  "contact": {
   "name": "Profirest",
   "url": "https://www.mujprofirest.cz/kontakt",
   "email": "info@profirest.cz"
  }
 },
 "servers": [
  {
   "url": "https://api.mujprofirest.cz/v2",
   "description": "Production. Test restaurants live here too.",
   "x-description-cs": "Ostrý provoz. Testovací provozovny jsou tady také."
  }
 ],
 "security": [
  {
   "oauth2": []
  }
 ],
 "tags": [
  {
   "name": "API",
   "description": "API root and the current connection.",
   "x-description-cs": "Kořen API a aktuální připojení."
  },
  {
   "name": "OAuth",
   "description": "Connecting a client to an account (\"Connect with Profirest\").",
   "x-description-cs": "Připojení klienta k účtu („Připojit přes Profirest“)."
  },
  {
   "name": "Restaurants",
   "description": "Restaurants of the connection, their opening hours, order hours, delivery zones and orderable times. Opening\nhours say when the restaurant is open (show them to guests); order hours say when orders from `web` applications\n(e-shops) are accepted – delivery and pickup alike. By default both are the same.\n",
   "x-description-cs": "Provozovny připojení, jejich otevírací doba, příjem objednávek, rozvozové zóny a časy, na které lze objednat.\nOtevírací doba říká, kdy má provozovna otevřeno (ukazujte ji hostům); příjem objednávek, kdy se přijímají\nobjednávky aplikací `web` (e-shopů) – rozvoz i osobní odběr. Výchozí je obojí stejné.\n"
  },
  {
   "name": "Catalog",
   "description": "Categories, products, prices and availability of one restaurant.",
   "x-description-cs": "Kategorie, produkty, ceny a dostupnost jedné provozovny."
  },
  {
   "name": "Orders",
   "description": "Quotes and orders that go to the kitchen display.",
   "x-description-cs": "Kalkulace a objednávky, které jdou do kuchyňského displeje."
  },
  {
   "name": "Customers",
   "description": "Linking your customers to the account's customer database and loyalty points.",
   "x-description-cs": "Propojení vašich zákazníků s databází klientů účtu a věrnostní body."
  },
  {
   "name": "Vouchers",
   "description": "Gift vouchers issued by the account.",
   "x-description-cs": "Dárkové vouchery vydané účtem."
  },
  {
   "name": "Reservations",
   "description": "Reservations of tables and of services with employees – free times, booking, changes, seating and the state of tables now.",
   "x-description-cs": "Rezervace stolů a služeb u pracovníků – volné časy, rezervace, změny, usazení a stav stolů v tuto chvíli."
  },
  {
   "name": "Lodging",
   "description": "Accommodation – guests staying now and the account of their room, so a register can charge a bill to the room.",
   "x-description-cs": "Ubytování – kdo je právě ubytovaný a účet jeho pokoje, aby pokladna mohla útratu zapsat na pokoj."
  },
  {
   "name": "Reception",
   "description": "The reception of a hotel – Profirest's own application only (`lodging_desk:*`, an employee with the role\n`reception` signed in on the device): rooms, the occupancy plan, stays with guests and their documents.\n",
   "x-description-cs": "Recepce hotelu – jen vlastní aplikace Profirestu (`lodging_desk:*`, na zařízení přihlášený zaměstnanec s rolí\n`reception`): pokoje, plán obsazenosti, pobyty s hosty a jejich doklady.\n"
  },
  {
   "name": "Housekeeping",
   "description": "Cleaning of rooms and their faults – the tasks of the day by room, ticking them off and reporting faults. No guest\ndata. With `Profirest-Staff-Token` the employee is recorded as who did the task or reported the fault. Profirest's\nown applications for maids and the reception must send it, with an employee with the role `housekeeping` or\n`reception` (since 26.11.23).\n",
   "x-description-cs": "Úklid pokojů a jejich závady – úkoly dne po pokojích, odškrtávání a hlášení závad. Bez údajů hostů.\nS `Profirest-Staff-Token` se zaměstnanec zapíše jako ten, kdo úkol udělal nebo závadu nahlásil. Vlastní aplikace\nProfirestu pro pokojské a recepci ho posílat musí, se zaměstnancem s rolí `housekeeping` nebo `reception` (od 26.11.23).\n"
  },
  {
   "name": "Guest passes",
   "description": "The QR code of a staying guest – a reader at the wellness, breakfast or car park checks what the guest may use.",
   "x-description-cs": "QR kód ubytovaného hosta – čtečka u wellness, snídaní nebo parkoviště ověří, co host smí."
  },
  {
   "name": "External references",
   "description": "Your own IDs and metadata on restaurants, categories, products, orders and customers.",
   "x-description-cs": "Vaše vlastní ID a metadata u provozoven, kategorií, produktů, objednávek a zákazníků."
  },
  {
   "name": "Events",
   "description": "Change feed with a cursor – page by page or live over Server-Sent Events. Webhooks deliver the same events.",
   "x-description-cs": "Proud změn s kurzorem – po stránkách nebo živě přes Server-Sent Events. Webhooky doručují stejné události."
  },
  {
   "name": "Staff",
   "description": "Employees on Profirest's own devices – who works in the restaurant and signing in with a PIN or card.",
   "x-description-cs": "Zaměstnanci na vlastních zařízeních Profirestu – kdo v provozovně pracuje a přihlášení PINem nebo čipem."
  },
  {
   "name": "Attendance",
   "description": "Arrivals, departures and breaks punched at Profirest's attendance terminals, and what the signed-in employee sees\nthere: their planned shifts and their requests for time off. Only for a restaurant whose licence includes the\nAttendance module, like the attendance in the administration; otherwise `403 module_not_licensed`.\n",
   "x-description-cs": "Příchody, odchody a přestávky z docházkových terminálů Profirestu a to, co tam vidí přihlášený zaměstnanec: své\nnaplánované směny a své žádosti o volno. Jen u provozovny, jejíž licence zahrnuje modul Docházka, stejně jako\ndocházka v administraci; jinak `403 module_not_licensed`.\n"
  },
  {
   "name": "Kitchen",
   "description": "The kitchen display – orders from every source (register, e-shop, delivery platforms, applications).",
   "x-description-cs": "Kuchyňský displej – objednávky ze všech zdrojů (pokladna, e-shop, rozvozové platformy, aplikace)."
  },
  {
   "name": "Deliveries",
   "description": "Couriers on shift, delivery routes planned in the kitchen, marking orders delivered, and the live location and driving of couriers.",
   "x-description-cs": "Kurýři na směně, rozvozové trasy plánované v kuchyni, označení doručených objednávek a živá poloha a jízda kurýrů."
  },
  {
   "name": "Receipts",
   "description": "The cash register and the waiter app: receipts priced by the server, cancellation by a manager, the shift of\nthe device and EET 2.0 sent by the server. Only for Profirest's own devices.\n",
   "x-description-cs": "Pokladna a mobilní číšník: účtenky spočítané serverem, storno vedoucím, směna zařízení a EET 2.0, které\nodesílá server. Jen pro vlastní zařízení Profirestu.\n"
  },
  {
   "name": "Stock",
   "description": "Stock taking on Profirest's own devices – the items to count and the result that sets the stock, as in the\nadministration (Warehouse → Stock taking). Only for Profirest's own devices.\n",
   "x-description-cs": "Inventura na vlastních zařízeních Profirestu – položky k přepočítání a výsledek, který nastaví stav skladu, jako\nv administraci (Sklad → Inventury). Jen pro vlastní zařízení Profirestu.\n"
  },
  {
   "name": "Backups",
   "description": "Backups of a register's local database – a ZIP the register uploads (periodically, on request, after the shift\nclosure) and downloads to restore, for example on a new device. Shared with the registers on API v1. Only for\nProfirest's own devices.\n",
   "x-description-cs": "Zálohy místní databáze pokladny – ZIP, který pokladna nahrává (pravidelně, na požádání, po uzávěrce) a stáhne\npři obnově, třeba na novém zařízení. Společné s pokladnami na API v1. Jen pro vlastní zařízení Profirestu.\n"
  },
  {
   "name": "Diagnostics",
   "description": "State, errors and logs of Profirest's own devices for the restaurant and Profirest support. The device checks in\nevery minute (`checkInDevice`), reports errors as they happen (`reportDeviceError`) and keeps its log on itself;\nthe whole log is uploaded only when asked (`upload_logs` command, `putLogUploadPart`). Bug reports from users\n(`createBugReport`) go to support by e-mail.\n",
   "x-description-cs": "Stav, chyby a logy vlastních zařízení Profirestu pro provozovnu a podporu Profirestu. Zařízení každou minutu\npřihlásí stav (`checkInDevice`), chyby hlásí hned (`reportDeviceError`) a log si drží u sebe; celý log nahraje\njen na vyžádání (příkaz `upload_logs`, `putLogUploadPart`). Hlášení chyb od uživatelů (`createBugReport`) jdou\npodpoře e-mailem.\n"
  },
  {
   "name": "Device settings",
   "description": "What Profirest's own devices need to work – company details, receipt layouts, printers, tables, licence.",
   "x-description-cs": "Co vlastní zařízení Profirestu potřebují k práci – údaje firmy, tiskové šablony, tiskárny, stoly, licence."
  },
  {
   "name": "Customer directory",
   "description": "Customers of the whole account for orders taken by the staff on the phone – search by phone or name with their\naddresses, and incoming calls. Only for Profirest's own devices.\n",
   "x-description-cs": "Zákazníci celého účtu pro objednávky, které personál bere po telefonu – hledání podle telefonu nebo jména s jejich\nadresami a příchozí hovory. Jen pro vlastní zařízení Profirestu.\n"
  },
  {
   "name": "Table ordering",
   "description": "Guests order from their table and call the staff from their phone. The main register of the restaurant decides\nabout everything and serves guests on the restaurant's Wi-Fi itself (its local API); these operations are the\nbackup path through the internet for phones that cannot reach it (`/table/…`, with the token of the phone at the\ntable) and the link of the main register to the cloud (the inbox of requests, the mirror of states, the\nheartbeat). Only for Profirest's own applications.\n",
   "x-description-cs": "Hosté objednávají od stolu a volají obsluhu ze svého telefonu. O všem rozhoduje hlavní kasa podniku a hosty na\nWi-Fi podniku obsluhuje sama (její místní API); tyto operace jsou záložní cesta přes internet pro telefony, které\nse k ní nedostanou (`/table/…`, s tokenem telefonu u stolu), a spojení hlavní kasy s cloudem (schránka žádostí,\nzrcadlo stavů, heartbeat). Jen pro vlastní aplikace Profirestu.\n"
  }
 ],
 "paths": {
  "/": {
   "get": {
    "tags": [
     "API"
    ],
    "operationId": "getApiRoot",
    "summary": "API root",
    "x-summary-cs": "Kořen API",
    "description": "Version of the API and links to related resources. Needs no token.",
    "x-description-cs": "Verze API a odkazy na související zdroje. Nepotřebuje token.",
    "security": [],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "API information.",
      "x-description-cs": "Informace o API.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ApiRoot"
        },
        "examples": {
         "default": {
          "value": {
           "name": "Profirest API",
           "version": "26.11.28",
           "docs_url": "https://api.mujprofirest.cz/v2/docs",
           "oauth_metadata_url": "https://api.mujprofirest.cz/.well-known/oauth-authorization-server",
           "stream_url": "https://api.mujprofirest.cz/v2/events/stream",
           "server_time": "2027-01-15T11:42:10+01:00"
          }
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/app-versions": {
   "get": {
    "tags": [
     "API"
    ],
    "operationId": "listAppVersions",
    "summary": "Latest versions of Profirest's apps",
    "x-summary-cs": "Nejnovější verze aplikací Profirestu",
    "description": "The newest released version of each of Profirest's own apps, stable and beta separately, with the download link\nand what changed – so an app can offer an update, even before it is paired. `critical` means the older version\nshould not be used any more. Needs no token; may be cached for 5 minutes.\n",
    "x-description-cs": "Nejnovější vydaná verze každé vlastní aplikace Profirestu, ostrá a beta zvlášť, s odkazem ke stažení a seznamem\nzměn – aby aplikace mohla nabídnout aktualizaci, i když ještě není spárovaná. `critical` znamená, že starší\nverzi už nemá používat. Nepotřebuje token; smí se 5 minut držet v mezipaměti.\n",
    "security": [],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The versions.",
      "x-description-cs": "Verze.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AppVersionList"
        },
        "examples": {
         "list": {
          "summary": "Latest app versions",
          "value": {
           "data": [
            {
             "app": "bar",
             "channel": "stable",
             "version": "3.4.1",
             "critical": false,
             "released_at": "2027-01-11T08:00:00+01:00",
             "download_url": "https://www.mujprofirest.cz/download/pokladna-3.4.1.apk",
             "changelog": "Rychlejší tisk účtenek, oprava dělené platby.",
             "sha256": "9f2c4b7e1a3d5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8",
             "size": 48213504
            },
            {
             "app": "kitchen",
             "channel": "stable",
             "version": "2.8.0",
             "critical": false,
             "released_at": "2027-01-05T08:00:00+01:00",
             "download_url": null,
             "changelog": "Chody a odbavení po stanovištích.",
             "sha256": null,
             "size": null
            },
            {
             "app": "kitchen_windows",
             "channel": "stable",
             "version": "27.1.2",
             "critical": false,
             "released_at": "2027-01-08T08:00:00+01:00",
             "download_url": "https://www.mujprofirest.cz/uploads/software/kds/windows/KDS-v27.1.2.exe",
             "changelog": "Účtenka rozvozu ze serveru.",
             "sha256": "4b1e8c0d2f7a9e3b5c6d1a2f8e7d4c3b2a1908f7e6d5c4b3a29180f7e6d5c4b3",
             "size": 31457280
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Poslední verze aplikací"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/connection": {
   "get": {
    "tags": [
     "API"
    ],
    "operationId": "getConnection",
    "summary": "Current connection",
    "x-summary-cs": "Aktuální připojení",
    "description": "Which account, restaurants and scopes the access token belongs to, and the owner's settings for it.",
    "x-description-cs": "Ke kterému účtu, provozovnám a oprávněním access token patří a jaká nastavení k němu zvolil majitel.",
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The connection.",
      "x-description-cs": "Připojení.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Connection"
        },
        "examples": {
         "partner": {
          "summary": "A partner application (an e-shop)",
          "value": {
           "id": "2208",
           "client": {
            "id": "eshop-u-lipy",
            "name": "E-shop Bistra U Lípy",
            "order_channel": "web"
           },
           "account_id": "7",
           "scopes": [
            "restaurants:read",
            "catalog:read",
            "orders:write",
            "orders:read"
           ],
           "restaurant_ids": [
            "123"
           ],
           "settings": {
            "customer_messages": "integrator"
           },
           "created_at": "2026-11-20T14:03:00+01:00",
           "device": null
          },
          "x-summary-cs": "Aplikace partnera (e-shop)"
         },
         "device": {
          "summary": "A paired device (a register)",
          "value": {
           "id": "3301",
           "client": {
            "id": "profirest-pos",
            "name": "Profirest Pokladna",
            "order_channel": "staff"
           },
           "account_id": "7",
           "scopes": [
            "restaurants:read",
            "catalog:read",
            "staff:read",
            "staff:authenticate",
            "receipts:read",
            "receipts:write"
           ],
           "restaurant_ids": [
            "123"
           ],
           "settings": {
            "customer_messages": "profirest"
           },
           "created_at": "2026-12-01T09:15:00+01:00",
           "device": {
            "id": "512",
            "name": "Pokladna u baru",
            "restaurant_id": "123",
            "platform": "android",
            "app_version": "3.4.1",
            "paired_at": "2026-12-01T09:15:00+01:00",
            "api_target": {
             "target": "v2",
             "base_url": "https://api.mujprofirest.cz/v2"
            }
           }
          },
          "x-summary-cs": "Spárované zařízení (pokladna)"
         }
        }
       }
      }
     },
     "401": {
      "description": "`invalid_token`: the access token is missing, invalid, expired or revoked.",
      "x-description-cs": "`invalid_token`: access token chybí, je neplatný, vypršel nebo byl zneplatněn.",
      "headers": {
       "WWW-Authenticate": {
        "schema": {
         "type": "string",
         "examples": [
          "Bearer error=\"invalid_token\""
         ]
        }
       }
      },
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "invalid_token": {
          "summary": "The token expired or was revoked",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#invalid_token",
           "title": "Access token chybí, je neplatný nebo vypršel",
           "status": 401,
           "code": "invalid_token",
           "detail": "The access token expired.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Token vypršel nebo byl zrušen"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/devices/current/legacy-identity": {
   "post": {
    "tags": [
     "API"
    ],
    "operationId": "createLegacyIdentity",
    "summary": "Get the API v1 identity of the device",
    "x-summary-cs": "Vyzvednout identitu API v1 zařízení",
    "x-requires-device": true,
    "x-idempotency": "none",
    "description": "Only Profirest's own register, kitchen display and courier apps. A device paired straight to API v2 gets a\nbackup API v1 identity, so that it can go back to API v1 without pairing again when the restaurant is moved\nback (`Profirest-Api-Target: v1`, or API v2 does not answer). Call it once after pairing, or at start when you\nhave no API v1 identity stored. Calling it again returns the same identity (`200`). Keep it only on the\ndevice; it is not shown anywhere else.\n",
    "x-description-cs": "Jen vlastní aplikace Profirestu pro pokladnu, kuchyňský displej a kurýra. Zařízení spárované rovnou na API v2\ndostane záložní identitu API v1, aby se při vrácení provozovny (`Profirest-Api-Target: v1`, nebo když API v2\nneodpovídá) vrátilo na API v1 bez nového párování. Zavolejte jednou po spárování, nebo při startu, když identitu\nAPI v1 uloženou nemáte. Opakované volání vrátí tutéž identitu (`200`). Držte ji jen na zařízení; nikde jinde se\nneukazuje.\n",
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LegacyIdentityRequest"
       },
       "examples": {
        "pos": {
         "summary": "A register paired straight to API v2",
         "value": {
          "v1_device_id": "REYWMDE5MZEWMJY5RKEYQKZBOTY2QTG0MEZDQZBGRT"
         },
         "x-summary-cs": "Pokladna spárovaná rovnou na API v2"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The backup API v1 identity was created.",
      "x-description-cs": "Záložní identita API v1 vznikla.",
      "headers": {
       "Cache-Control": {
        "schema": {
         "type": "string",
         "enum": [
          "no-store"
         ]
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LegacyIdentity"
        },
        "examples": {
         "pos": {
          "summary": "The backup identity of a register",
          "value": {
           "kind": "pos",
           "login": "ulipy",
           "device_id": "REYWMDE5MZEWMJY5RKEYQKZBOTY2QTG0MEZDQZBGRT",
           "app_key": "7f3c9a1e5b2d4c6a8e0f1b3d5c7a9e2f4b6d8a0c1e3f5a7b9d2c4e6f8a0b1c3d",
           "token": null,
           "password": null
          },
          "x-summary-cs": "Záložní identita pokladny"
         }
        }
       }
      }
     },
     "200": {
      "description": "The device already has an API v1 identity – the same one.",
      "x-description-cs": "Zařízení už identitu API v1 má – tatáž.",
      "headers": {
       "Cache-Control": {
        "schema": {
         "type": "string",
         "enum": [
          "no-store"
         ]
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LegacyIdentity"
        },
        "examples": {
         "kds": {
          "summary": "A kitchen display asks again – the same identity",
          "value": {
           "kind": "kds",
           "login": "ulipy",
           "device_id": "KDS-7F3C9A1E5B2D",
           "app_key": null,
           "token": "c4e6f8a0b1c3d7f3c9a1e5b2d4c6a8e0f1b3d5c7a9e2f4b6d8a0c1e3f5a7b9d2",
           "password": null
          },
          "x-summary-cs": "Kuchyňský displej se ptá znovu – tatáž identita"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "description": "`insufficient_scope` or `customer_not_verified`; on Profirest's own devices also `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` and – on the\nregister – `manager_approval_required`.\n",
      "x-description-cs": "`insufficient_scope` nebo `customer_not_verified`; na vlastních zařízeních Profirestu také `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` a – na pokladně –\n`manager_approval_required`.\n",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "insufficient_scope": {
          "summary": "The token lacks the scope",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#insufficient_scope",
           "title": "Token nemá potřebné oprávnění",
           "status": 403,
           "code": "insufficient_scope",
           "detail": "Missing scope: orders:write",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Token nemá potřebné oprávnění"
         },
         "legacy_identity_unsupported": {
          "summary": "An application without an API v1 identity",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#legacy_identity_unsupported",
           "title": "Tato aplikace identitu API v1 nemá",
           "status": 403,
           "code": "legacy_identity_unsupported",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Aplikace bez identity API v1"
         }
        }
       }
      }
     },
     "404": {
      "description": "`not_found`: the object does not exist or your connection may not see it.",
      "x-description-cs": "`not_found`: objekt neexistuje nebo ho vaše připojení nesmí vidět.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "not_found": {
          "summary": "No such object, or the connection cannot see it",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#not_found",
           "title": "Nenalezeno",
           "status": 404,
           "code": "not_found",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Objekt není, nebo ho připojení nevidí"
         },
         "no_legacy_identity": {
          "summary": "A courier in a restaurant without a web kitchen",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#no_legacy_identity",
           "title": "Provozovna pro tuto aplikaci identitu API v1 nemá",
           "status": 404,
           "code": "no_legacy_identity",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Kurýr v provozovně bez webové kuchyně"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/oauth/authorize": {
   "servers": [
    {
     "url": "https://api.mujprofirest.cz"
    }
   ],
   "get": {
    "tags": [
     "OAuth"
    ],
    "operationId": "oauthAuthorize",
    "summary": "Start the connection (browser)",
    "x-summary-cs": "Zahájit připojení (v prohlížeči)",
    "description": "Redirect the restaurant owner's browser here. The owner signs in to Profirest (including two-factor\nverification), picks restaurants and confirms the scopes. Profirest then redirects back to `redirect_uri` with\n`code`, `state` and `iss` (RFC 9207), or with `error`, `state` and `iss`. Check that `iss` equals\n`https://api.mujprofirest.cz`.\n\nOnly the owner of the Profirest account can grant access. Employees see an explanation instead.\n`redirect_uri` must exactly match one of the addresses registered for your client. Running the flow again for an\naccount that is already connected updates the existing connection – it never creates a second one: the scopes\nasked for are added to those it has, and its restaurants become the ones the owner selects (the current ones are\npre-selected). A connection the owner disconnected comes back with only the scopes asked for now.\n",
    "x-description-cs": "Sem přesměrujte prohlížeč majitele restaurace. Majitel se přihlásí do Profirestu (včetně dvoufázového ověření),\nvybere provozovny a potvrdí oprávnění. Profirest pak přesměruje zpět na `redirect_uri` s parametry `code`,\n`state` a `iss` (RFC 9207), nebo s `error`, `state` a `iss`. Ověřte, že `iss` je\n`https://api.mujprofirest.cz`.\n\nPřístup smí povolit jen majitel účtu Profirest. Zaměstnanec místo toho uvidí vysvětlení. `redirect_uri` musí\npřesně odpovídat jedné z adres registrovaných u vašeho klienta. Nové spuštění pro už připojený účet upraví\nstávající připojení – druhé nikdy nevznikne: požadovaná oprávnění se přidají k těm, která má, a jeho provozovny\nbudou ty, které majitel vybere (stávající jsou předvybrané). Připojení, které majitel odpojil, se obnoví jen\ns oprávněními, o která žádáte teď.\n",
    "security": [],
    "parameters": [
     {
      "name": "response_type",
      "in": "query",
      "required": true,
      "description": "Always `code`; anything else comes back as `unsupported_response_type`.",
      "x-description-cs": "Vždy `code`; cokoli jiného se vrátí jako `unsupported_response_type`.",
      "schema": {
       "type": "string",
       "enum": [
        "code"
       ]
      },
      "example": "code"
     },
     {
      "name": "client_id",
      "in": "query",
      "required": true,
      "description": "Your `client_id`. An unknown or inactive one gets the error page (`400`), no redirect.",
      "x-description-cs": "Vaše `client_id`. Neznámé nebo neaktivní dostane chybovou stránku (`400`), bez přesměrování.",
      "schema": {
       "type": "string",
       "maxLength": 64
      },
      "example": "eshop-u-lipy"
     },
     {
      "name": "redirect_uri",
      "in": "query",
      "required": true,
      "description": "Exactly one of the redirect URIs registered for your client; any other gets the error page (`400`), no redirect.",
      "x-description-cs": "Přesně jedna z adres pro přesměrování registrovaných u vašeho klienta; jiná dostane chybovou stránku (`400`), bez přesměrování.",
      "schema": {
       "type": "string",
       "format": "uri",
       "maxLength": 2000
      },
      "example": "https://shop.example/callback"
     },
     {
      "name": "scope",
      "in": "query",
      "required": true,
      "description": "Space-separated scopes, see the `oauth2` security scheme. Only the scopes of partner applications can be\nasked for here – the ones not in `x-first-party-scopes`; others, and scopes your client may not ask for, come\nback as `invalid_scope`.\n",
      "x-description-cs": "Oprávnění oddělená mezerou, viz bezpečnostní schéma `oauth2`. Žádat tu jde jen o oprávnění partnerských\naplikací – ta, která nejsou v `x-first-party-scopes`; ostatní a oprávnění, o která váš klient žádat nesmí, se\nvrátí jako `invalid_scope`.\n",
      "schema": {
       "type": "string",
       "examples": [
        "restaurants:read catalog:read orders:write orders:read"
       ]
      },
      "example": "restaurants:read catalog:read orders:write orders:read"
     },
     {
      "name": "state",
      "in": "query",
      "required": true,
      "description": "Random value you generate; returned unchanged. Protects against CSRF. Printable ASCII only (RFC 6749 VSCHAR), otherwise `invalid_request`.",
      "x-description-cs": "Náhodná hodnota, kterou vygenerujete; vrátí se beze změny. Chrání proti CSRF. Jen tisknutelné ASCII (RFC 6749 VSCHAR), jinak `invalid_request`.",
      "schema": {
       "type": "string",
       "minLength": 16,
       "maxLength": 512,
       "pattern": "^[\\x20-\\x7E]+$"
      },
      "example": "af0ifjsldkj"
     },
     {
      "name": "code_challenge",
      "in": "query",
      "required": true,
      "description": "PKCE challenge, BASE64URL(SHA-256(code_verifier)).",
      "x-description-cs": "PKCE výzva, BASE64URL(SHA-256(code_verifier)).",
      "schema": {
       "type": "string",
       "minLength": 43,
       "maxLength": 128
      },
      "example": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
     },
     {
      "name": "code_challenge_method",
      "in": "query",
      "required": true,
      "description": "Always `S256`; anything else comes back as `invalid_request`.",
      "x-description-cs": "Vždy `S256`; cokoli jiného se vrátí jako `invalid_request`.",
      "schema": {
       "type": "string",
       "enum": [
        "S256"
       ]
      },
      "example": "S256"
     },
     {
      "name": "prompt",
      "in": "query",
      "required": false,
      "description": "Only `consent` is accepted (another value comes back as `invalid_request`), and it changes nothing: the\nconsent screen is always shown, also when access was already granted – for example to add restaurants.\n",
      "x-description-cs": "Přijme se jen `consent` (jiná hodnota se vrátí jako `invalid_request`) a nic nemění: souhlasová stránka se\nukáže vždy, i když už přístup existuje – například kvůli přidání provozoven.\n",
      "schema": {
       "type": "string",
       "enum": [
        "consent"
       ]
      }
     }
    ],
    "responses": {
     "302": {
      "description": "Redirect to the Profirest sign-in and consent screen, then back to `redirect_uri` with `code` + `state` +\n`iss`, or with `error` + `state` + `iss`: `access_denied` (the owner declined), `invalid_scope` (an unknown\nscope or one your client may not ask for), `invalid_request` (`state` of 16–512 printable characters, PKCE\nS256, `prompt` other than `consent`) or `unsupported_response_type` (other than `code`).\n",
      "x-description-cs": "Přesměrování na přihlášení a souhlas v Profirestu, potom zpět na `redirect_uri` s `code` + `state` + `iss`,\nnebo s `error` + `state` + `iss`: `access_denied` (majitel odmítl), `invalid_scope` (neznámé oprávnění nebo\ntakové, o které váš klient žádat nesmí), `invalid_request` (`state` 16–512 tisknutelných znaků, PKCE S256,\n`prompt` jiný než `consent`) nebo `unsupported_response_type` (jiný než `code`).\n"
     },
     "400": {
      "description": "Unknown `client_id` or a `redirect_uri` that is not registered. Profirest does not redirect anywhere and shows an error page.",
      "x-description-cs": "Neznámé `client_id` nebo neregistrované `redirect_uri`. Profirest nikam nepřesměruje a ukáže chybovou stránku."
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/oauth/device_authorization": {
   "servers": [
    {
     "url": "https://api.mujprofirest.cz"
    }
   ],
   "post": {
    "tags": [
     "OAuth"
    ],
    "operationId": "oauthDeviceAuthorization",
    "summary": "Start pairing a device",
    "x-summary-cs": "Zahájit párování zařízení",
    "description": "Device Authorization Grant (RFC 8628) for devices without a comfortable browser: a point of sale, a kitchen\ndisplay, an attendance terminal or a courier phone. Only applications that Profirest allowed to pair devices\ncan use it (our own apps).\n\n1. The device calls this endpoint and shows `user_code` (and a QR code with `verification_uri_complete`).\n2. A manager opens `verification_uri` in Profirest, enters the code, picks the restaurant and confirms.\n3. Meanwhile the device polls `POST /oauth/token` with `grant_type=urn:ietf:params:oauth:grant-type:device_code`\n   every `interval` seconds and gets its tokens after the confirmation.\n\nThe device then works for one restaurant only, with the permissions its application has. Unpairing in\nProfirest stops it immediately. A code confirmed just before it expired can still be exchanged for 10 minutes\nafter the expiry; a confirmed device that never picks up its tokens is unpaired by the server later. At most\n30 codes a minute from one IP address (`429`).\n",
    "x-description-cs": "Párování zařízení bez pohodlného prohlížeče podle RFC 8628: pokladna, kuchyňský displej, píchačka nebo telefon\nkurýra. Jen aplikace, kterým to Profirest povolil (naše vlastní aplikace).\n\n1. Zařízení zavolá tento endpoint a ukáže `user_code` (a QR kód s `verification_uri_complete`).\n2. Vedoucí otevře v Profirestu `verification_uri`, zadá kód, vybere provozovnu a potvrdí.\n3. Zařízení mezitím každých `interval` sekund volá `POST /oauth/token` s\n   `grant_type=urn:ietf:params:oauth:grant-type:device_code` a po potvrzení dostane tokeny.\n\nZařízení pak pracuje jen pro jednu provozovnu a s oprávněními své aplikace. Odpárování v Profirestu ho\nzastaví okamžitě. Kód potvrzený těsně před vypršením jde vyměnit ještě 10 minut po vypršení; potvrzené zařízení,\nkteré si tokeny nikdy nevyzvedne, server později odpáruje. Z jedné IP adresy nejvýš 30 kódů za minutu (`429`).\n",
    "security": [
     {
      "clientBasic": []
     },
     {}
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "$ref": "#/components/schemas/DeviceAuthorizationRequest"
       },
       "examples": {
        "pos": {
         "summary": "A register asks for a code",
         "value": {
          "client_id": "profirest-pos",
          "scope": "restaurants:read catalog:read staff:read staff:authenticate receipts:read receipts:write",
          "device_name": "Pokladna u baru",
          "device_platform": "android",
          "app_version": "3.4.1"
         },
         "x-summary-cs": "Pokladna žádá o kód"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Codes for the device.",
      "x-description-cs": "Kódy pro zařízení.",
      "headers": {
       "Cache-Control": {
        "schema": {
         "type": "string",
         "enum": [
          "no-store"
         ]
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeviceAuthorizationResponse"
        },
        "examples": {
         "code": {
          "summary": "A code to confirm in the administration",
          "value": {
           "device_code": "pfd_CkWGM50A5JhqtDG1-YhmK69pAlM0TblR7bOxnjTGxAQ",
           "user_code": "BCDF-GHJK",
           "verification_uri": "https://www.mujprofirest.cz/zarizeni",
           "verification_uri_complete": "https://www.mujprofirest.cz/zarizeni?code=BCDFGHJK",
           "expires_in": 600,
           "interval": 5
          },
          "x-summary-cs": "Kód k potvrzení v administraci"
         }
        }
       }
      }
     },
     "400": {
      "description": "OAuth error (`invalid_request`, `invalid_scope`, `unauthorized_client`).",
      "x-description-cs": "Chyba OAuth (`invalid_request`, `invalid_scope`, `unauthorized_client`).",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OAuthError"
        },
        "examples": {
         "invalid_scope": {
          "summary": "A scope the application may not ask for",
          "value": {
           "error": "invalid_scope",
           "error_description": "The application may not ask for: customers:write",
           "api_target": null
          },
          "x-summary-cs": "Oprávnění, které aplikace nemá"
         },
         "invalid_request": {
          "summary": "An emoji in the device name",
          "value": {
           "error": "invalid_request",
           "error_description": "device_name must be valid UTF-8 without characters outside the Basic Multilingual Plane (emoji).",
           "api_target": null
          },
          "x-summary-cs": "Emoji v názvu zařízení"
         }
        }
       }
      }
     },
     "401": {
      "description": "Client authentication failed (`invalid_client`).",
      "x-description-cs": "Ověření klienta selhalo (`invalid_client`).",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OAuthError"
        },
        "examples": {
         "invalid_client": {
          "summary": "An unknown application",
          "value": {
           "error": "invalid_client",
           "error_description": "Client authentication failed.",
           "api_target": null
          },
          "x-summary-cs": "Neznámá aplikace"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/oauth/token": {
   "servers": [
    {
     "url": "https://api.mujprofirest.cz"
    }
   ],
   "post": {
    "tags": [
     "OAuth"
    ],
    "operationId": "oauthToken",
    "summary": "Get or refresh tokens",
    "x-summary-cs": "Získat nebo obnovit tokeny",
    "description": "Exchange an authorization code for tokens, or a refresh token for new tokens. A confidential client\nauthenticates with HTTP Basic (`client_secret_basic`) or with `client_id` and `client_secret` in the body\n(`client_secret_post`). A public client sends only `client_id` and relies on PKCE. Unknown parameters are\nignored (RFC 6749).\n\nA paired device polls with `grant_type=urn:ietf:params:oauth:grant-type:device_code` (RFC 8628): until the\nmanager confirms it gets `authorization_pending`; polling faster than `interval` gives `slow_down` (wait 5 more\nseconds from then on); `access_denied` when the manager refused and `expired_token` after 10 minutes. Device\ntokens are bound to the device: refreshing keeps them on it and unpairing revokes them.\n\nProfirest's own register, kitchen display and courier apps move between API v1 and API v2 without pairing\nagain, as the restaurant is switched (header `Profirest-Api-Target`, see `ApiTarget`). A device signed in to\nAPI v1 exchanges its API v1 identity for device tokens with `grant_type=urn:profirest:params:oauth:grant-type:v1-device`\n– only when the restaurant is on API v2 (otherwise `access_denied`), at most 5 exchanges an hour per device\n(`slow_down`). The device is the same one every time it comes back. Until its first request with the new tokens\nthe API v1 identity still works; then it sleeps. A refresh of a device that was moved back to API v1 answers\n`invalid_grant` with `api_target: v1` – sign in to API v1, the device is not unpaired.\n",
    "x-description-cs": "Výměna autorizačního kódu za tokeny, nebo refresh tokenu za nové tokeny. Důvěrný klient se ověří přes HTTP Basic\n(`client_secret_basic`) nebo parametry `client_id` a `client_secret` v těle (`client_secret_post`). Veřejný\nklient pošle jen `client_id` a spoléhá na PKCE. Neznámé parametry se ignorují (RFC 6749).\n\nPárované zařízení se ptá s `grant_type=urn:ietf:params:oauth:grant-type:device_code` (RFC 8628): dokud vedoucí\nnepotvrdí, dostává `authorization_pending`; při častějším dotazu než `interval` `slow_down` (od té doby čekejte\no 5 sekund déle); `access_denied`, když vedoucí odmítl, a `expired_token` po 10 minutách. Tokeny zařízení\npatří zařízení: obnova je na něm drží a odpárování je zneplatní.\n\nVlastní aplikace Profirestu pro pokladnu, kuchyňský displej a kurýra přecházejí mezi API v1 a API v2 bez\nnového párování podle toho, kam je provozovna přepnutá (hlavička `Profirest-Api-Target`, viz `ApiTarget`).\nZařízení přihlášené v API v1 vymění identitu API v1 za tokeny zařízení přes\n`grant_type=urn:profirest:params:oauth:grant-type:v1-device` – jen když je provozovna na API v2 (jinak\n`access_denied`), nejvýš 5 výměn za hodinu na zařízení (`slow_down`). Zařízení je pokaždé stejné. Do prvního\npožadavku s novými tokeny platí i identita API v1, pak usne. Obnova tokenu zařízení vráceného na API v1 vrátí\n`invalid_grant` s `api_target: v1` – přihlaste se v API v1, zařízení odpárované není.\n",
    "security": [
     {
      "clientBasic": []
     },
     {}
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "oneOf": [
         {
          "$ref": "#/components/schemas/TokenRequestAuthorizationCode"
         },
         {
          "$ref": "#/components/schemas/TokenRequestRefreshToken"
         },
         {
          "$ref": "#/components/schemas/TokenRequestDeviceCode"
         },
         {
          "$ref": "#/components/schemas/TokenRequestV1Device"
         }
        ],
        "discriminator": {
         "propertyName": "grant_type",
         "mapping": {
          "authorization_code": "#/components/schemas/TokenRequestAuthorizationCode",
          "refresh_token": "#/components/schemas/TokenRequestRefreshToken",
          "urn:ietf:params:oauth:grant-type:device_code": "#/components/schemas/TokenRequestDeviceCode",
          "urn:profirest:params:oauth:grant-type:v1-device": "#/components/schemas/TokenRequestV1Device"
         }
        }
       },
       "examples": {
        "authorization_code": {
         "summary": "Exchanging the code for tokens (PKCE)",
         "value": {
          "grant_type": "authorization_code",
          "code": "pfc_VpTQii5T_8rgwxA-Wtb2B2q9lg6x-KVldwQLwQKPcCs",
          "redirect_uri": "https://shop.example/callback",
          "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk",
          "client_id": "eshop-u-lipy"
         },
         "x-summary-cs": "Výměna kódu za tokeny (PKCE)"
        },
        "refresh_token": {
         "summary": "Refreshing the tokens",
         "value": {
          "grant_type": "refresh_token",
          "refresh_token": "pfr_1swKCIwHaDxlzSZoYMq42Us6GTexdCDZ2jDKKZwJ-3c",
          "client_id": "eshop-u-lipy"
         },
         "x-summary-cs": "Obnova tokenů"
        },
        "device_code": {
         "summary": "A device asks whether it is confirmed yet",
         "value": {
          "grant_type": "urn:ietf:params:oauth:grant-type:device_code",
          "device_code": "pfd_CkWGM50A5JhqtDG1-YhmK69pAlM0TblR7bOxnjTGxAQ",
          "client_id": "profirest-pos"
         },
         "x-summary-cs": "Zařízení se ptá, jestli už je potvrzené"
        },
        "v1_device": {
         "summary": "A register moves from API v1 without pairing again",
         "value": {
          "grant_type": "urn:profirest:params:oauth:grant-type:v1-device",
          "client_id": "profirest-pos",
          "v1_app_key": "Qm9rT2pWb0x6d2Fq3s1b9d0f4e5a6c7b8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4",
          "v1_login": "ulipy",
          "v1_device_id": "REYWMDE5MZEWMJY5RKEYQKZBOTY2QTG0MEZDQZBGRT",
          "device_platform": "android",
          "app_version": "29.9.296"
         },
         "x-summary-cs": "Pokladna přechází z API v1 bez nového párování"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Tokens.",
      "x-description-cs": "Tokeny.",
      "headers": {
       "Cache-Control": {
        "schema": {
         "type": "string",
         "enum": [
          "no-store"
         ]
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TokenResponse"
        },
        "examples": {
         "tokens": {
          "summary": "New tokens",
          "value": {
           "access_token": "pfa_oFYf1knNtrqnhAVfBRuteW6gr-8X_KOCGVSd7rpOjBo",
           "token_type": "Bearer",
           "expires_in": 1800,
           "refresh_token": "pfr_1swKCIwHaDxlzSZoYMq42Us6GTexdCDZ2jDKKZwJ-3c",
           "refresh_token_expires_in": 7776000,
           "scope": "restaurants:read catalog:read orders:write orders:read"
          },
          "x-summary-cs": "Nové tokeny"
         }
        }
       }
      }
     },
     "400": {
      "description": "OAuth error (RFC 6749 section 5.2).",
      "x-description-cs": "Chyba OAuth (RFC 6749, oddíl 5.2).",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OAuthError"
        },
        "examples": {
         "authorization_pending": {
          "summary": "A device: the manager has not confirmed the code yet – keep asking after the interval",
          "value": {
           "error": "authorization_pending",
           "error_description": "Waiting for the manager to confirm the code.",
           "api_target": null
          },
          "x-summary-cs": "Zařízení: vedoucí kód ještě nepotvrdil – ptejte se dál po intervalu"
         },
         "slow_down": {
          "summary": "A device asks too often – the interval grows by 5 s",
          "value": {
           "error": "slow_down",
           "error_description": "Polling too fast; wait 10 seconds between requests.",
           "api_target": null
          },
          "x-summary-cs": "Zařízení: ptá se moc často – interval se prodlouží o 5 s"
         },
         "access_denied": {
          "summary": "A device: the manager declined the pairing",
          "value": {
           "error": "access_denied",
           "error_description": "The pairing was refused.",
           "api_target": null
          },
          "x-summary-cs": "Zařízení: vedoucí párování odmítl"
         },
         "expired_token": {
          "summary": "A device: the code expired (10 minutes) – start again",
          "value": {
           "error": "expired_token",
           "error_description": "The device code has expired. Start the pairing again.",
           "api_target": null
          },
          "x-summary-cs": "Zařízení: kód vypršel (10 minut) – začněte znovu"
         },
         "invalid_grant": {
          "summary": "The refresh token is not valid (unpaired, expired, used twice)",
          "value": {
           "error": "invalid_grant",
           "error_description": "The refresh token is not valid.",
           "api_target": null
          },
          "x-summary-cs": "Refresh token neplatí (odpárováno, vypršel, použitý podruhé)"
         },
         "moved_to_v1": {
          "summary": "The device was moved back to API v1 – sign in there, it is not unpaired",
          "value": {
           "error": "invalid_grant",
           "error_description": "The device was moved back to API v1.",
           "api_target": "v1"
          },
          "x-summary-cs": "Zařízení se vrátilo na API v1 – přihlásit se tam, není odpárované"
         },
         "not_on_v2": {
          "summary": "Exchange from API v1: the restaurant has not moved to API v2 yet",
          "value": {
           "error": "access_denied",
           "error_description": "The restaurant has not moved to API v2 yet.",
           "api_target": null
          },
          "x-summary-cs": "Výměna z API v1: provozovna na API v2 ještě nepřešla"
         }
        }
       }
      }
     },
     "401": {
      "description": "Client authentication failed (`invalid_client`).",
      "x-description-cs": "Ověření klienta selhalo (`invalid_client`).",
      "headers": {
       "WWW-Authenticate": {
        "schema": {
         "type": "string",
         "examples": [
          "Basic realm=\"Profirest API\""
         ]
        }
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OAuthError"
        },
        "examples": {
         "invalid_client": {
          "summary": "A wrong secret of a confidential client",
          "value": {
           "error": "invalid_client",
           "error_description": "Client authentication failed.",
           "api_target": null
          },
          "x-summary-cs": "Špatné tajemství důvěrného klienta"
         }
        }
       }
      }
     }
    }
   }
  },
  "/oauth/revoke": {
   "servers": [
    {
     "url": "https://api.mujprofirest.cz"
    }
   ],
   "post": {
    "tags": [
     "OAuth"
    ],
    "operationId": "oauthRevoke",
    "summary": "Revoke a token",
    "x-summary-cs": "Zneplatnit token",
    "description": "Revoke an access or refresh token (RFC 7009). Revoking a refresh token ends its token family – all access and\nrefresh tokens that come from the same authorization, or from the same pairing of a device; other token families\nof the connection keep working. When the family belongs to a paired device, the device is unpaired as well and\nthe staff sessions on it end, as when a manager unpairs it in the administration – the device must be paired\nagain. Revoking an access token ends only that token. `token_type_hint` is not needed (it is ignored).\n\nAnswers 200 also for an unknown token or a token of another client; a request without `token` answers\n`400 invalid_request`. To disconnect completely, the owner uses \"Connected apps\" in Profirest.\n",
    "x-description-cs": "Zneplatní access nebo refresh token (RFC 7009). Zneplatnění refresh tokenu ukončí jeho řadu tokenů – všechny\naccess a refresh tokeny, které pocházejí ze stejného povolení nebo ze stejného spárování zařízení; ostatní řady\ntokenů připojení fungují dál. Patří-li řada spárovanému zařízení, zařízení se navíc odpáruje a přihlášení\nzaměstnanců na něm skončí, stejně jako když ho vedoucí odpáruje v administraci – zařízení se musí spárovat\nznovu. Zneplatnění access tokenu ukončí jen tento token. `token_type_hint` není potřeba (nečte se).\n\nOdpoví 200 i pro neznámý token nebo token jiného klienta; požadavek bez `token` odpoví `400 invalid_request`.\nÚplné odpojení udělá majitel v Profirestu v části „Připojené aplikace“.\n",
    "security": [
     {
      "clientBasic": []
     },
     {}
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "type": "object",
        "required": [
         "token"
        ],
        "properties": {
         "token": {
          "type": "string"
         },
         "token_type_hint": {
          "type": "string",
          "enum": [
           "access_token",
           "refresh_token"
          ]
         },
         "client_id": {
          "type": "string"
         },
         "client_secret": {
          "type": "string"
         }
        }
       },
       "examples": {
        "refresh_token": {
         "summary": "Unpairing a device / signing an application out",
         "value": {
          "token": "pfr_1swKCIwHaDxlzSZoYMq42Us6GTexdCDZ2jDKKZwJ-3c",
          "token_type_hint": "refresh_token",
          "client_id": "profirest-pos"
         },
         "x-summary-cs": "Odpárování zařízení / odhlášení aplikace"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Revoked (or unknown).",
      "x-description-cs": "Zneplatněno (nebo neznámý token)."
     },
     "400": {
      "description": "No `token`, or the body is not `application/x-www-form-urlencoded` (`invalid_request`).",
      "x-description-cs": "Chybí `token`, nebo tělo není `application/x-www-form-urlencoded` (`invalid_request`).",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OAuthError"
        }
       }
      }
     },
     "401": {
      "description": "Client authentication failed (`invalid_client`).",
      "x-description-cs": "Ověření klienta selhalo (`invalid_client`).",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OAuthError"
        },
        "examples": {
         "invalid_client": {
          "summary": "An unknown application or a wrong secret",
          "value": {
           "error": "invalid_client",
           "error_description": "Client authentication failed.",
           "api_target": null
          },
          "x-summary-cs": "Neznámá aplikace nebo špatné tajemství"
         }
        }
       }
      }
     }
    }
   }
  },
  "/.well-known/oauth-authorization-server": {
   "servers": [
    {
     "url": "https://api.mujprofirest.cz"
    }
   ],
   "get": {
    "tags": [
     "OAuth"
    ],
    "operationId": "oauthMetadata",
    "summary": "OAuth server metadata",
    "x-summary-cs": "Metadata OAuth serveru",
    "description": "RFC 8414 metadata for OAuth libraries that discover endpoints automatically.",
    "x-description-cs": "Metadata podle RFC 8414 pro OAuth knihovny, které si endpointy zjišťují samy.",
    "security": [],
    "responses": {
     "200": {
      "description": "Metadata.",
      "x-description-cs": "Metadata.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OAuthServerMetadata"
        },
        "examples": {
         "default": {
          "value": {
           "issuer": "https://api.mujprofirest.cz",
           "authorization_endpoint": "https://api.mujprofirest.cz/oauth/authorize",
           "token_endpoint": "https://api.mujprofirest.cz/oauth/token",
           "revocation_endpoint": "https://api.mujprofirest.cz/oauth/revoke",
           "scopes_supported": [
            "restaurants:read",
            "catalog:read",
            "orders:write",
            "orders:read",
            "customers:read",
            "customers:write",
            "loyalty:read",
            "vouchers:redeem"
           ],
           "response_types_supported": [
            "code"
           ],
           "grant_types_supported": [
            "authorization_code",
            "refresh_token",
            "urn:ietf:params:oauth:grant-type:device_code"
           ],
           "code_challenge_methods_supported": [
            "S256"
           ],
           "token_endpoint_auth_methods_supported": [
            "client_secret_basic",
            "client_secret_post",
            "none"
           ],
           "authorization_response_iss_parameter_supported": true,
           "device_authorization_endpoint": "https://api.mujprofirest.cz/oauth/device_authorization"
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/restaurants": {
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "listRestaurants",
    "summary": "Restaurants of the connection",
    "x-summary-cs": "Provozovny připojení",
    "description": "Restaurants the owner granted to your connection.",
    "x-description-cs": "Provozovny, ke kterým vám majitel povolil přístup.",
    "security": [
     {
      "oauth2": [
       "restaurants:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/ExternalIdFilter"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of restaurants.",
      "x-description-cs": "Stránka provozoven.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/RestaurantPage"
        },
        "examples": {
         "list": {
          "summary": "The restaurants of the connection",
          "value": {
           "data": [
            {
             "id": "123",
             "name": "Bistro U Lípy",
             "is_test": false,
             "address": {
              "street": "Vinohradská",
              "house_number": "1200/48",
              "city": "Praha 2",
              "postal_code": "120 00",
              "country": "CZ",
              "note": null,
              "formatted": "Vinohradská 1200/48, 120 00 Praha 2"
             },
             "location": {
              "lat": 50.0769,
              "lon": 14.4459
             },
             "phone": "+420222333444",
             "website": "https://www.bistroulipy.cz",
             "timezone": "Europe/Prague",
             "currency": "CZK",
             "ordering": {
              "accepting_orders": true,
              "open_now": true,
              "venue_open_now": true,
              "next_change_at": "2027-01-15T22:00:00+01:00",
              "delivery": {
               "enabled": true,
               "available_now": true
              },
              "pickup": {
               "enabled": true,
               "available_now": true
              },
              "scheduled_orders": {
               "enabled": true,
               "max_days_ahead": 7,
               "slot_minutes": 15,
               "lead_minutes": 90
              }
             },
             "portion_tracking": true,
             "external_id": "vinohrady",
             "metadata": {
              "branch": "praha-2"
             }
            },
            {
             "id": "124",
             "name": "Bistro U Lípy Karlín",
             "is_test": false,
             "address": {
              "street": "Sokolovská",
              "house_number": "316/101",
              "city": "Praha 8",
              "postal_code": "186 00",
              "country": "CZ",
              "note": null,
              "formatted": "Sokolovská 316/101, 186 00 Praha 8"
             },
             "location": {
              "lat": 50.0927,
              "lon": 14.4521
             },
             "phone": "+420222333555",
             "website": "https://www.bistroulipy.cz",
             "timezone": "Europe/Prague",
             "currency": "CZK",
             "ordering": {
              "accepting_orders": false,
              "open_now": false,
              "venue_open_now": false,
              "next_change_at": "2027-01-15T16:00:00+01:00",
              "delivery": {
               "enabled": true,
               "available_now": false
              },
              "pickup": {
               "enabled": true,
               "available_now": false
              },
              "scheduled_orders": {
               "enabled": true,
               "max_days_ahead": 7,
               "slot_minutes": 15,
               "lead_minutes": 90
              }
             },
             "portion_tracking": false,
             "external_id": "karlin",
             "metadata": {
              "branch": "praha-8"
             }
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Provozovny připojení"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getRestaurant",
    "summary": "Restaurant detail",
    "x-summary-cs": "Detail provozovny",
    "description": "Contact data, time zone, currency and what the restaurant accepts right now. `ordering` is computed at the moment\nof the request; reload it at `ordering.next_change_at` or on `restaurant.changed`.\n\n`restaurant.changed` comes when the administration saves the restaurant's details (name, phone, website), its\naddress, delivery zones, opening hours or order hours, or the rules for orders from applications. Other changes send no\nevent – for example the licence, the kitchen settings (`portion_tracking`) or anything changed through a\nregister on API v1 – so reload the restaurant from time to time as well.\n",
    "x-description-cs": "Kontaktní údaje, časová zóna, měna a co provozovna právě teď přijímá. `ordering` se počítá v okamžiku požadavku;\nnačtěte ho znovu v `ordering.next_change_at` nebo při `restaurant.changed`.\n\n`restaurant.changed` přijde, když administrace uloží údaje provozovny (název, telefon, web), její adresu,\nrozvozové zóny, otevírací dobu nebo příjem objednávek, nebo pravidla objednávek z aplikací. Jiné změny událost nevydají – třeba\nlicence, nastavení kuchyně (`portion_tracking`) nebo cokoli změněné přes pokladnu na API v1 – proto provozovnu\nobčas načtěte znovu i tak.\n",
    "security": [
     {
      "oauth2": [
       "restaurants:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The restaurant.",
      "x-description-cs": "Provozovna.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Restaurant"
        },
        "examples": {
         "restaurant": {
          "summary": "A restaurant",
          "value": {
           "id": "123",
           "name": "Bistro U Lípy",
           "is_test": false,
           "address": {
            "street": "Vinohradská",
            "house_number": "1200/48",
            "city": "Praha 2",
            "postal_code": "120 00",
            "country": "CZ",
            "note": null,
            "formatted": "Vinohradská 1200/48, 120 00 Praha 2"
           },
           "location": {
            "lat": 50.0769,
            "lon": 14.4459
           },
           "phone": "+420222333444",
           "website": "https://www.bistroulipy.cz",
           "timezone": "Europe/Prague",
           "currency": "CZK",
           "ordering": {
            "accepting_orders": true,
            "open_now": true,
            "venue_open_now": true,
            "next_change_at": "2027-01-15T22:00:00+01:00",
            "delivery": {
             "enabled": true,
             "available_now": true
            },
            "pickup": {
             "enabled": true,
             "available_now": true
            },
            "scheduled_orders": {
             "enabled": true,
             "max_days_ahead": 7,
             "slot_minutes": 15,
             "lead_minutes": 90
            }
           },
           "portion_tracking": true,
           "external_id": null,
           "metadata": {}
          },
          "x-summary-cs": "Provozovna"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/opening-hours": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getOpeningHours",
    "summary": "Opening hours",
    "x-summary-cs": "Otevírací doba",
    "description": "Effective opening hours per day for a date range, computed by Profirest, plus the weekly template for display.\nUse `days`, not your own calculation: future exceptions (holidays) will appear there without any change on\nyour side.\n",
    "x-description-cs": "Skutečná otevírací doba po dnech pro zadané období, spočítaná Profirestem, a k tomu týdenní šablona pro\nzobrazení. Používejte `days`, ne vlastní výpočet: budoucí výjimky (svátky) se tam objeví bez jakékoli změny na\nvaší straně.\n",
    "security": [
     {
      "oauth2": [
       "restaurants:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "from",
      "in": "query",
      "required": false,
      "description": "First day. Default today.",
      "x-description-cs": "První den. Výchozí je dnešek.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "to",
      "in": "query",
      "required": false,
      "description": "Last day, at most 31 days after `from`. Default `from` + 13 days.",
      "x-description-cs": "Poslední den, nejvýš 31 dní po `from`. Výchozí `from` + 13 dní.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-17"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Opening hours.",
      "x-description-cs": "Otevírací doba.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OpeningHours"
        },
        "examples": {
         "hours": {
          "summary": "Opening hours for the weekend",
          "value": {
           "restaurant_id": "123",
           "timezone": "Europe/Prague",
           "weekly": [
            {
             "day": 1,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 2,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 3,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 4,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 5,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 6,
             "intervals": [
              {
               "from": "12:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 7,
             "intervals": [
              {
               "from": "12:00",
               "to": "20:00"
              }
             ]
            }
           ],
           "days": [
            {
             "date": "2027-01-15",
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "date": "2027-01-16",
             "intervals": [
              {
               "from": "12:00",
               "to": "16:00"
              }
             ]
            },
            {
             "date": "2027-01-17",
             "intervals": [
              {
               "from": "12:00",
               "to": "20:00"
              }
             ]
            }
           ]
          },
          "x-summary-cs": "Otevírací doba na víkend"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "put": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "setOpeningHours",
    "summary": "Set the weekly opening hours",
    "x-summary-cs": "Nastavit týdenní otevírací dobu",
    "description": "Replaces the regular week of the restaurant – the same as saving Settings → Opening hours in the\nadministration. The e-shop, applications (ordering, time slots) and the administration use the new hours at\nonce, and the `restaurant.changed` event follows. Send all 7 days; a day without intervals is closed. The\nintervals of a day follow one another without overlapping (both ends are inclusive), `to` may be `24:00` and an\ninterval never crosses midnight – a night opening is two intervals on two days. Intervals that touch (`12:00`\nand `12:01`) are one continuous opening and come back joined. Exceptions (holidays) cannot be set yet. The\nresponse is the same as `getOpeningHours` for the next 14 days. Order hours (`getOrderHours`) change with the\nopening hours only while they are set the same as the opening hours; their own times are set in the\nadministration.\n",
    "x-description-cs": "Nahradí běžný týden provozovny – stejně jako uložení Nastavení → Otevírací doba v administraci. E-shop,\naplikace (objednávání, časy) i administrace novou dobu použijí hned a přijde událost `restaurant.changed`.\nPošlete všech 7 dní; den bez intervalů je zavřeno. Intervaly dne jdou po sobě bez překryvu (oba konce jsou\nvčetně), `to` může být `24:00` a interval nikdy nepřekračuje půlnoc – noční provoz jsou dva intervaly ve dvou\ndnech. Intervaly, které na sebe navazují (`12:00` a `12:01`), jsou souvislý provoz a vrátí se spojené. Výjimky\n(svátky) zatím nastavit nejde. Odpověď je stejná jako `getOpeningHours` na příštích 14 dní. Příjem objednávek\n(`getOrderHours`) se s otevírací dobou změní jen tehdy, když je nastavený stejně jako otevírací doba; vlastní časy\nse nastavují v administraci.\n",
    "security": [
     {
      "oauth2": [
       "opening_hours:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OpeningHoursInput"
       },
       "examples": {
        "week": {
         "summary": "Weekdays, Saturday with a break, closed on Sunday",
         "value": {
          "weekly": [
           {
            "day": 1,
            "intervals": [
             {
              "from": "11:00",
              "to": "22:00"
             }
            ]
           },
           {
            "day": 2,
            "intervals": [
             {
              "from": "11:00",
              "to": "22:00"
             }
            ]
           },
           {
            "day": 3,
            "intervals": [
             {
              "from": "11:00",
              "to": "22:00"
             }
            ]
           },
           {
            "day": 4,
            "intervals": [
             {
              "from": "11:00",
              "to": "22:00"
             }
            ]
           },
           {
            "day": 5,
            "intervals": [
             {
              "from": "11:00",
              "to": "22:00"
             }
            ]
           },
           {
            "day": 6,
            "intervals": [
             {
              "from": "11:00",
              "to": "15:00"
             },
             {
              "from": "17:00",
              "to": "24:00"
             }
            ]
           },
           {
            "day": 7,
            "intervals": []
           }
          ]
         },
         "x-summary-cs": "Všední dny, sobota s přestávkou, v neděli zavřeno"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The new opening hours.",
      "x-description-cs": "Nová otevírací doba.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OpeningHours"
        },
        "examples": {
         "hours": {
          "summary": "The new opening hours",
          "value": {
           "restaurant_id": "123",
           "timezone": "Europe/Prague",
           "weekly": [
            {
             "day": 1,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 2,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 3,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 4,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 5,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 6,
             "intervals": [
              {
               "from": "11:00",
               "to": "15:00"
              },
              {
               "from": "17:00",
               "to": "24:00"
              }
             ]
            },
            {
             "day": 7,
             "intervals": []
            }
           ],
           "days": [
            {
             "date": "2027-01-15",
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "date": "2027-01-16",
             "intervals": [
              {
               "from": "11:00",
               "to": "15:00"
              },
              {
               "from": "17:00",
               "to": "24:00"
              }
             ]
            },
            {
             "date": "2027-01-17",
             "intervals": []
            }
           ]
          },
          "x-summary-cs": "Nová otevírací doba"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/order-hours": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getOrderHours",
    "summary": "Order hours",
    "x-summary-cs": "Příjem objednávek",
    "description": "When the restaurant accepts orders from `web` applications (e-shops) – delivery and pickup, \"as soon as\npossible\" and for a later time – per day for a date range, plus the weekly template for display. The\nrestaurant sets them in the administration (Settings → Opening hours); by default they are the same as the\nopening hours (`same_as_opening_hours`). `ordering.open_now` and `listTimeSlots` of a `web` application follow\nthese hours, `ordering.venue_open_now` the opening hours. Show guests both when they differ, for example\n\"Open until 22:00 · Orders until 21:30\". `staff` and `kiosk` applications are not limited by them.\n",
    "x-description-cs": "Kdy provozovna přijímá objednávky aplikací `web` (e-shopů) – rozvoz i osobní odběr, „co nejdřív“ i na pozdější\nčas – po dnech pro zadané období, a k tomu týdenní šablona pro zobrazení. Provozovna je nastavuje v administraci\n(Nastavení → Otevírací doba); výchozí je stejně jako otevírací doba (`same_as_opening_hours`).\n`ordering.open_now` a `listTimeSlots` aplikace `web` se řídí těmito časy, `ordering.venue_open_now` otevírací\ndobou. Když se liší, ukazujte hostům obojí, třeba „Otevřeno do 22:00 · Objednávky do 21:30“. Aplikace `staff`\na `kiosk` neomezují.\n",
    "security": [
     {
      "oauth2": [
       "restaurants:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "from",
      "in": "query",
      "required": false,
      "description": "First day. Default today.",
      "x-description-cs": "První den. Výchozí je dnešek.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "to",
      "in": "query",
      "required": false,
      "description": "Last day, at most 31 days after `from`. Default `from` + 13 days.",
      "x-description-cs": "Poslední den, nejvýš 31 dní po `from`. Výchozí `from` + 13 dní.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-17"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Order hours.",
      "x-description-cs": "Příjem objednávek.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OrderHours"
        },
        "examples": {
         "order_hours": {
          "summary": "Orders start later and end earlier than the opening hours",
          "value": {
           "restaurant_id": "123",
           "timezone": "Europe/Prague",
           "same_as_opening_hours": false,
           "weekly": [
            {
             "day": 1,
             "intervals": [
              {
               "from": "11:30",
               "to": "21:30"
              }
             ]
            },
            {
             "day": 2,
             "intervals": [
              {
               "from": "11:30",
               "to": "21:30"
              }
             ]
            },
            {
             "day": 3,
             "intervals": [
              {
               "from": "11:30",
               "to": "21:30"
              }
             ]
            },
            {
             "day": 4,
             "intervals": [
              {
               "from": "11:30",
               "to": "21:30"
              }
             ]
            },
            {
             "day": 5,
             "intervals": [
              {
               "from": "11:30",
               "to": "21:30"
              }
             ]
            },
            {
             "day": 6,
             "intervals": [
              {
               "from": "12:00",
               "to": "21:30"
              }
             ]
            },
            {
             "day": 7,
             "intervals": [
              {
               "from": "12:00",
               "to": "19:30"
              }
             ]
            }
           ],
           "days": [
            {
             "date": "2027-01-15",
             "intervals": [
              {
               "from": "11:30",
               "to": "21:30"
              }
             ]
            },
            {
             "date": "2027-01-16",
             "intervals": [
              {
               "from": "12:00",
               "to": "15:30"
              }
             ]
            },
            {
             "date": "2027-01-17",
             "intervals": [
              {
               "from": "12:00",
               "to": "19:30"
              }
             ]
            }
           ]
          },
          "x-summary-cs": "Objednávky začínají později a končí dřív"
         },
         "same": {
          "summary": "The same as the opening hours",
          "value": {
           "restaurant_id": "123",
           "timezone": "Europe/Prague",
           "same_as_opening_hours": true,
           "weekly": [
            {
             "day": 1,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 2,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 3,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 4,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 5,
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 6,
             "intervals": [
              {
               "from": "12:00",
               "to": "22:00"
              }
             ]
            },
            {
             "day": 7,
             "intervals": [
              {
               "from": "12:00",
               "to": "20:00"
              }
             ]
            }
           ],
           "days": [
            {
             "date": "2027-01-15",
             "intervals": [
              {
               "from": "11:00",
               "to": "22:00"
              }
             ]
            },
            {
             "date": "2027-01-16",
             "intervals": [
              {
               "from": "12:00",
               "to": "16:00"
              }
             ]
            },
            {
             "date": "2027-01-17",
             "intervals": [
              {
               "from": "12:00",
               "to": "20:00"
              }
             ]
            }
           ]
          },
          "x-summary-cs": "Stejně jako otevírací doba"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/delivery-zones": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "listDeliveryZones",
    "summary": "Delivery zones",
    "x-summary-cs": "Rozvozové zóny",
    "description": "Areas the restaurant delivers to, with fee, minimum order and delivery schedule. For display and address hints\nonly: the zone of an order is always decided by Profirest in the quote. When an address lies in several zones,\nthe one with the lowest minimum order wins, then the one with the lowest fee. A zone keeps its `id` when the\nadministration saves the zones; a zone removed there disappears and a new zone gets a new `id`.\n",
    "x-description-cs": "Oblasti, kam provozovna rozváží, s cenou dopravy, minimální objednávkou a časy rozvozu. Jen pro zobrazení\na našeptávání adres: zónu objednávky vždy určí Profirest v kalkulaci. Když adresa leží ve více zónách, vyhraje\nta s nejnižší minimální objednávkou, potom ta s nejnižší cenou dopravy. Zóna si při uložení zón v administraci\nponechá své `id`; zóna, kterou tam odeberete, zmizí a nová zóna dostane nové `id`.\n",
    "security": [
     {
      "oauth2": [
       "restaurants:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of delivery zones.",
      "x-description-cs": "Stránka rozvozových zón.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeliveryZonePage"
        },
        "examples": {
         "zones": {
          "summary": "Delivery zones",
          "value": {
           "data": [
            {
             "id": "21",
             "name": "Vinohrady do 3 km",
             "fee": {
              "amount": 4900,
              "currency": "CZK"
             },
             "minimum_order": {
              "amount": 25000,
              "currency": "CZK"
             },
             "express_fee": {
              "amount": 4000,
              "currency": "CZK"
             },
             "area": {
              "type": "Polygon",
              "coordinates": [
               [
                [
                 14.4312,
                 50.0702
                ],
                [
                 14.4705,
                 50.0702
                ],
                [
                 14.4705,
                 50.0921
                ],
                [
                 14.4312,
                 50.0921
                ],
                [
                 14.4312,
                 50.0702
                ]
               ]
              ]
             },
             "schedule": [
              {
               "days": [
                1,
                2,
                3,
                4,
                5,
                6,
                7
               ],
               "from": "11:00",
               "to": "21:30"
              }
             ],
             "available_now": true
            },
            {
             "id": "22",
             "name": "Praha 2 a 3 do 6 km",
             "fee": {
              "amount": 8900,
              "currency": "CZK"
             },
             "minimum_order": {
              "amount": 40000,
              "currency": "CZK"
             },
             "express_fee": null,
             "area": {
              "type": "Polygon",
              "coordinates": [
               [
                [
                 14.4105,
                 50.0601
                ],
                [
                 14.495,
                 50.0601
                ],
                [
                 14.495,
                 50.101
                ],
                [
                 14.4105,
                 50.101
                ],
                [
                 14.4105,
                 50.0601
                ]
               ]
              ]
             },
             "schedule": [
              {
               "days": [
                1,
                2,
                3,
                4,
                5
               ],
               "from": "11:00",
               "to": "20:30"
              }
             ],
             "available_now": true
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Rozvozové zóny"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/time-slots": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "listTimeSlots",
    "summary": "Times you can order for",
    "x-summary-cs": "Časy, na které lze objednat",
    "description": "Whether an order \"as soon as possible\" is possible now and which times can be chosen on a given day. Computed by\nProfirest from order hours (`getOrderHours`), delivery schedules, lead time and courier start times. Orders for\na later time are accepted only while the restaurant accepts orders. Offer only these times; the quote checks\nthem again.\n\nFor a `staff` application (`GET /connection`) none of these time rules apply: `asap` is available whenever the\nrestaurant is active and `slots` lists every slot of the day that is not in the past. A `kiosk` on its own gets\n`asap` for pickup while open and no `slots`; a kiosk set to work as staff gets the `staff` answer.\n",
    "x-description-cs": "Zda lze právě teď objednat „co nejdřív“ a které časy lze zvolit pro zadaný den. Počítá Profirest z příjmu\nobjednávek (`getOrderHours`), časů rozvozu, předstihu a nástupu kurýrů. Objednávky na pozdější čas se přijímají\njen v době, kdy provozovna přijímá objednávky. Nabízejte jen tyto časy; kalkulace je ověří znovu.\n\nU aplikace `staff` (`GET /connection`) se žádné z těchto časových pravidel nepoužije: `asap` je k dispozici,\nkdykoli je provozovna aktivní, a `slots` obsahuje každý čas dne, který není v minulosti. Samostatný `kiosk`\ndostane `asap` pro osobní odběr, když je otevřeno, a žádné `slots`; kiosek nastavený jako obsluha odpověď\npro `staff`.\n",
    "security": [
     {
      "oauth2": [
       "restaurants:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "type",
      "in": "query",
      "required": true,
      "description": "`delivery` – times the customer can receive a delivery; `pickup` – times the order can be ready for pickup;\n`dine_in` – the same times as `pickup`, only for a kiosk and staff applications.\n",
      "x-description-cs": "`delivery` – časy, kdy může zákazník dostat rozvoz; `pickup` – časy, kdy může být objednávka připravená\nk vyzvednutí; `dine_in` – stejné časy jako `pickup`, jen pro kiosek a aplikace personálu.\n",
      "schema": {
       "$ref": "#/components/schemas/FulfillmentType"
      },
      "example": "delivery"
     },
     {
      "name": "date",
      "in": "query",
      "required": false,
      "description": "Day to list times for. Default today.",
      "x-description-cs": "Den, pro který vypsat časy. Výchozí je dnešek.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "zone_id",
      "in": "query",
      "required": false,
      "description": "For `delivery`, limit the times to the schedule of this delivery zone.",
      "x-description-cs": "U `delivery` omezí časy na rozvozový čas této zóny.",
      "schema": {
       "$ref": "#/components/schemas/Id"
      },
      "example": "21"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Available times.",
      "x-description-cs": "Dostupné časy.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TimeSlots"
        },
        "examples": {
         "slots": {
          "summary": "Delivery times for today",
          "value": {
           "restaurant_id": "123",
           "type": "delivery",
           "date": "2027-01-15",
           "asap": {
            "available": true,
            "reason": null
           },
           "slots": [
            {
             "time": "2027-01-15T12:30:00+01:00"
            },
            {
             "time": "2027-01-15T12:45:00+01:00"
            },
            {
             "time": "2027-01-15T13:00:00+01:00"
            },
            {
             "time": "2027-01-15T13:15:00+01:00"
            }
           ]
          },
          "x-summary-cs": "Časy rozvozu na dnešek"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "An invalid parameter",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/date",
             "code": "invalid_format",
             "message": "Neplatný formát."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Neplatný parametr"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/accounting-export": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getAccountingExport",
    "summary": "Accounting export for Pohoda or Money",
    "x-summary-cs": "Účetní export pro Pohodu nebo Money",
    "description": "The accounting file for one restaurant and at most 31 days: `receipts` or `invoices` of the orders finished in\nthe period (deleted ones left out; card payment at handover counts as card), or `summary` of the shift closes.\nPohoda: the XML format of current POHODA, the receipts that were paid (not the kitchen tickets of open tables),\n`receipts` as sales receipts (Prodejky) and `invoices` as issued invoices, with the VAT classification,\npre-accounting and the other document details the restaurant set for Pohoda in the administration (Settings →\nIntegrations); unlike the link with the token, the API does not filter by the form of payment or the agenda and\nit includes write-offs and employee meals. When there is nothing to export, the Pohoda file is empty (0 bytes) –\nPOHODA cannot import a file without documents. Money: the same XML that Money downloads with the token. The\nnumbers are the administration's to the haléř, gift vouchers outside VAT included. Invoices carry the buyers'\ndetails – keep the file like accounting records.\n",
    "x-description-cs": "Účetní soubor pro jednu provozovnu a nejvýš 31 dní: `receipts` (účtenky) nebo `invoices` (faktury) objednávek\ndokončených v období (bez smazaných; karta při převzetí se počítá jako karta), nebo `summary` (souhrny uzávěrek).\nPohoda: XML podle aktuální POHODY, jen zaplacené účtenky (ne kuchyňské bony otevřených stolů), `receipts` jako\nprodejky a `invoices` jako vydané faktury, s členěním DPH, předkontací a dalšími údaji dokladu podle nastavení\nPohody provozovny v administraci (Nastavení → Integrace); na rozdíl od odkazu s tokenem API nefiltruje podle formy\núhrady ani agendy a obsahuje i odpisy a obědy zaměstnanců. Když není co exportovat, je soubor pro Pohodu prázdný\n(0 bajtů) – POHODA soubor bez dokladů nenačte. Money: stejné XML, jaké Money stahuje tokenem. Čísla jsou na haléř\nstejná jako v administraci, včetně dárkových voucherů mimo DPH. Faktury nesou údaje odběratelů – se souborem\nzacházejte jako s účetními doklady.\n",
    "security": [
     {
      "oauth2": [
       "accounting:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "format",
      "in": "query",
      "required": true,
      "description": "The accounting program.",
      "x-description-cs": "Účetní program.",
      "schema": {
       "type": "string",
       "enum": [
        "pohoda",
        "money"
       ]
      },
      "example": "pohoda"
     },
     {
      "name": "type",
      "in": "query",
      "required": true,
      "description": "`receipts` – receipts of the orders, `invoices` – invoices of the orders, `summary` – summaries of the shift closes.",
      "x-description-cs": "`receipts` – účtenky objednávek, `invoices` – faktury objednávek, `summary` – souhrny uzávěrek.",
      "schema": {
       "type": "string",
       "enum": [
        "receipts",
        "invoices",
        "summary"
       ]
      },
      "example": "receipts"
     },
     {
      "name": "date_from",
      "in": "query",
      "required": true,
      "description": "First day of the period (by the day the order was finished, or the day of the close).",
      "x-description-cs": "První den období (podle dne dokončení objednávky, nebo dne uzávěrky).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-01"
     },
     {
      "name": "date_to",
      "in": "query",
      "required": true,
      "description": "Last day of the period, at most 30 days after `date_from`.",
      "x-description-cs": "Poslední den období, nejvýš 30 dní po `date_from`.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The XML document for the accounting program (for Pohoda empty when there is nothing to export).",
      "x-description-cs": "Dokument XML pro účetní program (pro Pohodu prázdný, když není co exportovat).",
      "headers": {
       "Content-Disposition": {
        "description": "`attachment; filename=\"profirest-{format}-{type}-{date_from}-{date_to}.xml\"`",
        "x-description-cs": "`attachment; filename=\"profirest-{format}-{type}-{date_from}-{date_to}.xml\"`",
        "schema": {
         "type": "string"
        }
       }
      },
      "content": {
       "application/xml": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/shift-closes": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "listShiftCloses",
    "summary": "Shift closes",
    "x-summary-cs": "Uzávěrky",
    "description": "Shift closes of the restaurant from all sources – registers on API v1 and v2, the web kitchen display, kitchen\ndisplays and the kitchen through this API – newest first, with the totals the administration shows in the\nclose detail. `source` tells from the orders of the close where it came from. Amounts are kept in the database\nwith limited precision; they are rounded to haléře here, exactly as the administration rounds them. A new close\nalso comes as the `shift.closed` event.\n",
    "x-description-cs": "Uzávěrky provozovny ze všech zdrojů – pokladny na API v1 i v2, webový kuchyňský displej, kuchyňské displeje\na kuchyně přes toto API – od nejnovější, se součty, jaké ukazuje detail uzávěrky v administraci. `source` podle\nobjednávek uzávěrky říká, odkud přišla. Částky jsou v databázi uložené s omezenou přesností; tady jsou\nzaokrouhlené na haléře stejně jako v administraci. Nová uzávěrka přichází i jako událost `shift.closed`.\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "date_from",
      "in": "query",
      "required": true,
      "description": "First day (the day of the close).",
      "x-description-cs": "První den (den uzávěrky).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-01"
     },
     {
      "name": "date_to",
      "in": "query",
      "required": true,
      "description": "Last day.",
      "x-description-cs": "Poslední den.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "One page of shift closes.",
      "x-description-cs": "Jedna stránka uzávěrek.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ShiftClosePage"
        },
        "examples": {
         "page": {
          "summary": "Shift closes",
          "value": {
           "data": [
            {
             "id": "5512",
             "restaurant_id": "123",
             "closed_at": "2027-01-15T23:05:12+01:00",
             "closed_by": {
              "id": "102",
              "name": "Jana Nováková"
             },
             "source": "mixed",
             "device_id": null,
             "orders": 87,
             "totals": {
              "completed": {
               "amount": 4573000,
               "currency": "CZK"
              },
              "by_payment": {
               "cash": {
                "amount": 1912000,
                "currency": "CZK"
               },
               "card": {
                "amount": 2511000,
                "currency": "CZK"
               },
               "meal_voucher": {
                "amount": 150000,
                "currency": "CZK"
               },
               "company_account": {
                "amount": 0,
                "currency": "CZK"
               },
               "invoice": {
                "amount": 0,
                "currency": "CZK"
               }
              },
              "not_completed": {
               "amount": 0,
               "currency": "CZK"
              },
              "cancelled_orders": {
               "amount": 39800,
               "currency": "CZK"
              },
              "cancelled_items": {
               "amount": 13800,
               "currency": "CZK"
              },
              "tips": {
               "total": {
                "amount": 52000,
                "currency": "CZK"
               },
               "cash": {
                "amount": 18000,
                "currency": "CZK"
               },
               "card": {
                "amount": 34000,
                "currency": "CZK"
               }
              },
              "discounts": {
               "order": {
                "amount": 12000,
                "currency": "CZK"
               },
               "items": {
                "amount": 4500,
                "currency": "CZK"
               }
              },
              "eet_registered": {
               "amount": 4573000,
               "currency": "CZK"
              },
              "by_ticket": {
               "kitchen": {
                "amount": 3120000,
                "currency": "CZK"
               },
               "bar": {
                "amount": 1453000,
                "currency": "CZK"
               }
              }
             }
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Uzávěrky"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/shift-closes/{close_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "close_id",
     "in": "path",
     "required": true,
     "description": "ID of the shift close (`ShiftClose.id`, also `shift_id` of `kitchen.shift_closed`).",
     "x-description-cs": "ID uzávěrky (`ShiftClose.id`, také `shift_id` z `kitchen.shift_closed`).",
     "schema": {
      "$ref": "#/components/schemas/Id"
     },
     "example": "5512"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getShiftClose",
    "summary": "One shift close",
    "x-summary-cs": "Jedna uzávěrka",
    "description": "One shift close with its totals. The administration can change orders of a closed shift later (payment,\ncancellation), so the totals can change too – the `ETag` tells.\n",
    "x-description-cs": "Jedna uzávěrka se součty. Administrace může objednávky uzavřené směny později změnit (platbu, storno), takže\nse součty mohou změnit také – poznáte to podle `ETag`.\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The shift close.",
      "x-description-cs": "Uzávěrka.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ShiftClose"
        },
        "examples": {
         "close": {
          "summary": "A shift close",
          "value": {
           "id": "5512",
           "restaurant_id": "123",
           "closed_at": "2027-01-15T23:05:12+01:00",
           "closed_by": {
            "id": "102",
            "name": "Jana Nováková"
           },
           "source": "mixed",
           "device_id": null,
           "orders": 87,
           "totals": {
            "completed": {
             "amount": 4573000,
             "currency": "CZK"
            },
            "by_payment": {
             "cash": {
              "amount": 1912000,
              "currency": "CZK"
             },
             "card": {
              "amount": 2511000,
              "currency": "CZK"
             },
             "meal_voucher": {
              "amount": 150000,
              "currency": "CZK"
             },
             "company_account": {
              "amount": 0,
              "currency": "CZK"
             },
             "invoice": {
              "amount": 0,
              "currency": "CZK"
             }
            },
            "not_completed": {
             "amount": 0,
             "currency": "CZK"
            },
            "cancelled_orders": {
             "amount": 39800,
             "currency": "CZK"
            },
            "cancelled_items": {
             "amount": 13800,
             "currency": "CZK"
            },
            "tips": {
             "total": {
              "amount": 52000,
              "currency": "CZK"
             },
             "cash": {
              "amount": 18000,
              "currency": "CZK"
             },
             "card": {
              "amount": 34000,
              "currency": "CZK"
             }
            },
            "discounts": {
             "order": {
              "amount": 12000,
              "currency": "CZK"
             },
             "items": {
              "amount": 4500,
              "currency": "CZK"
             }
            },
            "eet_registered": {
             "amount": 4573000,
             "currency": "CZK"
            },
            "by_ticket": {
             "kitchen": {
              "amount": 3120000,
              "currency": "CZK"
             },
             "bar": {
              "amount": 1453000,
              "currency": "CZK"
             }
            }
           }
          },
          "x-summary-cs": "Uzávěrka"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reports/sales-summary": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getSalesSummary",
    "summary": "Sales summary",
    "x-summary-cs": "Souhrn tržeb",
    "description": "Revenue, number of orders, average order and tips for the days, and one breakdown (`group_by`). Orders as the Statistics of the administration count them: not deleted, closed (`finished`) within the days, without\nthe tickets of open tables; revenue is the order total including delivery, the same numbers as the\nadministration shows.\nBreakdowns: `day` (only days with sales), `hour` and `weekday` (all 24 hours and 7 days, ISO 1 = Monday,\nby the time the order was closed), `payment` (card paid at handover counts as card), `source` (`pos`, `web`,\n`kitchen` and the delivery platforms `wolt`, `bolt`, `foodora`, `choice` by the start of the order name),\n`employee` (who closed the order; `0` = nobody, for example the web), `table` (accounts of the registers by\nname; other sources are left out because their name is the customer's) and `segment` (`food`, `lodging`,\n`tickets` – always all three).\n`segment` limits the orders to one kind of revenue: `food` (the register, the web shop with food, delivery\nand the platforms), `lodging` (documents of stays issued at departure – the stay, services and bills charged\nto the room) or `tickets` (tickets from the web shop and the box office).\nA restaurant that also sells accommodation or tickets gets a fair average order only with `segment=food` –\na document of a stay or a ticket purchase is no bill of a table.\n",
    "x-description-cs": "Tržba, počet objednávek, průměrná objednávka a spropitné za zadané dny a k tomu jeden rozpad (`group_by`).\nObjednávky tak, jak je počítají Statistiky v administraci: nesmazané, uzavřené (`finished`) v zadaných dnech, bez\nbonů otevřených stolů; tržba je celková částka objednávky i s dopravou – stejná čísla, jaká ukazuje\nadministrace.\nRozpady: `day` (jen dny s tržbou), `hour` a `weekday` (všech 24 hodin a 7 dní, ISO 1 = pondělí, podle času\nuzavření objednávky), `payment` (karta při převzetí jako karta), `source` (`pos`, `web`, `kitchen` a rozvozové\nplatformy `wolt`, `bolt`, `foodora`, `choice` podle začátku názvu objednávky), `employee` (kdo objednávku\nuzavřel; `0` = nikdo, třeba web), `table` (účty pokladen podle názvu; ostatní zdroje ne, jejich název je jméno\nzákazníka) a `segment` (`food`, `lodging`, `tickets` – vždy všechny tři).\n`segment` omezí objednávky na jeden druh tržby: `food` (pokladna, e-shop s jídlem, rozvoz a platformy),\n`lodging` (doklady za pobyt vystavené při odjezdu – ubytování, služby a útrata zapsaná na pokoj) nebo `tickets`\n(vstupenky z e-shopu a od vchodu).\nProvozovna, která prodává i ubytování nebo vstupenky, dostane férovou průměrnou objednávku jen se `segment=food` –\ndoklad za pobyt ani nákup vstupenek není účet od stolu.\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "date_from",
      "in": "query",
      "required": true,
      "description": "First day (the day the order was closed).",
      "x-description-cs": "První den (den, kdy se objednávka uzavřela).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-11"
     },
     {
      "name": "date_to",
      "in": "query",
      "required": true,
      "description": "Last day; at most 92 days in one request.",
      "x-description-cs": "Poslední den; nejvýš 92 dní v jednom požadavku.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "group_by",
      "in": "query",
      "required": false,
      "description": "The breakdown in `rows`. Default `day`.",
      "x-description-cs": "Rozpad v `rows`. Výchozí `day`.",
      "schema": {
       "type": "string",
       "enum": [
        "day",
        "hour",
        "weekday",
        "payment",
        "source",
        "employee",
        "table",
        "segment"
       ],
       "default": "day"
      },
      "example": "payment"
     },
     {
      "$ref": "#/components/parameters/RevenueSegment"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The summary.",
      "x-description-cs": "Souhrn.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SalesSummary"
        },
        "examples": {
         "payment": {
          "summary": "Revenue of the week by payment",
          "value": {
           "date_from": "2027-01-11",
           "date_to": "2027-01-15",
           "group_by": "payment",
           "segment": null,
           "totals": {
            "revenue": {
             "amount": 14250000,
             "currency": "CZK"
            },
            "orders": 512,
            "average_order": {
             "amount": 27832,
             "currency": "CZK"
            },
            "tips": {
             "amount": 318000,
             "currency": "CZK"
            }
           },
           "rows": [
            {
             "key": "card",
             "name": null,
             "revenue": {
              "amount": 8915000,
              "currency": "CZK"
             },
             "orders": 301
            },
            {
             "key": "cash",
             "name": null,
             "revenue": {
              "amount": 4830000,
              "currency": "CZK"
             },
             "orders": 196
            },
            {
             "key": "meal_voucher",
             "name": null,
             "revenue": {
              "amount": 505000,
              "currency": "CZK"
             },
             "orders": 15
            }
           ]
          },
          "x-summary-cs": "Tržby týdne podle platby"
         },
         "segment": {
          "summary": "Food, accommodation and tickets apart",
          "value": {
           "date_from": "2027-01-11",
           "date_to": "2027-01-15",
           "group_by": "segment",
           "segment": null,
           "totals": {
            "revenue": {
             "amount": 19870000,
             "currency": "CZK"
            },
            "orders": 563,
            "average_order": {
             "amount": 35293,
             "currency": "CZK"
            },
            "tips": {
             "amount": 318000,
             "currency": "CZK"
            }
           },
           "rows": [
            {
             "key": "food",
             "name": null,
             "revenue": {
              "amount": 14250000,
              "currency": "CZK"
             },
             "orders": 512
            },
            {
             "key": "lodging",
             "name": null,
             "revenue": {
              "amount": 3820000,
              "currency": "CZK"
             },
             "orders": 9
            },
            {
             "key": "tickets",
             "name": null,
             "revenue": {
              "amount": 1800000,
              "currency": "CZK"
             },
             "orders": 42
            }
           ]
          },
          "x-summary-cs": "Gastro, ubytování a vstupenky zvlášť"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reports/product-sales": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getProductSales",
    "summary": "Product sales",
    "x-summary-cs": "Prodej položek",
    "description": "Pieces sold and revenue by product, category, sortiment or production station, like \"Product performance\" in\nthe Statistics of the administration. Orders as the Statistics of the administration count them: not deleted, closed (`finished`) within the days, without\nthe tickets of open tables; revenue is the order total including delivery, the same numbers as the\nadministration shows.\n`revenue` is the price with packaging times the share of the order that was paid (a discount on the whole\norder lowers every item), a gift voucher sale in full; `discounts` are the discounts on items. Payments by\na gift voucher are no sale. Delivery is no item, so the sum of `revenue` is lower than the revenue of the\norders by the delivery fees.\n`segment` limits the orders to one kind of revenue: `food` (the register, the web shop with food, delivery\nand the platforms), `lodging` (documents of stays issued at departure – the stay, services and bills charged\nto the room) or `tickets` (tickets from the web shop and the box office).\nTickets and documents of stays are lines without a product (`key` `0`), each name on its own row.\n",
    "x-description-cs": "Prodané kusy a tržba po produktech, kategoriích, sortimentech nebo výrobních stanovištích, jako „Výkonnost\nproduktů“ ve Statistikách administrace. Objednávky tak, jak je počítají Statistiky v administraci: nesmazané, uzavřené (`finished`) v zadaných dnech, bez\nbonů otevřených stolů; tržba je celková částka objednávky i s dopravou – stejná čísla, jaká ukazuje\nadministrace.\n`revenue` je cena s obalem krát podíl zaplacené části objednávky (sleva na celý účet sníží každou položku),\nprodej dárkového voucheru celý; `discounts` jsou slevy na položky. Úhrada dárkovým voucherem prodej není.\nDoprava položka není, součet `revenue` je proto o dopravné nižší než tržba objednávek.\n`segment` omezí objednávky na jeden druh tržby: `food` (pokladna, e-shop s jídlem, rozvoz a platformy),\n`lodging` (doklady za pobyt vystavené při odjezdu – ubytování, služby a útrata zapsaná na pokoj) nebo `tickets`\n(vstupenky z e-shopu a od vchodu).\nVstupenky a doklady za pobyt jsou řádky bez produktu (`key` `0`), každý název na vlastním řádku.\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "date_from",
      "in": "query",
      "required": true,
      "description": "First day (the day the order was closed).",
      "x-description-cs": "První den (den, kdy se objednávka uzavřela).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-11"
     },
     {
      "name": "date_to",
      "in": "query",
      "required": true,
      "description": "Last day; at most 92 days in one request.",
      "x-description-cs": "Poslední den; nejvýš 92 dní v jednom požadavku.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "group_by",
      "in": "query",
      "required": false,
      "description": "`product` (default), `category`, `sortiment` or `station` (production station of the product).",
      "x-description-cs": "`product` (výchozí), `category`, `sortiment` nebo `station` (výrobní stanoviště produktu).",
      "schema": {
       "type": "string",
       "enum": [
        "product",
        "category",
        "sortiment",
        "station"
       ],
       "default": "product"
      },
      "example": "product"
     },
     {
      "name": "source",
      "in": "query",
      "required": false,
      "description": "Only orders from these sources, comma-separated (`pos`, `web`, `kitchen`). Default all.",
      "x-description-cs": "Jen objednávky z těchto zdrojů, oddělené čárkou (`pos`, `web`, `kitchen`). Výchozí všechny.",
      "schema": {
       "type": "string",
       "pattern": "^(pos|web|kitchen)(,(pos|web|kitchen)){0,2}$"
      }
     },
     {
      "$ref": "#/components/parameters/RevenueSegment"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Product sales.",
      "x-description-cs": "Prodej položek.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductSales"
        },
        "examples": {
         "products": {
          "summary": "Product sales of the week",
          "value": {
           "date_from": "2027-01-11",
           "date_to": "2027-01-15",
           "group_by": "product",
           "segment": null,
           "totals": {
            "quantity": 1416,
            "revenue": {
             "amount": 13981000,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 42000,
             "currency": "CZK"
            }
           },
           "rows": [
            {
             "key": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 214,
             "revenue": {
              "amount": 4258600,
              "currency": "CZK"
             },
             "discounts": {
              "amount": 19900,
              "currency": "CZK"
             }
            },
            {
             "key": "4590",
             "name": "Pivo 12° 0,5 l",
             "quantity": 688,
             "revenue": {
              "amount": 4747200,
              "currency": "CZK"
             },
             "discounts": {
              "amount": 0,
              "currency": "CZK"
             }
            }
           ]
          },
          "x-summary-cs": "Prodej položek týdne"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reports/tips": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getTipsReport",
    "summary": "Tips",
    "x-summary-cs": "Spropitné",
    "description": "Tips for the days by payment method, by the employee who closed the order and by the courier, like Statistics →\nTips in the administration. Orders as the Statistics of the administration count them: not deleted, closed (`finished`) within the days, without\nthe tickets of open tables; revenue is the order total including delivery, the same numbers as the\nadministration shows.\n",
    "x-description-cs": "Spropitné za zadané dny podle způsobu platby, podle zaměstnance, který objednávku uzavřel, a podle kurýra, jako\nStatistiky → Spropitné v administraci. Objednávky tak, jak je počítají Statistiky v administraci: nesmazané, uzavřené (`finished`) v zadaných dnech, bez\nbonů otevřených stolů; tržba je celková částka objednávky i s dopravou – stejná čísla, jaká ukazuje\nadministrace.\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "date_from",
      "in": "query",
      "required": true,
      "description": "First day (the day the order was closed).",
      "x-description-cs": "První den (den, kdy se objednávka uzavřela).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-11"
     },
     {
      "name": "date_to",
      "in": "query",
      "required": true,
      "description": "Last day; at most 92 days in one request.",
      "x-description-cs": "Poslední den; nejvýš 92 dní v jednom požadavku.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Tips.",
      "x-description-cs": "Spropitné.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TipsReport"
        },
        "examples": {
         "tips": {
          "summary": "Tips of the week",
          "value": {
           "date_from": "2027-01-11",
           "date_to": "2027-01-15",
           "totals": {
            "tips": {
             "amount": 318000,
             "currency": "CZK"
            },
            "orders_with_tip": 171,
            "orders": 512,
            "revenue": {
             "amount": 14250000,
             "currency": "CZK"
            }
           },
           "by_payment": [
            {
             "method": "card",
             "tips": {
              "amount": 251000,
              "currency": "CZK"
             },
             "orders": 139
            },
            {
             "method": "cash",
             "tips": {
              "amount": 67000,
              "currency": "CZK"
             },
             "orders": 32
            }
           ],
           "by_employee": [
            {
             "employee": {
              "id": "58",
              "name": "Jana Dvořáková"
             },
             "tips": {
              "amount": 204000,
              "currency": "CZK"
             },
             "orders": 108
            },
            {
             "employee": {
              "id": "61",
              "name": "Petr Novák"
             },
             "tips": {
              "amount": 114000,
              "currency": "CZK"
             },
             "orders": 63
            }
           ],
           "by_courier": []
          },
          "x-summary-cs": "Spropitné týdne"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reports/charges": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getChargesReport",
    "summary": "Charges",
    "x-summary-cs": "Poplatky",
    "description": "How many orders had a delivery fee, a surcharge to the minimum order and express delivery, and how much they\nbrought, like the charges in the Statistics of the administration – from all sources (registers, e-shop,\nkitchen display, applications). Orders as the Statistics of the administration count them: not deleted,\nclosed (`finished`) within the days, without the tickets of open tables; a cancellation by a reverse document\ntakes the order and the amount back on the day of the cancellation, like the revenue. An order whose charge is\nsplit into several VAT rates counts once. Always all three rows, in the order `delivery_fee`,\n`minimum_order_surcharge`, `express_delivery`.\n",
    "x-description-cs": "Kolik objednávek mělo dopravu, doplatek do minimální objednávky a expresní doručení a kolik vynesly, jako\npoplatky ve Statistikách administrace – ze všech zdrojů (pokladny, e-shop, kuchyňský displej, aplikace).\nObjednávky tak, jak je počítají Statistiky v administraci: nesmazané, uzavřené (`finished`) v zadaných dnech,\nbez bonů otevřených stolů; storno protidokladem vrátí objednávku i částku v den storna, stejně jako tržbu.\nObjednávka s poplatkem rozděleným do více sazeb DPH se počítá jednou. Vždy všechny tři řádky v pořadí\n`delivery_fee`, `minimum_order_surcharge`, `express_delivery`.\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "date_from",
      "in": "query",
      "required": true,
      "description": "First day (the day the order was closed).",
      "x-description-cs": "První den (den, kdy se objednávka uzavřela).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-11"
     },
     {
      "name": "date_to",
      "in": "query",
      "required": true,
      "description": "Last day; at most 92 days in one request.",
      "x-description-cs": "Poslední den; nejvýš 92 dní v jednom požadavku.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The charges.",
      "x-description-cs": "Poplatky.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ChargesReport"
        },
        "examples": {
         "charges": {
          "summary": "Charges of the week",
          "value": {
           "date_from": "2027-01-11",
           "date_to": "2027-01-15",
           "rows": [
            {
             "type": "delivery_fee",
             "name": "Doprava",
             "orders": 143,
             "amount": {
              "amount": 887900,
              "currency": "CZK"
             }
            },
            {
             "type": "minimum_order_surcharge",
             "name": "Doplatek do minimální objednávky",
             "orders": 9,
             "amount": {
              "amount": 41200,
              "currency": "CZK"
             }
            },
            {
             "type": "express_delivery",
             "name": "Expresní doručení",
             "orders": 21,
             "amount": {
              "amount": 84000,
              "currency": "CZK"
             }
            }
           ]
          },
          "x-summary-cs": "Poplatky týdne"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reports/vat": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getVatReport",
    "summary": "VAT by rate",
    "x-summary-cs": "Rozpis DPH",
    "description": "VAT by rate for the days, like the tax overview in the Statistics of the administration, computed the same way\nas the receipt copy and the accounting exports: a discount on the whole order, the delivery fee and a price\nadjustment are split into the rates by the gross amounts of the items, rounding is outside VAT. Orders as the\nStatistics of the administration count them: not deleted, closed (`finished`) within the days, without the\ntickets of open tables and without the orders paid to a company account. Sold gift vouchers are not subject\nto VAT and are in `vouchers_sold`; a payment by a gift voucher is no sale (the VAT is in the full price of the\nfood and drinks). The documents for an accountant are the accounting exports (`getAccountingExport`).\n",
    "x-description-cs": "DPH po sazbách za zadané dny jako daňový přehled ve Statistikách administrace, spočítané stejně jako kopie\núčtenky a účetní exporty: sleva na celý účet, doprava a úprava ceny se dělí do sazeb poměrem hrubých částek\npoložek, zaokrouhlení do DPH nevstupuje. Objednávky tak, jak je počítají Statistiky v administraci: nesmazané,\nuzavřené (`finished`) v zadaných dnech, bez bonů otevřených stolů a bez objednávek placených na účet podniku.\nProdané dárkové vouchery DPH nepodléhají a jsou v `vouchers_sold`; úhrada dárkovým voucherem prodej není (daň\nje v plné ceně jídla a pití). Podklady pro účetní jsou účetní exporty (`getAccountingExport`).\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "date_from",
      "in": "query",
      "required": true,
      "description": "First day (the day the order was closed).",
      "x-description-cs": "První den (den, kdy se objednávka uzavřela).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-11"
     },
     {
      "name": "date_to",
      "in": "query",
      "required": true,
      "description": "Last day; at most 92 days in one request.",
      "x-description-cs": "Poslední den; nejvýš 92 dní v jednom požadavku.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "VAT by rate.",
      "x-description-cs": "DPH po sazbách.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/VatReport"
        },
        "examples": {
         "vat": {
          "summary": "VAT of the week",
          "value": {
           "date_from": "2027-01-11",
           "date_to": "2027-01-15",
           "rates": [
            {
             "rate": "21",
             "base": {
              "amount": 3962810,
              "currency": "CZK"
             },
             "vat": {
              "amount": 832190,
              "currency": "CZK"
             },
             "total": {
              "amount": 4795000,
              "currency": "CZK"
             }
            },
            {
             "rate": "12",
             "base": {
              "amount": 8263393,
              "currency": "CZK"
             },
             "vat": {
              "amount": 991607,
              "currency": "CZK"
             },
             "total": {
              "amount": 9255000,
              "currency": "CZK"
             }
            }
           ],
           "vouchers_sold": {
            "amount": 200000,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "DPH týdne"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/sales": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "listSales",
    "summary": "Sales documents",
    "x-summary-cs": "Doklady prodeje",
    "description": "Sales documents of the restaurant from all sources – registers on API v1 and v2, the web, the kitchen and the\ndelivery platforms – oldest first by the time they were closed, so a bookkeeping or BI system can download\nthem day by day. The same orders as the Statistics of the administration (not deleted, without the tickets of\nopen tables). Amounts, the VAT breakdown, discounts on the whole bill, delivery, price adjustments, rounding and\npayments by gift vouchers are computed exactly as the receipt copy in the administration and the exports to\nPohoda and Money. A cancellation is its own document (`kind` `cancellation`, negative amounts, `cancels`).\nCustomer contacts are left out. New documents also come as `sale.created` events and cancelled ones as\n`sale.cancelled` (with `reports:read`), so the list is needed only to catch up.\n",
    "x-description-cs": "Doklady prodeje provozovny ze všech zdrojů – pokladny na API v1 i v2, web, kuchyň a rozvozové platformy – od\nnejstaršího podle času uzavření, takže si je účetní nebo BI systém může stahovat den po dni. Stejné objednávky\njako Statistiky v administraci (nesmazané, bez bonů otevřených stolů). Částky, rozpis DPH, slevy na celý účet,\ndopravu, úpravy ceny, zaokrouhlení a úhrady dárkovým voucherem počítá stejně jako kopie účtenky v administraci\na exporty do Pohody a Money. Storno je samostatný doklad (`kind` `cancellation`, záporné částky, `cancels`).\nKontakty zákazníků v dokladech nejsou. Nové doklady přicházejí i jako události `sale.created` a stornované jako\n`sale.cancelled` (s `reports:read`), seznam pak stačí na dohnání.\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "date_from",
      "in": "query",
      "required": true,
      "description": "First day (the day the document was closed).",
      "x-description-cs": "První den (den uzavření dokladu).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "date_to",
      "in": "query",
      "required": true,
      "description": "Last day; at most 92 days in one request (the cursor continues within them).",
      "x-description-cs": "Poslední den; nejvýš 92 dní v jednom požadavku (kurzor pokračuje v rámci nich).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "source",
      "in": "query",
      "required": false,
      "description": "Only documents from these sources, comma-separated (`pos`, `web`, `kitchen`). Default all.",
      "x-description-cs": "Jen doklady z těchto zdrojů, oddělené čárkou (`pos`, `web`, `kitchen`). Výchozí všechny.",
      "schema": {
       "type": "string",
       "pattern": "^(pos|web|kitchen)(,(pos|web|kitchen)){0,2}$"
      }
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "One page of documents.",
      "x-description-cs": "Jedna stránka dokladů.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SalePage"
        },
        "examples": {
         "page": {
          "summary": "Documents of the day",
          "value": {
           "data": [
            {
             "id": "880417",
             "number": "1043",
             "kind": "sale",
             "source": "pos",
             "platform": null,
             "table_name": "Stůl 4",
             "created_at": "2027-01-15T11:48:02+01:00",
             "closed_at": "2027-01-15T12:31:40+01:00",
             "employee": {
              "id": "58",
              "name": "Jana Dvořáková"
             },
             "lines": [
              {
               "type": "product",
               "product_id": "4567",
               "name": "Svíčková na smetaně, houskový knedlík",
               "quantity": 1,
               "unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "packaging_unit_price": null,
               "discount_per_unit": {
                "amount": 0,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "total": {
                "amount": 19900,
                "currency": "CZK"
               }
              },
              {
               "type": "product",
               "product_id": "4590",
               "name": "Pivo 12° 0,5 l",
               "quantity": 2,
               "unit_price": {
                "amount": 6900,
                "currency": "CZK"
               },
               "packaging_unit_price": null,
               "discount_per_unit": {
                "amount": 0,
                "currency": "CZK"
               },
               "vat_rate": "21",
               "total": {
                "amount": 13800,
                "currency": "CZK"
               }
              }
             ],
             "items_total": {
              "amount": 33700,
              "currency": "CZK"
             },
             "discounts": [],
             "delivery_fee": {
              "amount": 0,
              "currency": "CZK"
             },
             "price_adjustment": {
              "amount": 0,
              "currency": "CZK"
             },
             "rounding": {
              "amount": 0,
              "currency": "CZK"
             },
             "total": {
              "amount": 33700,
              "currency": "CZK"
             },
             "vat": [
              {
               "rate": "21",
               "base": {
                "amount": 11405,
                "currency": "CZK"
               },
               "vat": {
                "amount": 2395,
                "currency": "CZK"
               },
               "total": {
                "amount": 13800,
                "currency": "CZK"
               }
              },
              {
               "rate": "12",
               "base": {
                "amount": 17768,
                "currency": "CZK"
               },
               "vat": {
                "amount": 2132,
                "currency": "CZK"
               },
               "total": {
                "amount": 19900,
                "currency": "CZK"
               }
              }
             ],
             "voucher_payments": [],
             "amount_paid": {
              "amount": 33700,
              "currency": "CZK"
             },
             "payment_method": "card",
             "card_at_handover": false,
             "tip": {
              "amount": 3000,
              "currency": "CZK"
             },
             "eet": {
              "fik": null,
              "bkp": null,
              "status": "accepted",
              "pok": "ab12cd34-0000-4000-8000-000000000001-03"
             },
             "shift_id": "5512",
             "cancels": null,
             "cancelled_by": null
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Doklady dne"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/sales/{sale_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "sale_id",
     "in": "path",
     "required": true,
     "description": "ID of the document (`Sale.id`).",
     "x-description-cs": "ID dokladu (`Sale.id`).",
     "schema": {
      "$ref": "#/components/schemas/Id"
     },
     "example": "880417"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getSale",
    "summary": "One sales document",
    "x-summary-cs": "Jeden doklad prodeje",
    "description": "One document. The administration can change a document later (payment method, cancellation, its shift close),\nso it can change – the `ETag` tells.\n",
    "x-description-cs": "Jeden doklad. Administrace může doklad později změnit (způsob platby, storno, uzávěrka), takže se může\nzměnit – poznáte to podle `ETag`.\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The document.",
      "x-description-cs": "Doklad.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Sale"
        },
        "examples": {
         "sale": {
          "summary": "A register document",
          "value": {
           "id": "880417",
           "number": "1043",
           "kind": "sale",
           "source": "pos",
           "platform": null,
           "table_name": "Stůl 4",
           "created_at": "2027-01-15T11:48:02+01:00",
           "closed_at": "2027-01-15T12:31:40+01:00",
           "employee": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "lines": [
            {
             "type": "product",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 1,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "discount_per_unit": {
              "amount": 0,
              "currency": "CZK"
             },
             "vat_rate": "12",
             "total": {
              "amount": 19900,
              "currency": "CZK"
             }
            },
            {
             "type": "product",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "quantity": 2,
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "discount_per_unit": {
              "amount": 0,
              "currency": "CZK"
             },
             "vat_rate": "21",
             "total": {
              "amount": 13800,
              "currency": "CZK"
             }
            }
           ],
           "items_total": {
            "amount": 33700,
            "currency": "CZK"
           },
           "discounts": [],
           "delivery_fee": {
            "amount": 0,
            "currency": "CZK"
           },
           "price_adjustment": {
            "amount": 0,
            "currency": "CZK"
           },
           "rounding": {
            "amount": 0,
            "currency": "CZK"
           },
           "total": {
            "amount": 33700,
            "currency": "CZK"
           },
           "vat": [
            {
             "rate": "21",
             "base": {
              "amount": 11405,
              "currency": "CZK"
             },
             "vat": {
              "amount": 2395,
              "currency": "CZK"
             },
             "total": {
              "amount": 13800,
              "currency": "CZK"
             }
            },
            {
             "rate": "12",
             "base": {
              "amount": 17768,
              "currency": "CZK"
             },
             "vat": {
              "amount": 2132,
              "currency": "CZK"
             },
             "total": {
              "amount": 19900,
              "currency": "CZK"
             }
            }
           ],
           "voucher_payments": [],
           "amount_paid": {
            "amount": 33700,
            "currency": "CZK"
           },
           "payment_method": "card",
           "card_at_handover": false,
           "tip": {
            "amount": 3000,
            "currency": "CZK"
           },
           "eet": {
            "fik": null,
            "bkp": null,
            "status": "accepted",
            "pok": "ab12cd34-0000-4000-8000-000000000001-03"
           },
           "shift_id": "5512",
           "cancels": null,
           "cancelled_by": null
          },
          "x-summary-cs": "Doklad z pokladny"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/catalog": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Catalog"
    ],
    "operationId": "getCatalog",
    "summary": "Catalog of the restaurant",
    "x-summary-cs": "Sortiment provozovny",
    "description": "Everything the restaurant sells online at the moment `at`: categories, products with the prices of this\nrestaurant, add-ons, allergens and the daily menu of that day. Prices are final prices including VAT.\n\nPrices and availability of an order are those valid at its time (for \"as soon as possible\", now). For an order\nplaced for later, read the catalog with `at` set to that time. Time rules (hidden categories, the daily menu\nwindow) are already applied. `next_change_at` says when the result changes next because of time. Use\n`If-None-Match`, so an unchanged catalog costs almost nothing. The quote always recalculates prices.\n",
    "x-description-cs": "Vše, co provozovna prodává online v okamžiku `at`: kategorie, produkty s cenami této provozovny, přílohy\na doplňky, alergeny a denní menu toho dne. Ceny jsou konečné včetně DPH.\n\nPro objednávku platí ceny a dostupnost v jejím čase (u „co nejdřív“ teď). Pro objednávku na později načtěte\nsortiment s `at` nastaveným na ten čas. Časová pravidla (skryté kategorie, okno denního menu) jsou už použitá.\n`next_change_at` říká, kdy se výsledek kvůli času příště změní. Používejte `If-None-Match`, pak nezměněný\nsortiment nestojí skoro nic. Kalkulace ceny vždy přepočítá.\n",
    "security": [
     {
      "oauth2": [
       "catalog:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "at",
      "in": "query",
      "required": false,
      "description": "Moment the catalog is for. Default now. At most `ordering.scheduled_orders.max_days_ahead` days ahead.",
      "x-description-cs": "Okamžik, pro který sortiment platí. Výchozí je teď. Nejvýš `ordering.scheduled_orders.max_days_ahead` dní dopředu.",
      "schema": {
       "$ref": "#/components/schemas/Timestamp"
      }
     },
     {
      "name": "channel",
      "in": "query",
      "required": false,
      "description": "Whose offer: `web` (default) – what the e-shop offers (the restaurant's \"W\" switch); `kitchen` – the order\nmenu of the kitchen display (\"K\"); `pos` – the cash register (\"B\"). Only applications of the restaurant's\nstaff (`Connection.client.order_channel = staff`) and a kiosk set to work as staff may use `kitchen` and\n`pos`. Prices, time rules, the daily\nmenu and portions are the same in every channel; the `kitchen` channel uses the takeaway VAT rate of the\nproducts, as orders from the kitchen display do today.\n",
      "x-description-cs": "Čí nabídka: `web` (výchozí) – co nabízí e-shop (přepínač „W“ provozovny); `kitchen` – nabídka objednávky\nkuchyňského displeje („K“); `pos` – pokladna („B“). `kitchen` a `pos` smí používat jen aplikace personálu\nprovozovny (`Connection.client.order_channel = staff`) a kiosek nastavený jako obsluha. Ceny, časová\npravidla, denní menu a porce jsou\nve všech kanálech stejné; kanál `kitchen` počítá se sazbou DPH produktů „s sebou“ jako dnešní objednávky\nz kuchyňského displeje.\n",
      "schema": {
       "type": "string",
       "enum": [
        "web",
        "kitchen",
        "pos"
       ],
       "default": "web"
      },
      "example": "web"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The catalog.",
      "x-description-cs": "Sortiment.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Catalog"
        },
        "examples": {
         "catalog": {
          "summary": "The catalog for an e-shop",
          "value": {
           "restaurant_id": "123",
           "currency": "CZK",
           "at": "2027-01-15T11:42:00+01:00",
           "generated_at": "2027-01-15T11:40:00+01:00",
           "next_change_at": "2027-01-15T15:00:00+01:00",
           "categories": [
            {
             "id": "312",
             "name": "Hlavní jídla",
             "description": null,
             "image_url": null,
             "color": "#e53935",
             "icon": "fa-utensils",
             "position": 1,
             "external_id": null,
             "metadata": {}
            },
            {
             "id": "315",
             "name": "Pizza",
             "description": "Pečeme v peci na dřevo.",
             "image_url": null,
             "color": "#fb8c00",
             "icon": "fa-pizza-slice",
             "position": 2,
             "external_id": null,
             "metadata": {}
            },
            {
             "id": "320",
             "name": "Nápoje",
             "description": null,
             "image_url": null,
             "color": "#1e88e5",
             "icon": null,
             "position": 3,
             "external_id": null,
             "metadata": {}
            }
           ],
           "products": [
            {
             "id": "4567",
             "category_id": "312",
             "name": "Svíčková na smetaně, houskový knedlík",
             "description": "Hovězí svíčková, smetanová omáčka, brusinky, šlehačka.",
             "image_url": "https://www.mujprofirest.cz/data/products/4567.jpg",
             "price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "vat_rate": "12",
             "packaging_fee": null,
             "weight": 150,
             "allergens": [
              "1",
              "3",
              "7",
              "9"
             ],
             "labels": [
              "home_made"
             ],
             "age_restricted": false,
             "add_ons": [],
             "option_groups": [],
             "removable_ingredients": [],
             "split": null,
             "half_price": null,
             "position": 1,
             "ean": null,
             "kitchen_name": null,
             "size": null,
             "pos": null,
             "external_id": null,
             "metadata": {}
            },
            {
             "id": "4568",
             "category_id": "312",
             "name": "Smažený sýr, hranolky, tatarská omáčka",
             "description": "Eidam 120 g, hranolky, domácí tatarská omáčka.",
             "image_url": null,
             "price": {
              "amount": 17900,
              "currency": "CZK"
             },
             "vat_rate": "12",
             "packaging_fee": null,
             "weight": 120,
             "allergens": [
              "1",
              "3",
              "7"
             ],
             "labels": [],
             "age_restricted": false,
             "add_ons": [],
             "option_groups": [],
             "removable_ingredients": [],
             "split": null,
             "half_price": null,
             "position": 2,
             "ean": null,
             "kitchen_name": null,
             "size": null,
             "pos": null,
             "external_id": null,
             "metadata": {}
            },
            {
             "id": "4571",
             "category_id": "315",
             "name": "Pizza Margherita",
             "description": "Rajčata San Marzano, mozzarella, bazalka.",
             "image_url": null,
             "price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "vat_rate": "12",
             "packaging_fee": null,
             "weight": 450,
             "allergens": [
              "1",
              "7"
             ],
             "labels": [
              "bestseller"
             ],
             "age_restricted": false,
             "add_ons": [
              {
               "product_id": "4602",
               "name": "Extra sýr",
               "price": {
                "amount": 3000,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "7"
               ]
              }
             ],
             "option_groups": [],
             "removable_ingredients": [
              {
               "id": "9001",
               "name": "bazalka"
              },
              {
               "id": "9002",
               "name": "oregano"
              }
             ],
             "split": {
              "half_price": {
               "amount": 13300,
               "currency": "CZK"
              },
              "quarter_price": null
             },
             "half_price": null,
             "position": 1,
             "ean": null,
             "kitchen_name": null,
             "size": null,
             "pos": null,
             "external_id": null,
             "metadata": {}
            },
            {
             "id": "4590",
             "category_id": "315",
             "name": "Vlastní pizza Ø32cm",
             "description": "Složte si pizzu: těsto a až 8 ingrediencí, 4 jsou v ceně.",
             "image_url": null,
             "price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "vat_rate": "12",
             "packaging_fee": null,
             "weight": 450,
             "allergens": [
              "1",
              "7"
             ],
             "labels": [],
             "age_restricted": false,
             "add_ons": [],
             "option_groups": [
              {
               "id": "71",
               "name": "Těsto",
               "min_quantity": 1,
               "max_quantity": 1,
               "max_per_option": 1,
               "included_quantity": 0,
               "options": [
                {
                 "id": "1001",
                 "product_id": "4591",
                 "name": "Klasické těsto",
                 "price": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "base_price": null,
                 "vat_rate": "12",
                 "allergens": [
                  "1"
                 ]
                },
                {
                 "id": "1002",
                 "product_id": "4592",
                 "name": "Celozrnné těsto",
                 "price": {
                  "amount": 2000,
                  "currency": "CZK"
                 },
                 "base_price": null,
                 "vat_rate": "12",
                 "allergens": [
                  "1"
                 ]
                }
               ]
              },
              {
               "id": "72",
               "name": "Ingredience",
               "min_quantity": 0,
               "max_quantity": 8,
               "max_per_option": 2,
               "included_quantity": 4,
               "options": [
                {
                 "id": "1101",
                 "product_id": "4605",
                 "name": "Šunka",
                 "price": {
                  "amount": 2400,
                  "currency": "CZK"
                 },
                 "base_price": null,
                 "vat_rate": "12",
                 "allergens": []
                },
                {
                 "id": "1102",
                 "product_id": "4603",
                 "name": "Žampiony",
                 "price": {
                  "amount": 1900,
                  "currency": "CZK"
                 },
                 "base_price": null,
                 "vat_rate": "12",
                 "allergens": []
                },
                {
                 "id": "1103",
                 "product_id": "4604",
                 "name": "Krevety",
                 "price": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "base_price": {
                  "amount": 20900,
                  "currency": "CZK"
                 },
                 "vat_rate": "12",
                 "allergens": [
                  "2"
                 ]
                },
                {
                 "id": "1104",
                 "product_id": "4606",
                 "name": "Olivy",
                 "price": {
                  "amount": 1500,
                  "currency": "CZK"
                 },
                 "base_price": null,
                 "vat_rate": "12",
                 "allergens": []
                }
               ]
              }
             ],
             "removable_ingredients": [],
             "split": null,
             "half_price": null,
             "position": 4,
             "ean": null,
             "kitchen_name": null,
             "size": null,
             "pos": null,
             "external_id": null,
             "metadata": {}
            },
            {
             "id": "4580",
             "category_id": "315",
             "name": "Ø32cm Prosciutto",
             "description": "Šunka, mozzarella, rajčata.",
             "image_url": null,
             "price": {
              "amount": 21900,
              "currency": "CZK"
             },
             "vat_rate": "12",
             "packaging_fee": null,
             "weight": 450,
             "allergens": [
              "1",
              "7"
             ],
             "labels": [],
             "age_restricted": false,
             "add_ons": [],
             "option_groups": [],
             "removable_ingredients": [],
             "split": null,
             "half_price": null,
             "position": 2,
             "ean": null,
             "kitchen_name": null,
             "size": {
              "group_id": "4580",
              "name": "Ø32cm",
              "dish_name": "Prosciutto",
              "position": 1,
              "base": true
             },
             "pos": null,
             "external_id": null,
             "metadata": {}
            },
            {
             "id": "4583",
             "category_id": "315",
             "name": "Ø42cm Prosciutto",
             "description": "Šunka, mozzarella, rajčata.",
             "image_url": null,
             "price": {
              "amount": 30900,
              "currency": "CZK"
             },
             "vat_rate": "12",
             "packaging_fee": null,
             "weight": 700,
             "allergens": [
              "1",
              "7"
             ],
             "labels": [],
             "age_restricted": false,
             "add_ons": [],
             "option_groups": [],
             "removable_ingredients": [],
             "split": null,
             "half_price": null,
             "position": 3,
             "ean": null,
             "kitchen_name": null,
             "size": {
              "group_id": "4580",
              "name": "Ø42cm",
              "dish_name": "Prosciutto",
              "position": 2,
              "base": false
             },
             "pos": null,
             "external_id": null,
             "metadata": {}
            },
            {
             "id": "4590",
             "category_id": "320",
             "name": "Pivo 12° 0,5 l",
             "description": null,
             "image_url": null,
             "price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "vat_rate": "21",
             "packaging_fee": null,
             "weight": null,
             "allergens": [],
             "labels": [],
             "age_restricted": true,
             "add_ons": [],
             "option_groups": [],
             "removable_ingredients": [],
             "split": null,
             "half_price": null,
             "position": 1,
             "ean": null,
             "kitchen_name": null,
             "size": null,
             "pos": null,
             "external_id": null,
             "metadata": {}
            },
            {
             "id": "4593",
             "category_id": "320",
             "name": "Domácí limonáda 0,4 l",
             "description": "Citron, máta, třtinový cukr.",
             "image_url": null,
             "price": {
              "amount": 5900,
              "currency": "CZK"
             },
             "vat_rate": "12",
             "packaging_fee": null,
             "weight": null,
             "allergens": [],
             "labels": [],
             "age_restricted": false,
             "add_ons": [],
             "option_groups": [],
             "removable_ingredients": [],
             "split": null,
             "half_price": null,
             "position": 2,
             "ean": null,
             "kitchen_name": null,
             "size": null,
             "pos": null,
             "external_id": null,
             "metadata": {}
            }
           ],
           "daily_menu": {
            "date": "2027-01-15",
            "available_from": "11:00",
            "available_to": "15:00",
            "items": [
             {
              "product_id": "4567",
              "position": 1
             },
             {
              "product_id": "4568",
              "position": 2
             }
            ]
           },
           "allergens": [
            {
             "code": "1",
             "name": "Obiloviny obsahující lepek"
            },
            {
             "code": "3",
             "name": "Vejce"
            },
            {
             "code": "7",
             "name": "Mléko"
            },
            {
             "code": "9",
             "name": "Celer"
            }
           ]
          },
          "x-summary-cs": "Sortiment pro e-shop"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/availability": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Catalog"
    ],
    "operationId": "getAvailability",
    "summary": "Remaining portions",
    "x-summary-cs": "Zbývající porce",
    "description": "Products with a limited number of portions and how many are left now. Products not listed are not limited.\nChanges often, so it is separate from the catalog; reload it on `availability.changed`. Every add-on also uses\nup one portion of its own product. Applications of the restaurant staff see portions also when the restaurant\ntracks them only at its registers; guest applications only when it tracks them for the e-shop as well.\n",
    "x-description-cs": "Produkty s omezeným počtem porcí a kolik jich teď zbývá. Produkty, které tu nejsou, omezené nejsou. Mění se\nčasto, proto je oddělená od sortimentu; načtěte ji znovu při `availability.changed`. Každá příloha nebo\ndoplněk spotřebuje také jednu porci svého produktu. Aplikace personálu vidí porce i tehdy, když je provozovna\nhlídá jen na pokladnách; aplikace pro hosty jen tehdy, když je hlídá i pro e-shop.\n",
    "security": [
     {
      "oauth2": [
       "catalog:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "channel",
      "in": "query",
      "required": false,
      "description": "The catalog whose products are listed, as `channel` of `GET /catalog`.",
      "x-description-cs": "Katalog, jehož produkty se vypíšou, jako `channel` u `GET /catalog`.",
      "schema": {
       "type": "string",
       "enum": [
        "web",
        "kitchen",
        "pos"
       ],
       "default": "web"
      },
      "example": "web"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Current availability.",
      "x-description-cs": "Aktuální dostupnost.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Availability"
        },
        "examples": {
         "availability": {
          "summary": "Portions left",
          "value": {
           "restaurant_id": "123",
           "tracking": true,
           "generated_at": "2027-01-15T11:42:00+01:00",
           "items": [
            {
             "product_id": "4567",
             "remaining": 12,
             "sold_out": false
            },
            {
             "product_id": "4571",
             "remaining": 0,
             "sold_out": true
            }
           ]
          },
          "x-summary-cs": "Zbývající porce"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/availability/{product_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "product_id",
     "in": "path",
     "required": true,
     "description": "ID of a product of the restaurant's catalog (`Product.id`). Other IDs answer 404.",
     "x-description-cs": "ID produktu ze sortimentu provozovny (`Product.id`). Jiná ID vrátí 404.",
     "schema": {
      "$ref": "#/components/schemas/Id"
     },
     "example": "4567"
    }
   ],
   "put": {
    "tags": [
     "Catalog"
    ],
    "operationId": "setProductAvailability",
    "summary": "Set the remaining portions of a product",
    "x-summary-cs": "Nastavit zbývající porce produktu",
    "x-staff": "optional",
    "description": "Sets how many portions of a product are left, `0` marks it sold out and `null` removes the limit. The number goes\nwhere sales take portions from: today's daily menu when the product is in it with limited portions, otherwise\nthe restaurant's portions of the product – the same number as in the administration. `null` also removes the\nlimit from today's daily menu. It applies at once to the e-shop, the registers and applications, and an\n`availability.changed` event follows.\n\nStaff applications may change portions whenever the restaurant tracks them; guest applications only when it\ntracks them for the e-shop too, as `getAvailability` shows them. Otherwise `409 portion_tracking_disabled`.\nThe value is absolute: an order placed at the same moment can be overwritten, so send what you counted.\n",
    "x-description-cs": "Nastaví, kolik porcí produktu zbývá; `0` ho označí jako vyprodaný a `null` omezení zruší. Číslo se zapíše tam,\nodkud prodej porce bere: do dnešního denního menu, když v něm produkt je s omezenými porcemi, jinak do porcí\nproduktu v provozovně – stejné číslo jako v administraci. `null` zruší omezení i v dnešním denním menu. Platí\nhned pro e-shop, pokladny i aplikace a následuje událost `availability.changed`.\n\nAplikace personálu smí porce měnit, kdykoli je provozovna hlídá; aplikace hostů jen tehdy, když je hlídá i pro\ne-shop, tedy jak je ukazuje `getAvailability`. Jinak `409 portion_tracking_disabled`. Hodnota je absolutní:\nobjednávku ze stejného okamžiku může přepsat, proto posílejte, co jste napočítali.\n",
    "security": [
     {
      "oauth2": [
       "availability:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ProductAvailabilityInput"
       },
       "examples": {
        "sold_out": {
         "summary": "Sold out",
         "value": {
          "remaining": 0
         },
         "x-summary-cs": "Vyprodáno"
        },
        "left": {
         "summary": "12 portions left",
         "value": {
          "remaining": 12
         },
         "x-summary-cs": "Zbývá 12 porcí"
        },
        "unlimited": {
         "summary": "No limit",
         "value": {
          "remaining": null
         },
         "x-summary-cs": "Bez omezení"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The availability of the product after the change.",
      "x-description-cs": "Dostupnost produktu po změně.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductAvailability"
        },
        "examples": {
         "sold_out": {
          "summary": "A sold-out product",
          "value": {
           "product_id": "4567",
           "remaining": 0,
           "sold_out": true,
           "source": "restaurant"
          },
          "x-summary-cs": "Vyprodaný produkt"
         },
         "menu": {
          "summary": "Portions in today's daily menu",
          "value": {
           "product_id": "4567",
           "remaining": 12,
           "sold_out": false,
           "source": "daily_menu"
          },
          "x-summary-cs": "Porce v dnešním denním menu"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "portion_tracking_disabled": {
          "summary": "The restaurant does not track portions",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#portion_tracking_disabled",
           "title": "Provozovna pro vás porce nehlídá",
           "status": 409,
           "code": "portion_tracking_disabled",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Provozovna porce nehlídá"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/promotions": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Catalog"
    ],
    "operationId": "listPromotions",
    "summary": "Promotions and promo codes",
    "x-summary-cs": "Akce a slevové kódy",
    "description": "Promotions of the restaurant valid at `at` for orders from guest applications – to show them to customers\n(for example \"Free delivery over CZK 500\"). The restaurant sets them up in the administration. A promotion\nwithout a code applies by itself in the quote; for one with `requires_code` the customer enters the code and you\nsend it in `QuoteRequest.promo_codes`. The code itself is never returned. The quote always decides which\npromotions apply and how much they give (`Quote.discounts`); a promotion that has run out (`uses_left` 0) is not\nlisted. Reload the list on `promotions.changed`; send `If-None-Match`, then an unchanged list costs almost\nnothing.\n\nA promotion applies by the moment the order is sent – when you create the quote – not by the time of delivery\nor pickup: an order for the evening sent at noon gets the promotions of noon. The list contains promotions\nwhose validity (`valid_from`, `valid_until`) covers `at`; the days and the times of day (happy hour) are in\n`conditions.days` and `conditions.time_windows` – show them to the customer. Promotions for registered\ncustomers and loyalty cards apply only with a linked customer with a verified phone (see `Promotion`).\n",
    "x-description-cs": "Akce provozovny platné v okamžiku `at` pro objednávky z aplikací hostů – abyste je mohli ukázat zákazníkům\n(třeba „Doprava zdarma nad 500 Kč“). Nastavuje je provozovna v administraci. Akce bez kódu se v kalkulaci\nuplatní sama; u akce s `requires_code` zákazník zadá kód a vy ho pošlete v `QuoteRequest.promo_codes`. Kód\nsamotný se nikdy nevrací. Které akce se uplatní a kolik dají, rozhoduje vždy kalkulace (`Quote.discounts`);\nvyčerpaná akce (`uses_left` 0) v seznamu není. Seznam načtěte znovu při `promotions.changed`; posílejte\n`If-None-Match`, pak nezměněný seznam nestojí skoro nic.\n\nAkce platí podle okamžiku odeslání objednávky – když vytváříte kalkulaci –, ne podle času doručení nebo odběru:\nobjednávka na večer odeslaná v poledne dostane akce z poledne. V seznamu jsou akce, jejichž platnost\n(`valid_from`, `valid_until`) zahrnuje `at`; dny a denní doba (happy hour) jsou v `conditions.days`\na `conditions.time_windows` – ukažte je zákazníkovi. Akce pro registrované zákazníky a věrnostní karty platí\njen s propojeným zákazníkem s ověřeným telefonem (viz `Promotion`).\n",
    "security": [
     {
      "oauth2": [
       "catalog:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "at",
      "in": "query",
      "required": false,
      "description": "Moment the list is for – it filters only the validity (`valid_from`, `valid_until`), not the days and the\ntimes of day. Default now, which is also what the quote uses: the moment the order is sent.\n",
      "x-description-cs": "Okamžik, pro který seznam platí – filtruje jen platnost (`valid_from`, `valid_until`), ne dny a denní dobu.\nVýchozí je teď, a to bere i kalkulace: okamžik odeslání objednávky.\n",
      "schema": {
       "$ref": "#/components/schemas/Timestamp"
      }
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The promotions.",
      "x-description-cs": "Akce.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PromotionList"
        },
        "examples": {
         "promotions": {
          "summary": "Promotions of the restaurant",
          "value": {
           "restaurant_id": "123",
           "at": "2027-01-15T11:40:00+01:00",
           "promotions": [
            {
             "id": "31",
             "name": "Doprava zdarma nad 500 Kč",
             "description": "Při objednávce rozvozu od 500 Kč vezeme zdarma.",
             "requires_code": false,
             "code_type": null,
             "effect": {
              "type": "free_delivery",
              "percent": null,
              "amount": null,
              "max_discount": null,
              "nth_item": null,
              "gift": null,
              "bundle": null
             },
             "conditions": {
              "min_order": {
               "amount": 50000,
               "currency": "CZK"
              },
              "min_items": null,
              "scope": null,
              "fulfillment": "delivery",
              "valid_from": null,
              "valid_until": null,
              "days": [
               1,
               2,
               3,
               4,
               5,
               6,
               7
              ],
              "time_windows": [],
              "customer": "any",
              "max_per_customer": null,
              "uses_left": null
             },
             "combinable": true
            },
            {
             "id": "32",
             "name": "Podzimní sleva 10 %",
             "description": "Kód z podzimního letáku, platí do konce listopadu.",
             "requires_code": true,
             "code_type": "shared",
             "effect": {
              "type": "percent",
              "percent": 10,
              "amount": null,
              "max_discount": {
               "amount": 10000,
               "currency": "CZK"
              },
              "nth_item": null,
              "gift": null,
              "bundle": null
             },
             "conditions": {
              "min_order": {
               "amount": 30000,
               "currency": "CZK"
              },
              "min_items": null,
              "scope": null,
              "fulfillment": "any",
              "valid_from": "2026-10-01T00:00:00+02:00",
              "valid_until": "2027-12-01T00:00:00+01:00",
              "days": [
               1,
               2,
               3,
               4,
               5,
               6,
               7
              ],
              "time_windows": [],
              "customer": "any",
              "max_per_customer": null,
              "uses_left": 488
             },
             "combinable": true
            },
            {
             "id": "33",
             "name": "Věrnostní karta: každá 7. pizza zdarma",
             "description": "Pro registrované zákazníky – pizzy se sčítají i z dřívějších objednávek.",
             "requires_code": false,
             "code_type": null,
             "effect": {
              "type": "nth_item",
              "percent": null,
              "amount": null,
              "max_discount": null,
              "nth_item": {
               "every": 7,
               "percent": 100,
               "loyalty": true
              },
              "gift": null,
              "bundle": null
             },
             "conditions": {
              "min_order": null,
              "min_items": null,
              "scope": {
               "category_ids": [
                "315"
               ],
               "product_ids": [],
               "exclude_product_ids": []
              },
              "fulfillment": "any",
              "valid_from": "2026-11-01T00:00:00+01:00",
              "valid_until": null,
              "days": [
               1,
               2,
               3,
               4,
               5,
               6,
               7
              ],
              "time_windows": [],
              "customer": "registered",
              "max_per_customer": null,
              "uses_left": null
             },
             "combinable": true
            },
            {
             "id": "34",
             "name": "Limonáda zdarma k polednímu odběru",
             "description": "Pátek až neděle 11–14 h: k osobnímu odběru od 400 Kč domácí limonáda zdarma.",
             "requires_code": false,
             "code_type": null,
             "effect": {
              "type": "gift",
              "percent": null,
              "amount": null,
              "max_discount": null,
              "nth_item": null,
              "gift": {
               "product_id": "4593",
               "name": "Domácí limonáda 0,4 l"
              },
              "bundle": null
             },
             "conditions": {
              "min_order": {
               "amount": 40000,
               "currency": "CZK"
              },
              "min_items": null,
              "scope": null,
              "fulfillment": "pickup",
              "valid_from": null,
              "valid_until": null,
              "days": [
               5,
               6,
               7
              ],
              "time_windows": [
               {
                "from": "11:00",
                "to": "14:00"
               }
              ],
              "customer": "any",
              "max_per_customer": null,
              "uses_left": null
             },
             "combinable": true
            },
            {
             "id": "35",
             "name": "100 Kč na první objednávku",
             "description": "Jednorázový kód z letáku do schránky, jen na první objednávku.",
             "requires_code": true,
             "code_type": "single_use",
             "effect": {
              "type": "amount",
              "percent": null,
              "amount": {
               "amount": 10000,
               "currency": "CZK"
              },
              "max_discount": null,
              "nth_item": null,
              "gift": null,
              "bundle": null
             },
             "conditions": {
              "min_order": {
               "amount": 40000,
               "currency": "CZK"
              },
              "min_items": null,
              "scope": null,
              "fulfillment": "any",
              "valid_from": null,
              "valid_until": "2027-03-01T00:00:00+01:00",
              "days": [
               1,
               2,
               3,
               4,
               5,
               6,
               7
              ],
              "time_windows": [],
              "customer": "first_order",
              "max_per_customer": 1,
              "uses_left": 812
             },
             "combinable": false
            },
            {
             "id": "36",
             "name": "Víkendové menu: pizza a limonáda za 219 Kč",
             "description": "Sobota a neděle: libovolná pizza a domácí limonáda.",
             "requires_code": false,
             "code_type": null,
             "effect": {
              "type": "bundle",
              "percent": null,
              "amount": null,
              "max_discount": null,
              "nth_item": null,
              "gift": null,
              "bundle": {
               "price": {
                "amount": 21900,
                "currency": "CZK"
               },
               "groups": [
                {
                 "category_ids": [
                  "315"
                 ],
                 "product_ids": []
                },
                {
                 "category_ids": [],
                 "product_ids": [
                  "4593"
                 ]
                }
               ]
              }
             },
             "conditions": {
              "min_order": null,
              "min_items": null,
              "scope": null,
              "fulfillment": "any",
              "valid_from": null,
              "valid_until": null,
              "days": [
               6,
               7
              ],
              "time_windows": [],
              "customer": "any",
              "max_per_customer": null,
              "uses_left": null
             },
             "combinable": false
            }
           ]
          },
          "x-summary-cs": "Akce provozovny"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/daily-menu": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Catalog"
    ],
    "operationId": "getDailyMenu",
    "summary": "Daily menu of a week",
    "x-summary-cs": "Denní menu na týden",
    "description": "The daily menu of one week as the restaurant set it in the administration – for example for the restaurant's\nwebsite. For every day it is served you get its items with the menu prices; the items, prices, allergens and\nvisibility are the same as in the catalog of that day during the menu time (`GET …/catalog?at=`). Days without\na menu are left out, `enabled: false` means no menu that week. `every_day` marks items of the offer for the\nwhole week. The licence is not checked here: the menu is returned also when the restaurant's licence does not\ninclude the daily menu (`DeviceSettings.features.daily_menu`), the same way as the daily menu in the catalog.\n",
    "x-description-cs": "Denní menu jednoho týdne, jak ho provozovna nastavila v administraci – třeba pro web restaurace. Pro každý den,\nkdy se podává, dostanete jeho položky s cenami menu; položky, ceny, alergeny i viditelnost jsou stejné jako\nv sortimentu toho dne v čase menu (`GET …/catalog?at=`). Dny bez menu chybí, `enabled: false` znamená, že ten\ntýden menu není. `every_day` označuje položky nabídky na celý týden. Licence se tu nekontroluje: menu se vrátí,\ni když licence provozovny denní menu neobsahuje (`DeviceSettings.features.daily_menu`), stejně jako denní menu\nv sortimentu.\n",
    "security": [
     {
      "oauth2": [
       "catalog:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "week",
      "in": "query",
      "required": false,
      "description": "ISO week, for example `2026-W41`, of this, the last or the next year. Default the current week of the restaurant.",
      "x-description-cs": "Týden ISO, například `2026-W41`, letos, loni nebo příští rok. Výchozí je aktuální týden provozovny.",
      "schema": {
       "type": "string",
       "pattern": "^[0-9]{4}-W[0-9]{2}$"
      },
      "example": "2027-W02"
     },
     {
      "name": "channel",
      "in": "query",
      "required": false,
      "description": "The catalog the items come from, as `channel` of `GET /catalog`.",
      "x-description-cs": "Sortiment, ze kterého položky jsou, jako `channel` u `GET /catalog`.",
      "schema": {
       "type": "string",
       "enum": [
        "web",
        "kitchen",
        "pos"
       ],
       "default": "web"
      },
      "example": "web"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The daily menu of the week.",
      "x-description-cs": "Denní menu týdne.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DailyMenuWeek"
        },
        "examples": {
         "week": {
          "summary": "The daily menu for a week",
          "value": {
           "restaurant_id": "123",
           "week": "2027-W02",
           "enabled": true,
           "available_from": "11:00",
           "available_to": "15:00",
           "days": [
            {
             "date": "2027-01-11",
             "items": [
              {
               "product_id": "4700",
               "name": "Polévka dne – česnečka",
               "description": null,
               "price": {
                "amount": 4500,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "7"
               ],
               "image_url": null,
               "every_day": true
              },
              {
               "product_id": "4710",
               "name": "Kuřecí řízek, bramborový salát",
               "description": null,
               "price": {
                "amount": 16900,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "3",
                "7"
               ],
               "image_url": null,
               "every_day": false
              }
             ]
            },
            {
             "date": "2027-01-12",
             "items": [
              {
               "product_id": "4700",
               "name": "Polévka dne – česnečka",
               "description": null,
               "price": {
                "amount": 4500,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "7"
               ],
               "image_url": null,
               "every_day": true
              },
              {
               "product_id": "4711",
               "name": "Hovězí guláš, houskový knedlík",
               "description": null,
               "price": {
                "amount": 16900,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "3",
                "9"
               ],
               "image_url": null,
               "every_day": false
              }
             ]
            },
            {
             "date": "2027-01-13",
             "items": [
              {
               "product_id": "4700",
               "name": "Polévka dne – česnečka",
               "description": null,
               "price": {
                "amount": 4500,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "7"
               ],
               "image_url": null,
               "every_day": true
              },
              {
               "product_id": "4712",
               "name": "Smažený květák, vařené brambory",
               "description": null,
               "price": {
                "amount": 16900,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "3",
                "7"
               ],
               "image_url": null,
               "every_day": false
              }
             ]
            },
            {
             "date": "2027-01-14",
             "items": [
              {
               "product_id": "4700",
               "name": "Polévka dne – česnečka",
               "description": null,
               "price": {
                "amount": 4500,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "7"
               ],
               "image_url": null,
               "every_day": true
              },
              {
               "product_id": "4713",
               "name": "Vepřo knedlo zelo",
               "description": null,
               "price": {
                "amount": 16900,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "3"
               ],
               "image_url": null,
               "every_day": false
              }
             ]
            },
            {
             "date": "2027-01-15",
             "items": [
              {
               "product_id": "4700",
               "name": "Polévka dne – česnečka",
               "description": null,
               "price": {
                "amount": 4500,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "7"
               ],
               "image_url": null,
               "every_day": true
              },
              {
               "product_id": "4714",
               "name": "Svíčková na smetaně, houskový knedlík",
               "description": null,
               "price": {
                "amount": 16900,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "allergens": [
                "1",
                "3",
                "7",
                "9"
               ],
               "image_url": null,
               "every_day": false
              }
             ]
            }
           ]
          },
          "x-summary-cs": "Denní menu na týden"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/quotes": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Orders"
    ],
    "operationId": "createQuote",
    "summary": "Price a basket",
    "x-summary-cs": "Spočítat košík",
    "description": "Profirest prices the basket with the prices valid at the order time, finds the delivery zone, adds the delivery\nfee, the top-up to the zone's minimum order and express delivery when asked (`fulfillment.speed`), applies\npromotions of the restaurant and a promo code (`discounts`), applies vouchers and checks the time. The prices\nare guaranteed until `expires_at` (15 minutes). Nothing is reserved yet: portions and vouchers are reserved\nwhen you create the order.\n",
    "x-description-cs": "Profirest spočítá košík s cenami platnými v čase objednávky, najde rozvozovou zónu, přidá cenu dopravy,\ndoplatek do minimální objednávky zóny a na přání expresní doručení (`fulfillment.speed`), uplatní akce\nprovozovny a slevový kód (`discounts`), vouchery a ověří čas. Ceny jsou zaručené do `expires_at`\n(15 minut). Zatím se nic nerezervuje: porce a vouchery se rezervují při vytvoření objednávky.\n",
    "security": [
     {
      "oauth2": [
       "orders:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/QuoteRequest"
       },
       "examples": {
        "pickup": {
         "summary": "Pickup as soon as possible",
         "value": {
          "fulfillment": {
           "type": "pickup"
          },
          "items": [
           {
            "product_id": "4567",
            "quantity": 2
           }
          ]
         },
         "x-summary-cs": "Vyzvednutí co nejdřív"
        },
        "delivery": {
         "summary": "Delivery with an add-on, a note and a voucher",
         "value": {
          "fulfillment": {
           "type": "delivery",
           "time": null
          },
          "delivery_address": {
           "street": "Jeseniova",
           "house_number": "1196/52",
           "city": "Praha 3",
           "postal_code": "130 00",
           "country": "CZ",
           "note": "3. patro, zvonek Nováková",
           "location": {
            "lat": 50.0833,
            "lon": 14.4667
           }
          },
          "items": [
           {
            "product_id": "4571",
            "quantity": 1,
            "add_ons": [
             {
              "product_id": "4602"
             }
            ],
            "note": "Nekrájet"
           },
           {
            "product_id": "4593",
            "quantity": 2
           }
          ],
          "customer_id": "90321",
          "vouchers": [
           {
            "code": "KX7-9QD"
           }
          ]
         },
         "x-summary-cs": "Rozvoz s přílohou, poznámkou a voucherem"
        },
        "promo": {
         "summary": "Delivery with a promo code and free delivery",
         "value": {
          "fulfillment": {
           "type": "delivery",
           "time": null
          },
          "delivery_address": {
           "street": "Jeseniova",
           "house_number": "1196/52",
           "city": "Praha 3",
           "postal_code": "130 00",
           "country": "CZ",
           "note": "3. patro, zvonek Nováková",
           "location": {
            "lat": 50.0833,
            "lon": 14.4667
           }
          },
          "items": [
           {
            "product_id": "4567",
            "quantity": 3
           }
          ],
          "customer_id": "90321",
          "promo_codes": [
           {
            "code": "PODZIM10"
           }
          ],
          "end_user_id": "eshop-zakaznik-881"
         },
         "x-summary-cs": "Rozvoz se slevovým kódem a dopravou zdarma"
        },
        "loyalty": {
         "summary": "A loyalty card and a gift for a verified customer",
         "value": {
          "fulfillment": {
           "type": "pickup"
          },
          "items": [
           {
            "product_id": "4571",
            "quantity": 2
           },
           {
            "product_id": "4590",
            "quantity": 2
           }
          ],
          "customer_id": "90321",
          "end_user_id": "eshop-zakaznik-881"
         },
         "x-summary-cs": "Věrnostní karta a dárek ověřené zákaznici"
        },
        "express": {
         "summary": "Express delivery for the zone's surcharge",
         "value": {
          "fulfillment": {
           "type": "delivery",
           "speed": "express"
          },
          "delivery_address": {
           "street": "Jeseniova",
           "house_number": "1196/52",
           "city": "Praha 3",
           "postal_code": "130 00",
           "country": "CZ",
           "note": "3. patro, zvonek Nováková",
           "location": {
            "lat": 50.0833,
            "lon": 14.4667
           }
          },
          "items": [
           {
            "product_id": "4571",
            "quantity": 1,
            "add_ons": [
             {
              "product_id": "4602"
             }
            ],
            "note": "Nekrájet"
           },
           {
            "product_id": "4593",
            "quantity": 2
           }
          ],
          "customer_id": "90321"
         },
         "x-summary-cs": "Expresní doručení za příplatek zóny"
        },
        "pizza": {
         "summary": "A pizza from halves (½ Margherita without basil) and a custom pizza",
         "value": {
          "fulfillment": {
           "type": "pickup"
          },
          "items": [
           {
            "type": "split",
            "quantity": 1,
            "parts": [
             {
              "product_id": "4571",
              "removed_ingredient_ids": [
               "9001"
              ]
             },
             {
              "product_id": "4575",
              "add_ons": [
               {
                "product_id": "4602"
               }
              ]
             }
            ]
           },
           {
            "product_id": "4590",
            "quantity": 1,
            "options": [
             {
              "option_id": "1002"
             },
             {
              "option_id": "1101",
              "quantity": 2
             },
             {
              "option_id": "1102",
              "quantity": 2
             },
             {
              "option_id": "1103"
             },
             {
              "option_id": "1104"
             }
            ]
           }
          ]
         },
         "x-summary-cs": "Pizza z půlek (½ Margherita bez bazalky) a vlastní pizza"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The quote.",
      "x-description-cs": "Kalkulace.",
      "headers": {
       "Location": {
        "$ref": "#/components/headers/Location"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Quote"
        },
        "examples": {
         "pickup": {
          "summary": "A pickup quote",
          "value": {
           "id": "58213",
           "restaurant_id": "123",
           "created_at": "2027-01-15T11:42:10+01:00",
           "expires_at": "2027-01-15T11:57:10+01:00",
           "customer_id": null,
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:05:00+01:00"
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 2,
             "base_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 39800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [],
           "amount_due": {
            "amount": 39800,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Nabídka k vyzvednutí"
         },
         "pizza": {
          "summary": "A pizza from halves and a custom pizza",
          "value": {
           "id": "58213",
           "restaurant_id": "123",
           "created_at": "2027-01-15T11:42:10+01:00",
           "expires_at": "2027-01-15T11:57:10+01:00",
           "customer_id": null,
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:05:00+01:00"
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "split",
             "variant": "full",
             "product_id": null,
             "name": "½ Pizza Margherita + ½ Pizza Hawaii",
             "quantity": 1,
             "base_unit_price": {
              "amount": 27300,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 27300,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": [
              {
               "position": 1,
               "fraction": "1/2",
               "product_id": "4571",
               "name": "Pizza Margherita",
               "unit_price": {
                "amount": 13300,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "add_ons": [],
               "removed_ingredients": [
                {
                 "id": "9001",
                 "name": "bazalka"
                }
               ]
              },
              {
               "position": 2,
               "fraction": "1/2",
               "product_id": "4575",
               "name": "Pizza Hawaii",
               "unit_price": {
                "amount": 14000,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "add_ons": [
                {
                 "product_id": "4602",
                 "name": "Extra sýr",
                 "quantity": 1,
                 "unit_price": {
                  "amount": 3000,
                  "currency": "CZK"
                 },
                 "vat_rate": "12"
                }
               ],
               "removed_ingredients": []
              }
             ],
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 30300,
              "currency": "CZK"
             },
             "gift_of": null
            },
            {
             "id": "2",
             "type": "product",
             "variant": "full",
             "product_id": "4590",
             "name": "Vlastní pizza Ø32cm",
             "quantity": 1,
             "base_unit_price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 20900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [
              {
               "option_id": "1002",
               "group_id": "71",
               "group_name": "Těsto",
               "product_id": "4592",
               "name": "Celozrnné těsto",
               "quantity": 1,
               "included_quantity": 0,
               "charged_quantity": 1,
               "list_unit_price": {
                "amount": 2000,
                "currency": "CZK"
               },
               "unit_price": {
                "amount": 2000,
                "currency": "CZK"
               },
               "total": {
                "amount": 2000,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "reason": null
              },
              {
               "option_id": "1101",
               "group_id": "72",
               "group_name": "Ingredience",
               "product_id": "4605",
               "name": "Šunka",
               "quantity": 2,
               "included_quantity": 1,
               "charged_quantity": 1,
               "list_unit_price": {
                "amount": 2400,
                "currency": "CZK"
               },
               "unit_price": {
                "amount": 2400,
                "currency": "CZK"
               },
               "total": {
                "amount": 2400,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "reason": "partly_included"
              },
              {
               "option_id": "1102",
               "group_id": "72",
               "group_name": "Ingredience",
               "product_id": "4603",
               "name": "Žampiony",
               "quantity": 2,
               "included_quantity": 2,
               "charged_quantity": 0,
               "list_unit_price": {
                "amount": 1900,
                "currency": "CZK"
               },
               "unit_price": {
                "amount": 1900,
                "currency": "CZK"
               },
               "total": {
                "amount": 0,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "reason": "included"
              },
              {
               "option_id": "1103",
               "group_id": "72",
               "group_name": "Ingredience",
               "product_id": "4604",
               "name": "Krevety",
               "quantity": 1,
               "included_quantity": 0,
               "charged_quantity": 1,
               "list_unit_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "unit_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "total": {
                "amount": 0,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "reason": "in_base_price"
              },
              {
               "option_id": "1104",
               "group_id": "72",
               "group_name": "Ingredience",
               "product_id": "4606",
               "name": "Olivy",
               "quantity": 1,
               "included_quantity": 1,
               "charged_quantity": 0,
               "list_unit_price": {
                "amount": 1500,
                "currency": "CZK"
               },
               "unit_price": {
                "amount": 1500,
                "currency": "CZK"
               },
               "total": {
                "amount": 0,
                "currency": "CZK"
               },
               "vat_rate": "12",
               "reason": "included"
              }
             ],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 25300,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 55600,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 55600,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 49643,
               "currency": "CZK"
              },
              "vat": {
               "amount": 5957,
               "currency": "CZK"
              },
              "total": {
               "amount": 55600,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [],
           "amount_due": {
            "amount": 55600,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Pizza z půlek a vlastní pizza"
         },
         "delivery": {
          "summary": "A delivery quote with a voucher",
          "value": {
           "id": "58214",
           "restaurant_id": "123",
           "created_at": "2027-01-15T11:50:02+01:00",
           "expires_at": "2027-01-15T12:05:02+01:00",
           "customer_id": "90321",
           "fulfillment": {
            "type": "delivery",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:35:00+01:00"
           },
           "delivery": {
            "zone": {
             "id": "21",
             "name": "Vinohrady do 3 km"
            },
            "address": {
             "street": "Jeseniova",
             "house_number": "1196/52",
             "city": "Praha 3",
             "postal_code": "130 00",
             "country": "CZ",
             "note": "3. patro, zvonek Nováková",
             "formatted": "Jeseniova 1196/52, 130 00 Praha 3"
            },
            "location": {
             "lat": 50.0833,
             "lon": 14.4667
            },
            "fee": {
             "amount": 4900,
             "currency": "CZK"
            },
            "minimum_order": {
             "amount": 25000,
             "currency": "CZK"
            },
            "express_fee": {
             "amount": 4000,
             "currency": "CZK"
            }
           },
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4571",
             "name": "Pizza Margherita",
             "quantity": 1,
             "base_unit_price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [
              {
               "product_id": "4602",
               "name": "Extra sýr",
               "quantity": 1,
               "unit_price": {
                "amount": 3000,
                "currency": "CZK"
               },
               "vat_rate": "12"
              }
             ],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": "Nekrájet",
             "total": {
              "amount": 21900,
              "currency": "CZK"
             },
             "gift_of": null
            },
            {
             "id": "2",
             "type": "product",
             "variant": "full",
             "product_id": "4593",
             "name": "Domácí limonáda 0,4 l",
             "quantity": 2,
             "base_unit_price": {
              "amount": 5900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 5900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 11800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [
            {
             "type": "delivery_fee",
             "name": "Doprava",
             "amount": {
              "amount": 4900,
              "currency": "CZK"
             },
             "vat": [
              {
               "rate": "12",
               "base": {
                "amount": 4375,
                "currency": "CZK"
               },
               "vat": {
                "amount": 525,
                "currency": "CZK"
               },
               "total": {
                "amount": 4900,
                "currency": "CZK"
               }
              }
             ]
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 4900,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 38600,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 34464,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4136,
               "currency": "CZK"
              },
              "total": {
               "amount": 38600,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "1",
             "method": "voucher",
             "status": "pending",
             "amount": {
              "amount": 10000,
              "currency": "CZK"
             },
             "provider": null,
             "reference": null,
             "voucher_code": "KX7-***",
             "forfeited": null
            }
           ],
           "amount_due": {
            "amount": 28600,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Nabídka s rozvozem a voucherem"
         },
         "promo": {
          "summary": "A quote with a promo code discount and free delivery",
          "value": {
           "id": "58215",
           "restaurant_id": "123",
           "created_at": "2027-01-15T11:52:30+01:00",
           "expires_at": "2027-01-15T12:07:30+01:00",
           "customer_id": "90321",
           "fulfillment": {
            "type": "delivery",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:40:00+01:00"
           },
           "delivery": {
            "zone": {
             "id": "21",
             "name": "Vinohrady do 3 km"
            },
            "address": {
             "street": "Jeseniova",
             "house_number": "1196/52",
             "city": "Praha 3",
             "postal_code": "130 00",
             "country": "CZ",
             "note": "3. patro, zvonek Nováková",
             "formatted": "Jeseniova 1196/52, 130 00 Praha 3"
            },
            "location": {
             "lat": 50.0833,
             "lon": 14.4667
            },
            "fee": {
             "amount": 4900,
             "currency": "CZK"
            },
            "minimum_order": {
             "amount": 25000,
             "currency": "CZK"
            },
            "express_fee": {
             "amount": 4000,
             "currency": "CZK"
            }
           },
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 3,
             "base_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 59700,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [
            {
             "type": "delivery_fee",
             "name": "Doprava",
             "amount": {
              "amount": 4900,
              "currency": "CZK"
             },
             "vat": [
              {
               "rate": "12",
               "base": {
                "amount": 4375,
                "currency": "CZK"
               },
               "vat": {
                "amount": 525,
                "currency": "CZK"
               },
               "total": {
                "amount": 4900,
                "currency": "CZK"
               }
              }
             ]
            }
           ],
           "discounts": [
            {
             "type": "restaurant",
             "name": "Podzimní sleva 10 %",
             "amount": {
              "amount": -5970,
              "currency": "CZK"
             },
             "vat": [
              {
               "rate": "12",
               "base": {
                "amount": -5330,
                "currency": "CZK"
               },
               "vat": {
                "amount": -640,
                "currency": "CZK"
               },
               "total": {
                "amount": -5970,
                "currency": "CZK"
               }
              }
             ],
             "promotion": {
              "id": "32",
              "name": "Podzimní sleva 10 %",
              "code": "POD***"
             },
             "applies_to": "order",
             "line_id": null
            },
            {
             "type": "restaurant",
             "name": "Doprava zdarma nad 500 Kč",
             "amount": {
              "amount": -4900,
              "currency": "CZK"
             },
             "vat": [
              {
               "rate": "12",
               "base": {
                "amount": -4375,
                "currency": "CZK"
               },
               "vat": {
                "amount": -525,
                "currency": "CZK"
               },
               "total": {
                "amount": -4900,
                "currency": "CZK"
               }
              }
             ],
             "promotion": {
              "id": "31",
              "name": "Doprava zdarma nad 500 Kč",
              "code": null
             },
             "applies_to": "delivery_fee",
             "line_id": null
            }
           ],
           "totals": {
            "items": {
             "amount": 59700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 4900,
             "currency": "CZK"
            },
            "discounts": {
             "amount": -10870,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 53730,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 47973,
               "currency": "CZK"
              },
              "vat": {
               "amount": 5757,
               "currency": "CZK"
              },
              "total": {
               "amount": 53730,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [],
           "amount_due": {
            "amount": 53730,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Nabídka se slevou z kódu a dopravou zdarma"
         },
         "loyalty": {
          "summary": "A quote with a line discount (loyalty card) and a gift",
          "value": {
           "id": "58217",
           "restaurant_id": "123",
           "created_at": "2027-01-15T12:10:15+01:00",
           "expires_at": "2027-01-15T12:25:15+01:00",
           "customer_id": "90321",
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:35:00+01:00"
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4571",
             "name": "Pizza Margherita",
             "quantity": 2,
             "base_unit_price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 37800,
              "currency": "CZK"
             },
             "gift_of": null
            },
            {
             "id": "2",
             "type": "product",
             "variant": "full",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "quantity": 2,
             "base_unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "21",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             },
             "gift_of": null
            },
            {
             "id": "3",
             "type": "product",
             "variant": "full",
             "product_id": "4593",
             "name": "Domácí limonáda 0,4 l",
             "quantity": 1,
             "base_unit_price": {
              "amount": 5900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 5900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 5900,
              "currency": "CZK"
             },
             "gift_of": "34"
            }
           ],
           "charges": [],
           "discounts": [
            {
             "type": "restaurant",
             "name": "Věrnostní karta: každá 7. pizza zdarma",
             "amount": {
              "amount": -18900,
              "currency": "CZK"
             },
             "vat": [
              {
               "rate": "12",
               "base": {
                "amount": -16875,
                "currency": "CZK"
               },
               "vat": {
                "amount": -2025,
                "currency": "CZK"
               },
               "total": {
                "amount": -18900,
                "currency": "CZK"
               }
              }
             ],
             "promotion": {
              "id": "33",
              "name": "Věrnostní karta: každá 7. pizza zdarma",
              "code": null
             },
             "applies_to": "line",
             "line_id": "1"
            },
            {
             "type": "restaurant",
             "name": "Limonáda zdarma k polednímu odběru",
             "amount": {
              "amount": -5900,
              "currency": "CZK"
             },
             "vat": [
              {
               "rate": "12",
               "base": {
                "amount": -5268,
                "currency": "CZK"
               },
               "vat": {
                "amount": -632,
                "currency": "CZK"
               },
               "total": {
                "amount": -5900,
                "currency": "CZK"
               }
              }
             ],
             "promotion": {
              "id": "34",
              "name": "Limonáda zdarma k polednímu odběru",
              "code": null
             },
             "applies_to": "line",
             "line_id": "3"
            }
           ],
           "totals": {
            "items": {
             "amount": 57500,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": -24800,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 32700,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": 11405,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2395,
               "currency": "CZK"
              },
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": 16875,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2025,
               "currency": "CZK"
              },
              "total": {
               "amount": 18900,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [],
           "amount_due": {
            "amount": 32700,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Nabídka se slevou na řádek (věrnostní karta) a dárkem"
         },
         "express": {
          "summary": "A quote with express delivery",
          "value": {
           "id": "58216",
           "restaurant_id": "123",
           "created_at": "2027-01-15T11:53:05+01:00",
           "expires_at": "2027-01-15T12:08:05+01:00",
           "customer_id": "90321",
           "fulfillment": {
            "type": "delivery",
            "speed": "express",
            "asap": true,
            "time": null,
            "estimated_at": null
           },
           "delivery": {
            "zone": {
             "id": "21",
             "name": "Vinohrady do 3 km"
            },
            "address": {
             "street": "Jeseniova",
             "house_number": "1196/52",
             "city": "Praha 3",
             "postal_code": "130 00",
             "country": "CZ",
             "note": "3. patro, zvonek Nováková",
             "formatted": "Jeseniova 1196/52, 130 00 Praha 3"
            },
            "location": {
             "lat": 50.0833,
             "lon": 14.4667
            },
            "fee": {
             "amount": 4900,
             "currency": "CZK"
            },
            "minimum_order": {
             "amount": 25000,
             "currency": "CZK"
            },
            "express_fee": {
             "amount": 4000,
             "currency": "CZK"
            }
           },
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4571",
             "name": "Pizza Margherita",
             "quantity": 1,
             "base_unit_price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [
              {
               "product_id": "4602",
               "name": "Extra sýr",
               "quantity": 1,
               "unit_price": {
                "amount": 3000,
                "currency": "CZK"
               },
               "vat_rate": "12"
              }
             ],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": "Nekrájet",
             "total": {
              "amount": 21900,
              "currency": "CZK"
             },
             "gift_of": null
            },
            {
             "id": "2",
             "type": "product",
             "variant": "full",
             "product_id": "4593",
             "name": "Domácí limonáda 0,4 l",
             "quantity": 2,
             "base_unit_price": {
              "amount": 5900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 5900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 11800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [
            {
             "type": "delivery_fee",
             "name": "Doprava",
             "amount": {
              "amount": 4900,
              "currency": "CZK"
             },
             "vat": [
              {
               "rate": "12",
               "base": {
                "amount": 4375,
                "currency": "CZK"
               },
               "vat": {
                "amount": 525,
                "currency": "CZK"
               },
               "total": {
                "amount": 4900,
                "currency": "CZK"
               }
              }
             ]
            },
            {
             "type": "express_delivery",
             "name": "Expresní doručení",
             "amount": {
              "amount": 4000,
              "currency": "CZK"
             },
             "vat": [
              {
               "rate": "12",
               "base": {
                "amount": 3571,
                "currency": "CZK"
               },
               "vat": {
                "amount": 429,
                "currency": "CZK"
               },
               "total": {
                "amount": 4000,
                "currency": "CZK"
               }
              }
             ]
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 8900,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 42600,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 38036,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4564,
               "currency": "CZK"
              },
              "total": {
               "amount": 42600,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [],
           "amount_due": {
            "amount": 42600,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Nabídka s expresním doručením"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Too few options in a group",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/1/options",
             "code": "option_group_min",
             "message": "Ve skupině „Těsto“ vyberte aspoň 1 (vybráno 0)."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Málo voleb ve skupině"
         },
         "product_unavailable": {
          "summary": "A product is sold out",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#product_unavailable",
           "title": "Produkt je vyprodaný nebo se nenabízí",
           "status": 422,
           "code": "product_unavailable",
           "detail": "Pizza Margherita je vyprodaná.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/product_id",
             "code": "product_unavailable",
             "message": "Produkt teď nejde objednat."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Produkt došel"
         },
         "outside_delivery_zone": {
          "summary": "The address is outside delivery",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#outside_delivery_zone",
           "title": "Adresa je mimo rozvozové zóny",
           "status": 422,
           "code": "outside_delivery_zone",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Adresa mimo rozvoz"
         },
         "express_unavailable": {
          "summary": "No express delivery to the zone",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#express_unavailable",
           "title": "Expresní doručení není k dispozici",
           "status": 422,
           "code": "express_unavailable",
           "detail": "Do zóny této adresy provozovna expres nenabízí.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Do zóny se expres nenabízí"
         },
         "promo_code_not_applicable": {
          "summary": "The code does not apply to the order",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#promo_code_not_applicable",
           "title": "Slevový kód na tuto objednávku neplatí",
           "status": 422,
           "code": "promo_code_not_applicable",
           "detail": "Kód platí pro objednávky od 300 Kč (cena položek). Chybí 102 Kč.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/promo_codes/0/code",
             "code": "invalid_value",
             "message": "Slevový kód nejde použít."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Kód na objednávku neplatí"
         },
         "promo_code_used_up": {
          "summary": "The single-use code has been used",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#promo_code_used_up",
           "title": "Slevový kód je vyčerpaný",
           "status": 422,
           "code": "promo_code_used_up",
           "detail": "Tento jednorázový kód už někdo použil.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/promo_codes/0/code",
             "code": "invalid_value",
             "message": "Slevový kód nejde použít."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Jednorázový kód už je použitý"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/quotes/{quote_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "quote_id",
     "in": "path",
     "required": true,
     "schema": {
      "$ref": "#/components/schemas/Id"
     },
     "example": "58213"
    }
   ],
   "get": {
    "tags": [
     "Orders"
    ],
    "operationId": "getQuote",
    "summary": "Quote detail",
    "x-summary-cs": "Detail kalkulace",
    "description": "A quote created by your connection, also after it expired (kept 24 hours).",
    "x-description-cs": "Kalkulace vytvořená vaším připojením, i po vypršení (drží se 24 hodin).",
    "security": [
     {
      "oauth2": [
       "orders:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The quote.",
      "x-description-cs": "Kalkulace.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Quote"
        },
        "examples": {
         "quote": {
          "summary": "A quote",
          "value": {
           "id": "58213",
           "restaurant_id": "123",
           "created_at": "2027-01-15T11:42:10+01:00",
           "expires_at": "2027-01-15T11:57:10+01:00",
           "customer_id": null,
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:05:00+01:00"
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 2,
             "base_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 39800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [],
           "amount_due": {
            "amount": 39800,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Nabídka"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/orders": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Orders"
    ],
    "operationId": "createOrder",
    "summary": "Place an order",
    "x-summary-cs": "Vytvořit objednávku",
    "description": "Creates the order from a valid quote with the quote's prices. Portions and vouchers are reserved in the same\ntransaction; when something sold out or a voucher is no longer usable, you get the error and nothing is created.\n\n- Payments that are `paid` or `unpaid` (cash or card at delivery or pickup): the order goes to the kitchen at once\n  (`received`).\n- A `pending` online payment: the order waits in `awaiting_payment` until you call `confirm-payment`, at most until\n  `payment_deadline` (30 minutes). Then it is cancelled and the reservations are released. When the payment is\n  confirmed after the chosen time, the order goes to the kitchen as soon as possible (`fulfillment.asap` becomes\n  `true`) with a note for the kitchen.\n\nThe quote's time is checked again: when the restaurant closed meanwhile or the time left the grid of\n`time-slots`, you get `restaurant_closed`, `time_unavailable` (or another reason of the time slots) and nothing\nis created – create a new quote.\n\nThe promotions of the quote are checked again and their use is recorded (also the pieces of a loyalty card\nwithout a discount in this order): when a promotion ended or ran out meanwhile, the customer reached its limit\nper customer, or the single-use code was used by another order, you get `409 promotion_changed` and nothing is\ncreated – create a new quote. Cancelling the order gives the use back.\n\nThe payments must add up to the quote's `amount_due` to the minor unit. A retry with the same\n`Idempotency-Key` returns the same order; it never creates a second one.\n\nThe kitchen and the order detail in the administration show the order with a note made of the payments (for\nexample a gift voucher with its code masked, `ABC-***`, or the amount to collect), the address note, your\n`note` and the name of your application (`KitchenTicket.note`).\n",
    "x-description-cs": "Vytvoří objednávku z platné kalkulace s jejími cenami. Porce a vouchery se rezervují ve stejné transakci; když\nněco došlo nebo voucher už nelze použít, dostanete chybu a nic nevznikne.\n\n- Platby `paid` nebo `unpaid` (hotově či kartou při doručení nebo odběru): objednávka jde hned do kuchyně\n  (`received`).\n- Online platba `pending`: objednávka čeká ve stavu `awaiting_payment`, dokud nezavoláte `confirm-payment`,\n  nejdéle do `payment_deadline` (30 minut). Pak se zruší a rezervace se uvolní. Když platbu potvrdíte až po\n  zvoleném čase, jde objednávka do kuchyně jako co nejdřív (`fulfillment.asap` je pak `true`) s poznámkou pro\n  kuchyň.\n\nČas kalkulace se ověří znovu: když mezitím provozovna zavřela nebo čas vypadl z mřížky `time-slots`, dostanete\n`restaurant_closed`, `time_unavailable` (nebo jiný důvod z časů) a nic nevznikne – spočítejte košík znovu.\n\nAkce z kalkulace se ověří znovu a zapíše se jejich použití (i kusy věrnostní karty bez slevy v této\nobjednávce): když akce mezitím skončila nebo se vyčerpala, zákazník dosáhl svého limitu nebo jednorázový kód\npoužila jiná objednávka, dostanete `409 promotion_changed` a nic nevznikne – spočítejte košík znovu. Zrušení\nobjednávky použití vrátí.\n\nPlatby musí dohromady na haléř odpovídat `amount_due` kalkulace. Opakování se stejným `Idempotency-Key` vrátí\nstejnou objednávku; druhá nikdy nevznikne.\n\nKuchyně a detail objednávky v administraci ukazují objednávku s poznámkou složenou z plateb (třeba dárkový\nvoucher se zamaskovaným kódem `ABC-***` nebo částka k vybrání), poznámky k adrese, vaší `note` a názvu vaší\naplikace (`KitchenTicket.note`).\n",
    "security": [
     {
      "oauth2": [
       "orders:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OrderCreate"
       },
       "examples": {
        "cash": {
         "summary": "Paid on pickup",
         "value": {
          "quote_id": "58213",
          "customer": {
           "name": "Jana Nováková",
           "phone": "+420777123456",
           "email": "jana.novakova@example.cz"
          },
          "payments": [
           {
            "method": "cash",
            "status": "unpaid",
            "amount": {
             "amount": 39800,
             "currency": "CZK"
            }
           }
          ],
          "external_id": "A-2027-000123",
          "metadata": {
           "branch": "praha-3"
          }
         },
         "x-summary-cs": "Platba při vyzvednutí"
        },
        "online": {
         "summary": "Paid online, confirmed separately",
         "value": {
          "quote_id": "58213",
          "customer": {
           "name": "Jana Nováková",
           "phone": "+420777123456",
           "email": "jana.novakova@example.cz"
          },
          "payments": [
           {
            "method": "online",
            "status": "pending",
            "amount": {
             "amount": 39800,
             "currency": "CZK"
            },
            "provider": "gopay"
           }
          ],
          "external_id": "A-2027-000124"
         },
         "x-summary-cs": "Platba online, potvrdí se zvlášť"
        },
        "recorded_elsewhere": {
         "summary": "The restaurant's register already recorded the sale (EET)",
         "value": {
          "quote_id": "58213",
          "customer": {
           "name": "Jana Nováková",
           "phone": "+420777123456",
           "email": null
          },
          "payments": [
           {
            "method": "online",
            "status": "paid",
            "amount": {
             "amount": 39800,
             "currency": "CZK"
            },
            "provider": "pokladna-provozovny",
            "reference": "BAR-1/4411"
           }
          ],
          "eet": {
           "pok": "57c70e45-29d3-4063-beae-986a62bc6b63-03",
           "recorded_at": "2027-01-15T11:41:55+01:00",
           "total": {
            "amount": 39800,
            "currency": "CZK"
           },
           "register_id": "BAR-1",
           "sequence": "4411"
          }
         },
         "x-summary-cs": "Tržbu už zaevidovala pokladna provozovny (EET)"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The order.",
      "x-description-cs": "Objednávka.",
      "headers": {
       "Location": {
        "$ref": "#/components/headers/Location"
       },
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Order"
        },
        "examples": {
         "cash": {
          "summary": "The order goes to the kitchen",
          "value": {
           "id": "184223",
           "restaurant_id": "123",
           "kitchen_number": "027",
           "status": "received",
           "status_changed_at": "2027-01-15T11:42:31+01:00",
           "created_at": "2027-01-15T11:42:31+01:00",
           "payment_deadline": null,
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:05:00+01:00"
           },
           "customer": {
            "customer_id": null,
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "email": "jana.novakova@example.cz"
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 2,
             "base_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 39800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "301877",
             "method": "cash",
             "status": "unpaid",
             "amount": {
              "amount": 39800,
              "currency": "CZK"
             },
             "provider": null,
             "reference": null,
             "voucher_code": null,
             "forfeited": null
            }
           ],
           "amount_to_collect": {
            "amount": 39800,
            "currency": "CZK"
           },
           "loyalty_points_earned": null,
           "note": null,
           "cancellation": null,
           "eet": null,
           "external_id": "A-2027-000123",
           "metadata": {
            "branch": "praha-3"
           }
          },
          "x-summary-cs": "Objednávka jde do kuchyně"
         },
         "online": {
          "summary": "The order waits for the payment",
          "value": {
           "id": "184224",
           "restaurant_id": "123",
           "kitchen_number": null,
           "status": "awaiting_payment",
           "status_changed_at": "2027-01-15T11:42:31+01:00",
           "created_at": "2027-01-15T11:42:31+01:00",
           "payment_deadline": "2027-01-15T12:12:31+01:00",
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:05:00+01:00"
           },
           "customer": {
            "customer_id": null,
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "email": "jana.novakova@example.cz"
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 2,
             "base_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 39800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "301878",
             "method": "online",
             "status": "pending",
             "amount": {
              "amount": 39800,
              "currency": "CZK"
             },
             "provider": "gopay",
             "reference": null,
             "voucher_code": null,
             "forfeited": null
            }
           ],
           "amount_to_collect": {
            "amount": 0,
            "currency": "CZK"
           },
           "loyalty_points_earned": null,
           "note": null,
           "cancellation": null,
           "eet": null,
           "external_id": "A-2027-000124",
           "metadata": {
            "branch": "praha-3"
           }
          },
          "x-summary-cs": "Objednávka čeká na platbu"
         },
         "recorded_elsewhere": {
          "summary": "Another system recorded the sale – Profirest does not send it",
          "value": {
           "id": "184225",
           "restaurant_id": "123",
           "kitchen_number": "029",
           "status": "received",
           "status_changed_at": "2027-01-15T11:42:31+01:00",
           "created_at": "2027-01-15T11:42:31+01:00",
           "payment_deadline": null,
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:05:00+01:00"
           },
           "customer": {
            "customer_id": null,
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "email": null
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 2,
             "base_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 39800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "301879",
             "method": "online",
             "status": "paid",
             "amount": {
              "amount": 39800,
              "currency": "CZK"
             },
             "provider": "pokladna-provozovny",
             "reference": "BAR-1/4411",
             "voucher_code": null,
             "forfeited": null
            }
           ],
           "amount_to_collect": {
            "amount": 0,
            "currency": "CZK"
           },
           "loyalty_points_earned": null,
           "note": null,
           "cancellation": null,
           "eet": {
            "recorded_by": "other_system",
            "pok": "57c70e45-29d3-4063-beae-986a62bc6b63-03",
            "recorded_at": "2027-01-15T11:41:55+01:00",
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "register_id": "BAR-1",
            "sequence": "4411"
           },
           "external_id": null,
           "metadata": {}
          },
          "x-summary-cs": "Tržbu evidoval jiný systém – Profirest ji neodešle"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "quote_expired": {
          "summary": "The quote expired",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#quote_expired",
           "title": "Kalkulace vypršela",
           "status": 409,
           "code": "quote_expired",
           "detail": "Nabídka platila do 11:57. Vytvořte novou.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Nabídka vypršela"
         },
         "promotion_changed": {
          "summary": "A promotion changed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#promotion_changed",
           "title": "Akce z kalkulace se změnila",
           "status": 409,
           "code": "promotion_changed",
           "detail": "Akce z kalkulace mezitím skončila nebo se vyčerpala. Spočítejte košík znovu.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Akce se změnila"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "payment_amount_mismatch": {
          "summary": "The payments do not add up",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#payment_amount_mismatch",
           "title": "Platby neodpovídají částce k úhradě",
           "status": 422,
           "code": "payment_amount_mismatch",
           "detail": "Platby dávají 300,00 Kč, k úhradě je 398,00 Kč.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Platby nesedí"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   },
   "get": {
    "tags": [
     "Orders"
    ],
    "operationId": "listOrders",
    "summary": "Orders of this connection",
    "x-summary-cs": "Objednávky tohoto připojení",
    "description": "Orders your connection created at this restaurant, newest first.",
    "x-description-cs": "Objednávky, které vaše připojení vytvořilo na této provozovně, od nejnovější.",
    "security": [
     {
      "oauth2": [
       "orders:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/ExternalIdFilter"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of orders.",
      "x-description-cs": "Stránka objednávek.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/OrderPage"
        },
        "examples": {
         "list": {
          "summary": "Orders",
          "value": {
           "data": [
            {
             "id": "184223",
             "restaurant_id": "123",
             "kitchen_number": "027",
             "status": "received",
             "status_changed_at": "2027-01-15T11:42:31+01:00",
             "created_at": "2027-01-15T11:42:31+01:00",
             "payment_deadline": null,
             "fulfillment": {
              "type": "pickup",
              "speed": "standard",
              "asap": true,
              "time": null,
              "estimated_at": "2027-01-15T12:05:00+01:00"
             },
             "customer": {
              "customer_id": null,
              "name": "Jana Nováková",
              "phone": "+420777123456",
              "email": "jana.novakova@example.cz"
             },
             "delivery": null,
             "lines": [
              {
               "id": "1",
               "type": "product",
               "variant": "full",
               "product_id": "4567",
               "name": "Svíčková na smetaně, houskový knedlík",
               "quantity": 2,
               "base_unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "packaging_unit_price": null,
               "vat_rate": "12",
               "add_ons": [],
               "options": [],
               "parts": null,
               "removed_ingredients": [],
               "note": null,
               "total": {
                "amount": 39800,
                "currency": "CZK"
               },
               "gift_of": null
              }
             ],
             "charges": [],
             "discounts": [],
             "totals": {
              "items": {
               "amount": 39800,
               "currency": "CZK"
              },
              "charges": {
               "amount": 0,
               "currency": "CZK"
              },
              "discounts": {
               "amount": 0,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "12",
                "base": {
                 "amount": 35536,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 4264,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 39800,
                 "currency": "CZK"
                }
               }
              ]
             },
             "payments": [
              {
               "id": "301877",
               "method": "cash",
               "status": "unpaid",
               "amount": {
                "amount": 39800,
                "currency": "CZK"
               },
               "provider": null,
               "reference": null,
               "voucher_code": null,
               "forfeited": null
              }
             ],
             "amount_to_collect": {
              "amount": 39800,
              "currency": "CZK"
             },
             "loyalty_points_earned": null,
             "note": null,
             "cancellation": null,
             "eet": null,
             "external_id": "A-2027-000123",
             "metadata": {
              "branch": "praha-3"
             }
            },
            {
             "id": "184224",
             "restaurant_id": "123",
             "kitchen_number": null,
             "status": "awaiting_payment",
             "status_changed_at": "2027-01-15T11:42:31+01:00",
             "created_at": "2027-01-15T11:42:31+01:00",
             "payment_deadline": "2027-01-15T12:12:31+01:00",
             "fulfillment": {
              "type": "pickup",
              "speed": "standard",
              "asap": true,
              "time": null,
              "estimated_at": "2027-01-15T12:05:00+01:00"
             },
             "customer": {
              "customer_id": null,
              "name": "Jana Nováková",
              "phone": "+420777123456",
              "email": "jana.novakova@example.cz"
             },
             "delivery": null,
             "lines": [
              {
               "id": "1",
               "type": "product",
               "variant": "full",
               "product_id": "4567",
               "name": "Svíčková na smetaně, houskový knedlík",
               "quantity": 2,
               "base_unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "packaging_unit_price": null,
               "vat_rate": "12",
               "add_ons": [],
               "options": [],
               "parts": null,
               "removed_ingredients": [],
               "note": null,
               "total": {
                "amount": 39800,
                "currency": "CZK"
               },
               "gift_of": null
              }
             ],
             "charges": [],
             "discounts": [],
             "totals": {
              "items": {
               "amount": 39800,
               "currency": "CZK"
              },
              "charges": {
               "amount": 0,
               "currency": "CZK"
              },
              "discounts": {
               "amount": 0,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "12",
                "base": {
                 "amount": 35536,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 4264,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 39800,
                 "currency": "CZK"
                }
               }
              ]
             },
             "payments": [
              {
               "id": "301878",
               "method": "online",
               "status": "pending",
               "amount": {
                "amount": 39800,
                "currency": "CZK"
               },
               "provider": "gopay",
               "reference": null,
               "voucher_code": null,
               "forfeited": null
              }
             ],
             "amount_to_collect": {
              "amount": 0,
              "currency": "CZK"
             },
             "loyalty_points_earned": null,
             "note": null,
             "cancellation": null,
             "eet": null,
             "external_id": "A-2027-000124",
             "metadata": {
              "branch": "praha-3"
             }
            }
           ],
           "next_cursor": "eyJpZCI6MTg0MjI0fQ"
          },
          "x-summary-cs": "Objednávky"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/orders/{order_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/OrderId"
    }
   ],
   "get": {
    "tags": [
     "Orders"
    ],
    "operationId": "getOrder",
    "summary": "Order detail",
    "x-summary-cs": "Detail objednávky",
    "description": "Current state of an order created by your connection.",
    "x-description-cs": "Aktuální stav objednávky vytvořené vaším připojením.",
    "security": [
     {
      "oauth2": [
       "orders:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The order.",
      "x-description-cs": "Objednávka.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Order"
        },
        "examples": {
         "preparing": {
          "summary": "The kitchen is preparing it",
          "value": {
           "id": "184223",
           "restaurant_id": "123",
           "kitchen_number": "027",
           "status": "preparing",
           "status_changed_at": "2027-01-15T11:44:02+01:00",
           "created_at": "2027-01-15T11:42:31+01:00",
           "payment_deadline": null,
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:05:00+01:00"
           },
           "customer": {
            "customer_id": null,
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "email": "jana.novakova@example.cz"
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 2,
             "base_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 39800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "301877",
             "method": "cash",
             "status": "unpaid",
             "amount": {
              "amount": 39800,
              "currency": "CZK"
             },
             "provider": null,
             "reference": null,
             "voucher_code": null,
             "forfeited": null
            }
           ],
           "amount_to_collect": {
            "amount": 39800,
            "currency": "CZK"
           },
           "loyalty_points_earned": null,
           "note": null,
           "cancellation": null,
           "eet": null,
           "external_id": "A-2027-000123",
           "metadata": {
            "branch": "praha-3"
           }
          },
          "x-summary-cs": "Kuchyň ji připravuje"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/orders/{order_id}/confirm-payment": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/OrderId"
    }
   ],
   "post": {
    "tags": [
     "Orders"
    ],
    "operationId": "confirmOrderPayment",
    "summary": "Confirm the online payment",
    "x-summary-cs": "Potvrdit online platbu",
    "description": "Marks the `pending` online payment as paid and sends the order to the kitchen. Allowed only in\n`awaiting_payment`; after `payment_deadline` the order is already cancelled and you get\n`409 order_not_awaiting_payment`, then refund your customer. When the payment failed, cancel the order instead.\n",
    "x-description-cs": "Označí `pending` online platbu jako zaplacenou a pošle objednávku do kuchyně. Jen ve stavu `awaiting_payment`;\npo `payment_deadline` je objednávka už zrušená a dostanete `409 order_not_awaiting_payment`, pak peníze\nzákazníkovi vraťte. Když platba neprošla, objednávku místo toho zrušte.\n",
    "security": [
     {
      "oauth2": [
       "orders:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PaymentConfirmation"
       },
       "examples": {
        "gopay": {
         "summary": "Paid through a payment gateway",
         "value": {
          "provider": "gopay",
          "reference": "3260145812"
         },
         "x-summary-cs": "Zaplaceno přes platební bránu"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The order, now `received`.",
      "x-description-cs": "Objednávka, nyní ve stavu `received`.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Order"
        },
        "examples": {
         "paid": {
          "summary": "Paid, goes to the kitchen",
          "value": {
           "id": "184224",
           "restaurant_id": "123",
           "kitchen_number": "028",
           "status": "received",
           "status_changed_at": "2027-01-15T11:43:40+01:00",
           "created_at": "2027-01-15T11:42:31+01:00",
           "payment_deadline": null,
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:05:00+01:00"
           },
           "customer": {
            "customer_id": null,
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "email": "jana.novakova@example.cz"
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 2,
             "base_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 39800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "301878",
             "method": "online",
             "status": "paid",
             "amount": {
              "amount": 39800,
              "currency": "CZK"
             },
             "provider": "gopay",
             "reference": "3260145812",
             "voucher_code": null,
             "forfeited": null
            }
           ],
           "amount_to_collect": {
            "amount": 0,
            "currency": "CZK"
           },
           "loyalty_points_earned": null,
           "note": null,
           "cancellation": null,
           "eet": null,
           "external_id": "A-2027-000124",
           "metadata": {
            "branch": "praha-3"
           }
          },
          "x-summary-cs": "Zaplaceno, jde do kuchyně"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "order_not_awaiting_payment": {
          "summary": "The order no longer waits for a payment",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#order_not_awaiting_payment",
           "title": "Objednávka nečeká na platbu",
           "status": 409,
           "code": "order_not_awaiting_payment",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Objednávka už na platbu nečeká"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/orders/{order_id}/cancel": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/OrderId"
    }
   ],
   "post": {
    "tags": [
     "Orders"
    ],
    "operationId": "cancelOrder",
    "summary": "Cancel an order",
    "x-summary-cs": "Zrušit objednávku",
    "description": "Cancels the order in `awaiting_payment` or `received` (the kitchen has not started preparing it; Profirest\nchecks the kitchen again at the moment of cancelling). The ticket may already be printed; the order disappears\nfrom the kitchen display. Later answers `409 order_not_cancellable`;\nthen only the restaurant can cancel it. Reserved portions are released and vouchers are returned; an order\nalready in the kitchen is reversed there by a cancellation document. Refunding your customer's online\npayment is up to you.\n",
    "x-description-cs": "Zruší objednávku ve stavu `awaiting_payment` nebo `received` (kuchyně ji nezačala připravovat; Profirest to\nv okamžiku rušení ověří znovu). Bon už může být vytištěný; z displeje kuchyně objednávka zmizí. Později vrátí `409 order_not_cancellable`; pak ji\nmůže zrušit jen provozovna. Rezervované porce se uvolní a vouchery se vrátí; objednávku, která už je\nv kuchyni, tam zruší stornovací doklad. Vrácení online platby zákazníkovi je na vás.\n",
    "security": [
     {
      "oauth2": [
       "orders:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OrderCancel"
       },
       "examples": {
        "customer": {
         "summary": "The customer changed their mind",
         "value": {
          "reason": "Zákazník si objednávku rozmyslel."
         },
         "x-summary-cs": "Zákazník si to rozmyslel"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The cancelled order.",
      "x-description-cs": "Zrušená objednávka.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Order"
        },
        "examples": {
         "cancelled": {
          "summary": "A cancelled order",
          "value": {
           "id": "184223",
           "restaurant_id": "123",
           "kitchen_number": "027",
           "status": "cancelled",
           "status_changed_at": "2027-01-15T11:46:15+01:00",
           "created_at": "2027-01-15T11:42:31+01:00",
           "payment_deadline": null,
           "fulfillment": {
            "type": "pickup",
            "speed": "standard",
            "asap": true,
            "time": null,
            "estimated_at": "2027-01-15T12:05:00+01:00"
           },
           "customer": {
            "customer_id": null,
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "email": "jana.novakova@example.cz"
           },
           "delivery": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "variant": "full",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 2,
             "base_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "options": [],
             "parts": null,
             "removed_ingredients": [],
             "note": null,
             "total": {
              "amount": 39800,
              "currency": "CZK"
             },
             "gift_of": null
            }
           ],
           "charges": [],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "301877",
             "method": "cash",
             "status": "voided",
             "amount": {
              "amount": 39800,
              "currency": "CZK"
             },
             "provider": null,
             "reference": null,
             "voucher_code": null,
             "forfeited": null
            }
           ],
           "amount_to_collect": {
            "amount": 0,
            "currency": "CZK"
           },
           "loyalty_points_earned": null,
           "note": null,
           "cancellation": {
            "at": "2027-01-15T11:46:15+01:00",
            "by": "integrator",
            "reason_code": null,
            "reason": "Zákazník si objednávku rozmyslel."
           },
           "eet": null,
           "external_id": "A-2027-000123",
           "metadata": {
            "branch": "praha-3"
           }
          },
          "x-summary-cs": "Zrušená objednávka"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "order_not_cancellable": {
          "summary": "The order cannot be cancelled any more",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#order_not_cancellable",
           "title": "Objednávku už nelze zrušit",
           "status": 409,
           "code": "order_not_cancellable",
           "detail": "Kuchyň objednávku už připravuje.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Objednávku už nejde zrušit"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/customers": {
   "post": {
    "tags": [
     "Customers"
    ],
    "operationId": "createCustomer",
    "summary": "Link a customer",
    "x-summary-cs": "Propojit zákazníka",
    "description": "Links your customer to the account's customer database by phone number, so the customer's orders count for the\nsame person as at the restaurant. The answer never tells whether the phone number was already known, and\nProfirest never returns data it holds about that person: you see only what you sent. Loyalty points become\nvisible after the phone number is verified, because points are worth money.\n",
    "x-description-cs": "Propojí vašeho zákazníka s databází klientů účtu podle telefonního čísla, takže se jeho objednávky počítají\nstejnému člověku jako v restauraci. Odpověď nikdy neprozradí, zda už telefon známe, a Profirest nikdy nevrátí\núdaje, které o člověku má: vidíte jen to, co jste poslali. Věrnostní body uvidíte po ověření telefonu, protože\nbody mají hodnotu peněz.\n",
    "security": [
     {
      "oauth2": [
       "customers:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CustomerCreate"
       },
       "examples": {
        "new": {
         "summary": "A new e-shop customer",
         "value": {
          "phone": "+420777123456",
          "name": "Jana Nováková",
          "email": "jana.novakova@example.cz",
          "external_id": "zakaznik-881",
          "metadata": {
           "newsletter": "ano"
          }
         },
         "x-summary-cs": "Nový zákazník e-shopu"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The customer link.",
      "x-description-cs": "Propojení zákazníka.",
      "headers": {
       "Location": {
        "$ref": "#/components/headers/Location"
       },
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Customer"
        },
        "examples": {
         "created": {
          "summary": "The customer waits for the phone check",
          "value": {
           "id": "90321",
           "phone": "+420777123456",
           "name": "Jana Nováková",
           "email": "jana.novakova@example.cz",
           "phone_verified": false,
           "created_at": "2027-01-15T11:40:12+01:00",
           "external_id": "zakaznik-881",
           "metadata": {
            "newsletter": "ano"
           }
          },
          "x-summary-cs": "Zákazník čeká na ověření telefonu"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "conflict": {
          "summary": "The customer already exists",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#conflict",
           "title": "Konflikt s aktuálním stavem",
           "status": 409,
           "code": "conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": "90321",
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Zákazník už existuje"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "get": {
    "tags": [
     "Customers"
    ],
    "operationId": "listCustomers",
    "summary": "Customers linked by this connection",
    "x-summary-cs": "Zákazníci propojení tímto připojením",
    "description": "The customers your connection linked (`POST /customers`), in the order they were linked. Links made by other\nconnections of the account never appear, even for the same phone number – each connection sees only its own\n(all devices of one application on an account share one connection). Unverified customers are included. The only\nfilter is `external_id`.\n",
    "x-description-cs": "Zákazníci, které vaše připojení propojilo (`POST /customers`), v pořadí, v jakém byli propojeni. Propojení\njiných připojení účtu se nikdy neukážou, ani se stejným telefonním číslem – každé připojení vidí jen svá\n(všechna zařízení jedné aplikace na účtu sdílejí jedno připojení). Neověření zákazníci v seznamu jsou také.\nJediný filtr je `external_id`.\n",
    "security": [
     {
      "oauth2": [
       "customers:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/ExternalIdFilter"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of customers.",
      "x-description-cs": "Stránka zákazníků.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CustomerPage"
        },
        "examples": {
         "list": {
          "summary": "Customers",
          "value": {
           "data": [
            {
             "id": "90321",
             "phone": "+420777123456",
             "name": "Jana Nováková",
             "email": "jana.novakova@example.cz",
             "phone_verified": true,
             "created_at": "2026-11-28T18:20:00+01:00",
             "external_id": "zakaznik-881",
             "metadata": {
              "newsletter": "ano"
             }
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Zákazníci"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/customers/{customer_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/CustomerId"
    }
   ],
   "get": {
    "tags": [
     "Customers"
    ],
    "operationId": "getCustomer",
    "summary": "Customer detail",
    "x-summary-cs": "Detail zákazníka",
    "description": "One customer link of your connection with its `ETag` for `PATCH`. It holds only what your connection sent (see\n`Customer`). A link of another connection, a link you removed (`DELETE`), or one erased because the restaurant\ndeleted that customer in the administration answers `404`.\n",
    "x-description-cs": "Jedno propojení zákazníka vaším připojením s `ETag` pro `PATCH`. Obsahuje jen to, co vaše připojení poslalo\n(viz `Customer`). Propojení jiného připojení, propojení, které jste odebrali (`DELETE`), nebo smazané, protože\nprovozovna toho zákazníka smazala v administraci, vrátí `404`.\n",
    "security": [
     {
      "oauth2": [
       "customers:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The customer link.",
      "x-description-cs": "Propojení zákazníka.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Customer"
        },
        "examples": {
         "customer": {
          "summary": "A customer",
          "value": {
           "id": "90321",
           "phone": "+420777123456",
           "name": "Jana Nováková",
           "email": "jana.novakova@example.cz",
           "phone_verified": true,
           "created_at": "2026-11-28T18:20:00+01:00",
           "external_id": "zakaznik-881",
           "metadata": {
            "newsletter": "ano"
           }
          },
          "x-summary-cs": "Zákazník"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "patch": {
    "tags": [
     "Customers"
    ],
    "operationId": "updateCustomer",
    "summary": "Update a customer",
    "x-summary-cs": "Upravit zákazníka",
    "description": "Changes only the fields you send. Send the `ETag` you read in `If-Match`. Changing the phone number links the\ncustomer again and removes the verification.\n",
    "x-description-cs": "Změní jen poslaná pole. V `If-Match` pošlete `ETag`, který jste načetli. Změna telefonu zákazníka znovu propojí\na zruší ověření.\n",
    "security": [
     {
      "oauth2": [
       "customers:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CustomerUpdate"
       },
       "examples": {
        "email": {
         "summary": "Changing the e-mail and metadata",
         "value": {
          "email": "jana.novakova@example.com",
          "metadata": {
           "newsletter": "ne"
          }
         },
         "x-summary-cs": "Změna e-mailu a metadat"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The updated customer link.",
      "x-description-cs": "Upravené propojení zákazníka.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Customer"
        },
        "examples": {
         "updated": {
          "summary": "The updated customer",
          "value": {
           "id": "90321",
           "phone": "+420777123456",
           "name": "Jana Nováková",
           "email": "jana.novakova@example.com",
           "phone_verified": true,
           "created_at": "2026-11-28T18:20:00+01:00",
           "external_id": "zakaznik-881",
           "metadata": {
            "newsletter": "ne"
           }
          },
          "x-summary-cs": "Upravený zákazník"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "description": "`precondition_failed`: the object changed since you read it. Read it again and retry.",
      "x-description-cs": "`precondition_failed`: záznam se od načtení změnil. Načtěte ho znovu a zkuste to znovu.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "precondition_failed": {
          "summary": "Somebody changed the customer meanwhile",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#precondition_failed",
           "title": "Záznam se mezitím změnil",
           "status": 412,
           "code": "precondition_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Zákazníka mezitím někdo změnil"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "428": {
      "$ref": "#/components/responses/PreconditionRequired"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "delete": {
    "tags": [
     "Customers"
    ],
    "operationId": "deleteCustomer",
    "summary": "Unlink and erase a customer",
    "x-summary-cs": "Zrušit propojení a smazat zákazníka",
    "description": "Removes the link and every piece of data your connection sent about this customer (for example when the\ncustomer asks you to be forgotten). The restaurant's own customer record and the customer's past orders stay,\nbecause they belong to the restaurant.\n",
    "x-description-cs": "Odstraní propojení a všechny údaje, které vaše připojení o zákazníkovi poslalo (například když zákazník chce být\nzapomenut). Vlastní záznam restaurace o klientovi a jeho dřívější objednávky zůstávají, protože patří restauraci.\n",
    "security": [
     {
      "oauth2": [
       "customers:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Removed.",
      "x-description-cs": "Odstraněno."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/customers/{customer_id}/phone-verification": {
   "parameters": [
    {
     "$ref": "#/components/parameters/CustomerId"
    }
   ],
   "post": {
    "tags": [
     "Customers"
    ],
    "operationId": "startPhoneVerification",
    "summary": "Send a verification code",
    "x-summary-cs": "Poslat ověřovací kód",
    "description": "Profirest sends a 6-digit code by SMS to the customer's phone. The code is valid 10 minutes. Limits: a new code\nafter `resend_after`; at most 5 codes per phone number and connection per day and 15 per phone number from all\nconnections; a daily SMS quota per connection; SMS only to countries Profirest delivers to. The SMS is paid from the restaurant owner's credit.\n",
    "x-description-cs": "Profirest pošle zákazníkovi SMS se šestimístným kódem. Kód platí 10 minut. Omezení: nový kód až po\n`resend_after`; nejvýš 5 kódů na telefonní číslo a připojení za den a 15 na číslo ze všech připojení; denní\nkvóta SMS na připojení;\nSMS jen do zemí, kam Profirest doručuje. SMS se platí z kreditu majitele restaurace.\n",
    "security": [
     {
      "oauth2": [
       "customers:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "201": {
      "description": "The code was sent.",
      "x-description-cs": "Kód byl odeslán.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PhoneVerification"
        },
        "examples": {
         "sms": {
          "summary": "The code went by SMS",
          "value": {
           "id": "7731",
           "expires_at": "2027-01-15T11:52:00+01:00",
           "resend_after": "2027-01-15T11:43:00+01:00"
          },
          "x-summary-cs": "Kód odešel SMS"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "description": "`rate_limited` (requests of the connection or device), or a limit of the operation – `staff_locked`, `voucher_attempts_exceeded`, `verification_resend_too_early`, `sms_quota_exceeded`; see `code`. Wait `Retry-After` seconds.",
      "x-description-cs": "`rate_limited` (požadavky připojení nebo zařízení), nebo limit operace – `staff_locked`, `voucher_attempts_exceeded`, `verification_resend_too_early`, `sms_quota_exceeded`; viz `code`. Počkejte `Retry-After` sekund.",
      "headers": {
       "Retry-After": {
        "$ref": "#/components/headers/RetryAfter"
       }
      },
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "rate_limited": {
          "summary": "The request limit of the connection",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#rate_limited",
           "title": "Příliš mnoho požadavků",
           "status": 429,
           "code": "rate_limited",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Limit požadavků připojení"
         },
         "verification_resend_too_early": {
          "summary": "The code can be sent again a bit later",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#verification_resend_too_early",
           "title": "Nový kód lze poslat až později",
           "status": 429,
           "code": "verification_resend_too_early",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Kód jde poslat znovu až za chvíli"
         }
        }
       }
      }
     },
     "503": {
      "$ref": "#/components/responses/ServiceUnavailable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     }
    }
   }
  },
  "/customers/{customer_id}/phone-verification/confirm": {
   "parameters": [
    {
     "$ref": "#/components/parameters/CustomerId"
    }
   ],
   "post": {
    "tags": [
     "Customers"
    ],
    "operationId": "confirmPhoneVerification",
    "summary": "Confirm the verification code",
    "x-summary-cs": "Potvrdit ověřovací kód",
    "description": "The code verifies only the phone it was sent to; changing the customer's phone cancels it. After 5 wrong attempts the code stops working and a new one must be requested.",
    "x-description-cs": "Kód ověří jen telefon, na který odešel; změna telefonu zákazníka ho zruší. Po 5 špatných pokusech kód přestane platit a je potřeba vyžádat nový.",
    "security": [
     {
      "oauth2": [
       "customers:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PhoneVerificationConfirm"
       },
       "examples": {
        "code": {
         "summary": "The code from the SMS",
         "value": {
          "code": "482913"
         },
         "x-summary-cs": "Kód z SMS"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Verified. The customer now has `phone_verified = true`.",
      "x-description-cs": "Ověřeno. Zákazník má nyní `phone_verified = true`.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Customer"
        },
        "examples": {
         "verified": {
          "summary": "The phone is verified",
          "value": {
           "id": "90321",
           "phone": "+420777123456",
           "name": "Jana Nováková",
           "email": "jana.novakova@example.cz",
           "phone_verified": true,
           "created_at": "2026-11-28T18:20:00+01:00",
           "external_id": "zakaznik-881",
           "metadata": {
            "newsletter": "ano"
           }
          },
          "x-summary-cs": "Telefon ověřený"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "verification_failed": {
          "summary": "A wrong code",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#verification_failed",
           "title": "Ověřovací kód je špatný nebo vypršel",
           "status": 422,
           "code": "verification_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Špatný kód"
         }
        }
       }
      }
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/customers/{customer_id}/loyalty": {
   "parameters": [
    {
     "$ref": "#/components/parameters/CustomerId"
    }
   ],
   "get": {
    "tags": [
     "Customers"
    ],
    "operationId": "getCustomerLoyalty",
    "summary": "Loyalty points",
    "x-summary-cs": "Věrnostní body",
    "description": "Points of a verified customer. They are shared by all restaurants of the account. Orders placed through the API\nadd 1 point per whole CZK of the items before vouchers – the delivery fee and the minimum order surcharge do\nnot count (the same as at the register).\n",
    "x-description-cs": "Body ověřeného zákazníka. Jsou společné pro všechny provozovny účtu. Objednávky přes API přičtou 1 bod za každou\ncelou korunu ceny položek před vouchery – doprava ani doplatek do minima se nepočítají (stejně jako na pokladně).\n",
    "security": [
     {
      "oauth2": [
       "loyalty:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Points.",
      "x-description-cs": "Body.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Loyalty"
        },
        "examples": {
         "points": {
          "summary": "Loyalty points",
          "value": {
           "customer_id": "90321",
           "points": 120,
           "points_value": {
            "amount": 12000,
            "currency": "CZK"
           },
           "redeemable": false
          },
          "x-summary-cs": "Věrnostní body"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/vouchers/check": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Vouchers"
    ],
    "operationId": "checkVoucher",
    "summary": "Check a gift voucher",
    "x-summary-cs": "Ověřit dárkový voucher",
    "description": "Shows the state and balance of a voucher of this account without using it. The code travels in the body, never\nin the URL, because it is worth money. Vouchers of other accounts and vouchers not sold yet – also one that is\nblocked – look exactly like unknown codes (`422 voucher_invalid`); the same holds for a voucher in a quote, an\norder or a receipt payment. `blocked` comes only for a sold voucher.\n\nEvery unknown code counts as a failed attempt, also in quotes and orders. Limits: 10 failed attempts per\n`end_user_id` and 200 per connection within a fixed 10-minute window (starting at :00, :10, :20 …); then\n`429 voucher_attempts_exceeded` until the window ends (`Retry-After`, at most 10 minutes). On top of that\n500 failed attempts a day per connection and 1,000 a day per account across all connections; then `429` until\nmidnight. Send `end_user_id` (your stable, anonymous ID of the shopper), so one shopper cannot lock\nout your whole e-shop.\n\n**A paired register** (a device with `receipts:write`) sells vouchers too, so it sees also a voucher not sold\nyet, of a series that allows selling: `status` `for_sale` (or `blocked`), `value` is the price to sell it at,\n`balance` is zero and `valid_until` `null` – the validity starts on the day of the sale. Sell it as a\n`voucher_sale` line of the receipt; `unit_price` may be left out (since 26.11.26).\n",
    "x-description-cs": "Ukáže stav a zůstatek voucheru tohoto účtu, aniž by ho použil. Kód se posílá v těle, nikdy v URL, protože má\nhodnotu peněz. Vouchery jiných účtů a dosud neprodané vouchery – i zablokované – vypadají přesně jako neznámé\nkódy (`422 voucher_invalid`); stejně tak voucher v kalkulaci, v objednávce i v platbě účtenky. `blocked` přijde\njen u prodaného voucheru.\n\nKaždý neznámý kód se počítá jako neúspěšný pokus, i v kalkulacích a objednávkách. Limity: 10 neúspěšných pokusů\nna `end_user_id` a 200 na připojení v pevném desetiminutovém okně (začíná v :00, :10, :20 …); pak\n`429 voucher_attempts_exceeded` do konce okna (`Retry-After`, nejvýš 10 minut). Navíc 500 neúspěšných pokusů za\nden na připojení a 1 000 za den na účet napříč všemi připojeními; pak `429` do půlnoci.\nPosílejte `end_user_id` (vaše stálé anonymní ID nakupujícího), aby jeden nakupující nezablokoval celý váš\ne-shop.\n\n**Spárovaná pokladna** (zařízení s `receipts:write`) vouchery i prodává, a proto vidí i dosud neprodaný voucher\nsérie, která prodej povoluje: `status` `for_sale` (nebo `blocked`), `value` je cena, za kterou se prodá,\n`balance` je nula a `valid_until` `null` – platnost začíná dnem prodeje. Prodejte ho řádkem `voucher_sale`\núčtenky; `unit_price` smí chybět (od 26.11.26).\n",
    "security": [
     {
      "oauth2": [
       "vouchers:redeem"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/VoucherCheck"
       },
       "examples": {
        "check": {
         "summary": "Checking a gift voucher",
         "value": {
          "code": "KX7-9QD"
         },
         "x-summary-cs": "Kontrola dárkového voucheru"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The voucher exists in this account. See `status` and `accepted_here`.",
      "x-description-cs": "Voucher v tomto účtu existuje. Viz `status` a `accepted_here`.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Voucher"
        },
        "examples": {
         "active": {
          "summary": "A valid voucher with a balance",
          "value": {
           "code": "KX7-***",
           "status": "active",
           "value": {
            "amount": 50000,
            "currency": "CZK"
           },
           "balance": {
            "amount": 30000,
            "currency": "CZK"
           },
           "valid_until": "2027-06-30",
           "partial_redemption": true,
           "accepted_here": true
          },
          "x-summary-cs": "Platný voucher se zůstatkem"
         },
         "for_sale": {
          "summary": "A voucher not sold yet, on a register",
          "value": {
           "code": "KX7-***",
           "status": "for_sale",
           "value": {
            "amount": 50000,
            "currency": "CZK"
           },
           "balance": {
            "amount": 0,
            "currency": "CZK"
           },
           "valid_until": null,
           "partial_redemption": true,
           "accepted_here": true
          },
          "x-summary-cs": "Neprodaný voucher na pokladně"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "voucher_expired": {
          "summary": "The voucher expired",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#voucher_expired",
           "title": "Voucher vypršel",
           "status": 422,
           "code": "voucher_expired",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Voucher vypršel"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservation-settings": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "getReservationSettings",
    "summary": "Get reservation rules",
    "x-summary-cs": "Pravidla rezervací",
    "description": "How the restaurant takes reservations: how long guests sit at a table by the size of the party, the step of\noffered times, cleaning after a table, the last reservation before closing, the days without reservations and\nthe rules for guests booking online. The restaurant sets them in the administration (Reservations › Settings).\nUse them to explain your offer; which times are free tells you `getReservationAvailability`.\n",
    "x-description-cs": "Jak provozovna přijímá rezervace: jak dlouho hosté sedí u stolu podle velikosti skupiny, krok nabízených časů,\núklid stolu, poslední rezervace před zavřením, dny bez rezervací a pravidla pro hosty, kteří rezervují online.\nProvozovna je nastavuje v administraci (Rezervace › Nastavení). Použijte je k vysvětlení nabídky; které časy\njsou volné, řekne `getReservationAvailability`.\n",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The rules.",
      "x-description-cs": "Pravidla.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReservationSettings"
        },
        "examples": {
         "rules": {
          "summary": "Reservation rules",
          "value": {
           "slot_step_minutes": 15,
           "table_durations": [
            {
             "up_to_party_size": 2,
             "minutes": 90
            },
            {
             "up_to_party_size": 4,
             "minutes": 120
            },
            {
             "up_to_party_size": 99,
             "minutes": 150
            }
           ],
           "table_buffer_minutes": 15,
           "last_seating_before_close_minutes": 30,
           "use_opening_hours": true,
           "max_guests_per_slot": 12,
           "closed_dates": [
            "2027-02-14"
           ],
           "online": {
            "enabled": true,
            "confirmation": "auto",
            "confirm_within_minutes": 120,
            "lead_minutes": 60,
            "horizon_days": 60,
            "max_party_size": 8,
            "guest_cancel_hours": 2
           },
           "services_enabled": true,
           "deposit": {
            "mode": "from_party",
            "available": true,
            "from_party_size": 6,
            "per_person": {
             "amount": 20000,
             "currency": "CZK"
            },
            "per_reservation": {
             "amount": 0,
             "currency": "CZK"
            },
            "service_percent": 50,
            "pay_within_minutes": 60,
            "refund_until_hours": 24,
            "no_show_guests": true
           },
           "reminders": {
            "email_hours": 24,
            "sms_hours": 3
           },
           "feedback_enabled": true,
           "guest_max_moves": 3
          },
          "x-summary-cs": "Pravidla rezervací"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservation-services": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "listReservationServices",
    "summary": "List bookable services",
    "x-summary-cs": "Služby k rezervaci",
    "description": "Services a guest books with an employee – a haircut, a massage, a consultation – with their length, price and\nthe employees who do them. Empty when the licence of the restaurant has reservations of tables only\n(`ReservationSettings.services_enabled`). Services that are not offered at the moment are left out.\n",
    "x-description-cs": "Služby, které si host rezervuje u pracovníka – střih, masáž, konzultace – s délkou, cenou a pracovníky, kteří\nje dělají. Prázdné, když licence provozovny má jen rezervace stolů (`ReservationSettings.services_enabled`).\nSlužby, které se teď nenabízejí, chybí.\n",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The services.",
      "x-description-cs": "Služby.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReservationServiceList"
        },
        "examples": {
         "services": {
          "summary": "Bookable services",
          "value": {
           "data": [
            {
             "id": "12",
             "name": "Pánský střih",
             "category": "Vlasy",
             "description": null,
             "duration_minutes": 30,
             "buffer_minutes": 10,
             "price": {
              "amount": 45000,
              "currency": "CZK"
             },
             "max_party_size": 1,
             "online": true,
             "staff": [
              {
               "id": "58",
               "name": "Jana Dvořáková"
              },
              {
               "id": "61",
               "name": "Petr Novák"
              }
             ]
            }
           ]
          },
          "x-summary-cs": "Služby k rezervaci"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservation-availability": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "getReservationAvailability",
    "summary": "Free times of a day",
    "x-summary-cs": "Volné časy dne",
    "description": "The times of one day the restaurant offers, each with `available` and, when not available, the `reason`. For a\ntable send `party_size`; for a service `kind=service`, `service_id` and optionally `employee_id` (without it any\nfree employee). The tables or the employee in a slot are what `createReservation` would take at that moment –\na slot is not held for you, so create the reservation soon and expect `409 reservation_unavailable` when\nsomebody was faster.\n\n`channel=online` (default) applies the rules for guests booking online: only when the restaurant takes\nonline reservations, not sooner than `online.lead_minutes`, not further than `online.horizon_days`, only tables\noffered online, and times the guest can no longer book are left out. `channel=staff` is for applications of the\nstaff (a register, a reservation book): all tables and all times of the day.\n",
    "x-description-cs": "Časy jednoho dne, které provozovna nabízí, každý s `available` a u nedostupného s důvodem `reason`. U stolu\npošlete `party_size`; u služby `kind=service`, `service_id` a případně `employee_id` (bez něj kdokoli volný).\nStoly nebo pracovník u času jsou to, co by `createReservation` v tu chvíli vzal – čas se pro vás nedrží, proto\nrezervaci založte brzy a počítejte s `409 reservation_unavailable`, když byl někdo rychlejší.\n\n`channel=online` (výchozí) použije pravidla pro hosty, kteří rezervují online: jen když provozovna online\nrezervace přijímá, ne dřív než `online.lead_minutes`, ne dál než `online.horizon_days`, jen stoly nabízené\nonline, a časy, které host už rezervovat nemůže, chybí. `channel=staff` je pro aplikace obsluhy (pokladna,\nkniha rezervací): všechny stoly a všechny časy dne.\n",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "date",
      "in": "query",
      "required": true,
      "description": "The day (local date of the restaurant).",
      "x-description-cs": "Den (místní datum provozovny).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "kind",
      "in": "query",
      "required": false,
      "description": "`table` (default) or `service`.",
      "x-description-cs": "`table` (výchozí), nebo `service`.",
      "schema": {
       "type": "string",
       "enum": [
        "table",
        "service"
       ]
      }
     },
     {
      "name": "party_size",
      "in": "query",
      "required": false,
      "description": "Number of guests (default 2 for a table, 1 for a service).",
      "x-description-cs": "Počet hostů (výchozí 2 u stolu, 1 u služby).",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 500
      },
      "example": "4"
     },
     {
      "name": "service_id",
      "in": "query",
      "required": false,
      "description": "The service (`kind=service`).",
      "x-description-cs": "Služba (`kind=service`).",
      "schema": {
       "$ref": "#/components/schemas/Id"
      }
     },
     {
      "name": "employee_id",
      "in": "query",
      "required": false,
      "description": "Only this employee (`kind=service`).",
      "x-description-cs": "Jen tento pracovník (`kind=service`).",
      "schema": {
       "$ref": "#/components/schemas/Id"
      }
     },
     {
      "name": "channel",
      "in": "query",
      "required": false,
      "description": "`online` (default) – rules for guests; `staff` – an application of the staff.",
      "x-description-cs": "`online` (výchozí) – pravidla pro hosty; `staff` – aplikace obsluhy.",
      "schema": {
       "type": "string",
       "enum": [
        "online",
        "staff"
       ]
      }
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The times of the day.",
      "x-description-cs": "Časy dne.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReservationAvailability"
        },
        "examples": {
         "day": {
          "summary": "Free times for 4 guests",
          "value": {
           "date": "2027-01-15",
           "slots": [
            {
             "starts_at": "2027-01-15T18:45:00+01:00",
             "available": true,
             "reason": null,
             "table_ids": [
              "7"
             ],
             "employee_id": null
            },
            {
             "starts_at": "2027-01-15T19:00:00+01:00",
             "available": true,
             "reason": null,
             "table_ids": [
              "4"
             ],
             "employee_id": null
            },
            {
             "starts_at": "2027-01-15T19:15:00+01:00",
             "available": false,
             "reason": "no_table",
             "table_ids": [],
             "employee_id": null
            }
           ]
          },
          "x-summary-cs": "Volné časy pro 4 osoby"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "listReservations",
    "summary": "List reservations",
    "x-summary-cs": "Seznam rezervací",
    "description": "Reservations starting from `from` to `to` (local days, both included, at most 31 days; without them today),\nordered by the start. All sources – the administration, registers, guests online and other applications.\nPoll with `If-None-Match`, or follow `reservation.*` events.\n",
    "x-description-cs": "Rezervace se začátkem od `from` do `to` (místní dny včetně obou, nejvýš 31 dní; bez nich dnešek), podle\nzačátku. Ze všech zdrojů – administrace, pokladny, hosté online i jiné aplikace. Dotazujte se s\n`If-None-Match`, nebo sledujte události `reservation.*`.\n",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "from",
      "in": "query",
      "required": false,
      "description": "First day (default today).",
      "x-description-cs": "První den (výchozí dnešek).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "to",
      "in": "query",
      "required": false,
      "description": "Last day (default `from`).",
      "x-description-cs": "Poslední den (výchozí `from`).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "Only these states, comma separated (`requested,confirmed`).",
      "x-description-cs": "Jen tyto stavy, oddělené čárkou (`requested,confirmed`).",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The reservations.",
      "x-description-cs": "Rezervace.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReservationList"
        },
        "examples": {
         "day": {
          "summary": "Reservations of the day",
          "value": {
           "data": [
            {
             "id": "5121",
             "uuid": "01a318f0-a0c0-78f8-9b5a-f1b4bb6d17e9",
             "restaurant_id": "123",
             "kind": "service",
             "status": "confirmed",
             "source": "online",
             "party_size": 1,
             "starts_at": "2027-01-15T15:00:00+01:00",
             "ends_at": "2027-01-15T15:30:00+01:00",
             "blocked_until": "2027-01-15T15:40:00+01:00",
             "table_ids": [],
             "service_id": "12",
             "employee_id": "58",
             "employee_any": true,
             "resource_id": null,
             "guest": {
              "name": "Martin Černý",
              "phone": "+420603111222",
              "email": "martin.cerny@example.com",
              "customer_id": null
             },
             "note_guest": null,
             "note_internal": null,
             "tags": [],
             "deposit": {
              "amount": {
               "amount": 0,
               "currency": "CZK"
              },
              "status": "none",
              "due_at": null
             },
             "confirm_due_at": null,
             "tab_id": null,
             "cancel_reason": null,
             "version": 1,
             "created_at": "2027-01-15T11:40:12+01:00",
             "updated_at": "2027-01-15T11:40:12+01:00"
            },
            {
             "id": "5120",
             "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
             "restaurant_id": "123",
             "kind": "table",
             "status": "confirmed",
             "source": "online",
             "party_size": 4,
             "starts_at": "2027-01-15T19:00:00+01:00",
             "ends_at": "2027-01-15T21:00:00+01:00",
             "blocked_until": "2027-01-15T21:15:00+01:00",
             "table_ids": [
              "4"
             ],
             "service_id": null,
             "employee_id": null,
             "employee_any": false,
             "resource_id": null,
             "guest": {
              "name": "Jana Svobodová",
              "phone": "+420777123456",
              "email": "jana.svobodova@example.com",
              "customer_id": null
             },
             "note_guest": "U okna, slavíme narozeniny",
             "note_internal": null,
             "tags": [
              "narozeniny"
             ],
             "deposit": {
              "amount": {
               "amount": 0,
               "currency": "CZK"
              },
              "status": "none",
              "due_at": null
             },
             "confirm_due_at": null,
             "tab_id": null,
             "cancel_reason": null,
             "version": 1,
             "created_at": "2027-01-15T11:40:12+01:00",
             "updated_at": "2027-01-15T11:40:12+01:00"
            }
           ]
          },
          "x-summary-cs": "Rezervace dne"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "createReservation",
    "summary": "Create a reservation",
    "x-summary-cs": "Založit rezervaci",
    "description": "A reservation of a table (`kind=table`, `party_size`) or of a service with an employee (`kind=service`,\n`service_id`, optionally `employee_id`). The server checks the capacity and picks the tables or the employee\nitself (the smallest table that fits, else joined tables; the least busy employee); a full time answers\n`409 reservation_unavailable`, a time the rules do not allow `422 reservation_not_allowed`. You may send\n`table_ids` for `channel=staff`.\n\nAn application of the staff (`channel=staff`) may also set its own length of a table reservation\n(`duration_minutes`, a celebration, a blocked table), skip the deposit (`deposit: false`) and seat guests who\ncame without a reservation (`walk_in: true` – the start is now, the reservation is `seated` at once and the\nopening hours, closed days and the pace of arrivals do not apply; the table must be free).\n\n`channel=online` (default) is a guest booking through your application: the guest's phone and e-mail are\nrequired, the rules for online booking apply and the reservation is `confirmed` at once, or `requested` when the\nrestaurant confirms online reservations by hand (it expires when nobody confirms it in time). When the rules\nrequire a deposit, the reservation stays `requested` with `deposit.status` `pending` until it is paid.\n\nRepeat safely: the same `Idempotency-Key` returns the same reservation; your own `uuid` also does –\na second create with it returns the existing reservation.\n",
    "x-description-cs": "Rezervace stolu (`kind=table`, `party_size`), nebo služby u pracovníka (`kind=service`, `service_id`,\npřípadně `employee_id`). Server zkontroluje kapacitu a stoly nebo pracovníka vybere sám (nejmenší vhodný stůl,\njinak spojené stoly; nejméně vytížený pracovník); plný čas vrátí `409 reservation_unavailable`, čas, který\npravidla nedovolí, `422 reservation_not_allowed`. `table_ids` můžete poslat u `channel=staff`.\n\nAplikace obsluhy (`channel=staff`) může navíc zadat vlastní délku rezervace stolu (`duration_minutes`, oslava,\nblokace stolu), zálohu nechtít (`deposit: false`) a usadit hosty, kteří přišli bez rezervace (`walk_in: true` –\nzačátek je teď, rezervace je hned `seated` a neplatí otevírací doba, zavřené dny ani tempo příchodů; stůl musí\nbýt volný).\n\n`channel=online` (výchozí) je host, který rezervuje přes vaši aplikaci: telefon i e-mail hosta jsou povinné,\nplatí pravidla online rezervací a rezervace je hned `confirmed`, nebo `requested`, když provozovna online\nrezervace potvrzuje ručně (když ji nikdo včas nepotvrdí, propadne). Když pravidla chtějí zálohu, zůstane\nrezervace `requested` s `deposit.status` `pending`, dokud se nezaplatí.\n\nOpakování je bezpečné: stejný `Idempotency-Key` vrátí stejnou rezervaci; vaše vlastní `uuid` také –\ndruhé založení s ním vrátí existující rezervaci.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReservationCreate"
       },
       "examples": {
        "table": {
         "summary": "A table for 4 through a booking application",
         "value": {
          "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
          "channel": "online",
          "kind": "table",
          "party_size": 4,
          "starts_at": "2027-01-15T19:00:00+01:00",
          "guest": {
           "name": "Jana Svobodová",
           "phone": "+420777123456",
           "email": "jana.svobodova@example.com"
          },
          "note_guest": "U okna, slavíme narozeniny"
         },
         "x-summary-cs": "Stůl pro 4 přes rezervační aplikaci"
        },
        "service": {
         "summary": "A haircut with any free employee",
         "value": {
          "kind": "service",
          "service_id": "12",
          "starts_at": "2027-01-15T15:00:00+01:00",
          "guest": {
           "name": "Martin Černý",
           "phone": "+420603111222",
           "email": "martin.cerny@example.com"
          }
         },
         "x-summary-cs": "Střih u kohokoli volného"
        },
        "celebration": {
         "summary": "A 4-hour celebration taken by the staff",
         "value": {
          "channel": "staff",
          "kind": "table",
          "party_size": 12,
          "starts_at": "2027-01-15T17:00:00+01:00",
          "table_ids": [
           "7",
           "8"
          ],
          "duration_minutes": 240,
          "deposit": false,
          "guest": {
           "name": "Firma Alfa s.r.o.",
           "phone": "+420605222333"
          },
          "tags": [
           "firemní akce"
          ]
         },
         "x-summary-cs": "Oslava na 4 hodiny, zapsala obsluha"
        },
        "walk_in": {
         "summary": "Guests without a reservation at the door",
         "value": {
          "channel": "staff",
          "kind": "table",
          "party_size": 2,
          "starts_at": "2027-01-15T18:40:00+01:00",
          "walk_in": true,
          "guest": {
           "name": "Host bez rezervace"
          }
         },
         "x-summary-cs": "Hosté bez rezervace u dveří"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Created.",
      "x-description-cs": "Založeno.",
      "headers": {
       "Location": {
        "$ref": "#/components/headers/Location"
       },
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "created": {
          "summary": "The created reservation",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "confirmed",
           "source": "online",
           "party_size": 4,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T21:00:00+01:00",
           "blocked_until": "2027-01-15T21:15:00+01:00",
           "table_ids": [
            "4"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": null,
           "cancel_reason": null,
           "version": 1,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Založená rezervace"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "reservation_unavailable": {
          "summary": "No free table at 19:00 any more",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#reservation_unavailable",
           "title": "Termín není volný",
           "status": 409,
           "code": "reservation_unavailable",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "V 19:00 už není volný stůl"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "reservation_not_allowed": {
          "summary": "Online not sooner than in an hour",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#reservation_not_allowed",
           "title": "Pravidla provozovny tuto rezervaci nedovolí",
           "status": 422,
           "code": "reservation_not_allowed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Online jde rezervovat nejdřív za hodinu"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations/{reservation_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReservationId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "getReservation",
    "summary": "Get a reservation",
    "x-summary-cs": "Detail rezervace",
    "description": "The reservation with the guest's contacts and its `ETag` (the version).",
    "x-description-cs": "Rezervace s kontakty hosta a `ETag` (verzí).",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The reservation.",
      "x-description-cs": "Rezervace.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "reservation": {
          "summary": "A reservation",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "confirmed",
           "source": "online",
           "party_size": 4,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T21:00:00+01:00",
           "blocked_until": "2027-01-15T21:15:00+01:00",
           "table_ids": [
            "4"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": null,
           "cancel_reason": null,
           "version": 1,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Rezervace"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "patch": {
    "tags": [
     "Reservations"
    ],
    "operationId": "updateReservation",
    "summary": "Change a reservation",
    "x-summary-cs": "Změnit rezervaci",
    "description": "Send only what changes. A new time, party size, tables, service or employee is checked against the capacity\nagain (without this reservation); the server keeps the current tables or employee when they still fit,\notherwise it picks new ones. A seated reservation changes only its tables, party size and notes; a finished\none does not change (`409 reservation_state_conflict`). Send `If-Match` with the `ETag` you read.\n",
    "x-description-cs": "Pošlete jen to, co se mění. Nový čas, počet osob, stoly, služba nebo pracovník se znovu porovná s kapacitou\n(bez této rezervace); server ponechá stávající stoly nebo pracovníka, pokud pořád vyhovují, jinak vybere nové.\nUsazená rezervace mění jen stoly, počet osob a poznámky; ukončená se nemění (`409\nreservation_state_conflict`). Pošlete `If-Match` s načteným `ETag`.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReservationUpdate"
       },
       "examples": {
        "party": {
         "summary": "One more guest is coming",
         "value": {
          "party_size": 5
         },
         "x-summary-cs": "Přijde o jednoho víc"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Changed.",
      "x-description-cs": "Změněno.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "updated": {
          "summary": "The changed reservation",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "confirmed",
           "source": "online",
           "party_size": 5,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T21:30:00+01:00",
           "blocked_until": "2027-01-15T21:45:00+01:00",
           "table_ids": [
            "4",
            "7"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": null,
           "cancel_reason": null,
           "version": 2,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Změněná rezervace"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "description": "`precondition_failed`: the object changed since you read it. Read it again and retry.",
      "x-description-cs": "`precondition_failed`: záznam se od načtení změnil. Načtěte ho znovu a zkuste to znovu.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "precondition_failed": {
          "summary": "The staff changed the reservation meanwhile",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#precondition_failed",
           "title": "Záznam se mezitím změnil",
           "status": 412,
           "code": "precondition_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Rezervaci mezitím změnila obsluha"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "428": {
      "$ref": "#/components/responses/PreconditionRequired"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations/{reservation_id}/confirm": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReservationId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "confirmReservation",
    "summary": "Confirm a reservation",
    "x-summary-cs": "Potvrdit rezervaci",
    "description": "A `requested` reservation becomes `confirmed` (the restaurant accepts a reservation that waited for confirmation). A reservation in another state answers `409 reservation_state_conflict`. `If-Match` is optional: with it\nthe change happens only when nobody changed the reservation since you read it.\n",
    "x-description-cs": "Rezervace `requested` se stane `confirmed` (provozovna přijme rezervaci, která čekala na potvrzení). Rezervace v jiném stavu vrátí `409 reservation_state_conflict`. `If-Match` je nepovinný: s ním se změna\nprovede, jen když rezervaci od vašeho načtení nikdo nezměnil.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/ReservationIfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The reservation in its new state.",
      "x-description-cs": "Rezervace v novém stavu.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "confirmed": {
          "summary": "Confirmed",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "confirmed",
           "source": "online",
           "party_size": 4,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T21:00:00+01:00",
           "blocked_until": "2027-01-15T21:15:00+01:00",
           "table_ids": [
            "4"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": null,
           "cancel_reason": null,
           "version": 2,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Potvrzená"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "reservation_state_conflict": {
          "summary": "The reservation is already cancelled",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#reservation_state_conflict",
           "title": "Rezervace je v jiném stavu",
           "status": 409,
           "code": "reservation_state_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Rezervace už je zrušená"
         }
        }
       }
      }
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations/{reservation_id}/reject": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReservationId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "rejectReservation",
    "summary": "Reject a reservation",
    "x-summary-cs": "Odmítnout rezervaci",
    "description": "A `requested` reservation becomes `rejected` and frees its tables or employee. `reason` is shown to the guest. A reservation in another state answers `409 reservation_state_conflict`. `If-Match` is optional: with it\nthe change happens only when nobody changed the reservation since you read it.\n",
    "x-description-cs": "Rezervace `requested` se stane `rejected` a uvolní stoly nebo pracovníka. `reason` uvidí host. Rezervace v jiném stavu vrátí `409 reservation_state_conflict`. `If-Match` je nepovinný: s ním se změna\nprovede, jen když rezervaci od vašeho načtení nikdo nezměnil.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/ReservationIfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReservationAction"
       },
       "examples": {
        "full": {
         "summary": "Fully booked",
         "value": {
          "reason": "Na tento večer máme uzavřenou společnost."
         },
         "x-summary-cs": "Plno"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The reservation in its new state.",
      "x-description-cs": "Rezervace v novém stavu.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "rejected": {
          "summary": "Rejected",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "rejected",
           "source": "online",
           "party_size": 4,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T21:00:00+01:00",
           "blocked_until": "2027-01-15T21:15:00+01:00",
           "table_ids": [
            "4"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": null,
           "cancel_reason": "Na tento večer máme uzavřenou společnost.",
           "version": 2,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Odmítnutá"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations/{reservation_id}/cancel": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReservationId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "cancelReservation",
    "summary": "Cancel a reservation",
    "x-summary-cs": "Zrušit rezervaci",
    "description": "A `requested` or `confirmed` reservation becomes `cancelled` and frees its tables or employee. `reason` is shown to the guest. A reservation in another state answers `409 reservation_state_conflict`. `If-Match` is optional: with it\nthe change happens only when nobody changed the reservation since you read it.\n",
    "x-description-cs": "Rezervace `requested` nebo `confirmed` se stane `cancelled` a uvolní stoly nebo pracovníka. `reason` uvidí host. Rezervace v jiném stavu vrátí `409 reservation_state_conflict`. `If-Match` je nepovinný: s ním se změna\nprovede, jen když rezervaci od vašeho načtení nikdo nezměnil.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/ReservationIfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReservationAction"
       },
       "examples": {
        "guest": {
         "summary": "The guest called",
         "value": {
          "reason": "Host onemocněl"
         },
         "x-summary-cs": "Host volal"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The reservation in its new state.",
      "x-description-cs": "Rezervace v novém stavu.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "cancelled": {
          "summary": "Cancelled",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "cancelled",
           "source": "online",
           "party_size": 4,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T21:00:00+01:00",
           "blocked_until": "2027-01-15T21:15:00+01:00",
           "table_ids": [
            "4"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": null,
           "cancel_reason": "Host onemocněl",
           "version": 2,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Zrušená"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations/{reservation_id}/seat": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReservationId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "seatReservation",
    "summary": "Seat the guests",
    "x-summary-cs": "Usadit hosty",
    "description": "The guests arrived: the reservation becomes `seated`. Send `tab_id` when your register opened a tab for them (`putTab`) – the reservation keeps the link. A reservation in another state answers `409 reservation_state_conflict`. `If-Match` is optional: with it\nthe change happens only when nobody changed the reservation since you read it.\n",
    "x-description-cs": "Hosté přišli: rezervace se stane `seated`. Pošlete `tab_id`, když jim vaše pokladna otevřela účet (`putTab`) – rezervace si vazbu ponechá. Rezervace v jiném stavu vrátí `409 reservation_state_conflict`. `If-Match` je nepovinný: s ním se změna\nprovede, jen když rezervaci od vašeho načtení nikdo nezměnil.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/ReservationIfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReservationAction"
       },
       "examples": {
        "tab": {
         "summary": "Seated with an open tab",
         "value": {
          "tab_id": "01a318f0-a0c0-7834-8f31-7973aa8bb418"
         },
         "x-summary-cs": "Usazení s otevřeným účtem"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The reservation in its new state.",
      "x-description-cs": "Rezervace v novém stavu.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "seated": {
          "summary": "Guests at the table",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "seated",
           "source": "online",
           "party_size": 4,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T21:00:00+01:00",
           "blocked_until": "2027-01-15T21:15:00+01:00",
           "table_ids": [
            "4"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": "01a318f0-a0c0-7834-8f31-7973aa8bb418",
           "cancel_reason": null,
           "version": 2,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Hosté u stolu"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations/{reservation_id}/complete": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReservationId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "completeReservation",
    "summary": "Guests left",
    "x-summary-cs": "Hosté odešli",
    "description": "A `seated` reservation becomes `completed`. When the guests leave earlier than planned, the table is free at once (`ends_at` moves to now). A reservation in another state answers `409 reservation_state_conflict`. `If-Match` is optional: with it\nthe change happens only when nobody changed the reservation since you read it.\n",
    "x-description-cs": "Rezervace `seated` se stane `completed`. Když hosté odejdou dřív, než bylo v plánu, stůl je volný hned (`ends_at` se posune na teď). Rezervace v jiném stavu vrátí `409 reservation_state_conflict`. `If-Match` je nepovinný: s ním se změna\nprovede, jen když rezervaci od vašeho načtení nikdo nezměnil.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/ReservationIfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The reservation in its new state.",
      "x-description-cs": "Rezervace v novém stavu.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "completed": {
          "summary": "They left earlier",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "completed",
           "source": "online",
           "party_size": 4,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T20:40:00+01:00",
           "blocked_until": "2027-01-15T20:40:00+01:00",
           "table_ids": [
            "4"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": null,
           "cancel_reason": null,
           "version": 3,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Odešli dřív"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations/{reservation_id}/no-show": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReservationId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "markReservationNoShow",
    "summary": "Guests did not come",
    "x-summary-cs": "Hosté nepřišli",
    "description": "A `requested` or `confirmed` reservation becomes `no_show` and frees its tables or employee. A paid deposit is forfeited. A reservation in another state answers `409 reservation_state_conflict`. `If-Match` is optional: with it\nthe change happens only when nobody changed the reservation since you read it.\n",
    "x-description-cs": "Rezervace `requested` nebo `confirmed` se stane `no_show` a uvolní stoly nebo pracovníka. Zaplacená záloha propadne. Rezervace v jiném stavu vrátí `409 reservation_state_conflict`. `If-Match` je nepovinný: s ním se změna\nprovede, jen když rezervaci od vašeho načtení nikdo nezměnil.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/ReservationIfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The reservation in its new state.",
      "x-description-cs": "Rezervace v novém stavu.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "no_show": {
          "summary": "They did not come",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "no_show",
           "source": "online",
           "party_size": 4,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T21:00:00+01:00",
           "blocked_until": "2027-01-15T21:15:00+01:00",
           "table_ids": [
            "4"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": null,
           "cancel_reason": null,
           "version": 2,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Nepřišli"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations/{reservation_id}/payment-link": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReservationId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "sendReservationPaymentLink",
    "summary": "Send the link to pay the deposit",
    "x-summary-cs": "Poslat odkaz k zaplacení zálohy",
    "description": "For a `requested` or `confirmed` reservation whose deposit waits for payment (`deposit.status` `pending`) – for\nexample a booking taken by phone. Creates a new link to the guest's page of the reservation, sends it to the\nguest's e-mail (when there is one) and returns it, so you can send it by SMS too. The older link stops working.\nAnother reservation answers `409 reservation_state_conflict`.\n",
    "x-description-cs": "Pro rezervaci `requested` nebo `confirmed`, jejíž záloha čeká na zaplacení (`deposit.status` `pending`) – třeba\npřijatou po telefonu. Vytvoří nový odkaz na stránku rezervace hosta, pošle ho na e-mail hosta (má-li ho) a vrátí\nho, abyste ho mohli poslat i SMS. Starší odkaz přestane platit. Jiná rezervace vrátí `409\nreservation_state_conflict`.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The link.",
      "x-description-cs": "Odkaz.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReservationPaymentLink"
        },
        "examples": {
         "link": {
          "summary": "The link to pay the deposit",
          "value": {
           "url": "https://www.mujprofirest.cz/rezervace/sprava/4f1d0c9a7b2e8f61a3d5c7e9b0a2c4e6f8a1b3d5c7e9f0a2",
           "emailed": true,
           "due_at": "2027-01-15T12:40:12+01:00"
          },
          "x-summary-cs": "Odkaz k zaplacení zálohy"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "reservation_state_conflict": {
          "summary": "The deposit is already paid",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#reservation_state_conflict",
           "title": "Rezervace je v jiném stavu",
           "status": 409,
           "code": "reservation_state_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Záloha už je zaplacená"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservations/{reservation_id}/waive-deposit": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReservationId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "waiveReservationDeposit",
    "summary": "Waive the deposit",
    "x-summary-cs": "Odpustit zálohu",
    "description": "The deposit waiting for payment is waived (the guest pays on the spot, a regular guest …): `deposit.status`\nbecomes `none` and a reservation waiting only for the deposit becomes `confirmed`. A payment that arrives later is\nrefunded by itself. A reservation without a pending deposit answers `409 reservation_state_conflict`.\n",
    "x-description-cs": "Záloha čekající na zaplacení se odpustí (host zaplatí na místě, stálý host …): `deposit.status` bude `none`\na rezervace, která čekala jen na zálohu, bude `confirmed`. Platba, která přijde potom, se vrátí sama. Rezervace\nbez čekající zálohy vrátí `409 reservation_state_conflict`.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/ReservationIfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The reservation without the deposit.",
      "x-description-cs": "Rezervace bez zálohy.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Reservation"
        },
        "examples": {
         "waived": {
          "summary": "Without the deposit, confirmed",
          "value": {
           "id": "5120",
           "uuid": "01a318f0-a0c0-7a44-8d8d-ba7e70efcfaf",
           "restaurant_id": "123",
           "kind": "table",
           "status": "confirmed",
           "source": "phone",
           "party_size": 4,
           "starts_at": "2027-01-15T19:00:00+01:00",
           "ends_at": "2027-01-15T21:00:00+01:00",
           "blocked_until": "2027-01-15T21:15:00+01:00",
           "table_ids": [
            "4"
           ],
           "service_id": null,
           "employee_id": null,
           "employee_any": false,
           "resource_id": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana.svobodova@example.com",
            "customer_id": null
           },
           "note_guest": "U okna, slavíme narozeniny",
           "note_internal": null,
           "tags": [
            "narozeniny"
           ],
           "deposit": {
            "amount": {
             "amount": 40000,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "confirm_due_at": null,
           "tab_id": null,
           "cancel_reason": null,
           "version": 2,
           "created_at": "2027-01-15T11:40:12+01:00",
           "updated_at": "2027-01-15T11:40:12+01:00"
          },
          "x-summary-cs": "Bez zálohy, potvrzená"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "reservation_state_conflict": {
          "summary": "The reservation does not wait for a deposit",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#reservation_state_conflict",
           "title": "Rezervace je v jiném stavu",
           "status": 409,
           "code": "reservation_state_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Rezervace na zálohu nečeká"
         }
        }
       }
      }
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservation-guest": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "getReservationGuest",
    "summary": "Guest history",
    "x-summary-cs": "Historie hosta",
    "description": "A known guest by phone or e-mail – how many times they came, did not come or cancelled, their upcoming\nreservations, the last visit and tags of earlier reservations (allergies, VIP), across all restaurants of the\naccount. Use it while taking a reservation by phone. A phone matches with and without the `+420` prefix. Send at\nleast one of `phone` and `email`.\n",
    "x-description-cs": "Známý host podle telefonu nebo e-mailu – kolikrát přišel, nepřišel nebo zrušil, jeho budoucí rezervace, poslední\nnávštěva a štítky dřívějších rezervací (alergie, VIP), napříč provozovnami účtu. Hodí se při přijímání rezervace po\ntelefonu. Telefon se porovná s předvolbou `+420` i bez ní. Pošlete aspoň jedno z `phone` a `email`.\n",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "phone",
      "in": "query",
      "schema": {
       "type": "string",
       "maxLength": 32,
       "examples": [
        "+420777123456"
       ]
      },
      "example": "+420777123456"
     },
     {
      "name": "email",
      "in": "query",
      "schema": {
       "type": "string",
       "maxLength": 190
      }
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The guest.",
      "x-description-cs": "Host.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReservationGuestHistory"
        },
        "examples": {
         "known": {
          "summary": "A regular guest",
          "value": {
           "known": true,
           "name": "Jana Svobodová",
           "phone": "+420777123456",
           "email": "jana.svobodova@example.com",
           "visits": 7,
           "no_shows": 1,
           "cancelled": 1,
           "upcoming": 1,
           "last_visit_at": "2026-10-24T19:00:00+02:00",
           "tags": [
            "narozeniny",
            "alergie: ořechy"
           ]
          },
          "x-summary-cs": "Stálý host"
         },
         "new": {
          "summary": "A new guest",
          "value": {
           "known": false,
           "name": null,
           "phone": null,
           "email": null,
           "visits": 0,
           "no_shows": 0,
           "cancelled": 0,
           "upcoming": 0,
           "last_visit_at": null,
           "tags": []
          },
          "x-summary-cs": "Nový host"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/waitlist": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "listWaitlist",
    "summary": "Waiting list of today",
    "x-summary-cs": "Čekací listina dneška",
    "description": "Guests without a table who wait today – the longest waiting first. Entries that were seated or left are not listed.",
    "x-description-cs": "Hosté bez stolu, kteří dnes čekají – nejdéle čekající první. Usazení a odešlí v seznamu nejsou.",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The waiting list.",
      "x-description-cs": "Čekací listina.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/WaitlistList"
        },
        "examples": {
         "waiting": {
          "summary": "Two guests wait",
          "value": {
           "data": [
            {
             "id": "88",
             "name": "Rodina Nováková",
             "phone": "+420603123456",
             "party_size": 4,
             "note": "s kočárkem",
             "status": "notified",
             "created_at": "2027-01-15T18:35:10+01:00",
             "notified_at": "2027-01-15T18:52:40+01:00",
             "can_sms": true
            },
            {
             "id": "89",
             "name": "Petr",
             "phone": null,
             "party_size": 2,
             "note": null,
             "status": "waiting",
             "created_at": "2027-01-15T18:48:05+01:00",
             "notified_at": null,
             "can_sms": false
            }
           ]
          },
          "x-summary-cs": "Dva hosté čekají"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "addToWaitlist",
    "summary": "Add a guest to the waiting list",
    "x-summary-cs": "Zapsat hosta na čekací listinu",
    "description": "A guest without a free table. Send a name or a phone (for the SMS that the table is ready).",
    "x-description-cs": "Host bez volného stolu. Pošlete jméno nebo telefon (pro SMS, že je stůl připravený).",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/WaitlistEntryCreate"
       },
       "examples": {
        "family": {
         "summary": "A family of four",
         "value": {
          "name": "Rodina Nováková",
          "phone": "+420603123456",
          "party_size": 4,
          "note": "s kočárkem"
         },
         "x-summary-cs": "Rodina se čtyřmi"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The guest on the list.",
      "x-description-cs": "Host na listině.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/WaitlistEntry"
        },
        "examples": {
         "added": {
          "summary": "On the list",
          "value": {
           "id": "88",
           "name": "Rodina Nováková",
           "phone": "+420603123456",
           "party_size": 4,
           "note": "s kočárkem",
           "status": "waiting",
           "created_at": "2027-01-15T18:35:10+01:00",
           "notified_at": null,
           "can_sms": true
          },
          "x-summary-cs": "Na listině"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/waitlist/{waitlist_id}/notify": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/WaitlistId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "notifyWaitlistEntry",
    "summary": "Tell the guest the table is ready",
    "x-summary-cs": "Dát hostovi vědět, že je stůl připravený",
    "description": "Sends the guest an SMS that the table is ready (only to a Czech mobile number; paid from the credit like other SMS\nto guests). A guest without such a number answers `422 validation_failed` – call them. A guest no longer\nwaiting answers `409 reservation_state_conflict`; an SMS that could not be sent `503 service_unavailable`.\n",
    "x-description-cs": "Pošle hostovi SMS, že je stůl připravený (jen na české mobilní číslo; platí se z kreditu jako ostatní SMS\nhostům). Host bez takového čísla vrátí `422 validation_failed` – zavolejte mu. Host, který už nečeká, vrátí\n`409 reservation_state_conflict`; SMS, která neodešla, `503 service_unavailable`.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The entry after the SMS.",
      "x-description-cs": "Záznam po SMS.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/WaitlistEntry"
        },
        "examples": {
         "sent": {
          "summary": "The SMS was sent",
          "value": {
           "id": "88",
           "name": "Rodina Nováková",
           "phone": "+420603123456",
           "party_size": 4,
           "note": "s kočárkem",
           "status": "notified",
           "created_at": "2027-01-15T18:35:10+01:00",
           "notified_at": "2027-01-15T18:52:40+01:00",
           "can_sms": true
          },
          "x-summary-cs": "SMS odešla"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "The guest has no Czech mobile number",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Host nemá české mobilní číslo"
         }
        }
       }
      }
     },
     "503": {
      "$ref": "#/components/responses/ServiceUnavailable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/waitlist/{waitlist_id}/close": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/WaitlistId"
    }
   ],
   "post": {
    "tags": [
     "Reservations"
    ],
    "operationId": "closeWaitlistEntry",
    "summary": "Seat the guest or remove them from the list",
    "x-summary-cs": "Usadit hosta, nebo ho z listiny vyřadit",
    "description": "`seated` with the `reservation_id` of the reservation you created for the guest (`createReservation` with\n`channel=staff` and `walk_in: true`), or `left` when the guest did not wait.\n",
    "x-description-cs": "`seated` s `reservation_id` rezervace, kterou jste hostovi založili (`createReservation` s `channel=staff`\na `walk_in: true`), nebo `left`, když host nečekal.\n",
    "security": [
     {
      "oauth2": [
       "reservations:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/WaitlistClose"
       },
       "examples": {
        "seated": {
         "summary": "Seated as a walk-in",
         "value": {
          "status": "seated",
          "reservation_id": "5140"
         },
         "x-summary-cs": "Usazený jako host bez rezervace"
        },
        "left": {
         "summary": "Did not wait",
         "value": {
          "status": "left"
         },
         "x-summary-cs": "Nečekal"
        }
       }
      }
     }
    },
    "responses": {
     "204": {
      "description": "Closed.",
      "x-description-cs": "Uzavřeno."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservation-feedback": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "listReservationFeedback",
    "summary": "Guest ratings",
    "x-summary-cs": "Hodnocení hostů",
    "description": "Ratings after the visit (1–5 stars and a comment) of reservations starting in the period, newest first, at most\n500. The guest rates once, two hours after leaving, when the restaurant asks for ratings.\n",
    "x-description-cs": "Hodnocení po návštěvě (1–5 hvězdiček a komentář) rezervací začínajících v období, od nejnovějšího, nejvýš 500.\nHost hodnotí jednou, dvě hodiny po odchodu, když provozovna o hodnocení žádá.\n",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "from",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "date",
       "examples": [
        "2026-11-01"
       ]
      },
      "example": "2026-11-01"
     },
     {
      "name": "to",
      "in": "query",
      "required": true,
      "description": "Inclusive; at most 366 days after `from`.",
      "x-description-cs": "Včetně; nejvýš 366 dní po `from`.",
      "schema": {
       "type": "string",
       "format": "date",
       "examples": [
        "2026-11-30"
       ]
      },
      "example": "2026-11-30"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The ratings and their average.",
      "x-description-cs": "Hodnocení a jejich průměr.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReservationFeedbackList"
        },
        "examples": {
         "month": {
          "summary": "Ratings of November",
          "value": {
           "data": [
            {
             "reservation_id": "5120",
             "starts_at": "2027-01-15T19:00:00+01:00",
             "guest_name": "Jana Svobodová",
             "rating": 5,
             "comment": "Skvělá obsluha",
             "rated_at": "2027-01-15T23:10:00+01:00"
            },
            {
             "reservation_id": "5098",
             "starts_at": "2026-11-08T12:00:00+01:00",
             "guest_name": "Petr Dvořák",
             "rating": 3,
             "comment": "Dlouho jsme čekali na jídlo",
             "rated_at": "2026-11-08T15:02:11+01:00"
            }
           ],
           "count": 2,
           "average": 4.0
          },
          "x-summary-cs": "Hodnocení za listopad"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/reservation-stats": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "getReservationStats",
    "summary": "Reservation statistics",
    "x-summary-cs": "Přehled rezervací",
    "description": "The numbers of reservations starting in the period – the same as Reservations › Book › Overview in the\nadministration: reservations and guests, who came and who did not, cancellations, sources, guests by weekday and\nhour, deposits, ratings, returning guests, services and employees. `table_turn` is how long guests really sit at a\ntable (from seating to leaving) by the size of the party next to the rule, with a suggestion where the rule is\nat least 15 minutes off and there are at least 8 measurements. Blocked tables are not counted.\n",
    "x-description-cs": "Čísla rezervací začínajících v období – stejná jako Rezervace › Kniha › Přehled v administraci: rezervace a hosté,\nkdo přišel a kdo ne, zrušené, odkud přišly, hosté podle dne a hodiny, zálohy, hodnocení, vracející se hosté,\nslužby a pracovníci. `table_turn` je skutečná doba u stolu (od usazení do odchodu) podle velikosti skupiny vedle\npravidla, s návrhem tam, kde se pravidlo liší aspoň o 15 minut a měření je aspoň 8. Blokace stolů se nepočítají.\n",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "from",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "date",
       "examples": [
        "2026-11-01"
       ]
      },
      "example": "2026-11-01"
     },
     {
      "name": "to",
      "in": "query",
      "required": true,
      "description": "Inclusive; at most 366 days after `from`.",
      "x-description-cs": "Včetně; nejvýš 366 dní po `from`.",
      "schema": {
       "type": "string",
       "format": "date",
       "examples": [
        "2026-11-30"
       ]
      },
      "example": "2026-11-30"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The statistics of the period.",
      "x-description-cs": "Přehled za období.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReservationStats"
        },
        "examples": {
         "month": {
          "summary": "November at a glance",
          "value": {
           "from": "2026-11-01",
           "to": "2026-11-30",
           "reservations": 412,
           "guests": 1386,
           "arrived": 371,
           "arrived_guests": 1251,
           "no_show": 9,
           "no_show_rate": 2.4,
           "cancelled": 24,
           "rejected": 2,
           "expired": 3,
           "upcoming": 0,
           "unresolved": 3,
           "avg_party_size": 3.4,
           "avg_lead_days": 4.2,
           "returning_guests": 58,
           "sources": [
            {
             "source": "online",
             "count": 238
            },
            {
             "source": "phone",
             "count": 121
            },
            {
             "source": "admin",
             "count": 53
            }
           ],
           "weekdays": [
            118,
            132,
            160,
            201,
            288,
            310,
            177
           ],
           "hours": [
            {
             "hour": 12,
             "guests": 214
            },
            {
             "hour": 18,
             "guests": 402
            },
            {
             "hour": 19,
             "guests": 466
            },
            {
             "hour": 20,
             "guests": 304
            }
           ],
           "deposits": {
            "paid": {
             "amount": 1840000,
             "currency": "CZK"
            },
            "refunded": {
             "amount": 120000,
             "currency": "CZK"
            },
            "forfeited": {
             "amount": 60000,
             "currency": "CZK"
            }
           },
           "ratings": {
            "count": 96,
            "average": 4.6,
            "low": 5
           },
           "services": [],
           "employees": [],
           "table_turn": {
            "measured": 342,
            "groups": [
             {
              "up_to_party_size": 2,
              "planned_minutes": 90,
              "measured": 151,
              "median_minutes": 68
             },
             {
              "up_to_party_size": 4,
              "planned_minutes": 120,
              "measured": 140,
              "median_minutes": 112
             },
             {
              "up_to_party_size": 99,
              "planned_minutes": 150,
              "measured": 51,
              "median_minutes": 158
             }
            ],
            "suggestions": [
             {
              "up_to_party_size": 2,
              "planned_minutes": 90,
              "median_minutes": 68,
              "suggested_minutes": 75,
              "measured": 151
             }
            ]
           }
          },
          "x-summary-cs": "Přehled za listopad"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/table-status": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reservations"
    ],
    "operationId": "getTableStatus",
    "summary": "Which tables are free now",
    "x-summary-cs": "Které stoly jsou teď volné",
    "description": "Every table of the restaurant's map with its state now: `occupied` – an open tab of the table (also guests\nwithout a reservation) or seated guests of a reservation; `reserved` – a reservation starts within 30 minutes\nor is running and the guests have not been seated yet; `free` otherwise. `next_reservation` is the next one of\nthe day. Tabs carry only the name of the table, so they are matched to the map by name. Poll with\n`If-None-Match`.\n",
    "x-description-cs": "Každý stůl z mapy provozovny se stavem v tuto chvíli: `occupied` – otevřený účet stolu (i hosté bez rezervace)\nnebo usazení hosté rezervace; `reserved` – rezervace začíná do 30 minut nebo běží a hosté ještě nejsou usazení;\njinak `free`. `next_reservation` je další rezervace dne. Účty stolů nesou jen název stolu, s mapou se proto\npárují podle názvu. Dotazujte se s `If-None-Match`.\n",
    "security": [
     {
      "oauth2": [
       "reservations:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The tables.",
      "x-description-cs": "Stoly.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableStatus"
        },
        "examples": {
         "tables": {
          "summary": "Tables at 18:40",
          "value": {
           "at": "2027-01-15T18:40:00+01:00",
           "tables": [
            {
             "id": "4",
             "name": "Stůl 4",
             "room": "Restaurace",
             "seats_min": 2,
             "seats_max": 4,
             "state": "reserved",
             "tab_id": null,
             "reservation_id": "5120",
             "next_reservation": null
            },
            {
             "id": "7",
             "name": "Stůl 7",
             "room": "Restaurace",
             "seats_min": 2,
             "seats_max": 6,
             "state": "occupied",
             "tab_id": "01a318f0-a0c0-7b5f-897a-975233c4fa9d",
             "reservation_id": null,
             "next_reservation": {
              "id": "5133",
              "starts_at": "2027-01-15T20:30:00+01:00",
              "party_size": 6
             }
            }
           ]
          },
          "x-summary-cs": "Stoly v 18:40"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/in-house": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Lodging"
    ],
    "operationId": "listInHouseStays",
    "summary": "Guests staying now",
    "x-summary-cs": "Kdo je právě ubytovaný",
    "description": "Stays checked in now (`checked_in`), ordered by room – for the register to offer „to the room“. `balance` is\nwhat is left to pay on the account of the room. Guests who have not arrived yet or have left are not listed.\n",
    "x-description-cs": "Pobyty, které jsou právě ubytované (`checked_in`), seřazené podle pokoje – aby pokladna mohla nabídnout „na\npokoj“. `balance` je, co zbývá zaplatit na účtu pokoje. Hosté, kteří ještě nepřijeli nebo už odjeli, tu nejsou.\n",
    "security": [
     {
      "oauth2": [
       "lodging:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The stays.",
      "x-description-cs": "Pobyty.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/InHouseStays"
        },
        "examples": {
         "in_house": {
          "summary": "Guests staying now",
          "value": {
           "stays": [
            {
             "id": "193",
             "room": "101",
             "guest_name": "Jana Svobodová",
             "arrival": "2026-11-10",
             "departure": "2026-11-12",
             "guests": 2,
             "balance": {
              "amount": 496500,
              "currency": "CZK"
             },
             "package": null
            },
            {
             "id": "197",
             "room": "201",
             "guest_name": "Tomáš Král",
             "arrival": "2026-11-09",
             "departure": "2026-11-14",
             "guests": 4,
             "balance": {
              "amount": 1850000,
              "currency": "CZK"
             },
             "package": {
              "id": "7",
              "name": "3 + 1 noc zdarma s wellness"
             }
            }
           ]
          },
          "x-summary-cs": "Ubytovaní hosté"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/rooms": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reception"
    ],
    "operationId": "listLodgingRooms",
    "summary": "Rooms and room types",
    "x-summary-cs": "Pokoje a typy pokojů",
    "description": "The room types and the rooms of the restaurant in the order of the occupancy plan (by the type, then by the\nroom), with the state of cleaning. Rooms `out_of_order` cannot be booked. Prices are the basic price of a night;\nthe price of a stay counts the server (seasons, packages, extra beds).\n",
    "x-description-cs": "Typy pokojů a pokoje provozovny v pořadí plánu obsazenosti (podle typu, pak podle pokoje) se stavem úklidu.\nPokoj `out_of_order` nejde rezervovat. Ceny jsou základní cena noci; cenu pobytu počítá server (sezóny,\nbalíčky, přistýlky).\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:read"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The room types and rooms.",
      "x-description-cs": "Typy pokojů a pokoje.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingRooms"
        },
        "examples": {
         "rooms": {
          "summary": "Rooms of a guesthouse",
          "value": {
           "room_types": [
            {
             "id": "43",
             "name": "Dvoulůžkový",
             "description": "Manželská postel, sprcha.",
             "beds": 2,
             "extra_beds": 1,
             "price_night": {
              "amount": 300000,
              "currency": "CZK"
             },
             "price_extra_bed": {
              "amount": 60000,
              "currency": "CZK"
             },
             "min_nights": 1,
             "online": true,
             "sort": 1
            },
            {
             "id": "44",
             "name": "Rodinný",
             "description": null,
             "beds": 4,
             "extra_beds": 0,
             "price_night": {
              "amount": 370000,
              "currency": "CZK"
             },
             "price_extra_bed": {
              "amount": 0,
              "currency": "CZK"
             },
             "min_nights": 2,
             "online": true,
             "sort": 2
            }
           ],
           "rooms": [
            {
             "id": "104",
             "type_id": "43",
             "name": "104",
             "floor": "1",
             "sort": 4,
             "status": "clean",
             "note": null,
             "open_issues": 0
            },
            {
             "id": "105",
             "type_id": "43",
             "name": "105",
             "floor": "1",
             "sort": 5,
             "status": "dirty",
             "note": null,
             "open_issues": 1
            },
            {
             "id": "201",
             "type_id": "44",
             "name": "201",
             "floor": "2",
             "sort": 1,
             "status": "clean",
             "note": "Výhled do zahrady",
             "open_issues": 0
            }
           ]
          },
          "x-summary-cs": "Pokoje penzionu"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "description": "`insufficient_scope` or `customer_not_verified`; on Profirest's own devices also `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` and – on the\nregister – `manager_approval_required`.\n",
      "x-description-cs": "`insufficient_scope` nebo `customer_not_verified`; na vlastních zařízeních Profirestu také `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` a – na pokladně –\n`manager_approval_required`.\n",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "insufficient_scope": {
          "summary": "The token lacks the scope",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#insufficient_scope",
           "title": "Token nemá potřebné oprávnění",
           "status": 403,
           "code": "insufficient_scope",
           "detail": "Missing scope: orders:write",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Token nemá potřebné oprávnění"
         },
         "staff_role_missing": {
          "summary": "An employee without the reception role",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#staff_role_missing",
           "title": "Přihlášený zaměstnanec tohle nesmí",
           "status": 403,
           "code": "staff_role_missing",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Zaměstnanec bez role recepce"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/availability": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reception"
    ],
    "operationId": "getLodgingAvailability",
    "summary": "Free rooms and prices for a stay",
    "x-summary-cs": "Volné pokoje a ceny pro pobyt",
    "description": "For every room type: the rooms free from `arrival` to `departure` and the price of the stay for the number of\nguests (seasons, extra beds, the package `package_id`). `unavailable` says why the type cannot be booked\n(`no_room`, `too_many_guests`, `package_not_applicable`). The reception is not bound by the shortest stay of\nonline booking. When changing a stay send `exclude_stay_id` – its own room counts as free.\n",
    "x-description-cs": "Pro každý typ pokoje: pokoje volné od `arrival` do `departure` a cena pobytu pro počet hostů (sezóny,\npřistýlky, balíček `package_id`). `unavailable` říká, proč typ rezervovat nejde (`no_room`, `too_many_guests`,\n`package_not_applicable`). Recepci neváže nejkratší pobyt online rezervací. Při změně pobytu pošlete\n`exclude_stay_id` – jeho vlastní pokoj se počítá jako volný.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:read"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "name": "arrival",
      "in": "query",
      "required": true,
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2026-11-20"
     },
     {
      "name": "departure",
      "in": "query",
      "required": true,
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2026-11-22"
     },
     {
      "name": "adults",
      "in": "query",
      "required": false,
      "description": "Adults (default 1).",
      "x-description-cs": "Dospělí (výchozí 1).",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 50
      },
      "example": 2
     },
     {
      "name": "children",
      "in": "query",
      "required": false,
      "description": "Children (default 0).",
      "x-description-cs": "Děti (výchozí 0).",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "maximum": 50
      }
     },
     {
      "name": "package_id",
      "in": "query",
      "required": false,
      "description": "The price with this stay package (`listLodgingPackages`).",
      "x-description-cs": "Cena s tímto pobytovým balíčkem (`listLodgingPackages`).",
      "schema": {
       "type": "string",
       "maxLength": 20
      }
     },
     {
      "name": "exclude_stay_id",
      "in": "query",
      "required": false,
      "description": "The stay being changed – its rooms count as free.",
      "x-description-cs": "Měněný pobyt – jeho pokoje se počítají jako volné.",
      "schema": {
       "type": "string",
       "maxLength": 20
      }
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Room types with free rooms and prices.",
      "x-description-cs": "Typy pokojů s volnými pokoji a cenami.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingAvailability"
        },
        "examples": {
         "free": {
          "summary": "Free for the weekend",
          "value": {
           "arrival": "2026-11-20",
           "departure": "2026-11-22",
           "nights": 2,
           "adults": 2,
           "children": 0,
           "room_types": [
            {
             "type_id": "43",
             "name": "Dvoulůžkový",
             "free_rooms": [
              {
               "id": "104",
               "name": "104"
              },
              {
               "id": "105",
               "name": "105"
              }
             ],
             "quote": {
              "total": {
               "amount": 640000,
               "currency": "CZK"
              },
              "list_total": {
               "amount": 640000,
               "currency": "CZK"
              },
              "nights": 2,
              "extra_persons": 0,
              "per_night": [
               {
                "date": "2026-11-20",
                "price": {
                 "amount": 320000,
                 "currency": "CZK"
                },
                "rate": "Víkend"
               },
               {
                "date": "2026-11-21",
                "price": {
                 "amount": 320000,
                 "currency": "CZK"
                },
                "rate": "Víkend"
               }
              ],
              "package": null
             },
             "unavailable": null,
             "message": null
            },
            {
             "type_id": "44",
             "name": "Rodinný",
             "free_rooms": [],
             "quote": {
              "total": {
               "amount": 740000,
               "currency": "CZK"
              },
              "list_total": {
               "amount": 740000,
               "currency": "CZK"
              },
              "nights": 2,
              "extra_persons": 0,
              "per_night": [
               {
                "date": "2026-11-20",
                "price": {
                 "amount": 370000,
                 "currency": "CZK"
                },
                "rate": null
               },
               {
                "date": "2026-11-21",
                "price": {
                 "amount": 370000,
                 "currency": "CZK"
                },
                "rate": null
               }
              ],
              "package": null
             },
             "unavailable": "no_room",
             "message": "V tomto termínu už není volný pokoj tohoto typu."
            }
           ]
          },
          "x-summary-cs": "Volno na víkend"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/registration-lists": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reception"
    ],
    "operationId": "getLodgingRegistrationLists",
    "summary": "Lists for registering guests",
    "x-summary-cs": "Číselníky pro zápis hostů",
    "description": "Values for the form of a registered guest: countries (`nationality`), types of documents, purposes of the stay\nfor the foreign police (Ubyport) and reasons why a guest does not pay the city tax. They change rarely – keep\nthem with the `ETag`.\n",
    "x-description-cs": "Hodnoty pro formulář zapsaného hosta: státy (`nationality`), druhy dokladů, účely pobytu pro cizineckou policii\n(Ubyport) a důvody, proč host neplatí poplatek z pobytu. Mění se zřídka – držte si je s `ETag`.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:read"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The lists.",
      "x-description-cs": "Číselníky.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingRegistrationLists"
        },
        "examples": {
         "lists": {
          "summary": "The lists",
          "value": {
           "countries": [
            {
             "code": "CZ",
             "name": "Česko"
            },
            {
             "code": "DE",
             "name": "Německo"
            }
           ],
           "document_types": [
            {
             "code": "id",
             "name": "občanský průkaz"
            },
            {
             "code": "passport",
             "name": "cestovní pas"
            }
           ],
           "purposes": [
            {
             "code": "10",
             "name": "turistika"
            },
            {
             "code": "01",
             "name": "zaměstnání"
            }
           ],
           "city_tax": {
            "enabled": true,
            "exempt_under_age": 18
           }
          },
          "x-summary-cs": "Číselníky"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reception"
    ],
    "operationId": "listStays",
    "summary": "Stays of the occupancy plan",
    "x-summary-cs": "Pobyty plánu obsazenosti",
    "description": "Stays touching the days `from` – `to` (both included, at most 62 days; without them today): a stay that sleeps\na night in them, arrives or leaves in them. Ordered by the arrival. Without `status` the cancelled stays and\nno-shows are left out.\n\nToday's view of the reception is one call with `from` = `to` = today: arrivals have `arrival` today,\ndepartures `departure` today and the guests staying now `status` `checked_in`. `actions` say which steps the\nserver allows now – show only those buttons. Poll with `If-None-Match`.\n",
    "x-description-cs": "Pobyty, které zasahují do dnů `from` – `to` (oba včetně, nejvýš 62 dní; bez nich dnešek): pobyt, který v nich\nmá noc, přijíždí nebo odjíždí. Podle příjezdu. Bez `status` se zrušené pobyty a nepřijetí vynechají.\n\nDnešek recepce je jedno volání s `from` = `to` = dnes: příjezdy mají `arrival` dnes, odjezdy `departure` dnes\na právě ubytovaní `status` `checked_in`. `actions` říkají, které kroky server teď dovolí – ukažte jen tato\ntlačítka. Dotazujte se s `If-None-Match`.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:read"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "name": "from",
      "in": "query",
      "required": false,
      "description": "First day (default today).",
      "x-description-cs": "První den (výchozí dnešek).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2026-11-10"
     },
     {
      "name": "to",
      "in": "query",
      "required": false,
      "description": "Last day (default `from`).",
      "x-description-cs": "Poslední den (výchozí `from`).",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2026-11-10"
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "Only these states, comma separated (`tentative,confirmed`).",
      "x-description-cs": "Jen tyto stavy, oddělené čárkou (`tentative,confirmed`).",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The stays.",
      "x-description-cs": "Pobyty.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStayList"
        },
        "examples": {
         "today": {
          "summary": "Today at the reception",
          "value": {
           "data": [
            {
             "id": "197",
             "uuid": "0d8c6b2a-9e44-4f3b-8a71-5c2d9e1f4b37",
             "status": "checked_in",
             "source": "channel",
             "arrival": "2026-11-09",
             "departure": "2026-11-14",
             "nights": 5,
             "adults": 2,
             "children": 2,
             "rooms": [
              {
               "room_id": "201",
               "room": "201",
               "type_id": "44",
               "type": "Rodinný",
               "date_from": "2026-11-09",
               "date_to": "2026-11-14"
              }
             ],
             "price_total": {
              "amount": 1850000,
              "currency": "CZK"
             },
             "price_manual": false,
             "package": null,
             "guest": {
              "name": "Tomáš Král",
              "phone": null,
              "email": null,
              "lang": "cs"
             },
             "company": null,
             "note_guest": null,
             "note_internal": null,
             "tags": [],
             "registered_guests": 4,
             "deposit": {
              "amount": {
               "amount": 0,
               "currency": "CZK"
              },
              "status": "none",
              "due_at": null
             },
             "channel": {
              "name": "Booking.com",
              "ref": "4218877310"
             },
             "cancel_reason": null,
             "checked_in_at": "2026-11-09T15:40:00+01:00",
             "checked_out_at": null,
             "actions": [
              "check_out"
             ],
             "balance": {
              "amount": 1850000,
              "currency": "CZK"
             },
             "version": 7,
             "created_at": "2026-10-21T20:02:00+02:00",
             "updated_at": "2026-11-09T15:40:00+01:00"
            },
            {
             "id": "193",
             "uuid": "5b0c2f7e-4a51-4d0e-9a3c-1f2e7d9b6a10",
             "status": "confirmed",
             "source": "phone",
             "arrival": "2026-11-10",
             "departure": "2026-11-12",
             "nights": 2,
             "adults": 2,
             "children": 0,
             "rooms": [
              {
               "room_id": "104",
               "room": "104",
               "type_id": "43",
               "type": "Dvoulůžkový",
               "date_from": "2026-11-10",
               "date_to": "2026-11-12"
              }
             ],
             "price_total": {
              "amount": 600000,
              "currency": "CZK"
             },
             "price_manual": false,
             "package": null,
             "guest": {
              "name": "Jana Svobodová",
              "phone": "+420777123456",
              "email": "jana@example.com",
              "lang": "cs"
             },
             "company": null,
             "note_guest": "Přijedeme kolem 18:00.",
             "note_internal": null,
             "tags": [],
             "registered_guests": 0,
             "deposit": {
              "amount": {
               "amount": 0,
               "currency": "CZK"
              },
              "status": "none",
              "due_at": null
             },
             "channel": null,
             "cancel_reason": null,
             "checked_in_at": null,
             "checked_out_at": null,
             "actions": [
              "check_in",
              "cancel",
              "no_show"
             ],
             "balance": {
              "amount": 600000,
              "currency": "CZK"
             },
             "version": 3,
             "created_at": "2026-11-02T10:14:00+01:00",
             "updated_at": "2026-11-03T09:30:00+01:00"
            }
           ]
          },
          "x-summary-cs": "Dnešek recepce"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "createStay",
    "summary": "Create a stay",
    "x-summary-cs": "Založit pobyt",
    "description": "A booking at the reception: a room (`room_id`) or a room type (`room_type_id` – the server picks the first free\nroom), the dates, guests and the contact of the guest. The server checks the room is free (`409\nlodging_room_unavailable`) and that the guests fit the room (`422`), and counts the price by the price list\nand the package unless you send `price_total`. A stay from the reception is not bound by the rules of online\nbooking (the shortest stay, how far ahead). Repeat safely: the same `Idempotency-Key` or your own `uuid`\nreturn the same stay.\n",
    "x-description-cs": "Rezervace na recepci: pokoj (`room_id`) nebo typ pokoje (`room_type_id` – server vybere první volný pokoj),\ntermín, hosté a kontakt hosta. Server zkontroluje, že je pokoj volný (`409 lodging_room_unavailable`) a že se\nhosté do pokoje vejdou (`422`), a cenu spočítá podle ceníku a balíčku, pokud nepošlete `price_total`. Pobyt\nz recepce neváží pravidla online rezervací (nejkratší pobyt, jak daleko dopředu). Opakování je bezpečné: stejný\n`Idempotency-Key` nebo vaše `uuid` vrátí stejný pobyt.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LodgingStayCreate"
       },
       "examples": {
        "phone": {
         "summary": "A booking by phone",
         "value": {
          "room_id": "104",
          "arrival": "2026-11-10",
          "departure": "2026-11-12",
          "adults": 2,
          "guest": {
           "name": "Jana Svobodová",
           "phone": "+420777123456",
           "email": "jana@example.com",
           "lang": "cs"
          },
          "note_guest": "Přijedeme kolem 18:00.",
          "source": "phone"
         },
         "x-summary-cs": "Rezervace po telefonu"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Created.",
      "x-description-cs": "Založeno.",
      "headers": {
       "Location": {
        "$ref": "#/components/headers/Location"
       },
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStay"
        },
        "examples": {
         "created": {
          "summary": "Created",
          "value": {
           "id": "193",
           "uuid": "5b0c2f7e-4a51-4d0e-9a3c-1f2e7d9b6a10",
           "status": "confirmed",
           "source": "phone",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "nights": 2,
           "adults": 2,
           "children": 0,
           "rooms": [
            {
             "room_id": "104",
             "room": "104",
             "type_id": "43",
             "type": "Dvoulůžkový",
             "date_from": "2026-11-10",
             "date_to": "2026-11-12"
            }
           ],
           "price_total": {
            "amount": 600000,
            "currency": "CZK"
           },
           "price_manual": false,
           "package": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana@example.com",
            "lang": "cs"
           },
           "company": null,
           "note_guest": "Přijedeme kolem 18:00.",
           "note_internal": null,
           "tags": [],
           "registered_guests": 0,
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "channel": null,
           "cancel_reason": null,
           "checked_in_at": null,
           "checked_out_at": null,
           "actions": [
            "check_in",
            "cancel",
            "no_show"
           ],
           "balance": {
            "amount": 600000,
            "currency": "CZK"
           },
           "version": 1,
           "created_at": "2026-11-02T10:14:00+01:00",
           "updated_at": "2026-11-03T09:30:00+01:00"
          },
          "x-summary-cs": "Založeno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "lodging_room_unavailable": {
          "summary": "The room is taken",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#lodging_room_unavailable",
           "title": "Pokoj v tomto termínu není volný",
           "status": 409,
           "code": "lodging_room_unavailable",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Pokoj je obsazený"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "get": {
    "tags": [
     "Reception"
    ],
    "operationId": "getStay",
    "summary": "Get a stay",
    "x-summary-cs": "Detail pobytu",
    "description": "The stay with the registered guests and their documents, what is left to pay, the receipt for the stay and the\nhistory. The `ETag` is the version (`version`) – send it in `If-Match` when changing the stay.\n",
    "x-description-cs": "Pobyt se zapsanými hosty a jejich doklady, co zbývá zaplatit, doklad za pobyt a historie. `ETag` je verze\n(`version`) – při změně pobytu ji pošlete v `If-Match`.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:read"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The stay.",
      "x-description-cs": "Pobyt.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStayDetail"
        },
        "examples": {
         "detail": {
          "summary": "A stay from Booking.com",
          "value": {
           "stay": {
            "id": "197",
            "uuid": "0d8c6b2a-9e44-4f3b-8a71-5c2d9e1f4b37",
            "status": "checked_in",
            "source": "channel",
            "arrival": "2026-11-09",
            "departure": "2026-11-14",
            "nights": 5,
            "adults": 2,
            "children": 2,
            "rooms": [
             {
              "room_id": "201",
              "room": "201",
              "type_id": "44",
              "type": "Rodinný",
              "date_from": "2026-11-09",
              "date_to": "2026-11-14"
             }
            ],
            "price_total": {
             "amount": 1850000,
             "currency": "CZK"
            },
            "price_manual": false,
            "package": null,
            "guest": {
             "name": "Tomáš Král",
             "phone": null,
             "email": null,
             "lang": "cs"
            },
            "company": null,
            "note_guest": null,
            "note_internal": null,
            "tags": [],
            "registered_guests": 4,
            "deposit": {
             "amount": {
              "amount": 0,
              "currency": "CZK"
             },
             "status": "none",
             "due_at": null
            },
            "channel": {
             "name": "Booking.com",
             "ref": "4218877310"
            },
            "cancel_reason": null,
            "checked_in_at": "2026-11-09T15:40:00+01:00",
            "checked_out_at": null,
            "actions": [
             "check_out"
            ],
            "balance": {
             "amount": 1850000,
             "currency": "CZK"
            },
            "version": 7,
            "created_at": "2026-10-21T20:02:00+02:00",
            "updated_at": "2026-11-09T15:40:00+01:00"
           },
           "balance": {
            "amount": 1850000,
            "currency": "CZK"
           },
           "guests": [
            {
             "id": "611",
             "first_name": "Tomáš",
             "last_name": "Král",
             "birth_date": "1986-04-12",
             "nationality": "CZ",
             "nationality_name": "Česko",
             "foreigner": false,
             "document_type": "id",
             "document_no": "209384756",
             "visa_no": null,
             "address": "Lipová 12, Brno",
             "purpose": null,
             "arrival": "2026-11-09",
             "departure": "2026-11-14",
             "fee_exempt": null,
             "note": null,
             "ubyport": {
              "state": "none",
              "sent_at": null,
              "error": null
             }
            },
            {
             "id": "612",
             "first_name": "Anna",
             "last_name": "Müller",
             "birth_date": "1988-09-30",
             "nationality": "DE",
             "nationality_name": "Německo",
             "foreigner": true,
             "document_type": "passport",
             "document_no": "C01X00T47",
             "visa_no": null,
             "address": "Hauptstraße 5, Dresden",
             "purpose": "10",
             "arrival": "2026-11-09",
             "departure": "2026-11-14",
             "fee_exempt": null,
             "note": null,
             "ubyport": {
              "state": "sent",
              "sent_at": "2026-11-09T16:05:00+01:00",
              "error": null
             }
            }
           ],
           "receipt": null,
           "history": [
            {
             "at": "2026-10-21T20:02:00+02:00",
             "actor": "channel",
             "employee_id": null,
             "action": "created",
             "from_status": null,
             "to_status": "confirmed"
            },
            {
             "at": "2026-11-09T15:40:00+01:00",
             "actor": "employee",
             "employee_id": "27",
             "action": "checked_in",
             "from_status": "confirmed",
             "to_status": "checked_in"
            }
           ]
          },
          "x-summary-cs": "Pobyt z Booking.com"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "patch": {
    "tags": [
     "Reception"
    ],
    "operationId": "updateStay",
    "summary": "Change a stay",
    "x-summary-cs": "Změnit pobyt",
    "description": "Send only what changes: the guest's contact, the number of guests, notes, tags, the price or the package. More\nguests are checked against the room (`422`); the price not set by hand is counted again. The dates and the room\nchange with `moveStay`. A stay with an issued receipt does not change (`409 stay_state_conflict`). Send\n`If-Match` with the `ETag` of `getStay`.\n",
    "x-description-cs": "Pošlete jen to, co se mění: kontakt hosta, počet hostů, poznámky, štítky, cenu nebo balíček. Víc hostů se\nporovná s pokojem (`422`); cena, která není zadaná ručně, se spočítá znovu. Termín a pokoj mění `moveStay`.\nPobyt s vystaveným dokladem se nemění (`409 stay_state_conflict`). Pošlete `If-Match` s `ETag` z `getStay`.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IfMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LodgingStayUpdate"
       },
       "examples": {
        "more": {
         "summary": "A child comes too",
         "value": {
          "children": 1,
          "note_internal": "Dětská postýlka"
         },
         "x-summary-cs": "Přijede i dítě"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Changed.",
      "x-description-cs": "Změněno.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStay"
        },
        "examples": {
         "changed": {
          "summary": "Changed",
          "value": {
           "id": "193",
           "uuid": "5b0c2f7e-4a51-4d0e-9a3c-1f2e7d9b6a10",
           "status": "confirmed",
           "source": "phone",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "nights": 2,
           "adults": 2,
           "children": 1,
           "rooms": [
            {
             "room_id": "104",
             "room": "104",
             "type_id": "43",
             "type": "Dvoulůžkový",
             "date_from": "2026-11-10",
             "date_to": "2026-11-12"
            }
           ],
           "price_total": {
            "amount": 600000,
            "currency": "CZK"
           },
           "price_manual": false,
           "package": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana@example.com",
            "lang": "cs"
           },
           "company": null,
           "note_guest": "Přijedeme kolem 18:00.",
           "note_internal": "Dětská postýlka",
           "tags": [],
           "registered_guests": 0,
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "channel": null,
           "cancel_reason": null,
           "checked_in_at": null,
           "checked_out_at": null,
           "actions": [
            "check_in",
            "cancel",
            "no_show"
           ],
           "balance": {
            "amount": 600000,
            "currency": "CZK"
           },
           "version": 4,
           "created_at": "2026-11-02T10:14:00+01:00",
           "updated_at": "2026-11-03T09:30:00+01:00"
          },
          "x-summary-cs": "Změněno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "description": "`precondition_failed`: the object changed since you read it. Read it again and retry.",
      "x-description-cs": "`precondition_failed`: záznam se od načtení změnil. Načtěte ho znovu a zkuste to znovu.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "precondition_failed": {
          "summary": "Somebody changed the stay meanwhile",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#precondition_failed",
           "title": "Záznam se mezitím změnil",
           "status": 412,
           "code": "precondition_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Pobyt mezitím změnil někdo jiný"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "428": {
      "$ref": "#/components/responses/PreconditionRequired"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/move": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "moveStay",
    "summary": "Move or extend a stay",
    "x-summary-cs": "Přesunout nebo prodloužit pobyt",
    "description": "The stay gets the room and the dates (also a longer or shorter stay). The new room must be free in the new dates\n(without this stay) and not out of order (`409 lodging_room_unavailable`). Guests, services by nights and the city tax\nmove with the stay; a price not set by hand is counted again. A stay that has left or was cancelled does not move\n(`409 lodging_state_conflict`).\n",
    "x-description-cs": "Pobyt dostane pokoj a termín (i delší nebo kratší pobyt). Nový pokoj musí být v novém termínu volný (bez tohoto\npobytu) a ne mimo provoz (`409 lodging_room_unavailable`). Hosté, služby po nocích a poplatek z pobytu se posunou\ns pobytem; cena, která není zadaná ručně, se spočítá znovu. Odjetý nebo zrušený pobyt se nepřesouvá (`409\nlodging_state_conflict`).\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IfMatch"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LodgingStayMove"
       },
       "examples": {
        "longer": {
         "summary": "One night longer in another room",
         "value": {
          "room_id": "105",
          "arrival": "2026-11-10",
          "departure": "2026-11-13"
         },
         "x-summary-cs": "O noc déle a do jiného pokoje"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Moved.",
      "x-description-cs": "Přesunuto.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStay"
        },
        "examples": {
         "moved": {
          "summary": "Moved",
          "value": {
           "id": "193",
           "uuid": "5b0c2f7e-4a51-4d0e-9a3c-1f2e7d9b6a10",
           "status": "confirmed",
           "source": "phone",
           "arrival": "2026-11-10",
           "departure": "2026-11-13",
           "nights": 3,
           "adults": 2,
           "children": 0,
           "rooms": [
            {
             "room_id": "105",
             "room": "105",
             "type_id": "43",
             "type": "Dvoulůžkový",
             "date_from": "2026-11-10",
             "date_to": "2026-11-13"
            }
           ],
           "price_total": {
            "amount": 900000,
            "currency": "CZK"
           },
           "price_manual": false,
           "package": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana@example.com",
            "lang": "cs"
           },
           "company": null,
           "note_guest": "Přijedeme kolem 18:00.",
           "note_internal": null,
           "tags": [],
           "registered_guests": 0,
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "channel": null,
           "cancel_reason": null,
           "checked_in_at": null,
           "checked_out_at": null,
           "actions": [
            "check_in",
            "cancel",
            "no_show"
           ],
           "balance": {
            "amount": 600000,
            "currency": "CZK"
           },
           "version": 4,
           "created_at": "2026-11-02T10:14:00+01:00",
           "updated_at": "2026-11-03T09:30:00+01:00"
          },
          "x-summary-cs": "Přesunuto"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "lodging_room_unavailable": {
          "summary": "The room is taken in the new dates",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#lodging_room_unavailable",
           "title": "Pokoj v tomto termínu není volný",
           "status": 409,
           "code": "lodging_room_unavailable",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Pokoj je v novém termínu obsazený"
         }
        }
       }
      }
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "428": {
      "$ref": "#/components/responses/PreconditionRequired"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/confirm": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "confirmStay",
    "summary": "Confirm a stay",
    "x-summary-cs": "Potvrdit pobyt",
    "description": "A tentative stay becomes confirmed.\n",
    "x-description-cs": "Předběžný pobyt se stane potvrzeným.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/StayIfMatch"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Done.",
      "x-description-cs": "Hotovo.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStay"
        },
        "examples": {
         "confirmed": {
          "summary": "Confirmed",
          "value": {
           "id": "193",
           "uuid": "5b0c2f7e-4a51-4d0e-9a3c-1f2e7d9b6a10",
           "status": "confirmed",
           "source": "phone",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "nights": 2,
           "adults": 2,
           "children": 0,
           "rooms": [
            {
             "room_id": "104",
             "room": "104",
             "type_id": "43",
             "type": "Dvoulůžkový",
             "date_from": "2026-11-10",
             "date_to": "2026-11-12"
            }
           ],
           "price_total": {
            "amount": 600000,
            "currency": "CZK"
           },
           "price_manual": false,
           "package": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana@example.com",
            "lang": "cs"
           },
           "company": null,
           "note_guest": "Přijedeme kolem 18:00.",
           "note_internal": null,
           "tags": [],
           "registered_guests": 0,
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "channel": null,
           "cancel_reason": null,
           "checked_in_at": null,
           "checked_out_at": null,
           "actions": [
            "check_in",
            "cancel",
            "no_show"
           ],
           "balance": {
            "amount": 600000,
            "currency": "CZK"
           },
           "version": 3,
           "created_at": "2026-11-02T10:14:00+01:00",
           "updated_at": "2026-11-03T09:30:00+01:00"
          },
          "x-summary-cs": "Potvrzeno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/check-in": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "checkInStay",
    "summary": "Check guests in",
    "x-summary-cs": "Ubytovat hosty",
    "description": "From the day of arrival. Register the guests (`addStayGuest`) before or after – foreigners go to Ubyport.\n",
    "x-description-cs": "Ode dne příjezdu. Hosty zapište (`addStayGuest`) předem nebo potom – cizinci jdou do Ubyportu.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/StayIfMatch"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Done.",
      "x-description-cs": "Hotovo.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStay"
        },
        "examples": {
         "in": {
          "summary": "Checked in",
          "value": {
           "id": "193",
           "uuid": "5b0c2f7e-4a51-4d0e-9a3c-1f2e7d9b6a10",
           "status": "checked_in",
           "source": "phone",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "nights": 2,
           "adults": 2,
           "children": 0,
           "rooms": [
            {
             "room_id": "104",
             "room": "104",
             "type_id": "43",
             "type": "Dvoulůžkový",
             "date_from": "2026-11-10",
             "date_to": "2026-11-12"
            }
           ],
           "price_total": {
            "amount": 600000,
            "currency": "CZK"
           },
           "price_manual": false,
           "package": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana@example.com",
            "lang": "cs"
           },
           "company": null,
           "note_guest": "Přijedeme kolem 18:00.",
           "note_internal": null,
           "tags": [],
           "registered_guests": 0,
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "channel": null,
           "cancel_reason": null,
           "checked_in_at": "2026-11-10T17:52:00+01:00",
           "checked_out_at": null,
           "actions": [
            "check_out"
           ],
           "balance": {
            "amount": 600000,
            "currency": "CZK"
           },
           "version": 4,
           "created_at": "2026-11-02T10:14:00+01:00",
           "updated_at": "2026-11-03T09:30:00+01:00"
          },
          "x-summary-cs": "Ubytováno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "stay_state_conflict": {
          "summary": "Before the day of arrival",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#stay_state_conflict",
           "title": "Pobyt tento krok teď nedovolí",
           "status": 409,
           "code": "stay_state_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Před dnem příjezdu"
         }
        }
       }
      }
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/check-out": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "checkOutStay",
    "summary": "Check guests out",
    "x-summary-cs": "Odhlásit hosty",
    "description": "The guests leave: the room goes to cleaning. Leaving earlier ends the stay today and counts the price again.\nFrom a settled account (`balance` 0) the server makes the receipt for the stay (`getStay.receipt`); when something is\nleft to pay, settle it and the receipt comes after the payment.\n",
    "x-description-cs": "Hosté odjíždějí: pokoj jde k úklidu. Dřívější odjezd ukončí pobyt dnes a cenu spočítá znovu. Z vyrovnaného účtu\n(`balance` 0) server vystaví doklad za pobyt (`getStay.receipt`); když zbývá doplatit, doklad vznikne po zaplacení.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/StayIfMatch"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Done.",
      "x-description-cs": "Hotovo.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStay"
        },
        "examples": {
         "out": {
          "summary": "Checked out",
          "value": {
           "id": "197",
           "uuid": "0d8c6b2a-9e44-4f3b-8a71-5c2d9e1f4b37",
           "status": "checked_out",
           "source": "channel",
           "arrival": "2026-11-09",
           "departure": "2026-11-14",
           "nights": 5,
           "adults": 2,
           "children": 2,
           "rooms": [
            {
             "room_id": "201",
             "room": "201",
             "type_id": "44",
             "type": "Rodinný",
             "date_from": "2026-11-09",
             "date_to": "2026-11-14"
            }
           ],
           "price_total": {
            "amount": 1850000,
            "currency": "CZK"
           },
           "price_manual": false,
           "package": null,
           "guest": {
            "name": "Tomáš Král",
            "phone": null,
            "email": null,
            "lang": "cs"
           },
           "company": null,
           "note_guest": null,
           "note_internal": null,
           "tags": [],
           "registered_guests": 4,
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "channel": {
            "name": "Booking.com",
            "ref": "4218877310"
           },
           "cancel_reason": null,
           "checked_in_at": "2026-11-09T15:40:00+01:00",
           "checked_out_at": "2026-11-14T09:40:00+01:00",
           "actions": [],
           "balance": {
            "amount": 0,
            "currency": "CZK"
           },
           "version": 8,
           "created_at": "2026-10-21T20:02:00+02:00",
           "updated_at": "2026-11-09T15:40:00+01:00"
          },
          "x-summary-cs": "Odhlášeno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/cancel": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "cancelStay",
    "summary": "Cancel a stay",
    "x-summary-cs": "Zrušit pobyt",
    "description": "Before the arrival. A paid deposit goes back to the guest unless `keep_deposit`.\n",
    "x-description-cs": "Před příjezdem. Zaplacená záloha se hostovi vrátí, pokud nepošlete `keep_deposit`.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/StayIfMatch"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LodgingStayCancel"
       },
       "examples": {
        "reason": {
         "summary": "The guest cancelled",
         "value": {
          "reason": "Nemoc"
         },
         "x-summary-cs": "Host zrušil"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Done.",
      "x-description-cs": "Hotovo.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStay"
        },
        "examples": {
         "cancelled": {
          "summary": "Cancelled",
          "value": {
           "id": "193",
           "uuid": "5b0c2f7e-4a51-4d0e-9a3c-1f2e7d9b6a10",
           "status": "cancelled",
           "source": "phone",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "nights": 2,
           "adults": 2,
           "children": 0,
           "rooms": [
            {
             "room_id": "104",
             "room": "104",
             "type_id": "43",
             "type": "Dvoulůžkový",
             "date_from": "2026-11-10",
             "date_to": "2026-11-12"
            }
           ],
           "price_total": {
            "amount": 600000,
            "currency": "CZK"
           },
           "price_manual": false,
           "package": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana@example.com",
            "lang": "cs"
           },
           "company": null,
           "note_guest": "Přijedeme kolem 18:00.",
           "note_internal": null,
           "tags": [],
           "registered_guests": 0,
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "channel": null,
           "cancel_reason": "Nemoc",
           "checked_in_at": null,
           "checked_out_at": null,
           "actions": [],
           "balance": null,
           "version": 4,
           "created_at": "2026-11-02T10:14:00+01:00",
           "updated_at": "2026-11-03T09:30:00+01:00"
          },
          "x-summary-cs": "Zrušeno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/no-show": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "markStayNoShow",
    "summary": "Mark a no-show",
    "x-summary-cs": "Host nepřijel",
    "description": "From the day of arrival; the room is free again and a paid deposit is kept.\n",
    "x-description-cs": "Ode dne příjezdu; pokoj je zase volný a zaplacená záloha propadá.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/StayIfMatch"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Done.",
      "x-description-cs": "Hotovo.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStay"
        },
        "examples": {
         "no_show": {
          "summary": "Did not come",
          "value": {
           "id": "193",
           "uuid": "5b0c2f7e-4a51-4d0e-9a3c-1f2e7d9b6a10",
           "status": "no_show",
           "source": "phone",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "nights": 2,
           "adults": 2,
           "children": 0,
           "rooms": [
            {
             "room_id": "104",
             "room": "104",
             "type_id": "43",
             "type": "Dvoulůžkový",
             "date_from": "2026-11-10",
             "date_to": "2026-11-12"
            }
           ],
           "price_total": {
            "amount": 600000,
            "currency": "CZK"
           },
           "price_manual": false,
           "package": null,
           "guest": {
            "name": "Jana Svobodová",
            "phone": "+420777123456",
            "email": "jana@example.com",
            "lang": "cs"
           },
           "company": null,
           "note_guest": "Přijedeme kolem 18:00.",
           "note_internal": null,
           "tags": [],
           "registered_guests": 0,
           "deposit": {
            "amount": {
             "amount": 0,
             "currency": "CZK"
            },
            "status": "none",
            "due_at": null
           },
           "channel": null,
           "cancel_reason": null,
           "checked_in_at": null,
           "checked_out_at": null,
           "actions": [],
           "balance": null,
           "version": 4,
           "created_at": "2026-11-02T10:14:00+01:00",
           "updated_at": "2026-11-03T09:30:00+01:00"
          },
          "x-summary-cs": "Nepřijel"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/guests": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "addStayGuest",
    "summary": "Register a guest",
    "x-summary-cs": "Zapsat hosta",
    "description": "Adds a guest to the guest book of the stay. A foreigner waits for Ubyport (`ubyport.state` `pending`) and the\nserver sends him within the deadline.\n",
    "x-description-cs": "Přidá hosta do evidence pobytu. Cizinec čeká na Ubyport (`ubyport.state` `pending`) a server ho odešle ve\nlhůtě.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LodgingGuestInput"
       },
       "examples": {
        "foreigner": {
         "summary": "A foreigner with a passport",
         "value": {
          "first_name": "Anna",
          "last_name": "Müller",
          "birth_date": "1988-09-30",
          "nationality": "DE",
          "document_type": "passport",
          "document_no": "C01X00T47",
          "address": "Hauptstraße 5, Dresden",
          "purpose": "10"
         },
         "x-summary-cs": "Cizinka s pasem"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Registered.",
      "x-description-cs": "Zapsáno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingGuest"
        },
        "examples": {
         "registered": {
          "summary": "Registered",
          "value": {
           "id": "612",
           "first_name": "Anna",
           "last_name": "Müller",
           "birth_date": "1988-09-30",
           "nationality": "DE",
           "nationality_name": "Německo",
           "foreigner": true,
           "document_type": "passport",
           "document_no": "C01X00T47",
           "visa_no": null,
           "address": "Hauptstraße 5, Dresden",
           "purpose": "10",
           "arrival": "2026-11-09",
           "departure": "2026-11-14",
           "fee_exempt": null,
           "note": null,
           "ubyport": {
            "state": "pending",
            "sent_at": null,
            "error": null
           }
          },
          "x-summary-cs": "Zapsáno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "A foreigner without the date of birth",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Cizinec bez data narození"
         }
        }
       }
      }
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/guests/{guest_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    },
    {
     "name": "guest_id",
     "in": "path",
     "required": true,
     "description": "`LodgingGuest.id`.",
     "x-description-cs": "`LodgingGuest.id`.",
     "schema": {
      "type": "string",
      "maxLength": 20
     },
     "example": "612"
    }
   ],
   "put": {
    "tags": [
     "Reception"
    ],
    "operationId": "updateStayGuest",
    "summary": "Change a registered guest",
    "x-summary-cs": "Změnit zapsaného hosta",
    "description": "Replaces the guest's data. A foreigner already reported whose name, birth, document or dates change goes to\nUbyport again.\n",
    "x-description-cs": "Nahradí údaje hosta. Už nahlášený cizinec, kterému se změní jméno, narození, doklad nebo termín, jde do Ubyportu\nznovu.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LodgingGuestInput"
       },
       "examples": {
        "visa": {
         "summary": "The visa added",
         "value": {
          "first_name": "Anna",
          "last_name": "Müller",
          "birth_date": "1988-09-30",
          "nationality": "DE",
          "document_type": "passport",
          "document_no": "C01X00T47",
          "address": "Hauptstraße 5, Dresden",
          "purpose": "10",
          "visa_no": "CZE1234567"
         },
         "x-summary-cs": "Doplněné vízum"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Changed.",
      "x-description-cs": "Změněno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingGuest"
        },
        "examples": {
         "changed": {
          "summary": "Changed",
          "value": {
           "id": "612",
           "first_name": "Anna",
           "last_name": "Müller",
           "birth_date": "1988-09-30",
           "nationality": "DE",
           "nationality_name": "Německo",
           "foreigner": true,
           "document_type": "passport",
           "document_no": "C01X00T47",
           "visa_no": "CZE1234567",
           "address": "Hauptstraße 5, Dresden",
           "purpose": "10",
           "arrival": "2026-11-09",
           "departure": "2026-11-14",
           "fee_exempt": null,
           "note": null,
           "ubyport": {
            "state": "pending",
            "sent_at": null,
            "error": null
           }
          },
          "x-summary-cs": "Změněno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "delete": {
    "tags": [
     "Reception"
    ],
    "operationId": "deleteStayGuest",
    "summary": "Remove a registered guest",
    "x-summary-cs": "Smazat zapsaného hosta",
    "description": "Removes the guest from the guest book of the stay (a mistake, the guest did not come).",
    "x-description-cs": "Odebere hosta z evidence pobytu (omyl, host nepřijel).",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Removed.",
      "x-description-cs": "Smazáno."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/services": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reception"
    ],
    "operationId": "listLodgingServices",
    "summary": "Services of the price list",
    "x-summary-cs": "Služby ceníku",
    "description": "The services the reception can add to the account of a room (`addStayService`): breakfast, board, extra beds, pets, wellness, parking.\n",
    "x-description-cs": "Služby, které recepce přidá na účet pokoje (`addStayService`): snídaně, strava, přistýlky, mazlíčci, wellness, parkování.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:read"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The services.",
      "x-description-cs": "Služby.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingServiceList"
        },
        "examples": {
         "services": {
          "summary": "The price list of services",
          "value": {
           "data": [
            {
             "id": "11",
             "name": "Snídaně",
             "category": "breakfast",
             "unit": "person_night",
             "price": {
              "amount": 25000,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "online": true
            },
            {
             "id": "12",
             "name": "Pes",
             "category": "pet",
             "unit": "night",
             "price": {
              "amount": 20000,
              "currency": "CZK"
             },
             "vat_rate": 21,
             "online": true
            },
            {
             "id": "13",
             "name": "Wellness – 2 hodiny",
             "category": "wellness",
             "unit": "item",
             "price": {
              "amount": 45000,
              "currency": "CZK"
             },
             "vat_rate": 21,
             "online": false
            }
           ]
          },
          "x-summary-cs": "Ceník služeb"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/services": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "addStayService",
    "summary": "Add a service to the account",
    "x-summary-cs": "Přidat službu na účet",
    "description": "A service of the price list on the account of the room. The quantity follows the unit of the service: `stay`\nand `item` use `quantity`; `night` the nights from `date_from` to `date_to` (default the whole stay) × `quantity`;\n`person_night` the nights × `persons` (default all guests). An account with an issued receipt does not change\n(`409 stay_state_conflict`).\n",
    "x-description-cs": "Služba z ceníku na účet pokoje. Množství podle jednotky služby: `stay` a `item` podle `quantity`; `night` noci od\n`date_from` do `date_to` (výchozí celý pobyt) × `quantity`; `person_night` noci × `persons` (výchozí všichni\nhosté). Účet s vystaveným dokladem se nemění (`409 stay_state_conflict`).\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StayServiceInput"
       },
       "examples": {
        "breakfast": {
         "summary": "Breakfast for both",
         "value": {
          "service_id": "11"
         },
         "x-summary-cs": "Snídaně pro oba"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Added; the account.",
      "x-description-cs": "Přidáno; účet.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StayFolio"
        },
        "examples": {
         "added": {
          "summary": "On the account",
          "value": {
           "stay_id": "193",
           "status": "checked_in",
           "package": null,
           "room": "101",
           "guest_name": "Jana Svobodová",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "accommodation": {
            "amount": 600000,
            "currency": "CZK"
           },
           "city_tax": {
            "amount": {
             "amount": 12000,
             "currency": "CZK"
            },
            "estimate": false
           },
           "lines": [
            {
             "id": "301",
             "kind": "service",
             "name": "Snídaně",
             "quantity": 4,
             "unit_price": {
              "amount": 25000,
              "currency": "CZK"
             },
             "total": {
              "amount": 100000,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": "2026-11-10",
             "date_to": "2026-11-12",
             "reference": null,
             "created_at": "2026-11-10T15:12:40+01:00"
            },
            {
             "id": "305",
             "kind": "pos",
             "name": "Restaurace – účet 2026/1184",
             "quantity": 1,
             "unit_price": {
              "amount": 84500,
              "currency": "CZK"
             },
             "total": {
              "amount": 84500,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": null,
             "date_to": null,
             "reference": "pokladna-1:2026/1184",
             "created_at": "2026-11-10T21:04:12+01:00"
            }
           ],
           "total": {
            "amount": 796500,
            "currency": "CZK"
           },
           "payments": [
            {
             "id": "41",
             "amount": {
              "amount": 300000,
              "currency": "CZK"
             },
             "method": "transfer",
             "note": "záloha",
             "paid_at": "2026-11-03T09:30:00+01:00"
            }
           ],
           "paid": {
            "amount": 300000,
            "currency": "CZK"
           },
           "balance": {
            "amount": 496500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Na účtu"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "stay_state_conflict": {
          "summary": "The account has a receipt",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#stay_state_conflict",
           "title": "Pobyt tento krok teď nedovolí",
           "status": 409,
           "code": "stay_state_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Účet má vystavený doklad"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/folio-lines": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "addStayCharge",
    "summary": "Add an item to the account",
    "x-summary-cs": "Přidat položku na účet",
    "description": "An item outside the price list (a minibar, damage, a taxi) with its own name, price and VAT rate.\n",
    "x-description-cs": "Položka mimo ceník (minibar, škoda, taxi) s vlastním názvem, cenou a sazbou DPH.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StayChargeInput"
       },
       "examples": {
        "minibar": {
         "summary": "The minibar",
         "value": {
          "name": "Minibar",
          "amount": {
           "amount": 12000,
           "currency": "CZK"
          },
          "vat_rate": 21
         },
         "x-summary-cs": "Minibar"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Added; the account.",
      "x-description-cs": "Přidáno; účet.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StayFolio"
        },
        "examples": {
         "added": {
          "summary": "On the account",
          "value": {
           "stay_id": "193",
           "status": "checked_in",
           "package": null,
           "room": "101",
           "guest_name": "Jana Svobodová",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "accommodation": {
            "amount": 600000,
            "currency": "CZK"
           },
           "city_tax": {
            "amount": {
             "amount": 12000,
             "currency": "CZK"
            },
            "estimate": false
           },
           "lines": [
            {
             "id": "301",
             "kind": "service",
             "name": "Snídaně",
             "quantity": 4,
             "unit_price": {
              "amount": 25000,
              "currency": "CZK"
             },
             "total": {
              "amount": 100000,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": "2026-11-10",
             "date_to": "2026-11-12",
             "reference": null,
             "created_at": "2026-11-10T15:12:40+01:00"
            },
            {
             "id": "305",
             "kind": "pos",
             "name": "Restaurace – účet 2026/1184",
             "quantity": 1,
             "unit_price": {
              "amount": 84500,
              "currency": "CZK"
             },
             "total": {
              "amount": 84500,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": null,
             "date_to": null,
             "reference": "pokladna-1:2026/1184",
             "created_at": "2026-11-10T21:04:12+01:00"
            }
           ],
           "total": {
            "amount": 796500,
            "currency": "CZK"
           },
           "payments": [
            {
             "id": "41",
             "amount": {
              "amount": 300000,
              "currency": "CZK"
             },
             "method": "transfer",
             "note": "záloha",
             "paid_at": "2026-11-03T09:30:00+01:00"
            }
           ],
           "paid": {
            "amount": 300000,
            "currency": "CZK"
           },
           "balance": {
            "amount": 496500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Na účtu"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/folio-lines/{line_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    },
    {
     "name": "line_id",
     "in": "path",
     "required": true,
     "description": "`StayFolio.lines[].id`.",
     "x-description-cs": "`StayFolio.lines[].id`.",
     "schema": {
      "type": "string",
      "maxLength": 20
     },
     "example": "301"
    }
   ],
   "delete": {
    "tags": [
     "Reception"
    ],
    "operationId": "removeStayFolioLine",
    "summary": "Remove an item from the account",
    "x-summary-cs": "Odebrat položku z účtu",
    "description": "Removes a service or an item (a mistake). An account with an issued receipt does not change (`409 stay_state_conflict`).\n",
    "x-description-cs": "Odebere službu nebo položku (omyl). Účet s vystaveným dokladem se nemění (`409 stay_state_conflict`).\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Removed; the account.",
      "x-description-cs": "Odebráno; účet.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StayFolio"
        },
        "examples": {
         "removed": {
          "summary": "Removed",
          "value": {
           "stay_id": "193",
           "status": "checked_in",
           "package": null,
           "room": "101",
           "guest_name": "Jana Svobodová",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "accommodation": {
            "amount": 600000,
            "currency": "CZK"
           },
           "city_tax": {
            "amount": {
             "amount": 12000,
             "currency": "CZK"
            },
            "estimate": false
           },
           "lines": [
            {
             "id": "301",
             "kind": "service",
             "name": "Snídaně",
             "quantity": 4,
             "unit_price": {
              "amount": 25000,
              "currency": "CZK"
             },
             "total": {
              "amount": 100000,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": "2026-11-10",
             "date_to": "2026-11-12",
             "reference": null,
             "created_at": "2026-11-10T15:12:40+01:00"
            },
            {
             "id": "305",
             "kind": "pos",
             "name": "Restaurace – účet 2026/1184",
             "quantity": 1,
             "unit_price": {
              "amount": 84500,
              "currency": "CZK"
             },
             "total": {
              "amount": 84500,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": null,
             "date_to": null,
             "reference": "pokladna-1:2026/1184",
             "created_at": "2026-11-10T21:04:12+01:00"
            }
           ],
           "total": {
            "amount": 796500,
            "currency": "CZK"
           },
           "payments": [
            {
             "id": "41",
             "amount": {
              "amount": 300000,
              "currency": "CZK"
             },
             "method": "transfer",
             "note": "záloha",
             "paid_at": "2026-11-03T09:30:00+01:00"
            }
           ],
           "paid": {
            "amount": 300000,
            "currency": "CZK"
           },
           "balance": {
            "amount": 496500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Odebráno"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/payments": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "addStayPayment",
    "summary": "Record a payment",
    "x-summary-cs": "Zapsat platbu",
    "description": "A payment of the guest on the account of the room (also a deposit before the arrival). The register keeps the\nmoney: cash and card here are not a receipt – the receipt for the stay is made at the departure from a settled\naccount. A payment that settles the account of a guest who has left makes the receipt at once.\n",
    "x-description-cs": "Platba hosta na účet pokoje (i záloha před příjezdem). Peníze drží recepce: hotovost a karta tady nejsou účtenka –\ndoklad za pobyt vzniká při odjezdu z vyrovnaného účtu. Platba, která vyrovná účet hosta, který už odjel, doklad\nvystaví hned.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StayPaymentInput"
       },
       "examples": {
        "card": {
         "summary": "The rest by card",
         "value": {
          "amount": {
           "amount": 496500,
           "currency": "CZK"
          },
          "method": "card"
         },
         "x-summary-cs": "Doplatek kartou"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Recorded; the account.",
      "x-description-cs": "Zapsáno; účet.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StayFolio"
        },
        "examples": {
         "paid": {
          "summary": "Paid",
          "value": {
           "stay_id": "193",
           "status": "checked_in",
           "package": null,
           "room": "101",
           "guest_name": "Jana Svobodová",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "accommodation": {
            "amount": 600000,
            "currency": "CZK"
           },
           "city_tax": {
            "amount": {
             "amount": 12000,
             "currency": "CZK"
            },
            "estimate": false
           },
           "lines": [
            {
             "id": "301",
             "kind": "service",
             "name": "Snídaně",
             "quantity": 4,
             "unit_price": {
              "amount": 25000,
              "currency": "CZK"
             },
             "total": {
              "amount": 100000,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": "2026-11-10",
             "date_to": "2026-11-12",
             "reference": null,
             "created_at": "2026-11-10T15:12:40+01:00"
            },
            {
             "id": "305",
             "kind": "pos",
             "name": "Restaurace – účet 2026/1184",
             "quantity": 1,
             "unit_price": {
              "amount": 84500,
              "currency": "CZK"
             },
             "total": {
              "amount": 84500,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": null,
             "date_to": null,
             "reference": "pokladna-1:2026/1184",
             "created_at": "2026-11-10T21:04:12+01:00"
            }
           ],
           "total": {
            "amount": 796500,
            "currency": "CZK"
           },
           "payments": [
            {
             "id": "41",
             "amount": {
              "amount": 300000,
              "currency": "CZK"
             },
             "method": "transfer",
             "note": "záloha",
             "paid_at": "2026-11-03T09:30:00+01:00"
            }
           ],
           "paid": {
            "amount": 796500,
            "currency": "CZK"
           },
           "balance": {
            "amount": 0,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Zaplaceno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/payments/{payment_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    },
    {
     "name": "payment_id",
     "in": "path",
     "required": true,
     "description": "`StayFolio.payments[].id`.",
     "x-description-cs": "`StayFolio.payments[].id`.",
     "schema": {
      "type": "string",
      "maxLength": 20
     },
     "example": "41"
    }
   ],
   "delete": {
    "tags": [
     "Reception"
    ],
    "operationId": "deleteStayPayment",
    "summary": "Remove a payment",
    "x-summary-cs": "Smazat platbu",
    "description": "Removes a payment recorded by mistake. Not after the receipt for the stay is issued (`409 stay_state_conflict`).\nOnly an employee with the role `reception_manager` (since 26.11.23; others `403 staff_role_missing`).\n",
    "x-description-cs": "Smaže omylem zapsanou platbu. Ne po vystavení dokladu za pobyt (`409 stay_state_conflict`). Jen zaměstnanec\ns rolí `reception_manager` (od 26.11.23; ostatní `403 staff_role_missing`).\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Removed; the account.",
      "x-description-cs": "Smazáno; účet.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StayFolio"
        },
        "examples": {
         "removed": {
          "summary": "Removed",
          "value": {
           "stay_id": "193",
           "status": "checked_in",
           "package": null,
           "room": "101",
           "guest_name": "Jana Svobodová",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "accommodation": {
            "amount": 600000,
            "currency": "CZK"
           },
           "city_tax": {
            "amount": {
             "amount": 12000,
             "currency": "CZK"
            },
            "estimate": false
           },
           "lines": [
            {
             "id": "301",
             "kind": "service",
             "name": "Snídaně",
             "quantity": 4,
             "unit_price": {
              "amount": 25000,
              "currency": "CZK"
             },
             "total": {
              "amount": 100000,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": "2026-11-10",
             "date_to": "2026-11-12",
             "reference": null,
             "created_at": "2026-11-10T15:12:40+01:00"
            },
            {
             "id": "305",
             "kind": "pos",
             "name": "Restaurace – účet 2026/1184",
             "quantity": 1,
             "unit_price": {
              "amount": 84500,
              "currency": "CZK"
             },
             "total": {
              "amount": 84500,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": null,
             "date_to": null,
             "reference": "pokladna-1:2026/1184",
             "created_at": "2026-11-10T21:04:12+01:00"
            }
           ],
           "total": {
            "amount": 796500,
            "currency": "CZK"
           },
           "payments": [
            {
             "id": "41",
             "amount": {
              "amount": 300000,
              "currency": "CZK"
             },
             "method": "transfer",
             "note": "záloha",
             "paid_at": "2026-11-03T09:30:00+01:00"
            }
           ],
           "paid": {
            "amount": 300000,
            "currency": "CZK"
           },
           "balance": {
            "amount": 496500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Smazáno"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/receipt": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "issueStayReceipt",
    "summary": "Issue the receipt for the stay",
    "x-summary-cs": "Vystavit doklad za pobyt",
    "description": "After the departure, when the server did not make it itself. The account must be settled; a payment by invoice\nmakes an invoice for the company (finished in the administration). A second call returns the issued receipt.\n",
    "x-description-cs": "Po odjezdu, když ho server nevystavil sám. Účet musí být vyrovnaný; platba fakturou vystaví fakturu pro firmu\n(dokončí se v administraci). Druhé volání vrátí už vystavený doklad.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "201": {
      "description": "Issued.",
      "x-description-cs": "Vystaveno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingReceipt"
        },
        "examples": {
         "issued": {
          "summary": "The receipt for the stay",
          "value": {
           "id": "88",
           "kind": "sale",
           "number": 1042,
           "total": {
            "amount": 1850000,
            "currency": "CZK"
           },
           "invoice": false,
           "eet": true,
           "issued_at": "2026-11-14T09:41:00+01:00"
          },
          "x-summary-cs": "Doklad za pobyt"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "The account is not settled",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Účet není vyrovnaný"
         }
        }
       }
      }
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/receipt/cancel": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "cancelStayReceipt",
    "summary": "Cancel the receipt for the stay",
    "x-summary-cs": "Stornovat doklad za pobyt",
    "description": "Makes the cancelling receipt; the account of the room can change again. Answers the cancelling receipt. Only an\nemployee with the role `reception_manager` (since 26.11.23; others `403 staff_role_missing`).\n",
    "x-description-cs": "Vystaví protidoklad; účet pokoje jde zase měnit. Vrací protidoklad. Jen zaměstnanec s rolí `reception_manager`\n(od 26.11.23; ostatní `403 staff_role_missing`).\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StayReceiptCancel"
       },
       "examples": {
        "mistake": {
         "summary": "A wrong payment",
         "value": {
          "reason": "Host platil kartou, ne hotově"
         },
         "x-summary-cs": "Špatná platba"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Cancelled.",
      "x-description-cs": "Stornováno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingReceipt"
        },
        "examples": {
         "storno": {
          "summary": "The cancelling receipt",
          "value": {
           "id": "89",
           "kind": "storno",
           "number": 1043,
           "total": {
            "amount": -1850000,
            "currency": "CZK"
           },
           "invoice": false,
           "eet": true,
           "issued_at": "2026-11-14T09:41:00+01:00"
          },
          "x-summary-cs": "Protidoklad"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/guest-pass": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "get": {
    "tags": [
     "Reception"
    ],
    "operationId": "getStayGuestPass",
    "summary": "The QR code of the guest",
    "x-summary-cs": "QR kód hosta",
    "description": "The code for the guest's QR code (show it or print it) and what the guest may use by the account of the room –\nthe reader at the wellness, breakfast or car park checks it with `checkGuestPass`.\n",
    "x-description-cs": "Kód pro QR kód hosta (ukažte ho nebo vytiskněte) a co host smí podle účtu pokoje – čtečka u wellness, snídaní nebo\nparkoviště ho ověří přes `checkGuestPass`.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:read"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The code and the rights.",
      "x-description-cs": "Kód a co host smí.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StayGuestPass"
        },
        "examples": {
         "pass": {
          "summary": "The guest's QR code",
          "value": {
           "code": "PRU-197-3fa1c09b",
           "places": [
            {
             "place": "breakfast",
             "label": "Snídaně",
             "text": "4 osoby denně",
             "from": "2026-11-10",
             "to": "2026-11-14"
            },
            {
             "place": "wellness",
             "label": "Wellness",
             "text": "2 vstupy",
             "from": null,
             "to": null
            }
           ]
          },
          "x-summary-cs": "QR kód hosta"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/ubyport": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Reception"
    ],
    "operationId": "getUbyportStatus",
    "summary": "Foreigners waiting for Ubyport",
    "x-summary-cs": "Cizinci čekající na Ubyport",
    "description": "Whether reporting to the foreign police (Ubyport) is set up and the foreigners who wait for it or failed, with the\ndeadline (3 working days after the arrival). The server sends them every hour by itself.\n",
    "x-description-cs": "Jestli je hlášení cizinecké policii (Ubyport) nastavené a cizinci, kteří na něj čekají nebo s chybou, se lhůtou\n(3 pracovní dny po příjezdu). Server je odesílá sám každou hodinu.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:read"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The state.",
      "x-description-cs": "Stav.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UbyportStatus"
        },
        "examples": {
         "pending": {
          "summary": "Waiting for the report",
          "value": {
           "configured": true,
           "test": false,
           "pending": [
            {
             "guest_id": "612",
             "stay_id": "197",
             "name": "Anna Müller",
             "nationality": "DE",
             "arrival": "2026-11-09",
             "deadline": "2026-11-12",
             "late": false,
             "state": "pending",
             "error": null
            }
           ]
          },
          "x-summary-cs": "Čeká na hlášení"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/ubyport/send": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Reception"
    ],
    "operationId": "sendUbyport",
    "summary": "Send to Ubyport now",
    "x-summary-cs": "Odeslat do Ubyportu teď",
    "description": "Sends the waiting foreigners now instead of waiting for the hourly run. `failure` says when the service of the police does not answer.\n",
    "x-description-cs": "Odešle čekající cizince hned, bez čekání na hodinový běh. `failure` řekne, když služba policie neodpovídá.\n",
    "security": [
     {
      "oauth2": [
       "lodging_desk:write"
      ]
     }
    ],
    "x-requires-device": true,
    "x-staff": "required",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Sent.",
      "x-description-cs": "Odesláno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UbyportSendResult"
        },
        "examples": {
         "sent": {
          "summary": "Sent",
          "value": {
           "sent": 1,
           "errors": 0,
           "failure": null
          },
          "x-summary-cs": "Odesláno"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/folio": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "get": {
    "tags": [
     "Lodging"
    ],
    "operationId": "getStayFolio",
    "summary": "Account of the room",
    "x-summary-cs": "Účet pokoje",
    "description": "The account of a stay: the accommodation, the city tax, services and charges (also from registers), payments\nand what is left to pay (`balance`, negative when the guest paid more). `city_tax.estimate` is `true` while\nthe guests are not registered yet – the tax is counted from the number of guests.\n",
    "x-description-cs": "Účet pobytu: ubytování, poplatek z pobytu, služby a útraty (i z pokladen), platby a co zbývá zaplatit\n(`balance`, záporný při přeplatku). `city_tax.estimate` je `true`, dokud hosté nejsou zapsaní – poplatek se\npočítá z počtu osob.\n",
    "security": [
     {
      "oauth2": [
       "lodging:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The account.",
      "x-description-cs": "Účet.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StayFolio"
        },
        "examples": {
         "folio": {
          "summary": "The account of the room",
          "value": {
           "stay_id": "193",
           "status": "checked_in",
           "package": null,
           "room": "101",
           "guest_name": "Jana Svobodová",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "accommodation": {
            "amount": 600000,
            "currency": "CZK"
           },
           "city_tax": {
            "amount": {
             "amount": 12000,
             "currency": "CZK"
            },
            "estimate": false
           },
           "lines": [
            {
             "id": "301",
             "kind": "service",
             "name": "Snídaně",
             "quantity": 4,
             "unit_price": {
              "amount": 25000,
              "currency": "CZK"
             },
             "total": {
              "amount": 100000,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": "2026-11-10",
             "date_to": "2026-11-12",
             "reference": null,
             "created_at": "2026-11-10T15:12:40+01:00"
            },
            {
             "id": "305",
             "kind": "pos",
             "name": "Restaurace – účet 2026/1184",
             "quantity": 1,
             "unit_price": {
              "amount": 84500,
              "currency": "CZK"
             },
             "total": {
              "amount": 84500,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": null,
             "date_to": null,
             "reference": "pokladna-1:2026/1184",
             "created_at": "2026-11-10T21:04:12+01:00"
            }
           ],
           "total": {
            "amount": 796500,
            "currency": "CZK"
           },
           "payments": [
            {
             "id": "41",
             "amount": {
              "amount": 300000,
              "currency": "CZK"
             },
             "method": "transfer",
             "note": "záloha",
             "paid_at": "2026-11-03T09:30:00+01:00"
            }
           ],
           "paid": {
            "amount": 300000,
            "currency": "CZK"
           },
           "balance": {
            "amount": 496500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Účet pokoje"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stays/{stay_id}/charges": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StayId"
    }
   ],
   "post": {
    "tags": [
     "Lodging"
    ],
    "operationId": "chargeToStay",
    "summary": "Charge a bill to the room",
    "x-summary-cs": "Zapsat útratu na pokoj",
    "description": "Adds a charge to the account of a stay checked in now – a bill of the restaurant or the bar the guest pays at\ndeparture. The register does not issue a receipt for it: it closes the tab without a receipt and sends the total\nhere, one charge per VAT rate. The charge becomes revenue on the document of the stay that the accommodation issues\nat departure (with the accommodation, services and VAT) – a receipt from the register as well would count it twice.\nA stay that is not checked in answers `409 lodging_state_conflict` (the guest has not arrived yet or has left – the\nreception adds the charge in the administration).\n\n`reference` is your ID of the bill (for example the receipt number): a second charge with the same `reference`\ndoes not charge twice and answers `200` with the account. The answer is the whole account, so the register can\nshow what the guest owes.\n",
    "x-description-cs": "Přidá útratu na účet pobytu, který je právě ubytovaný – účet z restaurace nebo baru, který host zaplatí při\nodjezdu. Pokladna na ni účtenku nevystaví: účet stolu uzavře bez dokladu a pošle sem celkovou částku, za každou\nsazbu DPH zvlášť. Tržbou se útrata stane na dokladu za pobyt, který ubytování vystaví při odjezdu (s ubytováním,\nslužbami a DPH) – účtenka z pokladny navíc by ji započítala dvakrát. Pobyt, který není ubytovaný, vrátí\n`409 lodging_state_conflict` (host ještě nepřijel nebo už odjel – útratu zapíše recepce v administraci).\n\n`reference` je vaše ID útraty (třeba číslo dokladu): druhá útrata se stejnou `reference` se nezapíše dvakrát\na vrátí `200` s účtem. Odpověď je celý účet, aby pokladna mohla ukázat, kolik host dluží.\n",
    "security": [
     {
      "oauth2": [
       "lodging:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StayChargeInput"
       },
       "examples": {
        "bill": {
         "summary": "A bill of the restaurant",
         "value": {
          "name": "Restaurace – účet 2026/1184",
          "amount": {
           "amount": 84500,
           "currency": "CZK"
          },
          "vat_rate": 12,
          "reference": "pokladna-1:2026/1184"
         },
         "x-summary-cs": "Útrata z restaurace"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The charge was already there (same `reference`); the account.",
      "x-description-cs": "Útrata už na účtu byla (stejná `reference`); účet.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StayFolio"
        },
        "examples": {
         "duplicate": {
          "summary": "The same reference again",
          "value": {
           "stay_id": "193",
           "status": "checked_in",
           "package": null,
           "room": "101",
           "guest_name": "Jana Svobodová",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "accommodation": {
            "amount": 600000,
            "currency": "CZK"
           },
           "city_tax": {
            "amount": {
             "amount": 12000,
             "currency": "CZK"
            },
            "estimate": false
           },
           "lines": [
            {
             "id": "301",
             "kind": "service",
             "name": "Snídaně",
             "quantity": 4,
             "unit_price": {
              "amount": 25000,
              "currency": "CZK"
             },
             "total": {
              "amount": 100000,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": "2026-11-10",
             "date_to": "2026-11-12",
             "reference": null,
             "created_at": "2026-11-10T15:12:40+01:00"
            },
            {
             "id": "305",
             "kind": "pos",
             "name": "Restaurace – účet 2026/1184",
             "quantity": 1,
             "unit_price": {
              "amount": 84500,
              "currency": "CZK"
             },
             "total": {
              "amount": 84500,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": null,
             "date_to": null,
             "reference": "pokladna-1:2026/1184",
             "created_at": "2026-11-10T21:04:12+01:00"
            }
           ],
           "total": {
            "amount": 796500,
            "currency": "CZK"
           },
           "payments": [
            {
             "id": "41",
             "amount": {
              "amount": 300000,
              "currency": "CZK"
             },
             "method": "transfer",
             "note": "záloha",
             "paid_at": "2026-11-03T09:30:00+01:00"
            }
           ],
           "paid": {
            "amount": 300000,
            "currency": "CZK"
           },
           "balance": {
            "amount": 496500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Stejná reference podruhé"
         }
        }
       }
      }
     },
     "201": {
      "description": "Charged; the account after the charge.",
      "x-description-cs": "Zapsáno; účet po zápisu.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StayFolio"
        },
        "examples": {
         "charged": {
          "summary": "Charged to the room",
          "value": {
           "stay_id": "193",
           "status": "checked_in",
           "package": null,
           "room": "101",
           "guest_name": "Jana Svobodová",
           "arrival": "2026-11-10",
           "departure": "2026-11-12",
           "accommodation": {
            "amount": 600000,
            "currency": "CZK"
           },
           "city_tax": {
            "amount": {
             "amount": 12000,
             "currency": "CZK"
            },
            "estimate": false
           },
           "lines": [
            {
             "id": "301",
             "kind": "service",
             "name": "Snídaně",
             "quantity": 4,
             "unit_price": {
              "amount": 25000,
              "currency": "CZK"
             },
             "total": {
              "amount": 100000,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": "2026-11-10",
             "date_to": "2026-11-12",
             "reference": null,
             "created_at": "2026-11-10T15:12:40+01:00"
            },
            {
             "id": "305",
             "kind": "pos",
             "name": "Restaurace – účet 2026/1184",
             "quantity": 1,
             "unit_price": {
              "amount": 84500,
              "currency": "CZK"
             },
             "total": {
              "amount": 84500,
              "currency": "CZK"
             },
             "vat_rate": 12,
             "date_from": null,
             "date_to": null,
             "reference": "pokladna-1:2026/1184",
             "created_at": "2026-11-10T21:04:12+01:00"
            }
           ],
           "total": {
            "amount": 796500,
            "currency": "CZK"
           },
           "payments": [
            {
             "id": "41",
             "amount": {
              "amount": 300000,
              "currency": "CZK"
             },
             "method": "transfer",
             "note": "záloha",
             "paid_at": "2026-11-03T09:30:00+01:00"
            }
           ],
           "paid": {
            "amount": 300000,
            "currency": "CZK"
           },
           "balance": {
            "amount": 496500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Zapsáno na pokoj"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "lodging_state_conflict": {
          "summary": "The guest has left",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#lodging_state_conflict",
           "title": "Host teď není ubytovaný",
           "status": 409,
           "code": "lodging_state_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Host už odjel"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/packages": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Lodging"
    ],
    "operationId": "listLodgingPackages",
    "summary": "Stay packages",
    "x-summary-cs": "Pobytové balíčky",
    "description": "The packages the restaurant offers now – free nights (`pay_nights` + `free_nights`, the cheapest nights are free),\na discount, a surcharge per stay and services included in the price. `online` – offered on the booking page.\n",
    "x-description-cs": "Balíčky, které provozovna teď nabízí – noci zdarma (`pay_nights` + `free_nights`, zdarma jsou nejlevnější noci),\nsleva, příplatek za pobyt a služby v ceně. `online` – nabízí se na stránce rezervace.\n",
    "security": [
     {
      "oauth2": [
       "lodging:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The packages.",
      "x-description-cs": "Balíčky.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingPackageList"
        },
        "examples": {
         "packages": {
          "summary": "Packages",
          "value": {
           "data": [
            {
             "id": "7",
             "name": "3 + 1 noc zdarma s wellness",
             "description": "Čtvrtou noc máte od nás. Wellness bez omezení a snídaně v ceně.",
             "room_type_ids": [],
             "min_nights": 4,
             "pay_nights": 3,
             "free_nights": 1,
             "discount_percent": 0,
             "price_extra": {
              "amount": 0,
              "currency": "CZK"
             },
             "services": [
              {
               "id": "4",
               "name": "Snídaně",
               "category": "breakfast"
              },
              {
               "id": "9",
               "name": "Wellness neomezeně",
               "category": "wellness"
              }
             ],
             "valid_from": null,
             "valid_to": null,
             "online": true
            },
            {
             "id": "8",
             "name": "Romantický víkend",
             "description": "Lahev sektu na pokoji a masáž.",
             "room_type_ids": [
              "43"
             ],
             "min_nights": 2,
             "pay_nights": 0,
             "free_nights": 0,
             "discount_percent": 0,
             "price_extra": {
              "amount": 149000,
              "currency": "CZK"
             },
             "services": [
              {
               "id": "6",
               "name": "Lahev sektu",
               "category": "drink"
              }
             ],
             "valid_from": "2026-11-01",
             "valid_to": "2027-02-28",
             "online": true
            }
           ]
          },
          "x-summary-cs": "Balíčky"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/stats": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Lodging"
    ],
    "operationId": "getLodgingStats",
    "summary": "Accommodation statistics",
    "x-summary-cs": "Přehled ubytování",
    "description": "The numbers of the period – the same as Accommodation › Overview in the administration. Sold nights are room nights\nof confirmed, checked-in and finished stays (tentative ones are counted apart); the price of a stay is spread evenly\nover its nights, so a stay over the turn of a month is split. `occupancy` = sold / (rooms × days), `adr` = revenue /\nsold nights, `revpar` = revenue / available nights; the city tax is not revenue. Guests by country and age come from\nthe guest register (only stays that took place); sources, length, lead time and cancellations are by arrival in the\nperiod. `previous` are the same numbers a year before.\n",
    "x-description-cs": "Čísla za období – stejná jako Ubytování › Přehled v administraci. Prodané noci jsou noci pokojů potvrzených,\nubytovaných a skončených pobytů (nezávazné zvlášť); cena pobytu se rozpočítá rovnoměrně na jeho noci, takže pobyt přes\npřelom měsíce se rozdělí. `occupancy` = prodané / (pokoje × dny), `adr` = tržba / prodané noci, `revpar` = tržba /\ndostupné noci; poplatek z pobytu tržba není. Hosté podle zemí a věku jsou z evidence hostů (jen pobyty, které\nproběhly); zdroje, délka, předstih a storna podle příjezdu v období. `previous` jsou stejná čísla o rok dřív.\n",
    "security": [
     {
      "oauth2": [
       "lodging:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "from",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "date",
       "examples": [
        "2026-11-01"
       ]
      },
      "example": "2026-11-01"
     },
     {
      "name": "to",
      "in": "query",
      "required": true,
      "description": "Inclusive; at most 366 days after `from`.",
      "x-description-cs": "Včetně; nejvýš 366 dní po `from`.",
      "schema": {
       "type": "string",
       "format": "date",
       "examples": [
        "2026-11-30"
       ]
      },
      "example": "2026-11-30"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The statistics of the period.",
      "x-description-cs": "Přehled za období.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingStats"
        },
        "examples": {
         "month": {
          "summary": "November",
          "value": {
           "from": "2026-11-01",
           "to": "2026-11-30",
           "kpi": {
            "rooms": 10,
            "days": 30,
            "available_nights": 300,
            "sold_nights": 184,
            "tentative_nights": 3,
            "occupancy": 61.3,
            "revenue": {
             "amount": 37352000,
             "currency": "CZK"
            },
            "services_revenue": {
             "amount": 4120000,
             "currency": "CZK"
            },
            "adr": {
             "amount": 203000,
             "currency": "CZK"
            },
            "revpar": {
             "amount": 124507,
             "currency": "CZK"
            },
            "guest_nights": 352,
            "guests": 131,
            "stays": 68,
            "avg_length": 2.7,
            "avg_lead_days": 18.5,
            "cancelled": 4,
            "no_show": 1,
            "cancel_rate": 6.8
           },
           "previous": {
            "rooms": 10,
            "days": 30,
            "available_nights": 300,
            "sold_nights": 162,
            "tentative_nights": 3,
            "occupancy": 54,
            "revenue": {
             "amount": 31104000,
             "currency": "CZK"
            },
            "services_revenue": {
             "amount": 4120000,
             "currency": "CZK"
            },
            "adr": {
             "amount": 192000,
             "currency": "CZK"
            },
            "revpar": {
             "amount": 103680,
             "currency": "CZK"
            },
            "guest_nights": 352,
            "guests": 131,
            "stays": 68,
            "avg_length": 2.7,
            "avg_lead_days": 18.5,
            "cancelled": 4,
            "no_show": 1,
            "cancel_rate": 6.8
           },
           "days": [
            {
             "date": "2026-11-01",
             "sold": 7,
             "tentative": 0,
             "occupancy": 70,
             "arrivals": 2,
             "departures": 1,
             "revenue": {
              "amount": 1421000,
              "currency": "CZK"
             }
            }
           ],
           "room_types": [
            {
             "id": "43",
             "name": "Dvoulůžkový",
             "rooms": 6,
             "nights": 121,
             "occupancy": 67.2,
             "adr": {
              "amount": 189000,
              "currency": "CZK"
             },
             "revenue": {
              "amount": 22869000,
              "currency": "CZK"
             }
            }
           ],
           "sources": [
            {
             "source": "online",
             "stays": 31,
             "nights": 84,
             "revenue": {
              "amount": 17220000,
              "currency": "CZK"
             }
            },
            {
             "source": "channel",
             "stays": 22,
             "nights": 61,
             "revenue": {
              "amount": 12810000,
              "currency": "CZK"
             }
            }
           ],
           "countries": [
            {
             "country": "CZ",
             "guests": 78,
             "nights": 201
            },
            {
             "country": "DE",
             "guests": 21,
             "nights": 63
            },
            {
             "country": null,
             "guests": 4,
             "nights": 8
            }
           ],
           "ages": [
            {
             "group": "30-44",
             "guests": 52,
             "nights": 140
            },
            {
             "group": null,
             "guests": 4,
             "nights": 8
            }
           ],
           "services": [
            {
             "category": "breakfast",
             "revenue": {
              "amount": 2650000,
              "currency": "CZK"
             }
            },
            {
             "category": "wellness",
             "revenue": {
              "amount": 980000,
              "currency": "CZK"
             }
            }
           ],
           "packages": [
            {
             "id": "7",
             "name": "3 + 1 noc zdarma s wellness",
             "stays": 5,
             "revenue": {
              "amount": 3280000,
              "currency": "CZK"
             }
            }
           ],
           "guest_pass_entries": [
            {
             "place": "wellness",
             "entries": 142
            },
            {
             "place": "breakfast",
             "entries": 288
            }
           ],
           "reviews": {
            "count": 12,
            "average": 4.6
           }
          },
          "x-summary-cs": "Listopad"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "The period is too long",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Moc dlouhé období"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/reviews": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Lodging"
    ],
    "operationId": "listLodgingReviews",
    "summary": "Reviews of the accommodation",
    "x-summary-cs": "Recenze ubytování",
    "description": "Ratings of guests after their stay (`source` `direct`) and reviews from portals copied by the restaurant, newest\nfirst, with an overview: the average on the scale 1–5, counts by source and stars, sub-ratings and how many wait\nfor a reply. Guests' names are shortened (first name and initial).\n",
    "x-description-cs": "Hodnocení hostů po pobytu (`source` `direct`) a recenze z portálů, které provozovna přepsala, od nejnovější,\ns přehledem: průměr na stupnici 1–5, počty po zdrojích a hvězdičkách, dílčí hodnocení a kolik čeká na odpověď.\nJména hostů jsou zkrácená (křestní jméno a iniciála).\n",
    "security": [
     {
      "oauth2": [
       "lodging:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "filter",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "all",
        "unanswered",
        "low",
        "public"
       ],
       "default": "all"
      },
      "description": "`unanswered` without a reply, `low` up to 3 stars, `public` shown on the booking page.",
      "x-description-cs": "`unanswered` bez odpovědi, `low` do 3 hvězdiček, `public` na stránce rezervace.",
      "example": "all"
     },
     {
      "name": "source",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "direct",
        "booking",
        "google",
        "airbnb",
        "tripadvisor",
        "other"
       ]
      }
     },
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 200,
       "default": 50
      }
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The reviews and the overview.",
      "x-description-cs": "Recenze a přehled.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingReviewList"
        },
        "examples": {
         "reviews": {
          "summary": "Reviews",
          "value": {
           "summary": {
            "count": 3,
            "average": 4.53,
            "unanswered": 2,
            "low_unanswered": 0,
            "distribution": [
             0,
             0,
             0,
             0,
             3
            ],
            "sources": [
             {
              "source": "direct",
              "count": 1,
              "average": 5
             },
             {
              "source": "booking",
              "count": 1,
              "average": 4.6
             },
             {
              "source": "google",
              "count": 1,
              "average": 4
             }
            ],
            "categories": [
             {
              "key": "cleanliness",
              "average": 5,
              "count": 1
             },
             {
              "key": "staff",
              "average": 5,
              "count": 1
             },
             {
              "key": "breakfast",
              "average": 4,
              "count": 1
             }
            ]
           },
           "data": [
            {
             "id": "41",
             "stay_id": "193",
             "source": "direct",
             "rating": 5,
             "categories": {
              "cleanliness": 5,
              "staff": 5,
              "breakfast": 4
             },
             "comment": "Krásný pokoj, výborné snídaně.",
             "guest_name": "Jana S.",
             "country": "SK",
             "date": "2026-11-04",
             "public": true,
             "reply": null,
             "replied_at": null,
             "reply_sent": false,
             "link": null
            },
            {
             "id": "42",
             "stay_id": null,
             "source": "booking",
             "rating": 4.6,
             "categories": {},
             "comment": "Sehr freundlich, tolles Frühstück.",
             "guest_name": "Klaus",
             "country": null,
             "date": "2026-10-25",
             "public": false,
             "reply": "Vielen Dank, Klaus!",
             "replied_at": "2026-10-26T09:12:00+01:00",
             "reply_sent": false,
             "link": "https://www.booking.com/reviews"
            }
           ]
          },
          "x-summary-cs": "Recenze"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/lodging/reviews/{review_id}/reply": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "review_id",
     "in": "path",
     "required": true,
     "description": "`LodgingReview.id`. Other IDs answer 404.",
     "x-description-cs": "`LodgingReview.id`. Jiná ID vrátí 404.",
     "schema": {
      "type": "string",
      "maxLength": 20
     },
     "example": "41"
    }
   ],
   "post": {
    "tags": [
     "Lodging"
    ],
    "operationId": "replyToLodgingReview",
    "summary": "Reply to a review",
    "x-summary-cs": "Odpovědět na recenzi",
    "description": "Saves the reply (a new reply replaces the old one). A rating of a guest is also sent to the guest by e-mail with\n`send_to_guest` (when the guest has an e-mail); a review from a portal must be answered on the portal too.\n",
    "x-description-cs": "Uloží odpověď (nová nahradí starou). Hodnocení hosta s `send_to_guest` odejde hostovi i e-mailem (když host e-mail\nmá); na recenzi z portálu odpovězte i na portálu.\n",
    "security": [
     {
      "oauth2": [
       "lodging:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LodgingReviewReplyInput"
       },
       "examples": {
        "thanks": {
         "summary": "Thanking the guest",
         "value": {
          "reply": "Děkujeme za krásné hodnocení, těšíme se na příště!",
          "send_to_guest": true
         },
         "x-summary-cs": "Poděkování hostovi"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The review with the reply.",
      "x-description-cs": "Recenze s odpovědí.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LodgingReview"
        },
        "examples": {
         "replied": {
          "summary": "The reply was sent",
          "value": {
           "id": "41",
           "stay_id": "193",
           "source": "direct",
           "rating": 5,
           "categories": {
            "cleanliness": 5,
            "staff": 5,
            "breakfast": 4
           },
           "comment": "Krásný pokoj, výborné snídaně.",
           "guest_name": "Jana S.",
           "country": "SK",
           "date": "2026-11-04",
           "public": true,
           "reply": "Děkujeme za krásné hodnocení, těšíme se na příště!",
           "replied_at": "2026-11-05T10:20:00+01:00",
           "reply_sent": true,
           "link": null
          },
          "x-summary-cs": "Odpověď odešla"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/guest-passes/check": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Guest passes"
    ],
    "operationId": "checkGuestPass",
    "summary": "Check a guest's QR code",
    "x-summary-cs": "Ověřit QR kód hosta",
    "description": "A reader at the wellness, breakfast, half board or car park sends the code it read (`PRU-…`). The guest may use\nwhat is on the account of the room (services from the price list or included in a package) while checked in:\nunlimited, so many persons a day, or so many times a stay. `result` `ok` lets the guest in and records the entry\n(with `record: false` only checks); `denied` says why in `text`. Codes of other restaurants are `denied`. Guests'\nnames and contacts are never returned.\n",
    "x-description-cs": "Čtečka u wellness, snídaní, polopenze nebo parkoviště pošle přečtený kód (`PRU-…`). Host smí, co má na účtu pokoje\n(služby z ceníku nebo v ceně balíčku), dokud je ubytovaný: neomezeně, tolik osob denně, nebo tolikrát za pobyt.\n`result` `ok` hosta pustí a vstup zapíše (s `record: false` jen ověří); `denied` řekne proč v `text`. Kódy jiných\nprovozoven jsou `denied`. Jména a kontakty hostů se nikdy nevracejí.\n",
    "security": [
     {
      "oauth2": [
       "guest_passes:check"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/GuestPassCheckInput"
       },
       "examples": {
        "wellness": {
         "summary": "Entry to the wellness",
         "value": {
          "code": "PRU-300-3EE8T62F7H",
          "place": "wellness",
          "persons": 2,
          "device": "Vstup do wellness"
         },
         "x-summary-cs": "Vstup do wellness"
        },
        "breakfast": {
         "summary": "Breakfast",
         "value": {
          "code": "PRU-300-3EE8T62F7H",
          "place": "breakfast"
         },
         "x-summary-cs": "Snídaně"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The result of the check.",
      "x-description-cs": "Výsledek ověření.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/GuestPassCheck"
        },
        "examples": {
         "ok": {
          "summary": "Entry allowed",
          "value": {
           "result": "ok",
           "title": "Pokoj 201 · 2 osoby",
           "text": "Wellness neomezeně do 5. 11.",
           "check_id": "5521",
           "stay": {
            "id": "300",
            "room": "201",
            "persons": 2,
            "arrival": "2026-11-01",
            "departure": "2026-11-05",
            "package": "3 + 1 noc zdarma s wellness"
           },
           "used_today": 2,
           "allowed_today": null
          },
          "x-summary-cs": "Vstup povolen"
         },
         "denied": {
          "summary": "Used up today",
          "value": {
           "result": "denied",
           "title": "Dnes vyčerpáno",
           "text": "Dnes 2 osoby, už 2×.",
           "check_id": null,
           "stay": {
            "id": "300",
            "room": "201",
            "persons": 2,
            "arrival": "2026-11-01",
            "departure": "2026-11-05",
            "package": "3 + 1 noc zdarma s wellness"
           },
           "used_today": 2,
           "allowed_today": 2
          },
          "x-summary-cs": "Dnes vyčerpáno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/guest-passes/checks/{check_id}/undo": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "check_id",
     "in": "path",
     "required": true,
     "description": "`GuestPassCheck.check_id` of an `ok` check.",
     "x-description-cs": "`GuestPassCheck.check_id` povoleného čtení.",
     "schema": {
      "type": "string",
      "maxLength": 20
     },
     "example": "5521"
    }
   ],
   "post": {
    "tags": [
     "Guest passes"
    ],
    "operationId": "undoGuestPassCheck",
    "summary": "Undo an entry",
    "x-summary-cs": "Vrátit vstup",
    "description": "The guest did not go in after all – the entry no longer counts. Another check answers `409 lodging_state_conflict`.",
    "x-description-cs": "Host nakonec nešel – vstup se nepočítá. Jiné čtení vrátí `409 lodging_state_conflict`.",
    "security": [
     {
      "oauth2": [
       "guest_passes:check"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Undone.",
      "x-description-cs": "Vráceno."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "lodging_state_conflict": {
          "summary": "Already undone",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#lodging_state_conflict",
           "title": "Host teď není ubytovaný",
           "status": 409,
           "code": "lodging_state_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Už vráceno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/housekeeping": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Housekeeping"
    ],
    "operationId": "getHousekeepingDay",
    "summary": "Cleaning tasks of a day",
    "x-summary-cs": "Úkoly úklidu na den",
    "description": "Every room with its tasks for the day, the most urgent first: a room where guests arrive today and which is not\ncleaned yet, then departures, then occupied rooms. The tasks are counted from stays and the rules of the\nrestaurant each time – after a stay moves they follow it. `waiting` – the task cannot be done yet (the guest has\nnot left, or the room is not cleaned before the inspection). Guests' names are never included.\n\nTask keys: `checkout` cleaning after departure, `inspect` inspection after cleaning (when the restaurant wants it),\n`stay` daily cleaning of an occupied room, `extra_bed` prepare extra beds for today's arrival, `rule:{id}` a rule\nfor longer stays (towels, linen, disinfection), `task:{id}` a one-off task from the reception, `st:{stay_id}:{key}`\na task of a stay (an ordered service that brings a task for the maids, since 26.11.23). Send the key back as it is;\nnew kinds may come.\n",
    "x-description-cs": "Každý pokoj s úkoly na den, nejnaléhavější první: pokoj, kam dnes přijíždí host a ještě není uklizený, pak odjezdy,\npak obsazené pokoje. Úkoly se počítají z pobytů a pravidel provozovny pokaždé znovu – po přesunu pobytu ho\nnásledují. `waiting` – úkol ještě nejde udělat (host neodjel, nebo pokoj před kontrolou není uklizený). Jména hostů\ntu nikdy nejsou.\n\nKlíče úkolů: `checkout` úklid po odjezdu, `inspect` kontrola po úklidu (když ji provozovna chce), `stay` denní úklid\nobsazeného pokoje, `extra_bed` připravit přistýlky pro dnešní příjezd, `rule:{id}` pravidlo u delších pobytů\n(ručníky, povlečení, dezinfekce), `task:{id}` jednorázový úkol od recepce, `st:{stay_id}:{klíč}`\núkol k pobytu (objednaná služba, která přináší úkol pro pokojské, od 26.11.23). Klíč posílejte zpět beze změny; mohou\npřibýt další druhy.\n",
    "security": [
     {
      "oauth2": [
       "housekeeping:read"
      ]
     }
    ],
    "x-staff": "optional",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "name": "date",
      "in": "query",
      "description": "The day; today when missing.",
      "x-description-cs": "Den; bez něj dnešek.",
      "schema": {
       "type": "string",
       "format": "date",
       "examples": [
        "2026-11-05"
       ]
      },
      "example": "2026-11-05"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The rooms and their tasks.",
      "x-description-cs": "Pokoje a jejich úkoly.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HousekeepingDay"
        },
        "examples": {
         "day": {
          "summary": "Cleaning on Thursday",
          "value": {
           "date": "2026-11-05",
           "inspection": false,
           "summary": {
            "tasks": 5,
            "done": 0,
            "rooms": 3,
            "arrivals": 1,
            "waiting": 1
           },
           "rooms": [
            {
             "id": "104",
             "name": "104",
             "floor": "1",
             "type": "Dvoulůžkový",
             "status": "dirty",
             "occupied": false,
             "arrival": {
              "persons": 3,
              "extra_beds": 1,
              "from": "14:00",
              "checked_in": false
             },
             "departure": {
              "left": true
             },
             "tasks": [
              {
               "key": "checkout",
               "name": "Úklid po odjezdu",
               "done": false,
               "done_at": null,
               "done_by_employee_id": null,
               "waiting": false,
               "note": null,
               "manual": false
              },
              {
               "key": "extra_bed",
               "name": "Připravit přistýlku",
               "done": false,
               "done_at": null,
               "done_by_employee_id": null,
               "waiting": false,
               "note": null,
               "manual": false
              }
             ],
             "assigned_employee_id": "102",
             "issues": []
            },
            {
             "id": "201",
             "name": "201",
             "floor": "2",
             "type": "Jednolůžkový",
             "status": "clean",
             "occupied": true,
             "arrival": null,
             "departure": {
              "left": false
             },
             "tasks": [
              {
               "key": "checkout",
               "name": "Úklid po odjezdu",
               "done": false,
               "done_at": null,
               "done_by_employee_id": null,
               "waiting": true,
               "note": "Host ještě neodjel (odjezd do 10:00)",
               "manual": false
              }
             ],
             "assigned_employee_id": "101",
             "issues": []
            },
            {
             "id": "102",
             "name": "102",
             "floor": "1",
             "type": "Dvoulůžkový",
             "status": "clean",
             "occupied": true,
             "arrival": null,
             "departure": null,
             "tasks": [
              {
               "key": "stay",
               "name": "Úklid obsazeného pokoje",
               "done": false,
               "done_at": null,
               "done_by_employee_id": null,
               "waiting": false,
               "note": null,
               "manual": false
              },
              {
               "key": "rule:3",
               "name": "Výměna ručníků",
               "done": false,
               "done_at": null,
               "done_by_employee_id": null,
               "waiting": false,
               "note": null,
               "manual": false
              }
             ],
             "assigned_employee_id": "102",
             "issues": [
              {
               "id": "57",
               "room_id": "102",
               "room": "102",
               "text": "Kape kohoutek v koupelně",
               "blocks_room": false,
               "status": "open",
               "created_at": "2026-11-05T09:12:40+01:00",
               "created_by_employee_id": "102",
               "fixed_at": null,
               "fix_note": null
              }
             ]
            }
           ]
          },
          "x-summary-cs": "Úklid na čtvrtek"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/housekeeping/rooms/{room_id}/done": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/RoomId"
    }
   ],
   "post": {
    "tags": [
     "Housekeeping"
    ],
    "operationId": "completeHousekeepingTask",
    "summary": "Tick a task off",
    "x-summary-cs": "Odškrtnout úkol",
    "description": "Marks the task of the room and day as done. Cleaning after departure makes the room `clean`, the inspection\n`inspected`. Ticking off a done task again changes nothing. A task that is `waiting` answers\n`409 lodging_state_conflict`; a task of a later day `422 validation_failed`. With a staff token the employee is\nrecorded as the one who did it.\n",
    "x-description-cs": "Označí úkol pokoje a dne jako hotový. Úklid po odjezdu přepne pokoj na `clean`, kontrola na `inspected`. Opakované\nodškrtnutí nic nezmění. Úkol, který je `waiting`, vrátí `409 lodging_state_conflict`; úkol pozdějšího dne\n`422 validation_failed`. Se staff tokenem se zapíše zaměstnanec, který úkol udělal.\n",
    "security": [
     {
      "oauth2": [
       "housekeeping:write"
      ]
     }
    ],
    "x-staff": "optional",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/HousekeepingTaskInput"
       },
       "examples": {
        "checkout": {
         "summary": "The room is cleaned after departure",
         "value": {
          "task": "checkout",
          "date": "2026-11-05"
         },
         "x-summary-cs": "Pokoj po odjezdu uklizený"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The room after the change.",
      "x-description-cs": "Pokoj po změně.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HousekeepingRoom"
        },
        "examples": {
         "cleaned": {
          "summary": "The room is clean",
          "value": {
           "id": "104",
           "name": "104",
           "floor": "1",
           "type": "Dvoulůžkový",
           "status": "clean",
           "occupied": false,
           "arrival": {
            "persons": 3,
            "extra_beds": 1,
            "from": "14:00",
            "checked_in": false
           },
           "departure": {
            "left": true
           },
           "tasks": [
            {
             "key": "checkout",
             "name": "Úklid po odjezdu",
             "done": true,
             "done_at": "2026-11-05T10:15:02+01:00",
             "done_by_employee_id": "102",
             "waiting": false,
             "note": null,
             "manual": false
            },
            {
             "key": "extra_bed",
             "name": "Připravit přistýlku",
             "done": false,
             "done_at": null,
             "done_by_employee_id": null,
             "waiting": false,
             "note": null,
             "manual": false
            }
           ],
           "assigned_employee_id": "102",
           "issues": []
          },
          "x-summary-cs": "Pokoj je uklizený"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "lodging_state_conflict": {
          "summary": "The guest has not left yet",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#lodging_state_conflict",
           "title": "Host teď není ubytovaný",
           "status": 409,
           "code": "lodging_state_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Host ještě neodjel"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/housekeeping/rooms/{room_id}/undo": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/RoomId"
    }
   ],
   "post": {
    "tags": [
     "Housekeeping"
    ],
    "operationId": "undoHousekeepingTask",
    "summary": "Undo a ticked task",
    "x-summary-cs": "Vrátit odškrtnutý úkol",
    "description": "Returns a task ticked by mistake. Cleaning after departure returns the room to `dirty`; it cannot be undone while\nthe inspection is done (`409 lodging_state_conflict`) – undo the inspection first.\n",
    "x-description-cs": "Vrátí omylem odškrtnutý úkol. Úklid po odjezdu vrátí pokoj na `dirty`; dokud je hotová kontrola, vrátit nejde\n(`409 lodging_state_conflict`) – nejdřív vraťte kontrolu.\n",
    "security": [
     {
      "oauth2": [
       "housekeeping:write"
      ]
     }
    ],
    "x-staff": "optional",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/HousekeepingTaskInput"
       },
       "examples": {
        "mistake": {
         "summary": "Ticked off by mistake",
         "value": {
          "task": "checkout",
          "date": "2026-11-05"
         },
         "x-summary-cs": "Odškrtnuto omylem"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The room after the change.",
      "x-description-cs": "Pokoj po změně.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HousekeepingRoom"
        },
        "examples": {
         "back": {
          "summary": "To be cleaned again",
          "value": {
           "id": "104",
           "name": "104",
           "floor": "1",
           "type": "Dvoulůžkový",
           "status": "dirty",
           "occupied": false,
           "arrival": {
            "persons": 3,
            "extra_beds": 1,
            "from": "14:00",
            "checked_in": false
           },
           "departure": {
            "left": true
           },
           "tasks": [
            {
             "key": "checkout",
             "name": "Úklid po odjezdu",
             "done": false,
             "done_at": null,
             "done_by_employee_id": null,
             "waiting": false,
             "note": null,
             "manual": false
            },
            {
             "key": "extra_bed",
             "name": "Připravit přistýlku",
             "done": false,
             "done_at": null,
             "done_by_employee_id": null,
             "waiting": false,
             "note": null,
             "manual": false
            }
           ],
           "assigned_employee_id": "102",
           "issues": []
          },
          "x-summary-cs": "Zase k úklidu"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/room-issues": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Housekeeping"
    ],
    "operationId": "listRoomIssues",
    "summary": "Faults of rooms",
    "x-summary-cs": "Závady pokojů",
    "description": "Open faults and faults fixed in the last 30 days, open first, newest first, at most 300.",
    "x-description-cs": "Otevřené závady a závady opravené za posledních 30 dní, otevřené první, od nejnovější, nejvýš 300.",
    "security": [
     {
      "oauth2": [
       "housekeeping:read"
      ]
     }
    ],
    "x-staff": "optional",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The faults.",
      "x-description-cs": "Závady.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/RoomIssueList"
        },
        "examples": {
         "issues": {
          "summary": "Faults",
          "value": {
           "data": [
            {
             "id": "57",
             "room_id": "102",
             "room": "102",
             "text": "Kape kohoutek v koupelně",
             "blocks_room": false,
             "status": "open",
             "created_at": "2026-11-05T09:12:40+01:00",
             "created_by_employee_id": "102",
             "fixed_at": null,
             "fix_note": null
            },
            {
             "id": "52",
             "room_id": "202",
             "room": "202",
             "text": "Výměna sprchového koutu",
             "blocks_room": true,
             "status": "fixed",
             "created_at": "2026-10-28T08:40:00+01:00",
             "created_by_employee_id": null,
             "fixed_at": "2026-11-02T16:05:00+01:00",
             "fix_note": "Nový kout"
            }
           ]
          },
          "x-summary-cs": "Závady"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "post": {
    "tags": [
     "Housekeeping"
    ],
    "operationId": "reportRoomIssue",
    "summary": "Report a fault",
    "x-summary-cs": "Nahlásit závadu",
    "description": "A fault of a room for the maintenance. With `blocks_room` the room goes `out_of_order` and cannot be sold until the\nfault is fixed; when the room has stays from today on, `warning` says to move them.\n",
    "x-description-cs": "Závada pokoje pro údržbu. S `blocks_room` je pokoj `out_of_order` a nejde prodat, dokud se závada neopraví; když má\npokoj pobyty od dneška dál, `warning` řekne, ať se přesunou.\n",
    "security": [
     {
      "oauth2": [
       "housekeeping:write"
      ]
     }
    ],
    "x-staff": "optional",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RoomIssueInput"
       },
       "examples": {
        "tap": {
         "summary": "A dripping tap",
         "value": {
          "room_id": "102",
          "text": "Kape kohoutek v koupelně",
          "blocks_room": false
         },
         "x-summary-cs": "Kapající kohoutek"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Reported.",
      "x-description-cs": "Nahlášeno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/RoomIssueReported"
        },
        "examples": {
         "reported": {
          "summary": "Reported",
          "value": {
           "issue": {
            "id": "57",
            "room_id": "102",
            "room": "102",
            "text": "Kape kohoutek v koupelně",
            "blocks_room": false,
            "status": "open",
            "created_at": "2026-11-05T09:12:40+01:00",
            "created_by_employee_id": "102",
            "fixed_at": null,
            "fix_note": null
           },
           "warning": null
          },
          "x-summary-cs": "Nahlášeno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/room-issues/{issue_id}/fix": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/IssueId"
    }
   ],
   "post": {
    "tags": [
     "Housekeeping"
    ],
    "operationId": "fixRoomIssue",
    "summary": "Mark a fault fixed",
    "x-summary-cs": "Označit závadu jako opravenou",
    "description": "The fault is fixed. A room that was out of order because of it returns as `dirty` (to be cleaned after the\nrepair) when no other open fault blocks it. A fixed fault answers `409 lodging_state_conflict`.\n",
    "x-description-cs": "Závada je opravená. Pokoj, který byl kvůli ní mimo provoz, se vrátí jako `dirty` (po opravě k úklidu), když ho\nneblokuje jiná otevřená závada. Opravená závada vrátí `409 lodging_state_conflict`.\n",
    "security": [
     {
      "oauth2": [
       "housekeeping:write"
      ]
     }
    ],
    "x-staff": "optional",
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RoomIssueFixInput"
       },
       "examples": {
        "fixed": {
         "summary": "Fixed",
         "value": {
          "note": "Vyměněn ventil"
         },
         "x-summary-cs": "Opraveno"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The fault after the fix.",
      "x-description-cs": "Závada po opravě.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/RoomIssue"
        },
        "examples": {
         "fixed": {
          "summary": "The fault is fixed",
          "value": {
           "id": "57",
           "room_id": "102",
           "room": "102",
           "text": "Kape kohoutek v koupelně",
           "blocks_room": false,
           "status": "fixed",
           "created_at": "2026-11-05T09:12:40+01:00",
           "created_by_employee_id": "102",
           "fixed_at": "2026-11-05T13:30:00+01:00",
           "fix_note": "Vyměněn ventil"
          },
          "x-summary-cs": "Závada opravená"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "lodging_state_conflict": {
          "summary": "Already fixed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#lodging_state_conflict",
           "title": "Host teď není ubytovaný",
           "status": 409,
           "code": "lodging_state_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Už opravená"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/staff": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Staff"
    ],
    "operationId": "listStaff",
    "summary": "Employees of the restaurant",
    "x-summary-cs": "Zaměstnanci provozovny",
    "description": "Employees assigned to the restaurant and their roles on devices, ordered by name. PINs and card numbers never\nleave the server: `sign_in` only tells whether the employee has a PIN or a card. Only for Profirest's own\napplications.\n",
    "x-description-cs": "Zaměstnanci přiřazení k provozovně a jejich role na zařízeních, podle jména. PINy a čísla čipů server nikdy\nnevydá: `sign_in` říká jen to, zda má zaměstnanec PIN nebo čip. Jen pro vlastní aplikace Profirestu.\n",
    "security": [
     {
      "oauth2": [
       "staff:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of employees.",
      "x-description-cs": "Stránka zaměstnanců.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StaffMemberPage"
        },
        "examples": {
         "list": {
          "summary": "Employees without PINs",
          "value": {
           "data": [
            {
             "id": "58",
             "name": "Jana Dvořáková",
             "roles": [
              "pos"
             ],
             "attendance": {
              "enabled": true
             },
             "sign_in": {
              "pin": true,
              "card": true
             },
             "offline_approval": {
              "salt": "pHk3r9QnW1xY0aBcDeFgHw",
              "iterations": 100000,
              "check": 141
             },
             "offline_sign_in": {
              "salt": "pHk3r9QnW1xY0aBcDeFgHw",
              "iterations": 100000,
              "check": 141
             }
            },
            {
             "id": "61",
             "name": "Petr Novák",
             "roles": [
              "pos",
              "pos_manager",
              "kitchen_manager"
             ],
             "attendance": {
              "enabled": true
             },
             "sign_in": {
              "pin": true,
              "card": true
             },
             "offline_approval": {
              "salt": "pHk3r9QnW1xY0aBcDeFgHw",
              "iterations": 100000,
              "check": 141
             },
             "offline_sign_in": {
              "salt": "pHk3r9QnW1xY0aBcDeFgHw",
              "iterations": 100000,
              "check": 141
             }
            },
            {
             "id": "66",
             "name": "Lucie Svobodová",
             "roles": [
              "kitchen"
             ],
             "attendance": {
              "enabled": true
             },
             "sign_in": {
              "pin": true,
              "card": true
             },
             "offline_approval": {
              "salt": "pHk3r9QnW1xY0aBcDeFgHw",
              "iterations": 100000,
              "check": 141
             },
             "offline_sign_in": {
              "salt": "pHk3r9QnW1xY0aBcDeFgHw",
              "iterations": 100000,
              "check": 141
             }
            },
            {
             "id": "64",
             "name": "Tomáš Král",
             "roles": [],
             "attendance": {
              "enabled": true
             },
             "sign_in": {
              "pin": true,
              "card": false
             },
             "offline_approval": {
              "salt": "pHk3r9QnW1xY0aBcDeFgHw",
              "iterations": 100000,
              "check": 141
             },
             "offline_sign_in": {
              "salt": "pHk3r9QnW1xY0aBcDeFgHw",
              "iterations": 100000,
              "check": 141
             }
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Zaměstnanci bez PINů"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/staff-sessions": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Staff"
    ],
    "operationId": "createStaffSession",
    "summary": "Sign an employee in on the device",
    "x-summary-cs": "Přihlásit zaměstnance na zařízení",
    "x-requires-device": true,
    "x-idempotency": "none",
    "description": "Checks the employee's PIN or card on the server and returns a staff token for this device. Send it in the\n`Profirest-Staff-Token` header with operations done by the employee; the device token stays in `Authorization`.\nThe staff token works only on the device that signed in and only in this restaurant. It expires after\n`idle_timeout_seconds` without use and at `max_expires_at` at the latest.\n\nOnly employees assigned to the restaurant can sign in. When several of them share the PIN, the answer is\n`409 staff_ambiguous` with `candidates`; let the person choose and send the request again with `employee_id`.\nAfter repeated wrong PINs the device gets `429 staff_locked` for the time set in the restaurant's attendance\nsettings (by default 5 wrong PINs within 5 minutes lock the device until those 5 minutes pass). A correct PIN\ndoes not reset the count – otherwise someone who knows one PIN could keep guessing the others. Cards have their\nown lock: 20 unknown cards within 5 minutes lock cards on the device for those 5 minutes (card numbers are\noften printed on the card and cards of one batch go in sequence). Three times as many wrong attempts from all\ndevices of the restaurant lock the whole restaurant. Every attempt counts, also when several requests arrive\nat once.\n\nNo `Idempotency-Key`: a repeated sign-in only opens another session, and the answer carries a secret that is\nnever stored.\n",
    "x-description-cs": "Ověří PIN nebo čip zaměstnance na serveru a vrátí token zaměstnance pro toto zařízení. Posílejte ho v hlavičce\n`Profirest-Staff-Token` u operací, které dělá zaměstnanec; token zařízení zůstává v `Authorization`. Token\nzaměstnance platí jen na zařízení, které přihlásilo, a jen v této provozovně. Vyprší po `idle_timeout_seconds`\nbez použití a nejpozději v `max_expires_at`.\n\nPřihlásit se mohou jen zaměstnanci přiřazení k provozovně. Když mají PIN stejný víc z nich, odpověď je\n`409 staff_ambiguous` se seznamem `candidates`; nechte člověka vybrat a pošlete požadavek znovu s `employee_id`.\nPo opakovaně špatném PINu dostane zařízení `429 staff_locked` na dobu podle nastavení docházky provozovny\n(výchozí je 5 špatných PINů během 5 minut a zámek do konce těch 5 minut). Správný PIN počítání nevynuluje –\njinak by kdokoli, kdo zná jeden PIN, mohl dál hádat ostatní. Čipy mají vlastní zámek: 20 neznámých čipů\nběhem 5 minut zamkne čipy na zařízení na těch 5 minut (číslo bývá na čipu vytištěné a čipy z jedné várky jdou\npo sobě). Třikrát tolik špatných pokusů ze všech zařízení provozovny zamkne celou provozovnu. Počítá se každý\npokus, i když přijde víc požadavků najednou.\n\nBez `Idempotency-Key`: opakované přihlášení jen založí další relaci a odpověď nese tajemství, které se nikam\nneukládá.\n",
    "security": [
     {
      "oauth2": [
       "staff:authenticate"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StaffCredential"
       },
       "examples": {
        "pin": {
         "summary": "Signing in with a PIN",
         "value": {
          "method": "pin",
          "secret": "4321"
         },
         "x-summary-cs": "Přihlášení PINem"
        },
        "card": {
         "summary": "Signing in with a card",
         "value": {
          "method": "card",
          "secret": "04A3B2C1D5"
         },
         "x-summary-cs": "Přihlášení čipem"
        },
        "choose": {
         "summary": "After 409 staff_ambiguous with the chosen employee",
         "value": {
          "method": "pin",
          "secret": "1234",
          "employee_id": "58"
         },
         "x-summary-cs": "Po 409 staff_ambiguous s vybraným zaměstnancem"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Signed in.",
      "x-description-cs": "Přihlášeno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StaffSession"
        },
        "examples": {
         "session": {
          "summary": "Jana signed in",
          "value": {
           "token": "pfe_xfJc1S39DYennALz7S7F_mZZyQTbS0VzjnJDKTXKoQc",
           "expires_at": "2027-01-15T12:08:18+01:00",
           "max_expires_at": "2027-01-15T23:59:59+01:00",
           "idle_timeout_seconds": 300,
           "employee": {
            "id": "58",
            "name": "Jana Dvořáková",
            "roles": [
             "pos"
            ],
            "attendance": {
             "enabled": true
            },
            "sign_in": {
             "pin": true,
             "card": true
            },
            "offline_approval": {
             "salt": "pHk3r9QnW1xY0aBcDeFgHw",
             "iterations": 100000,
             "check": 141
            },
            "offline_sign_in": {
             "salt": "pHk3r9QnW1xY0aBcDeFgHw",
             "iterations": 100000,
             "check": 141
            }
           }
          },
          "x-summary-cs": "Přihlášená Jana"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "staff_ambiguous": {
          "summary": "Several people share the PIN",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#staff_ambiguous",
           "title": "Tento PIN má víc zaměstnanců; vyberte jednoho",
           "status": 409,
           "code": "staff_ambiguous",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [
            {
             "id": "58",
             "name": "Jana Dvořáková"
            },
            {
             "id": "71",
             "name": "Karel Dvořák"
            }
           ],
           "paid_by": null
          },
          "x-summary-cs": "Stejný PIN má víc lidí"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "staff_credentials_invalid": {
          "summary": "A wrong PIN or card",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#staff_credentials_invalid",
           "title": "Špatný PIN nebo neznámý čip",
           "status": 422,
           "code": "staff_credentials_invalid",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Špatný PIN nebo čip"
         }
        }
       }
      }
     },
     "429": {
      "description": "`rate_limited` (requests of the connection or device), or a limit of the operation – `staff_locked`, `voucher_attempts_exceeded`, `verification_resend_too_early`, `sms_quota_exceeded`; see `code`. Wait `Retry-After` seconds.",
      "x-description-cs": "`rate_limited` (požadavky připojení nebo zařízení), nebo limit operace – `staff_locked`, `voucher_attempts_exceeded`, `verification_resend_too_early`, `sms_quota_exceeded`; viz `code`. Počkejte `Retry-After` sekund.",
      "headers": {
       "Retry-After": {
        "$ref": "#/components/headers/RetryAfter"
       }
      },
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "rate_limited": {
          "summary": "The request limit of the connection",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#rate_limited",
           "title": "Příliš mnoho požadavků",
           "status": 429,
           "code": "rate_limited",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Limit požadavků připojení"
         },
         "staff_locked": {
          "summary": "Too many wrong attempts",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#staff_locked",
           "title": "Příliš mnoho špatných PINů nebo čipů",
           "status": 429,
           "code": "staff_locked",
           "detail": "Zkuste to znovu za 5 minut.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Moc špatných pokusů"
         }
        }
       }
      }
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/staff-sessions/current": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "delete": {
    "tags": [
     "Staff"
    ],
    "operationId": "deleteStaffSession",
    "summary": "Sign the employee out",
    "x-summary-cs": "Odhlásit zaměstnance",
    "x-requires-device": true,
    "description": "Ends the staff session from the `Profirest-Staff-Token` header at once. A session that already ended answers\n`204` as well. Without the header the answer is `403 staff_session_required`.\n",
    "x-description-cs": "Hned ukončí relaci zaměstnance z hlavičky `Profirest-Staff-Token`. Už ukončená relace odpoví také `204`.\nBez hlavičky je odpověď `403 staff_session_required`.\n",
    "security": [
     {
      "oauth2": [
       "staff:authenticate"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Signed out.",
      "x-description-cs": "Odhlášeno."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/staff-sessions/current/pin": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Staff"
    ],
    "operationId": "changeStaffPin",
    "summary": "Change the signed-in employee's PIN",
    "x-summary-cs": "Změnit PIN přihlášeného zaměstnance",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "The signed-in employee changes their own PIN. The current PIN is checked again, with the same lockout after\nwrong PINs as signing in (`422 staff_credentials_invalid`, `429 staff_locked`). The new PIN applies everywhere the\nemployee uses a PIN – on all devices, on the attendance terminal and in the employee sign-in to the\nadministration – and the change appears in the employee audit of the administration. Another employee's PIN is\nchanged only in the administration.\n\nA PIN has 4 to 9 digits and does not start with 0. A PIN that another employee of the account already has\ncannot be used (`422` at `/new_pin`, counted as a wrong PIN), and one employee can try at most 5 changes an hour\n(`429 rate_limited`). Retry with the same `Idempotency-Key`: once the PIN is changed, the current PIN you sent is\nno longer valid.\n",
    "x-description-cs": "Přihlášený zaměstnanec si mění vlastní PIN. Současný PIN se ověří znovu, se stejným zámkem po špatných PINech\njako přihlášení (`422 staff_credentials_invalid`, `429 staff_locked`). Nový PIN platí všude, kde ho zaměstnanec\npoužívá – na všech zařízeních, na docházkovém terminálu i při přihlášení zaměstnance do administrace – a změna\nse ukáže v auditu zaměstnanců v administraci. PIN jiného zaměstnance se mění jen v administraci.\n\nPIN má 4 až 9 číslic a nezačíná nulou. PIN, který už má jiný zaměstnanec účtu, použít nejde (`422` u `/new_pin`,\npočítá se jako špatný PIN), a jeden zaměstnanec smí zkusit nejvýš 5 změn za hodinu (`429 rate_limited`).\nOpakujte se stejným `Idempotency-Key`: po změně už poslaný současný PIN neplatí.\n",
    "security": [
     {
      "oauth2": [
       "staff:authenticate"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StaffPinChange"
       },
       "examples": {
        "change": {
         "summary": "Changing one's own PIN",
         "value": {
          "current_pin": "4321",
          "new_pin": "8642"
         },
         "x-summary-cs": "Změna vlastního PINu"
        }
       }
      }
     }
    },
    "responses": {
     "204": {
      "description": "The PIN is changed.",
      "x-description-cs": "PIN je změněný."
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "staff_credentials_invalid": {
          "summary": "The current PIN is wrong",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#staff_credentials_invalid",
           "title": "Špatný PIN nebo neznámý čip",
           "status": 422,
           "code": "staff_credentials_invalid",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Současný PIN nesedí"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/attendance/terminal": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Attendance"
    ],
    "operationId": "getAttendanceTerminal",
    "summary": "Settings of the attendance terminal",
    "x-summary-cs": "Nastavení docházkového terminálu",
    "description": "What an attendance terminal of this restaurant shows and allows: the restaurant's name, the look the restaurant\nchose in the administration (its logo, colour, light or dark screen and a welcome line – `null` means Profirest's\nown look) and whether the terminal may record punches without a network and how old they may be when they arrive\n(older ones the server rejects with `occurred_at_out_of_range`). Read it after pairing and every few minutes, and\nkeep the last answer on the device so the terminal starts in the right look even without a network.\n",
    "x-description-cs": "Co docházkový terminál této provozovny ukazuje a smí: jméno provozovny, vzhled, který si provozovna zvolila\nv administraci (logo, barva, světlá nebo tmavá obrazovka a uvítání – `null` znamená vzhled Profirestu), a jestli\nterminál smí zapisovat píchnutí bez sítě a jak stará smí při doručení být (starší server odmítne\ns `occurred_at_out_of_range`). Načtěte ho po spárování a pak každých pár minut a poslední odpověď držte\nv zařízení, ať terminál nastartuje ve správném vzhledu i bez sítě.\n",
    "security": [
     {
      "oauth2": [
       "attendance:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The terminal's settings.",
      "x-description-cs": "Nastavení terminálu.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AttendanceTerminal"
        },
        "examples": {
         "branded": {
          "summary": "The restaurant's own look",
          "value": {
           "restaurant_name": "Bistro U Lípy",
           "branding": {
            "logo_url": "https://www.mujprofirest.cz/uploads/terminal/123-logo.png",
            "accent_color": "#0e7c66",
            "theme": "light",
            "welcome_text": "Dobré ráno, ať se dnes daří!"
           },
           "offline": {
            "allowed": true,
            "max_age_hours": 24
           },
           "absence_requests": {
            "enabled": true,
            "types": [
             "holiday",
             "unpaid",
             "sick"
            ],
            "notice_days": 14,
            "max_days": 14,
            "horizon_days": 180
           }
          },
          "x-summary-cs": "Vlastní vzhled provozovny"
         },
         "default": {
          "summary": "Profirest's own look",
          "value": {
           "restaurant_name": "Bistro U Lípy",
           "branding": {
            "logo_url": null,
            "accent_color": null,
            "theme": "dark",
            "welcome_text": null
           },
           "offline": {
            "allowed": true,
            "max_age_hours": 24
           },
           "absence_requests": {
            "enabled": false,
            "types": [
             "holiday",
             "unpaid"
            ],
            "notice_days": 14,
            "max_days": 14,
            "horizon_days": 180
           }
          },
          "x-summary-cs": "Vzhled Profirestu"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/attendance/presence": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Attendance"
    ],
    "operationId": "listAttendancePresence",
    "summary": "Who is at work",
    "x-summary-cs": "Kdo je v práci",
    "description": "Employees kept in attendance at this restaurant and where they are now: `off`, `working` or `on_break`,\nordered by name.\n",
    "x-description-cs": "Zaměstnanci, kteří se na této provozovně vedou v docházce, a kde právě jsou: `off`, `working` nebo `on_break`,\npodle jména.\n",
    "security": [
     {
      "oauth2": [
       "attendance:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of employees and their attendance state.",
      "x-description-cs": "Stránka zaměstnanců a jejich stavu docházky.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AttendancePresencePage"
        },
        "examples": {
         "presence": {
          "summary": "Who is at work",
          "value": {
           "data": [
            {
             "employee": {
              "id": "58",
              "name": "Jana Dvořáková"
             },
             "state": "working",
             "since": "2027-01-15T09:58:12+01:00",
             "shift_started_at": "2027-01-15T09:58:12+01:00"
            },
            {
             "employee": {
              "id": "66",
              "name": "Lucie Svobodová"
             },
             "state": "on_break",
             "since": "2027-01-15T11:30:05+01:00",
             "shift_started_at": "2027-01-15T08:00:40+01:00"
            },
            {
             "employee": {
              "id": "61",
              "name": "Petr Novák"
             },
             "state": "off",
             "since": null,
             "shift_started_at": null
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Kdo je v práci"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/attendance/punches": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Attendance"
    ],
    "operationId": "createAttendancePunch",
    "summary": "Record an arrival, a departure or a break",
    "x-summary-cs": "Zapsat příchod, odchod nebo přestávku",
    "x-requires-device": true,
    "x-staff": "optional",
    "x-idempotency": "body-id",
    "description": "One punch of an employee at the device. Identify the employee by `credential` (PIN or card entered at the\ndevice) or by a staff session in `Profirest-Staff-Token`.\n\n`id` is your UUID of the punch, made on the device when the person punched. Sending the same `id` again never\nrecords it twice: you get the first result with `200`, and a punch rejected for the attendance state or its time\nkeeps answering the same rejection. Sign-in errors (`staff_credentials_invalid`, `staff_ambiguous`,\n`staff_locked`) are not stored: send the same `id` again with the right PIN, the chosen `employee_id` or later.\n\n`occurred_at` is when the person punched. Leave it out or send the current time for a live punch. A punch older\nthan 2 minutes is an offline record: it is accepted only when the restaurant allows offline records on terminals\n(`offline_records_disabled`) and only up to the age set there (`occurred_at_out_of_range`). A time up to\n5 minutes ahead is taken as now; later is rejected.\n\nThe rules are those of the restaurant's attendance terminal: an arrival only without a running shift, a departure\nand a break only during a shift; a departure during a break also ends the break. The shift is then evaluated by\nthe restaurant's attendance rules (tolerances, breaks, overtime) exactly as when punching at the terminal.\n",
    "x-description-cs": "Jedno píchnutí zaměstnance na zařízení. Zaměstnance určí `credential` (PIN nebo čip zadaný na zařízení), nebo\nrelace zaměstnance v `Profirest-Staff-Token`.\n\n`id` je vaše UUID píchnutí, vytvořené na zařízení ve chvíli, kdy člověk píchl. Opakované odeslání stejného `id`\nnikdy nezapíše záznam dvakrát: dostanete první výsledek s `200` a píchnutí odmítnuté kvůli stavu docházky nebo\nčasu vrací dál stejné odmítnutí. Chyby přihlášení (`staff_credentials_invalid`, `staff_ambiguous`,\n`staff_locked`) se neukládají: pošlete stejné `id` znovu se správným PINem, vybraným `employee_id` nebo později.\n\n`occurred_at` je chvíle, kdy člověk píchl. U živého píchnutí ji vynechte nebo pošlete aktuální čas. Píchnutí\nstarší než 2 minuty je offline záznam: přijme se, jen když provozovna offline zápisy na terminálech povoluje\n(`offline_records_disabled`), a jen do stáří, které je tam nastavené (`occurred_at_out_of_range`). Čas\nnejvýš 5 minut napřed se bere jako teď; pozdější se odmítne.\n\nPlatí pravidla docházkového terminálu provozovny: příchod jen bez běžící směny, odchod a přestávka jen během\nsměny; odchod během přestávky ukončí i přestávku. Směna se pak vyhodnotí pravidly docházky provozovny\n(tolerance, přestávky, přesčasy) stejně jako při píchnutí na terminálu.\n",
    "security": [
     {
      "oauth2": [
       "attendance:punch"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AttendancePunchCreate"
       },
       "examples": {
        "terminal": {
         "summary": "A terminal: the PIN in the request",
         "value": {
          "id": "01a318f0-a0c0-7ee7-995a-8607b7545591",
          "type": "clock_in",
          "credential": {
           "method": "pin",
           "secret": "4321"
          }
         },
         "x-summary-cs": "Píchačka: PIN v požadavku"
        },
        "signed_in": {
         "summary": "A signed-in employee (Profirest-Staff-Token)",
         "value": {
          "id": "01a318f0-a0c0-757a-9acb-1aaf7e49dcb1",
          "type": "break_start"
         },
         "x-summary-cs": "Přihlášený zaměstnanec (Profirest-Staff-Token)"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "This `id` was already recorded; the first result.",
      "x-description-cs": "Toto `id` už bylo zapsáno; první výsledek.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AttendancePunch"
        },
        "examples": {
         "duplicate": {
          "summary": "The same id again – already recorded",
          "value": {
           "id": "01a318f0-a0c0-7ee7-995a-8607b7545591",
           "employee": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "type": "clock_in",
           "occurred_at": "2027-01-15T09:58:12+01:00",
           "received_at": "2027-01-15T09:58:13+01:00",
           "offline": false,
           "state": "working",
           "shift": {
            "started_at": "2027-01-15T09:58:12+01:00",
            "ended_at": null,
            "break_minutes": null,
            "worked_minutes": null
           }
          },
          "x-summary-cs": "Stejné id podruhé – už zapsané"
         }
        }
       }
      }
     },
     "201": {
      "description": "Recorded.",
      "x-description-cs": "Zapsáno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AttendancePunch"
        },
        "examples": {
         "created": {
          "summary": "The arrival is recorded",
          "value": {
           "id": "01a318f0-a0c0-7ee7-995a-8607b7545591",
           "employee": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "type": "clock_in",
           "occurred_at": "2027-01-15T09:58:12+01:00",
           "received_at": "2027-01-15T09:58:13+01:00",
           "offline": false,
           "state": "working",
           "shift": {
            "started_at": "2027-01-15T09:58:12+01:00",
            "ended_at": null,
            "break_minutes": null,
            "worked_minutes": null
           }
          },
          "x-summary-cs": "Příchod zapsaný"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "attendance_state_conflict": {
          "summary": "Not possible now",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#attendance_state_conflict",
           "title": "Záznam nesedí na aktuální stav docházky",
           "status": 409,
           "code": "attendance_state_conflict",
           "detail": "Jana Dvořáková už je v práci.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Tohle teď nejde"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/attendance/punches/batch": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Attendance"
    ],
    "operationId": "createAttendancePunchBatch",
    "summary": "Send punches recorded offline",
    "x-summary-cs": "Odeslat píchnutí pořízená offline",
    "x-requires-device": true,
    "x-idempotency": "body-id",
    "description": "Up to 100 punches in the order they happened. Each one is processed like `POST …/attendance/punches` on its own\nand gets its own result; a rejected punch does not stop the others. Every item carries its `credential`,\nbecause a staff session cannot be opened without a network.\n\n`status` of an item: `created`, `duplicate` (this `id` was recorded before; `punch` is the first result) or\n`rejected` (see `problem`). A rejected item with `retryable: true` (for example `staff_locked`) was not decided\nyet: send it again later with the same `id`. After the first `staff_locked` the rest of the batch is not\nprocessed (every next item answers `staff_locked`, retryable), so the records keep their order – send them again\nafter the lock, not sooner. A wrong PIN or card stays wrong – show it to the manager, the record\nhas to be added in the administration by hand. Rejections for the attendance state or the time\n(`attendance_state_conflict`, `occurred_at_out_of_range`), and `attendance_not_enabled` and\n`offline_records_disabled`, are final: the same `id` keeps answering them and never becomes `duplicate`. An `id`\nalready used by another device or restaurant is `rejected` with `punch_id_conflict`.\n",
    "x-description-cs": "Nejvýš 100 píchnutí v pořadí, v jakém se stala. Každé se zpracuje samostatně jako `POST …/attendance/punches`\na má vlastní výsledek; odmítnuté píchnutí nezastaví ostatní. Každá položka nese svůj `credential`, protože\nrelaci zaměstnance nejde bez sítě otevřít.\n\n`status` položky: `created`, `duplicate` (toto `id` už bylo zapsáno; `punch` je první výsledek) nebo\n`rejected` (viz `problem`). Odmítnutá položka s `retryable: true` (třeba `staff_locked`) ještě rozhodnutá\nnení: pošlete ji později znovu se stejným `id`. Po prvním `staff_locked` se zbytek dávky nezpracuje (každá další\npoložka odpoví `staff_locked`, k opakování), takže záznamy zůstanou v pořadí – pošlete je znovu po zámku, ne dřív.\nŠpatný PIN nebo čip zůstane špatný – ukažte ho vedoucímu, záznam\nje potřeba doplnit v administraci ručně. Odmítnutí kvůli stavu docházky nebo času (`attendance_state_conflict`,\n`occurred_at_out_of_range`) a také `attendance_not_enabled` a `offline_records_disabled` jsou konečná: stejné\n`id` je bude vracet dál a nikdy z něj nebude `duplicate`. `id`, které už použilo jiné zařízení nebo jiná\nprovozovna, je `rejected` s `punch_id_conflict`.\n",
    "security": [
     {
      "oauth2": [
       "attendance:punch"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AttendancePunchBatch"
       },
       "examples": {
        "offline": {
         "summary": "Records from a network outage",
         "value": {
          "items": [
           {
            "id": "01a318f0-a0c0-7659-af30-64e055b22d85",
            "type": "break_start",
            "occurred_at": "2027-01-15T11:30:05+01:00",
            "credential": {
             "method": "card",
             "secret": "04B7C2D9E1"
            }
           },
           {
            "id": "01a318f0-a0c0-7804-a3a6-4d8707f841b2",
            "type": "break_end",
            "occurred_at": "2027-01-15T11:45:10+01:00",
            "credential": {
             "method": "card",
             "secret": "04B7C2D9E1"
            }
           },
           {
            "id": "01a318f0-a0c0-791a-b9db-5935f9c3e239",
            "type": "clock_in",
            "occurred_at": "2027-01-15T11:47:00+01:00",
            "credential": {
             "method": "pin",
             "secret": "9999"
            }
           }
          ]
         },
         "x-summary-cs": "Záznamy z výpadku sítě"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "One result per item, in the order of the request.",
      "x-description-cs": "Jeden výsledek na položku, v pořadí požadavku.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AttendancePunchBatchResult"
        },
        "examples": {
         "results": {
          "summary": "The result of every record",
          "value": {
           "results": [
            {
             "id": "01a318f0-a0c0-7659-af30-64e055b22d85",
             "status": "created",
             "retryable": false,
             "punch": {
              "id": "01a318f0-a0c0-7659-af30-64e055b22d85",
              "employee": {
               "id": "66",
               "name": "Lucie Svobodová"
              },
              "type": "break_start",
              "occurred_at": "2027-01-15T11:30:05+01:00",
              "received_at": "2027-01-15T11:52:30+01:00",
              "offline": true,
              "state": "on_break",
              "shift": {
               "started_at": "2027-01-15T08:00:40+01:00",
               "ended_at": null,
               "break_minutes": null,
               "worked_minutes": null
              }
             },
             "problem": null,
             "employee": null
            },
            {
             "id": "01a318f0-a0c0-7804-a3a6-4d8707f841b2",
             "status": "duplicate",
             "retryable": false,
             "punch": {
              "id": "01a318f0-a0c0-7804-a3a6-4d8707f841b2",
              "employee": {
               "id": "66",
               "name": "Lucie Svobodová"
              },
              "type": "break_end",
              "occurred_at": "2027-01-15T11:45:10+01:00",
              "received_at": "2027-01-15T11:52:30+01:00",
              "offline": true,
              "state": "working",
              "shift": {
               "started_at": "2027-01-15T08:00:40+01:00",
               "ended_at": null,
               "break_minutes": 15,
               "worked_minutes": null
              }
             },
             "problem": null,
             "employee": null
            },
            {
             "id": "01a318f0-a0c0-791a-b9db-5935f9c3e239",
             "status": "rejected",
             "retryable": false,
             "punch": null,
             "problem": {
              "type": "https://api.mujprofirest.cz/v2/docs/errors#staff_credentials_invalid",
              "title": "Špatný PIN nebo neznámý čip",
              "status": 422,
              "code": "staff_credentials_invalid",
              "detail": null,
              "instance": null,
              "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
              "errors": [],
              "existing_id": null,
              "candidates": [],
              "paid_by": null
             },
             "employee": null
            }
           ]
          },
          "x-summary-cs": "Výsledek každého záznamu"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/attendance/my-schedule": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Attendance"
    ],
    "operationId": "getMyAttendanceSchedule",
    "summary": "The signed-in employee's schedule",
    "x-summary-cs": "Rozpis přihlášeného zaměstnance",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "Shifts and time off of the employee from `Profirest-Staff-Token` planned at this restaurant, from today for\n`days` days, in the order they start: work shifts with their section and absences (holiday, unpaid leave,\nsickness) as the administration's shift planner has them. A shift running across midnight into today is\nincluded. Only the employee's own schedule – other people's shifts are not shown.\n",
    "x-description-cs": "Směny a volno zaměstnance z `Profirest-Staff-Token` naplánované na této provozovně, od dneška na `days` dní,\nv pořadí začátku: pracovní směny se sekcí a absence (dovolená, neplacené volno, nemoc) tak, jak je má rozpis\nsměn v administraci. Patří sem i směna, která přes půlnoc zasahuje do dneška. Jen vlastní rozpis zaměstnance –\nsměny ostatních se neukazují.\n",
    "security": [
     {
      "oauth2": [
       "attendance:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "days",
      "in": "query",
      "required": false,
      "description": "How many days from today, at most 31. Default 14.",
      "x-description-cs": "Na kolik dní od dneška, nejvýš 31. Výchozí 14.",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 31,
       "default": 14
      }
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The employee's schedule.",
      "x-description-cs": "Rozpis zaměstnance.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AttendanceSchedule"
        },
        "examples": {
         "schedule": {
          "summary": "Jana's schedule for two weeks",
          "value": {
           "employee": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "from": "2027-01-15",
           "to": "2027-01-28",
           "items": [
            {
             "type": "work",
             "starts_at": "2027-01-15T16:00:00+01:00",
             "ends_at": "2027-01-15T23:00:00+01:00",
             "section": {
              "id": "4",
              "name": "Bar"
             }
            },
            {
             "type": "work",
             "starts_at": "2027-01-16T16:00:00+01:00",
             "ends_at": "2027-01-16T23:30:00+01:00",
             "section": {
              "id": "4",
              "name": "Bar"
             }
            },
            {
             "type": "work",
             "starts_at": "2027-01-20T10:00:00+01:00",
             "ends_at": "2027-01-20T18:00:00+01:00",
             "section": {
              "id": "4",
              "name": "Bar"
             }
            },
            {
             "type": "holiday",
             "starts_at": "2027-01-25T00:00:00+01:00",
             "ends_at": "2027-01-28T00:00:00+01:00",
             "section": null
            }
           ]
          },
          "x-summary-cs": "Rozpis Jany na dva týdny"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/attendance/absence-requests": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Attendance"
    ],
    "operationId": "listMyAbsenceRequests",
    "summary": "The signed-in employee's requests for time off",
    "x-summary-cs": "Žádosti o volno přihlášeného zaměstnance",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "Requests for time off of the employee from `Profirest-Staff-Token` at this restaurant: every pending one and\nthe others whose time off ended at most 60 days ago or was decided within that time, newest first, at most 50.\nA manager decides them in the administration; an approved request is written to the shift planner as an\nabsence.\n",
    "x-description-cs": "Žádosti o volno zaměstnance z `Profirest-Staff-Token` na této provozovně: všechny čekající a ostatní, jejichž\nvolno skončilo nejvýš před 60 dny, od nejnovější, nejvýš 50. Rozhoduje o nich vedoucí v administraci; schválená\nžádost se zapíše do rozpisu směn jako absence.\n",
    "security": [
     {
      "oauth2": [
       "attendance:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The employee's requests.",
      "x-description-cs": "Žádosti zaměstnance.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AbsenceRequestList"
        },
        "examples": {
         "requests": {
          "summary": "Jana's requests",
          "value": {
           "data": [
            {
             "id": "31",
             "type": "holiday",
             "date_from": "2027-02-08",
             "date_to": "2027-02-12",
             "days": 5,
             "note": "Hory s rodinou",
             "status": "pending",
             "decided_automatically": false,
             "created_at": "2027-01-15T16:02:00+01:00",
             "decided_at": null,
             "decision_note": null
            },
            {
             "id": "27",
             "type": "holiday",
             "date_from": "2027-01-25",
             "date_to": "2027-01-27",
             "days": 3,
             "note": null,
             "status": "approved",
             "decided_automatically": false,
             "created_at": "2027-01-02T09:12:00+01:00",
             "decided_at": "2027-01-04T11:40:00+01:00",
             "decision_note": "Užij si to!"
            }
           ]
          },
          "x-summary-cs": "Žádosti Jany"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "post": {
    "tags": [
     "Attendance"
    ],
    "operationId": "createAbsenceRequest",
    "summary": "Request time off for the signed-in employee",
    "x-summary-cs": "Požádat o volno za přihlášeného zaměstnance",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "The employee from `Profirest-Staff-Token` asks for whole days off. The rules are the restaurant's\n(`AttendanceTerminal.absence_requests`): which kinds may be requested, how many days in advance (a sickness\nfrom today, without notice), how many days at most and how far ahead, and how many people of one section may be\noff on the same day. A request that breaks a rule answers `422 absence_request_not_allowed` with `detail` saying\nwhat to change; time off of the employee already requested or planned for the same days answers\n`409 absence_request_conflict`; requests switched off answer `403 absence_requests_disabled`.\n\nA new request is `pending` until a manager decides it in the administration. When the restaurant lets requests\nbe approved automatically and the employee has no shift planned in the period, the answer is already\n`approved` (`decided_automatically: true`) and the time off is in the shift planner.\n",
    "x-description-cs": "Zaměstnanec z `Profirest-Staff-Token` žádá o volno na celé dny. Pravidla určuje provozovna\n(`AttendanceTerminal.absence_requests`): o jaké volno se smí žádat, kolik dní předem (nemoc od dneška, bez\npředstihu), nejvýš kolik dní a jak daleko dopředu a kolik lidí z jedné sekce smí mít týž den volno. Žádost,\nkterá pravidlo poruší, odpoví `422 absence_request_not_allowed` a `detail` říká, co změnit; volno zaměstnance už\npožádané nebo naplánované na stejné dny odpoví `409 absence_request_conflict`; vypnuté žádosti\n`403 absence_requests_disabled`.\n\nNová žádost je `pending`, dokud o ní nerozhodne vedoucí v administraci. Když provozovna dovoluje schvalovat\nsamo a zaměstnanec v tom období nemá naplánovanou směnu, odpověď už je `approved`\n(`decided_automatically: true`) a volno je v rozpisu.\n",
    "security": [
     {
      "oauth2": [
       "attendance:punch"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AbsenceRequestCreate"
       },
       "examples": {
        "holiday": {
         "summary": "A five-day holiday",
         "value": {
          "type": "holiday",
          "date_from": "2027-02-08",
          "date_to": "2027-02-12",
          "note": "Hory s rodinou"
         },
         "x-summary-cs": "Dovolená na pět dní"
        },
        "sick": {
         "summary": "Sickness from today",
         "value": {
          "type": "sick",
          "date_from": "2027-01-15",
          "date_to": "2027-01-16"
         },
         "x-summary-cs": "Nemoc od dneška"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The request is created.",
      "x-description-cs": "Žádost je podaná.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AbsenceRequest"
        },
        "examples": {
         "pending": {
          "summary": "Waits for a manager",
          "value": {
           "id": "31",
           "type": "holiday",
           "date_from": "2027-02-08",
           "date_to": "2027-02-12",
           "days": 5,
           "note": "Hory s rodinou",
           "status": "pending",
           "decided_automatically": false,
           "created_at": "2027-01-15T16:02:00+01:00",
           "decided_at": null,
           "decision_note": null
          },
          "x-summary-cs": "Čeká na vedoucího"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "description": "`insufficient_scope` or `customer_not_verified`; on Profirest's own devices also `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` and – on the\nregister – `manager_approval_required`.\n",
      "x-description-cs": "`insufficient_scope` nebo `customer_not_verified`; na vlastních zařízeních Profirestu také `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` a – na pokladně –\n`manager_approval_required`.\n",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "insufficient_scope": {
          "summary": "The token lacks the scope",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#insufficient_scope",
           "title": "Token nemá potřebné oprávnění",
           "status": 403,
           "code": "insufficient_scope",
           "detail": "Missing scope: orders:write",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Token nemá potřebné oprávnění"
         },
         "absence_requests_disabled": {
          "summary": "Requests are switched off",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#absence_requests_disabled",
           "title": "Provozovna žádosti o volno nepřijímá",
           "status": 403,
           "code": "absence_requests_disabled",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Žádosti jsou vypnuté"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "absence_request_conflict": {
          "summary": "Time off already requested",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#absence_request_conflict",
           "title": "Zaměstnanec už v tu dobu volno má",
           "status": 409,
           "code": "absence_request_conflict",
           "detail": "V tom období už máte žádost o volno (8. 2. – 12. 2. 2027).",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Volno už je požádané"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "absence_request_not_allowed": {
          "summary": "Too short notice",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#absence_request_not_allowed",
           "title": "Žádost porušuje pravidlo provozovny",
           "status": 422,
           "code": "absence_request_not_allowed",
           "detail": "O dovolenou je potřeba požádat nejméně 14 dní předem, tedy nejdřív od 29. 1. 2027.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Málo předem"
         }
        }
       }
      }
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/attendance/absence-requests/{request_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "request_id",
     "in": "path",
     "required": true,
     "description": "ID of the request (`AbsenceRequest.id`).",
     "x-description-cs": "ID žádosti (`AbsenceRequest.id`).",
     "schema": {
      "$ref": "#/components/schemas/Id"
     },
     "example": "31"
    }
   ],
   "delete": {
    "tags": [
     "Attendance"
    ],
    "operationId": "cancelAbsenceRequest",
    "summary": "Withdraw a pending request for time off",
    "x-summary-cs": "Vzít zpět čekající žádost o volno",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "The employee from `Profirest-Staff-Token` withdraws their own pending request; the answer is the request with\n`status: cancelled`. A request already withdrawn answers the same. A decided request answers\n`409 absence_request_decided` – approved time off is cancelled by a manager in the administration. Another\nemployee's request answers `404`.\n",
    "x-description-cs": "Zaměstnanec z `Profirest-Staff-Token` bere zpět svou čekající žádost; odpovědí je žádost se\n`status: cancelled`. Už vzatá zpět odpoví stejně. Vyřízená žádost odpoví `409 absence_request_decided` –\nschválené volno ruší vedoucí v administraci. Žádost jiného zaměstnance odpoví `404`.\n",
    "security": [
     {
      "oauth2": [
       "attendance:punch"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The request is withdrawn.",
      "x-description-cs": "Žádost je vzatá zpět.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AbsenceRequest"
        },
        "examples": {
         "cancelled": {
          "summary": "Withdrawn",
          "value": {
           "id": "31",
           "type": "holiday",
           "date_from": "2027-02-08",
           "date_to": "2027-02-12",
           "days": 5,
           "note": "Hory s rodinou",
           "status": "cancelled",
           "decided_automatically": false,
           "created_at": "2027-01-15T16:02:00+01:00",
           "decided_at": "2027-01-15T16:10:00+01:00",
           "decision_note": null
          },
          "x-summary-cs": "Vzatá zpět"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "absence_request_decided": {
          "summary": "Already approved",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#absence_request_decided",
           "title": "Žádost už je vyřízená",
           "status": 409,
           "code": "absence_request_decided",
           "detail": "Žádost už je schválená. Zrušit volno může vedoucí v administraci.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Už schválená"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/tickets": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "listKitchenTickets",
    "summary": "Orders on the kitchen board",
    "x-summary-cs": "Objednávky na tabuli kuchyně",
    "description": "Kitchen tickets of every order of the restaurant – from the register, the e-shop, delivery platforms and\napplications – the same ones the kitchen display shows today.\n\n- `view=active` (default): not started and preparing, due within 2 hours (by the scheduled time of preorders,\n  otherwise by the time the order came), oldest first.\n- `view=preorders`: scheduled more than 2 hours ahead.\n- `view=history`: finished and cancelled orders of the current shift (until the shift is closed), newest first;\n  orders that are `not_delivered` stay here until the restaurant settles them.\n\n`area=kitchen` (default) shows the orders of every source except the registers (`source` other than `pos`);\n`area=bar` is the bar handout: open-table tickets from the registers (`createKitchenTicket`, registers on API v1)\nof the last 2 days. Paid register receipts sent to the kitchen (`send_to_kitchen`) are in neither area, as on\ntoday's kitchen display – they reach the production stations and the order-number screen.\n\nThe board answers `304` to `If-None-Match` when nothing changed, so a display can ask every few seconds.\nNew tickets come as `kitchen.ticket_created` events and changes as `kitchen.ticket_updated`: changes made\nthrough this API at once, tickets and changes from elsewhere (registers, the web kitchen display, the e-shop,\ndelivery platforms) within about two minutes. A display that must react within seconds keeps asking the board.\n",
    "x-description-cs": "Kuchyňské bony všech objednávek provozovny – z pokladny, e-shopu, rozvozových platforem i aplikací – stejné,\njaké dnes ukazuje kuchyňský displej.\n\n- `view=active` (výchozí): nezačaté a rozpracované s termínem do 2 hodin (u předobjednávek podle\n  objednaného času, jinak podle příchodu), nejstarší první.\n- `view=preorders`: objednané na čas víc než 2 hodiny dopředu.\n- `view=history`: hotové a zrušené objednávky aktuální směny (do uzávěrky), nejnovější první; objednávky\n  `not_delivered` tu zůstávají, dokud je provozovna nevyřeší.\n\n`area=kitchen` (výchozí) ukazuje objednávky ze všech zdrojů kromě pokladen (`source` jiný než `pos`);\n`area=bar` je výdej baru: bony otevřených stolů z pokladen (`createKitchenTicket`, pokladny na API v1) za\nposlední 2 dny. Zaplacené účtenky pokladny poslané do kuchyně (`send_to_kitchen`) nejsou v žádné z oblastí,\nstejně jako na dnešním kuchyňském displeji – dostanou se na výrobní stanoviště a na obrazovku s čísly\nobjednávek.\n\nTabule na `If-None-Match` odpoví `304`, když se nic nezměnilo, takže se displej může ptát každých pár sekund.\nNové bony přicházejí jako události `kitchen.ticket_created` a změny jako `kitchen.ticket_updated`: změny přes\ntoto API hned, bony a změny odjinud (pokladny, webový kuchyňský displej, e-shop, rozvozové platformy) do zhruba\ndvou minut. Displej, který musí reagovat během sekund, se na tabuli ptá dál.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "view",
      "in": "query",
      "required": false,
      "description": "`active` (default) – not started and being prepared, due within 2 hours, oldest first; `preorders` – ordered\nfor more than 2 hours ahead; `history` – finished and cancelled orders of the current shift, newest first.\n",
      "x-description-cs": "`active` (výchozí) – nezačaté a rozpracované s termínem do 2 hodin, nejstarší první; `preorders` – objednané\nvíc než 2 hodiny dopředu; `history` – hotové a zrušené objednávky aktuální směny, nejnovější první.\n",
      "schema": {
       "type": "string",
       "enum": [
        "active",
        "preorders",
        "history"
       ],
       "default": "active"
      },
      "example": "active"
     },
     {
      "name": "area",
      "in": "query",
      "required": false,
      "description": "`kitchen` (default) – orders of every source except the registers; `bar` – the bar handout, open-table\ntickets from the registers of the last 2 days. `preorders_later` counts only the `kitchen` area.\n",
      "x-description-cs": "`kitchen` (výchozí) – objednávky ze všech zdrojů kromě pokladen; `bar` – výdej baru, bony otevřených stolů\nz pokladen za poslední 2 dny. `preorders_later` počítá jen oblast `kitchen`.\n",
      "schema": {
       "type": "string",
       "enum": [
        "kitchen",
        "bar"
       ],
       "default": "kitchen"
      },
      "example": "kitchen"
     },
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of kitchen tickets.",
      "x-description-cs": "Stránka kuchyňských bonů.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenTicketPage"
        },
        "examples": {
         "active": {
          "summary": "Tickets in the kitchen",
          "value": {
           "data": [
            {
             "id": "77812",
             "order_id": "184223",
             "number": "027",
             "status": "preparing",
             "area": "kitchen",
             "source": "web",
             "platform": null,
             "name": "Jana Nováková",
             "fulfillment": "takeaway",
             "express": false,
             "customer": {
              "name": "Jana Nováková",
              "phone": "+420777123456",
              "not_delivered_count": 0,
              "last_not_delivered_at": null
             },
             "delivery_address": null,
             "delivery_zone": null,
             "note": null,
             "payment_method": "cash",
             "total": {
              "amount": 39800,
              "currency": "CZK"
             },
             "delivery_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "amount_due": {
              "amount": 39800,
              "currency": "CZK"
             },
             "paid_by": null,
             "created_at": "2027-01-15T11:42:31+01:00",
             "scheduled_for": null,
             "printed": true,
             "courier": null,
             "not_delivered": null,
             "items": [
              {
               "id": "52011",
               "product_id": "4567",
               "name": "Svíčková na smetaně, houskový knedlík",
               "kitchen_name": null,
               "note": null,
               "quantity": 2,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "312",
                "name": "Hlavní jídla"
               },
               "from_daily_menu": false,
               "station_id": "2",
               "status": "pending",
               "handed_out": false,
               "part": null,
               "size": null,
               "unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": []
              }
             ],
             "receipt": {
              "items": {
               "amount": 39800,
               "currency": "CZK"
              },
              "discounts": [],
              "delivery": {
               "amount": 0,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "adjustment": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              },
              "to_pay": {
               "amount": 39800,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "12",
                "base": {
                 "amount": 35536,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 4264,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 39800,
                 "currency": "CZK"
                }
               }
              ],
              "document": {
               "title": "Účtenka",
               "number": "184223",
               "tax_document": "Zjednodušený daňový doklad"
              }
             }
            },
            {
             "id": "77814",
             "order_id": "184230",
             "number": "029",
             "status": "received",
             "area": "kitchen",
             "source": "pos",
             "platform": null,
             "name": "Stůl 4",
             "fulfillment": "dine_in",
             "express": false,
             "customer": null,
             "delivery_address": null,
             "delivery_zone": null,
             "note": null,
             "payment_method": "cash",
             "total": {
              "amount": 19900,
              "currency": "CZK"
             },
             "delivery_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "amount_due": {
              "amount": 0,
              "currency": "CZK"
             },
             "paid_by": null,
             "created_at": "2027-01-15T11:51:40+01:00",
             "scheduled_for": null,
             "printed": false,
             "courier": null,
             "not_delivered": null,
             "items": [
              {
               "id": "52020",
               "product_id": "4567",
               "name": "Svíčková na smetaně, houskový knedlík",
               "kitchen_name": null,
               "note": null,
               "quantity": 1,
               "kind": "full",
               "charge": null,
               "course": 1,
               "category": {
                "id": "312",
                "name": "Hlavní jídla"
               },
               "from_daily_menu": false,
               "station_id": "2",
               "status": "pending",
               "handed_out": false,
               "part": null,
               "size": null,
               "unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": []
              }
             ],
             "receipt": {
              "items": {
               "amount": 19900,
               "currency": "CZK"
              },
              "discounts": [],
              "delivery": {
               "amount": 0,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "adjustment": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 19900,
               "currency": "CZK"
              },
              "to_pay": {
               "amount": 19900,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "12",
                "base": {
                 "amount": 17768,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 2132,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 19900,
                 "currency": "CZK"
                }
               }
              ],
              "document": {
               "title": "Účtenka",
               "number": "184230",
               "tax_document": "Zjednodušený daňový doklad"
              }
             }
            },
            {
             "id": "77815",
             "order_id": "184226",
             "number": "030",
             "status": "ready",
             "area": "kitchen",
             "source": "web",
             "platform": null,
             "name": "Jana Nováková",
             "fulfillment": "delivery",
             "express": false,
             "customer": {
              "name": "Jana Nováková",
              "phone": "+420777123456",
              "not_delivered_count": 0,
              "last_not_delivered_at": null
             },
             "delivery_address": {
              "street": "Jeseniova 1196/52",
              "city": "Praha 3",
              "location": {
               "lat": 50.0833,
               "lon": 14.4667
              }
             },
             "delivery_zone": {
              "id": "21",
              "name": "Vinohrady do 3 km"
             },
             "note": "3. patro, zvonek Nováková",
             "payment_method": "cash",
             "total": {
              "amount": 38600,
              "currency": "CZK"
             },
             "delivery_price": {
              "amount": 4900,
              "currency": "CZK"
             },
             "amount_due": {
              "amount": 38600,
              "currency": "CZK"
             },
             "paid_by": null,
             "created_at": "2027-01-15T11:50:40+01:00",
             "scheduled_for": null,
             "printed": true,
             "courier": null,
             "not_delivered": null,
             "items": [
              {
               "id": "52031",
               "product_id": "4571",
               "name": "Pizza Margherita",
               "kitchen_name": null,
               "note": "Nekrájet",
               "quantity": 1,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "315",
                "name": "Pizza"
               },
               "from_daily_menu": false,
               "station_id": "3",
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": {
                "name": "Ø32cm",
                "dish_name": "Pizza Margherita"
               },
               "unit_price": {
                "amount": 18900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": [
                {
                 "id": "52032",
                 "charge": null,
                 "product_id": "4602",
                 "name": "Extra sýr",
                 "kitchen_name": null,
                 "note": null,
                 "quantity": 1,
                 "kind": "full",
                 "status": "done",
                 "handed_out": false,
                 "part": null,
                 "size": null,
                 "unit_price": {
                  "amount": 3000,
                  "currency": "CZK"
                 },
                 "packaging_price": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "discount": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "gift": false,
                 "vat_rate": "12",
                 "removed_ingredients": []
                }
               ]
              },
              {
               "id": "52033",
               "product_id": "4593",
               "name": "Domácí limonáda 0,4 l",
               "kitchen_name": null,
               "note": null,
               "quantity": 2,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "320",
                "name": "Nápoje"
               },
               "from_daily_menu": false,
               "station_id": null,
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": null,
               "unit_price": {
                "amount": 5900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": []
              }
             ],
             "receipt": {
              "items": {
               "amount": 33700,
               "currency": "CZK"
              },
              "discounts": [],
              "delivery": {
               "amount": 4900,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "adjustment": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 38600,
               "currency": "CZK"
              },
              "to_pay": {
               "amount": 38600,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "12",
                "base": {
                 "amount": 34464,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 4136,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 38600,
                 "currency": "CZK"
                }
               }
              ],
              "document": {
               "title": "Účtenka",
               "number": "184226",
               "tax_document": "Zjednodušený daňový doklad"
              }
             }
            }
           ],
           "next_cursor": null,
           "preorders_later": 2
          },
          "x-summary-cs": "Bony v kuchyni"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "post": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "createKitchenTicket",
    "summary": "Send items of a table to the kitchen",
    "x-summary-cs": "Poslat položky stolu do kuchyně",
    "x-requires-device": true,
    "x-staff": "required",
    "x-idempotency": "body-id",
    "description": "A kitchen ticket from the register or the waiter app before the bill is paid – today's \"bon\" of an open table.\nIt shows on the kitchen display in the `bar` area and at the production stations, without prices: the money is\non the receipt later (`createReceipt`), so sales and stock are never counted twice. Every round of items is a\nnew ticket, as today.\n\nWhen the restaurant sends its tickets to another restaurant's kitchen (a setting in the administration), the\nticket is created there, named \"PRESMEROVANO Z …\" as today; the response is that ticket.\n\nFollow the ticket with `getKitchenTicket` (scope `kitchen:read`) – for example to tell the waiter that the food\nis ready. Changes come as `kitchen.ticket_updated` events – at once when the kitchen works through this API,\nwithin about two minutes when it works elsewhere (the web kitchen display, devices on API v1). A redirected\nticket belongs to the other restaurant, so a device paired with this restaurant cannot follow it.\n\n`id` is your UUID of the ticket made on the device; the same `id` again from the same device returns the ticket\nwith `200` (`409 conflict` when the `id` belongs to another device).\n",
    "x-description-cs": "Kuchyňský bon z pokladny nebo mobilního číšníka před zaplacením – dnešní „bon“ otevřeného stolu. Ukáže se na\nkuchyňském displeji v oblasti `bar` a ve výrobě po stanovištích, bez cen: peníze jsou až na účtence\n(`createReceipt`), takže se tržba ani sklad nikdy nezapočítají dvakrát. Každé kolo položek je nový bon jako dnes.\n\nKdyž provozovna posílá bony do kuchyně jiné provozovny (nastavení v administraci), bon vznikne tam s názvem\n„PRESMEROVANO Z …“ jako dnes; odpověď je ten bon.\n\nBon sledujte přes `getKitchenTicket` (oprávnění `kitchen:read`) – třeba abyste číšníkovi ukázali, že je jídlo\nhotové. Změny přicházejí jako události `kitchen.ticket_updated` – hned, když kuchyně pracuje přes toto API,\ndo zhruba dvou minut, když pracuje jinde (webový kuchyňský displej, zařízení na API v1). Přesměrovaný bon patří\ndruhé provozovně, takže ho zařízení spárované s touto provozovnou sledovat nemůže.\n\n`id` je vaše UUID bonu vytvořené na zařízení; stejné `id` znovu ze stejného zařízení vrátí bon s `200`\n(`409 conflict`, když `id` patří jinému zařízení).\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/KitchenTicketCreate"
       },
       "examples": {
        "table": {
         "summary": "A ticket for a table from the register",
         "value": {
          "id": "01a318f0-a0c0-799d-bed5-0149428de555",
          "table_name": "Stůl 4",
          "order_type": "dine_in",
          "items": [
           {
            "product_id": "4567",
            "quantity": 1,
            "course": 1
           },
           {
            "product_id": "4571",
            "quantity": 1,
            "add_ons": [
             {
              "product_id": "4602"
             }
            ],
            "removed_ingredient_ids": [
             "9001"
            ],
            "note": "Pálivé",
            "course": 1
           }
          ]
         },
         "x-summary-cs": "Bon ke stolu z pokladny"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "This `id` was already sent; the ticket.",
      "x-description-cs": "Toto `id` už bylo poslané; bon.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenTicket"
        },
        "examples": {
         "duplicate": {
          "summary": "The same id again – already created",
          "value": {
           "id": "77814",
           "order_id": "184230",
           "number": "029",
           "status": "received",
           "area": "kitchen",
           "source": "pos",
           "platform": null,
           "name": "Stůl 4",
           "fulfillment": "dine_in",
           "express": false,
           "customer": null,
           "delivery_address": null,
           "delivery_zone": null,
           "note": null,
           "payment_method": "cash",
           "total": {
            "amount": 19900,
            "currency": "CZK"
           },
           "delivery_price": {
            "amount": 0,
            "currency": "CZK"
           },
           "amount_due": {
            "amount": 0,
            "currency": "CZK"
           },
           "paid_by": null,
           "created_at": "2027-01-15T11:51:40+01:00",
           "scheduled_for": null,
           "printed": false,
           "courier": null,
           "not_delivered": null,
           "items": [
            {
             "id": "52020",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "kitchen_name": null,
             "note": null,
             "quantity": 1,
             "kind": "full",
             "charge": null,
             "course": 1,
             "category": {
              "id": "312",
              "name": "Hlavní jídla"
             },
             "from_daily_menu": false,
             "station_id": "2",
             "status": "pending",
             "handed_out": false,
             "part": null,
             "size": null,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [],
             "modifiers": []
            }
           ],
           "receipt": {
            "items": {
             "amount": 19900,
             "currency": "CZK"
            },
            "discounts": [],
            "delivery": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "adjustment": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 19900,
             "currency": "CZK"
            },
            "to_pay": {
             "amount": 19900,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2132,
               "currency": "CZK"
              },
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             }
            ],
            "document": {
             "title": "Účtenka",
             "number": "184230",
             "tax_document": "Zjednodušený daňový doklad"
            }
           }
          },
          "x-summary-cs": "Stejné id podruhé – už založený"
         }
        }
       }
      }
     },
     "201": {
      "description": "Sent to the kitchen.",
      "x-description-cs": "Posláno do kuchyně.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenTicket"
        },
        "examples": {
         "created": {
          "summary": "A new ticket",
          "value": {
           "id": "77814",
           "order_id": "184230",
           "number": "029",
           "status": "received",
           "area": "kitchen",
           "source": "pos",
           "platform": null,
           "name": "Stůl 4",
           "fulfillment": "dine_in",
           "express": false,
           "customer": null,
           "delivery_address": null,
           "delivery_zone": null,
           "note": null,
           "payment_method": "cash",
           "total": {
            "amount": 41800,
            "currency": "CZK"
           },
           "delivery_price": {
            "amount": 0,
            "currency": "CZK"
           },
           "amount_due": {
            "amount": 0,
            "currency": "CZK"
           },
           "paid_by": null,
           "created_at": "2027-01-15T11:51:40+01:00",
           "scheduled_for": null,
           "printed": false,
           "courier": null,
           "not_delivered": null,
           "items": [
            {
             "id": "52020",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "kitchen_name": null,
             "note": null,
             "quantity": 1,
             "kind": "full",
             "charge": null,
             "course": 1,
             "category": {
              "id": "312",
              "name": "Hlavní jídla"
             },
             "from_daily_menu": false,
             "station_id": "2",
             "status": "pending",
             "handed_out": false,
             "part": null,
             "size": null,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [],
             "modifiers": []
            },
            {
             "id": "52021",
             "product_id": "4571",
             "name": "Pizza Margherita",
             "kitchen_name": null,
             "note": "Pálivé",
             "quantity": 1,
             "kind": "full",
             "charge": null,
             "course": 1,
             "category": {
              "id": "315",
              "name": "Pizza"
             },
             "from_daily_menu": false,
             "station_id": "3",
             "status": "pending",
             "handed_out": false,
             "part": null,
             "size": {
              "name": "Ø32cm",
              "dish_name": "Pizza Margherita"
             },
             "unit_price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [
              "bazalka"
             ],
             "modifiers": [
              {
               "id": "52022",
               "charge": null,
               "product_id": "4602",
               "name": "Extra sýr",
               "kitchen_name": null,
               "note": null,
               "quantity": 1,
               "kind": "full",
               "status": "pending",
               "handed_out": false,
               "part": null,
               "size": null,
               "unit_price": {
                "amount": 3000,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": []
              }
             ]
            }
           ],
           "receipt": {
            "items": {
             "amount": 41800,
             "currency": "CZK"
            },
            "discounts": [],
            "delivery": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "adjustment": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 41800,
             "currency": "CZK"
            },
            "to_pay": {
             "amount": 41800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 37321,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4479,
               "currency": "CZK"
              },
              "total": {
               "amount": 41800,
               "currency": "CZK"
              }
             }
            ],
            "document": {
             "title": "Účtenka",
             "number": "184230",
             "tax_document": "Zjednodušený daňový doklad"
            }
           }
          },
          "x-summary-cs": "Nový bon"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "price_changed": {
          "summary": "The prices changed meanwhile",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#price_changed",
           "title": "Cena se změnila; načtěte sortiment znovu",
           "status": 409,
           "code": "price_changed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Ceny se mezitím změnily"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "The product has no such removable ingredient",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/1/removed_ingredient_ids/0",
             "code": "ingredient_not_removable",
             "message": "Tuhle surovinu produkt k odebrání nemá."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Surovinu produkt k odebrání nemá"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/queue": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "getKitchenQueue",
    "summary": "Order numbers for the customers' screen",
    "x-summary-cs": "Čísla objednávek pro obrazovku hostů",
    "description": "The order-number screen at the counter, the same as the kitchen display shows in its queue mode: orders from the\nregisters (receipts and open-table tickets, through this API or API v1), pick-ups ordered on the web – the\ne-shop or a guest application (`order_channel` `web`) – and pick-ups from a kiosk (`kiosk`, in either of its\nmodes), except orders named after a delivery platform (Wolt, Bolt, Foodora, Choice), due within 2 hours and at\nmost 12 hours old, from the current numbering only (closing the kitchen restarts it). Orders the staff take in the kitchen – phone orders of the kitchen display and orders of\nstaff applications (`order_channel` `staff`), pick-ups included – and web deliveries are not on the screen.\n`preparing` until the production stations have finished every item they make, then `ready` (to be picked up); a\nclosed order leaves the screen. Without production stations nothing becomes `ready`. Only numbers and times – no\nnames, no items – so it can be shown to everyone. Answers `304` to `If-None-Match` when nothing changed.\n",
    "x-description-cs": "Pořadník u pultu stejně jako kuchyňský displej v režimu pořadníku: objednávky z pokladen (účtenky a bony\notevřených stolů, přes toto API i API v1), osobní odběry objednané přes web – e-shop nebo aplikaci pro hosty\n(`order_channel` `web`) – a osobní odběry z kiosku (`kiosk`, v kterémkoli jeho režimu), kromě objednávek\npojmenovaných podle rozvozové platformy (Wolt, Bolt, Foodora, Choice), s termínem do 2 hodin, nejvýš 12 hodin\nstaré a jen z aktuálního číslování (uzávěrka kuchyně ho začne znovu).\nObjednávky, které personál bere v kuchyni – telefonické objednávky kuchyňského displeje a objednávky aplikací\npersonálu (`order_channel` `staff`), i osobní odběry – a rozvozy z webu na obrazovce nejsou. `preparing`, dokud\nvýrobní stanoviště neodbaví všechno, co vyrábějí, pak `ready` (k vyzvednutí); uzavřená objednávka z obrazovky\nzmizí. Bez výrobních stanovišť se nic `ready` nestane. Jen čísla a časy – žádná jména ani položky – takže se dá\nukazovat všem. Na `If-None-Match` odpoví `304`, když se nic nezměnilo.\n",
    "security": [
     {
      "oauth2": [
       "queue:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The numbers.",
      "x-description-cs": "Čísla.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenQueue"
        },
        "examples": {
         "queue": {
          "summary": "The queue for customers",
          "value": {
           "preparing": [
            {
             "ticket_id": "77812",
             "number": "027",
             "since": "2027-01-15T11:44:02+01:00"
            },
            {
             "ticket_id": "77814",
             "number": "029",
             "since": "2027-01-15T11:52:00+01:00"
            }
           ],
           "ready": [
            {
             "ticket_id": "77815",
             "number": "030",
             "since": "2027-01-15T11:58:20+01:00"
            }
           ]
          },
          "x-summary-cs": "Pořadník pro zákazníky"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/stations/{station_id}/tickets": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StationId"
    }
   ],
   "get": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "listStationTickets",
    "summary": "Orders for one production station",
    "x-summary-cs": "Objednávky pro jedno výrobní stanoviště",
    "description": "For a split kitchen (Devices → Kitchen display → production stations in the administration). Orders on the board\n(as `view=active`, open tables of the last 7 days) that contain something this station makes, with the items of\nthe station grouped into courses and categories – the same segments the station screen shows today – whether\nthis station is working on the order and which other stations are.\n",
    "x-description-cs": "Pro rozdělenou kuchyni (výrobní stanoviště v administraci). Objednávky na tabuli (jako `view=active`, otevřené\nstoly za posledních 7 dní), ve kterých je něco, co toto stanoviště dělá, s jeho položkami rozdělenými do chodů\na kategorií – stejné segmenty, jaké dnes ukazuje obrazovka stanoviště – a s tím, zda na objednávce stanoviště\npracuje a která další stanoviště také.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The orders of the station.",
      "x-description-cs": "Objednávky stanoviště.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StationTicketList"
        },
        "examples": {
         "station": {
          "summary": "Tickets of the station",
          "value": {
           "data": [
            {
             "ticket": {
              "id": "77812",
              "order_id": "184223",
              "number": "027",
              "status": "preparing",
              "area": "kitchen",
              "source": "web",
              "platform": null,
              "name": "Jana Nováková",
              "fulfillment": "takeaway",
              "express": false,
              "customer": {
               "name": "Jana Nováková",
               "phone": "+420777123456",
               "not_delivered_count": 0,
               "last_not_delivered_at": null
              },
              "delivery_address": null,
              "delivery_zone": null,
              "note": null,
              "payment_method": "cash",
              "total": {
               "amount": 39800,
               "currency": "CZK"
              },
              "delivery_price": {
               "amount": 0,
               "currency": "CZK"
              },
              "amount_due": {
               "amount": 39800,
               "currency": "CZK"
              },
              "paid_by": null,
              "created_at": "2027-01-15T11:42:31+01:00",
              "scheduled_for": null,
              "printed": true,
              "courier": null,
              "not_delivered": null,
              "items": [
               {
                "id": "52011",
                "product_id": "4567",
                "name": "Svíčková na smetaně, houskový knedlík",
                "kitchen_name": null,
                "note": null,
                "quantity": 2,
                "kind": "full",
                "charge": null,
                "course": 0,
                "category": {
                 "id": "312",
                 "name": "Hlavní jídla"
                },
                "from_daily_menu": false,
                "station_id": "2",
                "status": "pending",
                "handed_out": false,
                "part": null,
                "size": null,
                "unit_price": {
                 "amount": 19900,
                 "currency": "CZK"
                },
                "packaging_price": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "discount": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "gift": false,
                "vat_rate": "12",
                "removed_ingredients": [],
                "modifiers": []
               }
              ],
              "receipt": {
               "items": {
                "amount": 39800,
                "currency": "CZK"
               },
               "discounts": [],
               "delivery": {
                "amount": 0,
                "currency": "CZK"
               },
               "rounding": {
                "amount": 0,
                "currency": "CZK"
               },
               "adjustment": {
                "amount": 0,
                "currency": "CZK"
               },
               "total": {
                "amount": 39800,
                "currency": "CZK"
               },
               "to_pay": {
                "amount": 39800,
                "currency": "CZK"
               },
               "vat": [
                {
                 "rate": "12",
                 "base": {
                  "amount": 35536,
                  "currency": "CZK"
                 },
                 "vat": {
                  "amount": 4264,
                  "currency": "CZK"
                 },
                 "total": {
                  "amount": 39800,
                  "currency": "CZK"
                 }
                }
               ],
               "document": {
                "title": "Účtenka",
                "number": "184223",
                "tax_document": "Zjednodušený daňový doklad"
               }
              }
             },
             "working": true,
             "other_stations": [],
             "courses": [
              {
               "course": 0,
               "done": false,
               "categories": [
                {
                 "id": "312",
                 "name": "Hlavní jídla",
                 "done": false,
                 "item_ids": [
                  "52011"
                 ]
                }
               ]
              }
             ]
            },
            {
             "ticket": {
              "id": "77814",
              "order_id": "184230",
              "number": "029",
              "status": "received",
              "area": "kitchen",
              "source": "pos",
              "platform": null,
              "name": "Stůl 4",
              "fulfillment": "dine_in",
              "express": false,
              "customer": null,
              "delivery_address": null,
              "delivery_zone": null,
              "note": null,
              "payment_method": "cash",
              "total": {
               "amount": 19900,
               "currency": "CZK"
              },
              "delivery_price": {
               "amount": 0,
               "currency": "CZK"
              },
              "amount_due": {
               "amount": 0,
               "currency": "CZK"
              },
              "paid_by": null,
              "created_at": "2027-01-15T11:51:40+01:00",
              "scheduled_for": null,
              "printed": false,
              "courier": null,
              "not_delivered": null,
              "items": [
               {
                "id": "52020",
                "product_id": "4567",
                "name": "Svíčková na smetaně, houskový knedlík",
                "kitchen_name": null,
                "note": null,
                "quantity": 1,
                "kind": "full",
                "charge": null,
                "course": 1,
                "category": {
                 "id": "312",
                 "name": "Hlavní jídla"
                },
                "from_daily_menu": false,
                "station_id": "2",
                "status": "pending",
                "handed_out": false,
                "part": null,
                "size": null,
                "unit_price": {
                 "amount": 19900,
                 "currency": "CZK"
                },
                "packaging_price": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "discount": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "gift": false,
                "vat_rate": "12",
                "removed_ingredients": [],
                "modifiers": []
               }
              ],
              "receipt": {
               "items": {
                "amount": 19900,
                "currency": "CZK"
               },
               "discounts": [],
               "delivery": {
                "amount": 0,
                "currency": "CZK"
               },
               "rounding": {
                "amount": 0,
                "currency": "CZK"
               },
               "adjustment": {
                "amount": 0,
                "currency": "CZK"
               },
               "total": {
                "amount": 19900,
                "currency": "CZK"
               },
               "to_pay": {
                "amount": 19900,
                "currency": "CZK"
               },
               "vat": [
                {
                 "rate": "12",
                 "base": {
                  "amount": 17768,
                  "currency": "CZK"
                 },
                 "vat": {
                  "amount": 2132,
                  "currency": "CZK"
                 },
                 "total": {
                  "amount": 19900,
                  "currency": "CZK"
                 }
                }
               ],
               "document": {
                "title": "Účtenka",
                "number": "184230",
                "tax_document": "Zjednodušený daňový doklad"
               }
              }
             },
             "working": false,
             "other_stations": [
              {
               "id": "3",
               "name": "Pizza"
              }
             ],
             "courses": [
              {
               "course": 1,
               "done": false,
               "categories": [
                {
                 "id": "312",
                 "name": "Hlavní jídla",
                 "done": false,
                 "item_ids": [
                  "52020"
                 ]
                }
               ]
              }
             ]
            }
           ]
          },
          "x-summary-cs": "Bony stanoviště Teplá kuchyně"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/stations/{station_id}/tickets/{ticket_id}/working": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StationId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "put": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "startStationWork",
    "summary": "The station starts working on the order",
    "x-summary-cs": "Stanoviště začíná na objednávce pracovat",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "Other stations see it; the order counts as being prepared (`order.status_changed` with `preparing`).",
    "x-description-cs": "Ostatní stanoviště to vidí; objednávka se počítá jako připravovaná (`order.status_changed` s `preparing`).",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Working.",
      "x-description-cs": "Pracuje."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "delete": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "stopStationWork",
    "summary": "The station stops working on the order",
    "x-summary-cs": "Stanoviště na objednávce přestává pracovat",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "Takes back `startStationWork`: other stations no longer see this station working on the order; items already\ndone stay done. When nothing else marks the order as being prepared (no other station working on it, nothing\ndone or handed out, the kitchen did not set `preparing`), an application's order goes back to `received`\n(`order.status_changed`). Stopping a station that is not working changes nothing and sends no event. A\ncancelled order answers `409 ticket_cancelled`.\n",
    "x-description-cs": "Vezme zpět `startStationWork`: ostatní stanoviště už nevidí, že na objednávce toto stanoviště pracuje; hotové\npoložky zůstanou hotové. Když objednávku jako připravovanou nic jiného neoznačuje (nepracuje na ní jiné\nstanoviště, nic není hotové ani vydané, kuchyně nenastavila `preparing`), objednávka aplikace se vrátí do\n`received` (`order.status_changed`). Ukončení práce stanoviště, které nepracuje, nic nezmění a nevydá událost.\nZrušená objednávka vrátí `409 ticket_cancelled`.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Not working any more.",
      "x-description-cs": "Už nepracuje."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/stations/{station_id}/tickets/{ticket_id}/complete": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StationId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "post": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "completeStationSegment",
    "summary": "Mark a segment of the station done",
    "x-summary-cs": "Odbavit segment stanoviště",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "Marks the open items of this station done: the whole order (`scope=order`), one course (`course`) or one category\nwithin a course (`category` with `course` and `category_id`). The action goes to the station's history and can be\nundone. Nothing open in the segment answers `409 nothing_to_complete` – also when another display finished it a\nmoment earlier (two taps at once give one action). A cancelled order answers `409 ticket_cancelled`.\n",
    "x-description-cs": "Odbaví otevřené položky tohoto stanoviště: celou objednávku (`scope=order`), jeden chod (`course`) nebo jednu\nkategorii v chodu (`category` s `course` a `category_id`). Akce se zapíše do historie stanoviště a jde vzít zpět.\nKdyž v segmentu nic otevřené není, odpověď je `409 nothing_to_complete` – i když ho o chvilku dřív odbavil jiný\ndisplej (dvě klepnutí naráz dají jednu akci). Zrušená objednávka vrátí `409 ticket_cancelled`.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StationSegmentComplete"
       },
       "examples": {
        "order": {
         "summary": "The whole order is done",
         "value": {
          "scope": "order"
         },
         "x-summary-cs": "Hotová celá objednávka"
        },
        "course": {
         "summary": "Course 1 is done",
         "value": {
          "scope": "course",
          "course": 1
         },
         "x-summary-cs": "Hotový 1. chod"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The action in the station's history.",
      "x-description-cs": "Akce v historii stanoviště.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionAction"
        },
        "examples": {
         "done": {
          "summary": "Done",
          "value": {
           "id": "9921",
           "ticket_id": "77812",
           "kind": "production",
           "scope": "order",
           "name": "Celá objednávka",
           "item_count": 2,
           "undone": false,
           "created_at": "2027-01-15T11:57:02+01:00",
           "employee": {
            "id": "66",
            "name": "Lucie Svobodová"
           }
          },
          "x-summary-cs": "Odbaveno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "nothing_to_complete": {
          "summary": "Nothing to complete",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#nothing_to_complete",
           "title": "V tomto segmentu nic otevřeného není",
           "status": 409,
           "code": "nothing_to_complete",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Není co odbavit"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/stations/{station_id}/actions": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StationId"
    }
   ],
   "get": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "listStationActions",
    "summary": "Recent actions of the station",
    "x-summary-cs": "Poslední akce stanoviště",
    "description": "The last 12 actions of the station within 12 hours, newest first, for taking one back.",
    "x-description-cs": "Posledních 12 akcí stanoviště za 12 hodin, nejnovější první, aby šla některá vzít zpět.",
    "security": [
     {
      "oauth2": [
       "kitchen:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The actions.",
      "x-description-cs": "Akce.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionActionList"
        },
        "examples": {
         "history": {
          "summary": "The history of the station",
          "value": {
           "data": [
            {
             "id": "9921",
             "ticket_id": "77812",
             "kind": "production",
             "scope": "order",
             "name": "Celá objednávka",
             "item_count": 2,
             "undone": false,
             "created_at": "2027-01-15T11:57:02+01:00",
             "employee": {
              "id": "66",
              "name": "Lucie Svobodová"
             }
            }
           ]
          },
          "x-summary-cs": "Historie stanoviště"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/stations/{station_id}/actions/{action_id}/undo": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StationId"
    },
    {
     "name": "action_id",
     "in": "path",
     "required": true,
     "schema": {
      "$ref": "#/components/schemas/Id"
     },
     "example": "9921"
    }
   ],
   "post": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "undoStationAction",
    "summary": "Take an action of the station back",
    "x-summary-cs": "Vzít akci stanoviště zpět",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "The items of that action are open again (only those it switched, not what another screen did meanwhile).\nAn action taken back already answers `409 action_already_undone`.\n",
    "x-description-cs": "Položky té akce jsou znovu otevřené (jen ty, které přepnula, ne co mezitím udělala jiná obrazovka). Už vrácená\nakce odpoví `409 action_already_undone`.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The action, now taken back.",
      "x-description-cs": "Akce, teď vzatá zpět.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionAction"
        },
        "examples": {
         "undone": {
          "summary": "Undone",
          "value": {
           "id": "9921",
           "ticket_id": "77812",
           "kind": "production",
           "scope": "order",
           "name": "Celá objednávka",
           "item_count": 2,
           "undone": true,
           "created_at": "2027-01-15T11:57:02+01:00",
           "employee": {
            "id": "66",
            "name": "Lucie Svobodová"
           }
          },
          "x-summary-cs": "Vráceno"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "action_already_undone": {
          "summary": "Already undone",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#action_already_undone",
           "title": "Akce už byla vzata zpět",
           "status": 409,
           "code": "action_already_undone",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Už vrácené"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/tickets/{ticket_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "get": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "getKitchenTicket",
    "summary": "One kitchen ticket",
    "x-summary-cs": "Jeden kuchyňský bon",
    "description": "One kitchen ticket of the restaurant by its ID, whatever its state and wherever the order came from – also a\nfinished or cancelled one, or one that is no longer on the board (`listKitchenTickets` shows only the current\nviews). Use it to follow a ticket you sent (`createKitchenTicket`) or the ticket of a `kitchen.ticket_created`\nor `kitchen.ticket_updated` event. Answers `304` to `If-None-Match` when nothing changed. A ticket redirected to the kitchen of another\nrestaurant belongs to that restaurant and answers `404` here.\n",
    "x-description-cs": "Jeden kuchyňský bon provozovny podle ID, v jakémkoli stavu a odkudkoli objednávka přišla – i hotový nebo\nzrušený, nebo takový, který už na tabuli není (`listKitchenTickets` ukazuje jen aktuální pohledy). Slouží ke\nsledování bonu, který jste poslali (`createKitchenTicket`), nebo bonu z události `kitchen.ticket_created` nebo\n`kitchen.ticket_updated`. Na\n`If-None-Match` odpoví `304`, když se nic nezměnilo. Bon přesměrovaný do kuchyně jiné provozovny patří té\nprovozovně a tady vrátí `404`.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The ticket.",
      "x-description-cs": "Bon.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenTicket"
        },
        "examples": {
         "ticket": {
          "summary": "A ticket",
          "value": {
           "id": "77812",
           "order_id": "184223",
           "number": "027",
           "status": "preparing",
           "area": "kitchen",
           "source": "web",
           "platform": null,
           "name": "Jana Nováková",
           "fulfillment": "takeaway",
           "express": false,
           "customer": {
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "not_delivered_count": 0,
            "last_not_delivered_at": null
           },
           "delivery_address": null,
           "delivery_zone": null,
           "note": null,
           "payment_method": "cash",
           "total": {
            "amount": 39800,
            "currency": "CZK"
           },
           "delivery_price": {
            "amount": 0,
            "currency": "CZK"
           },
           "amount_due": {
            "amount": 39800,
            "currency": "CZK"
           },
           "paid_by": null,
           "created_at": "2027-01-15T11:42:31+01:00",
           "scheduled_for": null,
           "printed": true,
           "courier": null,
           "not_delivered": null,
           "items": [
            {
             "id": "52011",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "kitchen_name": null,
             "note": null,
             "quantity": 2,
             "kind": "full",
             "charge": null,
             "course": 0,
             "category": {
              "id": "312",
              "name": "Hlavní jídla"
             },
             "from_daily_menu": false,
             "station_id": "2",
             "status": "pending",
             "handed_out": false,
             "part": null,
             "size": null,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [],
             "modifiers": []
            }
           ],
           "receipt": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "discounts": [],
            "delivery": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "adjustment": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "to_pay": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ],
            "document": {
             "title": "Účtenka",
             "number": "184223",
             "tax_document": "Zjednodušený daňový doklad"
            }
           }
          },
          "x-summary-cs": "Bon"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/tickets/{ticket_id}/status": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "post": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "setKitchenTicketStatus",
    "summary": "Move an order in the kitchen",
    "x-summary-cs": "Posunout objednávku v kuchyni",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "`received` – back to the queue, `preparing` – the kitchen started, `ready` – done and waiting for handout or\na courier, `delivered` – handed out. A cancelled order stays cancelled (`409 ticket_cancelled`); cancel with\n`POST …/cancel`. An order that was handed out goes back only with a signed-in kitchen manager\n(`403 staff_role_missing`); an application's order stays `delivered` for the application. The same status\nagain changes nothing and sends no event.\n\nAs on the kitchen display today: when an order becomes `ready` and the restaurant sends the \"order is ready\"\nSMS, the customer gets it (not when the application that created the order writes to its customers itself).\nMoving an order back to `received` or `preparing` takes it off a courier's route. Applications that created\nthe order learn the new status from their `order.status_changed` event.\n",
    "x-description-cs": "`received` – zpět do fronty, `preparing` – kuchyně začala, `ready` – hotovo a čeká na výdej nebo kurýra,\n`delivered` – vydáno. Zrušená objednávka zůstane zrušená (`409 ticket_cancelled`); rušení je\n`POST …/cancel`. Vydanou objednávku vrátí zpět jen přihlášený vedoucí kuchyně (`403 staff_role_missing`);\nobjednávka aplikace pro aplikaci zůstane `delivered`. Stejný stav znovu nic nezmění a nevydá událost.\n\nJako dnes na kuchyňském displeji: když se objednávka stane `ready` a provozovna posílá SMS „objednávka je\nhotová“, zákazník ji dostane (ne když zákazníkům píše sama aplikace, která objednávku vytvořila). Vrácení\ndo `received` nebo `preparing` objednávku sundá z trasy kurýra. Aplikace, která objednávku vytvořila, se nový\nstav dozví z události `order.status_changed`.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/KitchenTicketStatusChange"
       },
       "examples": {
        "ready": {
         "summary": "Ready to hand out",
         "value": {
          "status": "ready"
         },
         "x-summary-cs": "Hotovo k výdeji"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The ticket after the change.",
      "x-description-cs": "Bon po změně.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenTicket"
        },
        "examples": {
         "ready": {
          "summary": "The ticket is ready",
          "value": {
           "id": "77812",
           "order_id": "184223",
           "number": "027",
           "status": "ready",
           "area": "kitchen",
           "source": "web",
           "platform": null,
           "name": "Jana Nováková",
           "fulfillment": "takeaway",
           "express": false,
           "customer": {
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "not_delivered_count": 0,
            "last_not_delivered_at": null
           },
           "delivery_address": null,
           "delivery_zone": null,
           "note": null,
           "payment_method": "cash",
           "total": {
            "amount": 39800,
            "currency": "CZK"
           },
           "delivery_price": {
            "amount": 0,
            "currency": "CZK"
           },
           "amount_due": {
            "amount": 39800,
            "currency": "CZK"
           },
           "paid_by": null,
           "created_at": "2027-01-15T11:42:31+01:00",
           "scheduled_for": null,
           "printed": true,
           "courier": null,
           "not_delivered": null,
           "items": [
            {
             "id": "52011",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "kitchen_name": null,
             "note": null,
             "quantity": 2,
             "kind": "full",
             "charge": null,
             "course": 0,
             "category": {
              "id": "312",
              "name": "Hlavní jídla"
             },
             "from_daily_menu": false,
             "station_id": "2",
             "status": "done",
             "handed_out": false,
             "part": null,
             "size": null,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [],
             "modifiers": []
            }
           ],
           "receipt": {
            "items": {
             "amount": 39800,
             "currency": "CZK"
            },
            "discounts": [],
            "delivery": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "adjustment": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 39800,
             "currency": "CZK"
            },
            "to_pay": {
             "amount": 39800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 35536,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4264,
               "currency": "CZK"
              },
              "total": {
               "amount": 39800,
               "currency": "CZK"
              }
             }
            ],
            "document": {
             "title": "Účtenka",
             "number": "184223",
             "tax_document": "Zjednodušený daňový doklad"
            }
           }
          },
          "x-summary-cs": "Bon je hotový"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "ticket_cancelled": {
          "summary": "The ticket is cancelled",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#ticket_cancelled",
           "title": "Objednávka je v kuchyni zrušená",
           "status": 409,
           "code": "ticket_cancelled",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Bon je stornovaný"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/tickets/{ticket_id}/cancel": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "post": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "cancelKitchenTicket",
    "summary": "Cancel an order in the kitchen",
    "x-summary-cs": "Zrušit objednávku v kuchyni",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "Cancels the order with a cancellation document, exactly as the cancel button of the kitchen display: sales\nand stock go back, a gift voucher paid with goes back to the voucher. Only an employee with the\n`kitchen_manager` role signed in on the device may do it (`403 staff_role_missing`); the employee is recorded.\nA cancelled order cannot be brought back (`409 ticket_cancelled`). With `write_off` the order is written off:\nthe takings go back, but no stock does – the food was made and is lost (an order the customer did not take\nover); without `reason` the reason of the courier's report is used.\n",
    "x-description-cs": "Zruší objednávku protidokladem, stejně jako tlačítko storno na kuchyňském displeji: tržba i sklad se vrátí,\nzaplacený dárkový voucher se vrátí na voucher. Smí jen zaměstnanec s rolí `kitchen_manager` přihlášený na\nzařízení (`403 staff_role_missing`); zaměstnanec se zapíše. Zrušenou objednávku nejde vrátit\n(`409 ticket_cancelled`). S `write_off` se objednávka odepíše: tržba se vrátí, ale sklad ne – jídlo je\nuvařené a ztracené (objednávka, kterou zákazník nepřevzal); bez `reason` se použije důvod z hlášení kurýra.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/KitchenTicketCancel"
       },
       "examples": {
        "left": {
         "summary": "The guest left",
         "value": {
          "reason": "Host odešel před vydáním."
         },
         "x-summary-cs": "Host odešel"
        },
        "write_off": {
         "summary": "Writing off an order not taken over",
         "value": {
          "reason": null,
          "write_off": true
         },
         "x-summary-cs": "Odpis nepřevzaté objednávky"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The cancelled ticket.",
      "x-description-cs": "Zrušený bon.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenTicket"
        },
        "examples": {
         "cancelled": {
          "summary": "A cancelled ticket",
          "value": {
           "id": "77814",
           "order_id": "184230",
           "number": "029",
           "status": "cancelled",
           "area": "kitchen",
           "source": "pos",
           "platform": null,
           "name": "Stůl 4",
           "fulfillment": "dine_in",
           "express": false,
           "customer": null,
           "delivery_address": null,
           "delivery_zone": null,
           "note": null,
           "payment_method": "cash",
           "total": {
            "amount": 19900,
            "currency": "CZK"
           },
           "delivery_price": {
            "amount": 0,
            "currency": "CZK"
           },
           "amount_due": {
            "amount": 0,
            "currency": "CZK"
           },
           "paid_by": null,
           "created_at": "2027-01-15T11:51:40+01:00",
           "scheduled_for": null,
           "printed": false,
           "courier": null,
           "not_delivered": null,
           "items": [
            {
             "id": "52020",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "kitchen_name": null,
             "note": null,
             "quantity": 1,
             "kind": "full",
             "charge": null,
             "course": 1,
             "category": {
              "id": "312",
              "name": "Hlavní jídla"
             },
             "from_daily_menu": false,
             "station_id": "2",
             "status": "pending",
             "handed_out": false,
             "part": null,
             "size": null,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [],
             "modifiers": []
            }
           ],
           "receipt": {
            "items": {
             "amount": 19900,
             "currency": "CZK"
            },
            "discounts": [],
            "delivery": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "adjustment": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 19900,
             "currency": "CZK"
            },
            "to_pay": {
             "amount": 19900,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2132,
               "currency": "CZK"
              },
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             }
            ],
            "document": {
             "title": "Účtenka",
             "number": "184230",
             "tax_document": "Zjednodušený daňový doklad"
            }
           }
          },
          "x-summary-cs": "Stornovaný bon"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "description": "`insufficient_scope` or `customer_not_verified`; on Profirest's own devices also `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` and – on the\nregister – `manager_approval_required`.\n",
      "x-description-cs": "`insufficient_scope` nebo `customer_not_verified`; na vlastních zařízeních Profirestu také `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` a – na pokladně –\n`manager_approval_required`.\n",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "insufficient_scope": {
          "summary": "The token lacks the scope",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#insufficient_scope",
           "title": "Token nemá potřebné oprávnění",
           "status": 403,
           "code": "insufficient_scope",
           "detail": "Missing scope: orders:write",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Token nemá potřebné oprávnění"
         },
         "staff_role_missing": {
          "summary": "Only a kitchen manager may cancel",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#staff_role_missing",
           "title": "Přihlášený zaměstnanec tohle nesmí",
           "status": 403,
           "code": "staff_role_missing",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stornovat smí jen vedoucí kuchyně"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/tickets/{ticket_id}/printed": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "put": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "markKitchenTicketPrinted",
    "summary": "Confirm the ticket was printed",
    "x-summary-cs": "Potvrdit vytištění bonu",
    "x-requires-device": true,
    "description": "The display printed the ticket; other displays will not print it again. Repeating it does no harm.",
    "x-description-cs": "Displej bon vytiskl; ostatní displeje ho znovu tisknout nebudou. Opakování nevadí.",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Printed.",
      "x-description-cs": "Vytištěno."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/tickets/{ticket_id}/items": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "post": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "addKitchenTicketItems",
    "summary": "Add items to an order in the kitchen",
    "x-summary-cs": "Přidat položky k objednávce v kuchyni",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "The ADD ITEMS button of the kitchen display: what the customer adds on the phone goes to the same order, not to\na second one. Profirest prices the items from the catalog of `channel` (default `kitchen`) exactly like a quote;\nthe device sends no prices. As today the new items get their own groups after the existing ones, the note of\nthe order ends with `[UPRAVENO: +…]`, the total grows and the ticket is printed again (`printed: false`).\n\nOnly while the order waits or is being prepared, and not when it is paid by card, online or in advance. Orders\ncreated through this API by applications of the restaurant staff can be extended – the order in the API gets\nthe new lines, totals and amount to collect too (`order.updated`); orders of guest applications cannot, their\ncustomer pays what the application showed (`409 ticket_not_amendable`; create a new order). Prices and the offer\nare those of the moment the items are added – for a pre-order whose time is still ahead, those of its time. A\nproduct that is not offered or sold out rejects the whole request (`422 product_unavailable`); nothing is added\nhalf-way.\n",
    "x-description-cs": "Tlačítko PŘIDAT POLOŽKY kuchyňského displeje: co zákazník přidá po telefonu, jde do stejné objednávky, ne do\ndruhé. Ceny položek Profirest spočítá z katalogu kanálu `channel` (výchozí `kitchen`) přesně jako kalkulaci;\nzařízení žádné ceny neposílá. Jako dnes dostanou nové položky vlastní skupiny za stávajícími, poznámka\nobjednávky končí `[UPRAVENO: +…]`, součet vzroste a bon se vytiskne znovu (`printed: false`).\n\nJen dokud objednávka čeká nebo se připravuje, a ne když je zaplacená kartou, online nebo předem. Objednávky, které\npřes toto API založily aplikace personálu provozovny, rozšířit jde – i objednávka v API dostane nové řádky,\nsoučty a částku k vybrání (`order.updated`); objednávky aplikací pro hosty ne, jejich zákazník platí to, co mu\naplikace ukázala (`409 ticket_not_amendable`; založte novou objednávku). Ceny a nabídka jsou ty z okamžiku\npřidání – u předobjednávky, jejíž termín je ještě před námi, ty z jejího termínu. Produkt, který se nenabízí nebo\ndošel, odmítne celý požadavek (`422 product_unavailable`); nic se nepřidá napůl.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/KitchenTicketItemsAdd"
       },
       "examples": {
        "more": {
         "summary": "The guest ordered more",
         "value": {
          "items": [
           {
            "product_id": "4568",
            "quantity": 1,
            "note": "Bez tatarky"
           }
          ],
          "channel": "pos"
         },
         "x-summary-cs": "Host si přiobjednal"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The order with the added items.",
      "x-description-cs": "Objednávka s přidanými položkami.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenTicket"
        },
        "examples": {
         "added": {
          "summary": "The ticket with the added item",
          "value": {
           "id": "77814",
           "order_id": "184230",
           "number": "029",
           "status": "received",
           "area": "kitchen",
           "source": "pos",
           "platform": null,
           "name": "Stůl 4",
           "fulfillment": "dine_in",
           "express": false,
           "customer": null,
           "delivery_address": null,
           "delivery_zone": null,
           "note": null,
           "payment_method": "cash",
           "total": {
            "amount": 37800,
            "currency": "CZK"
           },
           "delivery_price": {
            "amount": 0,
            "currency": "CZK"
           },
           "amount_due": {
            "amount": 0,
            "currency": "CZK"
           },
           "paid_by": null,
           "created_at": "2027-01-15T11:51:40+01:00",
           "scheduled_for": null,
           "printed": false,
           "courier": null,
           "not_delivered": null,
           "items": [
            {
             "id": "52020",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "kitchen_name": null,
             "note": null,
             "quantity": 1,
             "kind": "full",
             "charge": null,
             "course": 1,
             "category": {
              "id": "312",
              "name": "Hlavní jídla"
             },
             "from_daily_menu": false,
             "station_id": "2",
             "status": "pending",
             "handed_out": false,
             "part": null,
             "size": null,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [],
             "modifiers": []
            },
            {
             "id": "52024",
             "product_id": "4568",
             "name": "Smažený sýr, hranolky, tatarská omáčka",
             "kitchen_name": null,
             "note": "Bez tatarky",
             "quantity": 1,
             "kind": "full",
             "charge": null,
             "course": 1,
             "category": {
              "id": "312",
              "name": "Hlavní jídla"
             },
             "from_daily_menu": false,
             "station_id": "2",
             "status": "pending",
             "handed_out": false,
             "part": null,
             "size": null,
             "unit_price": {
              "amount": 17900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [],
             "modifiers": []
            }
           ],
           "receipt": {
            "items": {
             "amount": 37800,
             "currency": "CZK"
            },
            "discounts": [],
            "delivery": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "adjustment": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 37800,
             "currency": "CZK"
            },
            "to_pay": {
             "amount": 37800,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 33750,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4050,
               "currency": "CZK"
              },
              "total": {
               "amount": 37800,
               "currency": "CZK"
              }
             }
            ],
            "document": {
             "title": "Účtenka",
             "number": "184230",
             "tax_document": "Zjednodušený daňový doklad"
            }
           }
          },
          "x-summary-cs": "Bon s přidanou položkou"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "ticket_not_amendable": {
          "summary": "Items can no longer be added to the ticket",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#ticket_not_amendable",
           "title": "K této objednávce nejde přidat položky",
           "status": 409,
           "code": "ticket_not_amendable",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "K bonu už nejde přidávat"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/tickets/{ticket_id}/handover": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "post": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "handOverTicketSegment",
    "summary": "Mark a part of the order handed out",
    "x-summary-cs": "Označit část objednávky jako vydanou",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "The pass (the handover screen of the kitchen display): the staff tick off what they took to the customer – the\nwhole order (`scope=order`), one course, or one category in a course – without finishing the order, so the soup\ngoes out while the main course is still cooking. It covers all stations and does not change the production\nstatus of the items (`handed_out` of the items does). The action goes to the history of the pass and can be\ntaken back. When nothing in the segment is left to hand out, the answer is `409 nothing_to_complete`. A cancelled\norder answers `409 ticket_cancelled` (also when taking back, starting or stopping work on it).\n",
    "x-description-cs": "Výdej (obrazovka výdeje kuchyňského displeje): personál odškrtne, co odnesl zákazníkovi – celou objednávku\n(`scope=order`), jeden chod nebo jednu kategorii v chodu – a objednávku tím neuzavře, takže polévka jde ven,\nzatímco se hlavní jídlo ještě vaří. Platí přes všechna stanoviště a stav výroby položek nemění (mění jejich\n`handed_out`). Akce se zapíše do historie výdeje a jde vzít zpět. Když v segmentu nic k vydání nezbývá,\nodpověď je `409 nothing_to_complete`. Zrušená objednávka vrátí `409 ticket_cancelled` (i při vracení výdeje,\npřevzetí a ukončení práce na ní).\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StationSegmentComplete"
       },
       "examples": {
        "order": {
         "summary": "Handed out completely",
         "value": {
          "scope": "order"
         },
         "x-summary-cs": "Vydáno celé"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The action in the history of the pass.",
      "x-description-cs": "Akce v historii výdeje.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionAction"
        },
        "examples": {
         "handover": {
          "summary": "Handed out",
          "value": {
           "id": "9930",
           "ticket_id": "77812",
           "kind": "handover",
           "scope": "order",
           "name": "Celá objednávka",
           "item_count": 2,
           "undone": false,
           "created_at": "2027-01-15T12:04:11+01:00",
           "employee": {
            "id": "58",
            "name": "Jana Dvořáková"
           }
          },
          "x-summary-cs": "Vydáno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "delete": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "takeBackTicketHandover",
    "summary": "Untick a handed-out part",
    "x-summary-cs": "Zrušit označení vydané části",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "Takes the handover marks of the segment back without a history record – the second tap on the pass. Repeating\nit does no harm.\n",
    "x-description-cs": "Vezme označení vydání segmentu zpět bez zápisu do historie – druhé klepnutí na výdeji. Opakování nevadí.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "name": "scope",
      "in": "query",
      "required": true,
      "description": "The segment, as in `POST …/handover`: `order` – the whole order, `course` – one course (send `course`),\n`category` – one category within a course (send `course` and `category_id`).\n",
      "x-description-cs": "Segment jako u `POST …/handover`: `order` – celá objednávka, `course` – jeden chod (pošlete `course`),\n`category` – jedna kategorie v chodu (pošlete `course` a `category_id`).\n",
      "schema": {
       "type": "string",
       "enum": [
        "order",
        "course",
        "category"
       ]
      },
      "example": "order"
     },
     {
      "name": "course",
      "in": "query",
      "description": "The course for `course` and `category`.",
      "x-description-cs": "Chod u `course` a `category`.",
      "schema": {
       "type": "integer",
       "minimum": 0
      }
     },
     {
      "name": "category_id",
      "in": "query",
      "description": "The category for `category`.",
      "x-description-cs": "Kategorie u `category`.",
      "schema": {
       "$ref": "#/components/schemas/Id"
      }
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Not handed out any more.",
      "x-description-cs": "Už není vydané."
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/handover/actions": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "listHandoverActions",
    "summary": "Recent actions of the pass",
    "x-summary-cs": "Poslední akce výdeje",
    "description": "The last 12 actions of the pass within 12 hours, newest first, for taking one back.",
    "x-description-cs": "Posledních 12 akcí výdeje za 12 hodin, nejnovější první, aby šla některá vzít zpět.",
    "security": [
     {
      "oauth2": [
       "kitchen:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The actions.",
      "x-description-cs": "Akce.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionActionList"
        },
        "examples": {
         "history": {
          "summary": "The handover history",
          "value": {
           "data": [
            {
             "id": "9930",
             "ticket_id": "77812",
             "kind": "handover",
             "scope": "order",
             "name": "Celá objednávka",
             "item_count": 2,
             "undone": false,
             "created_at": "2027-01-15T12:04:11+01:00",
             "employee": {
              "id": "58",
              "name": "Jana Dvořáková"
             }
            }
           ]
          },
          "x-summary-cs": "Historie výdeje"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/handover/actions/{action_id}/undo": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "action_id",
     "in": "path",
     "required": true,
     "schema": {
      "$ref": "#/components/schemas/Id"
     },
     "example": "9930"
    }
   ],
   "post": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "undoHandoverAction",
    "summary": "Take an action of the pass back",
    "x-summary-cs": "Vzít akci výdeje zpět",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "The items of that action are not handed out any more; an order closed by the pass goes back to the queue. An\naction taken back already answers `409 action_already_undone`.\n",
    "x-description-cs": "Položky té akce už nejsou vydané; objednávka, kterou výdej uzavřel, se vrátí do fronty. Už vrácená akce odpoví\n`409 action_already_undone`.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The action, now taken back.",
      "x-description-cs": "Akce, teď vzatá zpět.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProductionAction"
        },
        "examples": {
         "undone": {
          "summary": "The handover undone",
          "value": {
           "id": "9930",
           "ticket_id": "77812",
           "kind": "handover",
           "scope": "order",
           "name": "Celá objednávka",
           "item_count": 2,
           "undone": true,
           "created_at": "2027-01-15T12:04:11+01:00",
           "employee": {
            "id": "58",
            "name": "Jana Dvořáková"
           }
          },
          "x-summary-cs": "Výdej vrácený"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/shift": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "getKitchenShift",
    "summary": "Totals of the open kitchen shift",
    "x-summary-cs": "Součty otevřené směny kuchyně",
    "x-requires-device": true,
    "description": "What the shift close would contain now: orders from the web and from the kitchen not closed yet, the takings for\ndone and handed-out orders in total and by payment, what still waits or is being prepared (it stays for the next\nshift), cancelled orders, and the same per courier – a courier's cash before they hand it over. With\n`courier_id` only that courier's orders.\n",
    "x-description-cs": "Co by teď obsahovala uzávěrka: objednávky z webu a z kuchyně, které ještě nejsou uzavřené, tržba za hotové\na vydané celkem i podle platby, co ještě čeká nebo se připravuje (zůstane do další směny), zrušené a totéž po\nkurýrech – hotovost kurýra, než ji odevzdá. S `courier_id` jen objednávky toho kurýra.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "courier_id",
      "in": "query",
      "description": "Only the orders of this courier.",
      "x-description-cs": "Jen objednávky tohoto kurýra.",
      "schema": {
       "$ref": "#/components/schemas/Id"
      }
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The open shift.",
      "x-description-cs": "Otevřená směna.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenShiftSummary"
        },
        "examples": {
         "shift": {
          "summary": "The takings of the kitchen shift",
          "value": {
           "orders": 64,
           "completed": {
            "amount": 1954300,
            "currency": "CZK"
           },
           "by_payment": {
            "cash": {
             "amount": 802100,
             "currency": "CZK"
            },
            "card": {
             "amount": 1029500,
             "currency": "CZK"
            },
            "meal_voucher": {
             "amount": 0,
             "currency": "CZK"
            },
            "company_account": {
             "amount": 0,
             "currency": "CZK"
            },
            "invoice": {
             "amount": 122700,
             "currency": "CZK"
            }
           },
           "not_completed": {
            "amount": 0,
            "currency": "CZK"
           },
           "not_delivered": {
            "orders": 1,
            "total": {
             "amount": 38600,
             "currency": "CZK"
            }
           },
           "cancelled": {
            "amount": 18900,
            "currency": "CZK"
           },
           "courier_id": null,
           "couriers": [
            {
             "orders": 9,
             "completed": {
              "amount": 352800,
              "currency": "CZK"
             },
             "by_payment": {
              "cash": {
               "amount": 214300,
               "currency": "CZK"
              },
              "card": {
               "amount": 138500,
               "currency": "CZK"
              },
              "meal_voucher": {
               "amount": 0,
               "currency": "CZK"
              },
              "company_account": {
               "amount": 0,
               "currency": "CZK"
              },
              "invoice": {
               "amount": 0,
               "currency": "CZK"
              }
             },
             "not_completed": {
              "amount": 0,
              "currency": "CZK"
             },
             "not_delivered": {
              "orders": 1,
              "total": {
               "amount": 38600,
               "currency": "CZK"
              }
             },
             "cancelled": {
              "amount": 0,
              "currency": "CZK"
             },
             "courier": {
              "id": "64",
              "name": "Tomáš Král"
             }
            }
           ]
          },
          "x-summary-cs": "Tržby směny kuchyně"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/kitchen/shift/close": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Kitchen"
    ],
    "operationId": "closeKitchenShift",
    "summary": "Close the kitchen shift",
    "x-summary-cs": "Uzavřít směnu kuchyně",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "The shift close of the kitchen display, as today: a record in the shift closes of the administration with the\ntakings by payment and with what was not paid yet, all orders that left the queue (done, handed out, cancelled)\ngo into it and the kitchen numbering starts again from 1. With `courier_id` only that courier's orders are\nclosed (couriers change during the day) and the numbering goes on; `courier_id` must be a courier of the\nrestaurant. Orders of applications that were closed count as delivered. Needs a signed-in employee with\na kitchen role; it cannot be taken back. When no order left the queue since the last close (another display\nclosed a moment earlier), the answer is `409 pos_shift_empty` – the same code as an empty shift of a register,\ndespite its name – and nothing changes: the numbering is not reset again.\n",
    "x-description-cs": "Uzávěrka kuchyňského displeje jako dnes: záznam v uzávěrkách administrace s tržbou podle platby a s tím, co\nještě zaplacené není, přiřadí se do ní všechny objednávky, které opustily frontu (hotové, vydané, zrušené),\na číslování kuchyně začne znovu od 1. S `courier_id` se uzavřou jen objednávky toho kurýra (kurýři se během dne\nstřídají) a číslování běží dál; `courier_id` musí být kurýr provozovny. Uzavřené objednávky z aplikací jsou\ndoručené. Potřebuje přihlášeného zaměstnance s rolí v kuchyni; vzít zpět ji nejde. Když od poslední uzávěrky\nfrontu žádná objednávka neopustila (jiný displej uzavřel o chvilku dřív), odpověď je `409 pos_shift_empty` –\nstejný kód jako u prázdné směny pokladny, navzdory názvu – a nic se nezmění: číslování se znovu nenuluje.\n",
    "security": [
     {
      "oauth2": [
       "kitchen:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/KitchenShiftCloseRequest"
       },
       "examples": {
        "all": {
         "summary": "Closing the whole kitchen",
         "value": {
          "courier_id": null
         },
         "x-summary-cs": "Uzávěrka celé kuchyně"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The shift close.",
      "x-description-cs": "Uzávěrka.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenShiftClose"
        },
        "examples": {
         "closed": {
          "summary": "The shift is closed",
          "value": {
           "id": "1187",
           "closed_at": "2027-01-15T22:15:40+01:00",
           "closed_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "closed_orders": 64,
           "numbering_reset": true,
           "summary": {
            "orders": 64,
            "completed": {
             "amount": 1954300,
             "currency": "CZK"
            },
            "by_payment": {
             "cash": {
              "amount": 802100,
              "currency": "CZK"
             },
             "card": {
              "amount": 1029500,
              "currency": "CZK"
             },
             "meal_voucher": {
              "amount": 0,
              "currency": "CZK"
             },
             "company_account": {
              "amount": 0,
              "currency": "CZK"
             },
             "invoice": {
              "amount": 122700,
              "currency": "CZK"
             }
            },
            "not_completed": {
             "amount": 0,
             "currency": "CZK"
            },
            "not_delivered": {
             "orders": 1,
             "total": {
              "amount": 38600,
              "currency": "CZK"
             }
            },
            "cancelled": {
             "amount": 18900,
             "currency": "CZK"
            },
            "courier_id": null,
            "couriers": [
             {
              "orders": 9,
              "completed": {
               "amount": 352800,
               "currency": "CZK"
              },
              "by_payment": {
               "cash": {
                "amount": 214300,
                "currency": "CZK"
               },
               "card": {
                "amount": 138500,
                "currency": "CZK"
               },
               "meal_voucher": {
                "amount": 0,
                "currency": "CZK"
               },
               "company_account": {
                "amount": 0,
                "currency": "CZK"
               },
               "invoice": {
                "amount": 0,
                "currency": "CZK"
               }
              },
              "not_completed": {
               "amount": 0,
               "currency": "CZK"
              },
              "not_delivered": {
               "orders": 1,
               "total": {
                "amount": 38600,
                "currency": "CZK"
               }
              },
              "cancelled": {
               "amount": 0,
               "currency": "CZK"
              },
              "courier": {
               "id": "64",
               "name": "Tomáš Král"
              }
             }
            ]
           }
          },
          "x-summary-cs": "Směna uzavřená"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/couriers": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "listCouriers",
    "summary": "Couriers of the restaurant",
    "x-summary-cs": "Kurýři provozovny",
    "description": "Employees who can deliver – as on the kitchen display today, those with the kitchen role in this restaurant –\nwith their shift and the number of open routes, ordered by name.\n",
    "x-description-cs": "Zaměstnanci, kteří mohou rozvážet – stejně jako dnes na kuchyňském displeji ti s rolí kuchyně v této provozovně –\ns přihlášením na směnu a počtem otevřených tras, podle jména.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of couriers.",
      "x-description-cs": "Stránka kurýrů.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CourierPage"
        },
        "examples": {
         "list": {
          "summary": "Couriers",
          "value": {
           "data": [
            {
             "employee": {
              "id": "64",
              "name": "Tomáš Král"
             },
             "on_shift": true,
             "on_shift_since": "2027-01-15T10:30:00+01:00",
             "open_routes": 1
            },
            {
             "employee": {
              "id": "68",
              "name": "Martin Beneš"
             },
             "on_shift": false,
             "on_shift_since": null,
             "open_routes": 0
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Kurýři"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/couriers/{employee_id}/shift": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/EmployeeId"
    }
   ],
   "put": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "startCourierShift",
    "summary": "Check a courier in for the shift",
    "x-summary-cs": "Přihlásit kurýra na směnu",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "The courier is available for routes. Signed in on the device must be the courier or an employee with the\n`kitchen_manager` role (`403 staff_role_missing`). Checking in again keeps the original time. This is not an\nattendance punch.\n",
    "x-description-cs": "Kurýr je k dispozici pro trasy. Na zařízení musí být přihlášený ten kurýr, nebo zaměstnanec s rolí\n`kitchen_manager` (`403 staff_role_missing`). Opakované přihlášení nechá původní čas. Není to píchnutí do docházky.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The courier on shift.",
      "x-description-cs": "Kurýr na směně.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Courier"
        },
        "examples": {
         "on_shift": {
          "summary": "The courier is on shift",
          "value": {
           "employee": {
            "id": "64",
            "name": "Tomáš Král"
           },
           "on_shift": true,
           "on_shift_since": "2027-01-15T10:30:00+01:00",
           "open_routes": 0
          },
          "x-summary-cs": "Kurýr je na směně"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "delete": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "endCourierShift",
    "summary": "Check a courier out of the shift",
    "x-summary-cs": "Odhlásit kurýra ze směny",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "Same rules as checking in. Routes the courier is on stay as they are.",
    "x-description-cs": "Stejná pravidla jako přihlášení. Trasy, na kterých kurýr je, zůstanou beze změny.",
    "security": [
     {
      "oauth2": [
       "deliveries:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Checked out.",
      "x-description-cs": "Odhlášen."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/delivery-routes": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "listDeliveryRoutes",
    "summary": "Delivery routes",
    "x-summary-cs": "Rozvozové trasy",
    "x-staff": "optional",
    "description": "`status=open` (default) – routes still being delivered; `status=completed` – finished routes. Both list only\nroutes of the current shift, the same way as the register (API v1): routes with at least one order that is not\nin a closed kitchen shift yet. A kitchen shift close (of the whole shift or of the courier) takes in also done\norders that are still on a route, so after it such a route leaves `status=open` (and `Courier.open_routes`)\nalthough it is still being delivered; `getDeliveryRoute` keeps returning it. `courier_id` narrows them to one\ncourier. Newest first. Answers `304` to `If-None-Match` when nothing changed.\n\nA courier's phone (a device without `kitchen:read`) needs a signed-in employee (`403 staff_session_required`)\nand sees only that courier's own routes, with customer addresses and phones, unless the employee is a\n`kitchen_manager`. The kitchen display sees the routes of all couriers.\n",
    "x-description-cs": "`status=open` (výchozí) – trasy, které se ještě rozvážejí; `status=completed` – dokončené trasy. Oba výpisy\nobsahují jen trasy aktuální směny, stejně jako pokladna (API v1): trasy, které mají aspoň jednu objednávku, jež\nještě není v uzavřené směně kuchyně. Uzávěrka kuchyně (celé směny nebo kurýra) zahrne i hotové objednávky, které\njsou ještě na trase, takže taková trasa po ní ze `status=open` (i z `Courier.open_routes`) zmizí, přestože se\nještě rozváží; `getDeliveryRoute` ji vrací dál. `courier_id` je zúží na jednoho kurýra. Nejnovější první. Na\n`If-None-Match` odpoví `304`, když se nic nezměnilo.\n\nTelefon kurýra (zařízení bez `kitchen:read`) potřebuje přihlášeného zaměstnance (`403 staff_session_required`)\na vidí jen trasy toho kurýra s adresami a telefony zákazníků, pokud zaměstnanec není `kitchen_manager`.\nKuchyňský displej vidí trasy všech kurýrů.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "name": "status",
      "in": "query",
      "required": false,
      "description": "`open` (default) – routes still being delivered; `completed` – finished routes. Both only of the current shift.",
      "x-description-cs": "`open` (výchozí) – trasy, které se ještě rozvážejí; `completed` – dokončené trasy. Obojí jen z aktuální směny.",
      "schema": {
       "type": "string",
       "enum": [
        "open",
        "completed"
       ],
       "default": "open"
      },
      "example": "open"
     },
     {
      "name": "courier_id",
      "in": "query",
      "required": false,
      "description": "Only the routes of this courier. On a courier's phone whose signed-in employee is not a `kitchen_manager` it\nis always that employee – another `courier_id` is ignored. An ID that is not a courier gives an empty list.\n",
      "x-description-cs": "Jen trasy tohoto kurýra. Na telefonu kurýra, jehož přihlášený zaměstnanec není `kitchen_manager`, je to vždy\ntento zaměstnanec – jiné `courier_id` se nebere. ID, které kurýrovi nepatří, dá prázdný seznam.\n",
      "schema": {
       "$ref": "#/components/schemas/Id"
      }
     },
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of routes.",
      "x-description-cs": "Stránka tras.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeliveryRoutePage"
        },
        "examples": {
         "open": {
          "summary": "Open routes",
          "value": {
           "data": [
            {
             "id": "3307",
             "courier": {
              "id": "64",
              "name": "Tomáš Král"
             },
             "status": "open",
             "created_at": "2027-01-15T12:06:40+01:00",
             "completed_at": null,
             "tickets": [
              {
               "id": "77815",
               "order_id": "184226",
               "number": "030",
               "status": "out_for_delivery",
               "area": "kitchen",
               "source": "web",
               "platform": null,
               "name": "Jana Nováková",
               "fulfillment": "delivery",
               "express": false,
               "customer": {
                "name": "Jana Nováková",
                "phone": "+420777123456",
                "not_delivered_count": 0,
                "last_not_delivered_at": null
               },
               "delivery_address": {
                "street": "Jeseniova 1196/52",
                "city": "Praha 3",
                "location": {
                 "lat": 50.0833,
                 "lon": 14.4667
                }
               },
               "delivery_zone": {
                "id": "21",
                "name": "Vinohrady do 3 km"
               },
               "note": "3. patro, zvonek Nováková",
               "payment_method": "cash",
               "total": {
                "amount": 38600,
                "currency": "CZK"
               },
               "delivery_price": {
                "amount": 4900,
                "currency": "CZK"
               },
               "amount_due": {
                "amount": 38600,
                "currency": "CZK"
               },
               "paid_by": null,
               "created_at": "2027-01-15T11:50:40+01:00",
               "scheduled_for": null,
               "printed": true,
               "courier": {
                "id": "64",
                "name": "Tomáš Král"
               },
               "not_delivered": null,
               "items": [
                {
                 "id": "52031",
                 "product_id": "4571",
                 "name": "Pizza Margherita",
                 "kitchen_name": null,
                 "note": "Nekrájet",
                 "quantity": 1,
                 "kind": "full",
                 "charge": null,
                 "course": 0,
                 "category": {
                  "id": "315",
                  "name": "Pizza"
                 },
                 "from_daily_menu": false,
                 "station_id": "3",
                 "status": "done",
                 "handed_out": false,
                 "part": null,
                 "size": {
                  "name": "Ø32cm",
                  "dish_name": "Pizza Margherita"
                 },
                 "unit_price": {
                  "amount": 18900,
                  "currency": "CZK"
                 },
                 "packaging_price": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "discount": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "gift": false,
                 "vat_rate": "12",
                 "removed_ingredients": [],
                 "modifiers": [
                  {
                   "id": "52032",
                   "charge": null,
                   "product_id": "4602",
                   "name": "Extra sýr",
                   "kitchen_name": null,
                   "note": null,
                   "quantity": 1,
                   "kind": "full",
                   "status": "done",
                   "handed_out": false,
                   "part": null,
                   "size": null,
                   "unit_price": {
                    "amount": 3000,
                    "currency": "CZK"
                   },
                   "packaging_price": {
                    "amount": 0,
                    "currency": "CZK"
                   },
                   "discount": {
                    "amount": 0,
                    "currency": "CZK"
                   },
                   "gift": false,
                   "vat_rate": "12",
                   "removed_ingredients": []
                  }
                 ]
                },
                {
                 "id": "52033",
                 "product_id": "4593",
                 "name": "Domácí limonáda 0,4 l",
                 "kitchen_name": null,
                 "note": null,
                 "quantity": 2,
                 "kind": "full",
                 "charge": null,
                 "course": 0,
                 "category": {
                  "id": "320",
                  "name": "Nápoje"
                 },
                 "from_daily_menu": false,
                 "station_id": null,
                 "status": "done",
                 "handed_out": false,
                 "part": null,
                 "size": null,
                 "unit_price": {
                  "amount": 5900,
                  "currency": "CZK"
                 },
                 "packaging_price": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "discount": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "gift": false,
                 "vat_rate": "12",
                 "removed_ingredients": [],
                 "modifiers": []
                }
               ],
               "receipt": {
                "items": {
                 "amount": 33700,
                 "currency": "CZK"
                },
                "discounts": [],
                "delivery": {
                 "amount": 4900,
                 "currency": "CZK"
                },
                "rounding": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "adjustment": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 38600,
                 "currency": "CZK"
                },
                "to_pay": {
                 "amount": 38600,
                 "currency": "CZK"
                },
                "vat": [
                 {
                  "rate": "12",
                  "base": {
                   "amount": 34464,
                   "currency": "CZK"
                  },
                  "vat": {
                   "amount": 4136,
                   "currency": "CZK"
                  },
                  "total": {
                   "amount": 38600,
                   "currency": "CZK"
                  }
                 }
                ],
                "document": {
                 "title": "Účtenka",
                 "number": "184226",
                 "tax_document": "Zjednodušený daňový doklad"
                }
               }
              }
             ]
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Otevřené trasy"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "post": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "createDeliveryRoute",
    "summary": "Send orders out with a courier",
    "x-summary-cs": "Poslat objednávky s kurýrem",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "Puts delivery orders on one route of a courier in the given order, as the route planner of the kitchen\ndisplay does: the orders become done (`out_for_delivery`) and the courier takes them. Each order must be\na delivery of this restaurant, not cancelled, not delivered and not on another open route; otherwise\n`422 validation_failed` points at it. The \"order is ready\" SMS goes to customers whose order becomes done just\nnow (not twice, and not when the application that created the order writes to its customers itself).\nOn a courier's phone (a device without `kitchen:read`) an employee must be signed in (`403\nstaff_session_required`); a courier who is not a kitchen manager sends out only themselves (`403\nstaff_role_missing`) and only orders that are done and not given to another courier (`422` with `not_ready`\nor `other_courier`). An order that was `not_delivered` goes out again this way; its report stays in the\nhistory of the order.\n",
    "x-description-cs": "Dá rozvozové objednávky na jednu trasu kurýra v zadaném pořadí, jako plánovač tras na kuchyňském displeji:\nobjednávky se stanou hotovými (`out_for_delivery`) a kurýr je převezme. Každá objednávka musí být rozvozem\ntéto provozovny, nezrušená, nedoručená a ne na jiné otevřené trase; jinak na ni ukáže `422 validation_failed`.\nSMS „objednávka je hotová“ dostanou zákazníci, jejichž objednávka se hotovou stala právě teď (ne podruhé\na ne když zákazníkům píše sama aplikace, která objednávku vytvořila). Na telefonu kurýra (zařízení bez\n`kitchen:read`) musí být přihlášený zaměstnanec (`403 staff_session_required`); kurýr, který není vedoucí\nkuchyně, pošle jen sám sebe (`403 staff_role_missing`) a jen objednávky hotové a nepřidělené jinému kurýrovi\n(`422` s `not_ready` nebo `other_courier`). Takhle se znovu posílá i objednávka, která byla `not_delivered`;\njejí hlášení zůstane v historii objednávky.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeliveryRouteCreate"
       },
       "examples": {
        "route": {
         "summary": "A route for a courier",
         "value": {
          "courier_id": "64",
          "ticket_ids": [
           "77815"
          ]
         },
         "x-summary-cs": "Trasa pro kurýra"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The route.",
      "x-description-cs": "Trasa.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeliveryRoute"
        },
        "examples": {
         "created": {
          "summary": "A new route",
          "value": {
           "id": "3307",
           "courier": {
            "id": "64",
            "name": "Tomáš Král"
           },
           "status": "open",
           "created_at": "2027-01-15T12:06:40+01:00",
           "completed_at": null,
           "tickets": [
            {
             "id": "77815",
             "order_id": "184226",
             "number": "030",
             "status": "out_for_delivery",
             "area": "kitchen",
             "source": "web",
             "platform": null,
             "name": "Jana Nováková",
             "fulfillment": "delivery",
             "express": false,
             "customer": {
              "name": "Jana Nováková",
              "phone": "+420777123456",
              "not_delivered_count": 0,
              "last_not_delivered_at": null
             },
             "delivery_address": {
              "street": "Jeseniova 1196/52",
              "city": "Praha 3",
              "location": {
               "lat": 50.0833,
               "lon": 14.4667
              }
             },
             "delivery_zone": {
              "id": "21",
              "name": "Vinohrady do 3 km"
             },
             "note": "3. patro, zvonek Nováková",
             "payment_method": "cash",
             "total": {
              "amount": 38600,
              "currency": "CZK"
             },
             "delivery_price": {
              "amount": 4900,
              "currency": "CZK"
             },
             "amount_due": {
              "amount": 38600,
              "currency": "CZK"
             },
             "paid_by": null,
             "created_at": "2027-01-15T11:50:40+01:00",
             "scheduled_for": null,
             "printed": true,
             "courier": {
              "id": "64",
              "name": "Tomáš Král"
             },
             "not_delivered": null,
             "items": [
              {
               "id": "52031",
               "product_id": "4571",
               "name": "Pizza Margherita",
               "kitchen_name": null,
               "note": "Nekrájet",
               "quantity": 1,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "315",
                "name": "Pizza"
               },
               "from_daily_menu": false,
               "station_id": "3",
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": {
                "name": "Ø32cm",
                "dish_name": "Pizza Margherita"
               },
               "unit_price": {
                "amount": 18900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": [
                {
                 "id": "52032",
                 "charge": null,
                 "product_id": "4602",
                 "name": "Extra sýr",
                 "kitchen_name": null,
                 "note": null,
                 "quantity": 1,
                 "kind": "full",
                 "status": "done",
                 "handed_out": false,
                 "part": null,
                 "size": null,
                 "unit_price": {
                  "amount": 3000,
                  "currency": "CZK"
                 },
                 "packaging_price": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "discount": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "gift": false,
                 "vat_rate": "12",
                 "removed_ingredients": []
                }
               ]
              },
              {
               "id": "52033",
               "product_id": "4593",
               "name": "Domácí limonáda 0,4 l",
               "kitchen_name": null,
               "note": null,
               "quantity": 2,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "320",
                "name": "Nápoje"
               },
               "from_daily_menu": false,
               "station_id": null,
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": null,
               "unit_price": {
                "amount": 5900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": []
              }
             ],
             "receipt": {
              "items": {
               "amount": 33700,
               "currency": "CZK"
              },
              "discounts": [],
              "delivery": {
               "amount": 4900,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "adjustment": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 38600,
               "currency": "CZK"
              },
              "to_pay": {
               "amount": 38600,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "12",
                "base": {
                 "amount": 34464,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 4136,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 38600,
                 "currency": "CZK"
                }
               }
              ],
              "document": {
               "title": "Účtenka",
               "number": "184226",
               "tax_document": "Zjednodušený daňový doklad"
              }
             }
            }
           ]
          },
          "x-summary-cs": "Nová trasa"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/delivery-routes/{route_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/RouteId"
    }
   ],
   "get": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "getDeliveryRoute",
    "summary": "One delivery route",
    "x-summary-cs": "Jedna rozvozová trasa",
    "x-staff": "optional",
    "description": "A courier's phone (a device without `kitchen:read`) needs a signed-in employee and gets `404` for a route of\nanother courier, unless the employee is a `kitchen_manager`.\n",
    "x-description-cs": "Telefon kurýra (zařízení bez `kitchen:read`) potřebuje přihlášeného zaměstnance a na trasu jiného kurýra dostane\n`404`, pokud zaměstnanec není `kitchen_manager`.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The route.",
      "x-description-cs": "Trasa.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeliveryRoute"
        },
        "examples": {
         "route": {
          "summary": "A route",
          "value": {
           "id": "3307",
           "courier": {
            "id": "64",
            "name": "Tomáš Král"
           },
           "status": "open",
           "created_at": "2027-01-15T12:06:40+01:00",
           "completed_at": null,
           "tickets": [
            {
             "id": "77815",
             "order_id": "184226",
             "number": "030",
             "status": "out_for_delivery",
             "area": "kitchen",
             "source": "web",
             "platform": null,
             "name": "Jana Nováková",
             "fulfillment": "delivery",
             "express": false,
             "customer": {
              "name": "Jana Nováková",
              "phone": "+420777123456",
              "not_delivered_count": 0,
              "last_not_delivered_at": null
             },
             "delivery_address": {
              "street": "Jeseniova 1196/52",
              "city": "Praha 3",
              "location": {
               "lat": 50.0833,
               "lon": 14.4667
              }
             },
             "delivery_zone": {
              "id": "21",
              "name": "Vinohrady do 3 km"
             },
             "note": "3. patro, zvonek Nováková",
             "payment_method": "cash",
             "total": {
              "amount": 38600,
              "currency": "CZK"
             },
             "delivery_price": {
              "amount": 4900,
              "currency": "CZK"
             },
             "amount_due": {
              "amount": 38600,
              "currency": "CZK"
             },
             "paid_by": null,
             "created_at": "2027-01-15T11:50:40+01:00",
             "scheduled_for": null,
             "printed": true,
             "courier": {
              "id": "64",
              "name": "Tomáš Král"
             },
             "not_delivered": null,
             "items": [
              {
               "id": "52031",
               "product_id": "4571",
               "name": "Pizza Margherita",
               "kitchen_name": null,
               "note": "Nekrájet",
               "quantity": 1,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "315",
                "name": "Pizza"
               },
               "from_daily_menu": false,
               "station_id": "3",
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": {
                "name": "Ø32cm",
                "dish_name": "Pizza Margherita"
               },
               "unit_price": {
                "amount": 18900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": [
                {
                 "id": "52032",
                 "charge": null,
                 "product_id": "4602",
                 "name": "Extra sýr",
                 "kitchen_name": null,
                 "note": null,
                 "quantity": 1,
                 "kind": "full",
                 "status": "done",
                 "handed_out": false,
                 "part": null,
                 "size": null,
                 "unit_price": {
                  "amount": 3000,
                  "currency": "CZK"
                 },
                 "packaging_price": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "discount": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "gift": false,
                 "vat_rate": "12",
                 "removed_ingredients": []
                }
               ]
              },
              {
               "id": "52033",
               "product_id": "4593",
               "name": "Domácí limonáda 0,4 l",
               "kitchen_name": null,
               "note": null,
               "quantity": 2,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "320",
                "name": "Nápoje"
               },
               "from_daily_menu": false,
               "station_id": null,
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": null,
               "unit_price": {
                "amount": 5900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": []
              }
             ],
             "receipt": {
              "items": {
               "amount": 33700,
               "currency": "CZK"
              },
              "discounts": [],
              "delivery": {
               "amount": 4900,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "adjustment": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 38600,
               "currency": "CZK"
              },
              "to_pay": {
               "amount": 38600,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "12",
                "base": {
                 "amount": 34464,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 4136,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 38600,
                 "currency": "CZK"
                }
               }
              ],
              "document": {
               "title": "Účtenka",
               "number": "184226",
               "tax_document": "Zjednodušený daňový doklad"
              }
             }
            }
           ]
          },
          "x-summary-cs": "Trasa"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/delivery-routes/{route_id}/tickets/{ticket_id}/delivered": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/RouteId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "post": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "markTicketDelivered",
    "summary": "Mark an order of the route delivered",
    "x-summary-cs": "Označit objednávku trasy jako doručenou",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "The courier delivered the order. When every order of the route is delivered, cancelled or not delivered, the\nroute is completed (also when the kitchen display marks, cancels or takes back the last order). Marking it\nagain does no harm. An order that is `not_delivered` can be marked delivered too, until it is cancelled – the\ncustomer picked it up later, or the courier tapped by mistake. With an employee signed in who is not a\n`kitchen_manager`, only orders on that employee's own routes can be marked (`403 staff_role_missing`); a\ncourier's phone (a device without `kitchen:read`) needs a signed-in employee (`403 staff_session_required`).\nApplications that created the order get `order.status_changed` with `delivered`.\n",
    "x-description-cs": "Kurýr objednávku doručil. Když jsou doručené, zrušené nebo nepřevzaté všechny objednávky trasy, trasa se\ndokončí (i když poslední objednávku označí, stornuje nebo vrátí do fronty kuchyňský displej). Opakované\noznačení nevadí. Jako doručenou jde označit i objednávku `not_delivered`, dokud není zrušená – zákazník si ji\nvyzvedl později, nebo kurýr ťukl omylem. Když je přihlášený zaměstnanec bez role `kitchen_manager`, smí označit\njen objednávky na svých trasách (`403 staff_role_missing`); telefon kurýra (zařízení bez `kitchen:read`)\npotřebuje přihlášeného zaměstnance (`403 staff_session_required`). Aplikace, která objednávku vytvořila,\ndostane `order.status_changed` s `delivered`.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The route after the change.",
      "x-description-cs": "Trasa po změně.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeliveryRoute"
        },
        "examples": {
         "delivered": {
          "summary": "Delivered, the route is done",
          "value": {
           "id": "3307",
           "courier": {
            "id": "64",
            "name": "Tomáš Král"
           },
           "status": "completed",
           "created_at": "2027-01-15T12:06:40+01:00",
           "completed_at": "2027-01-15T12:31:10+01:00",
           "tickets": [
            {
             "id": "77815",
             "order_id": "184226",
             "number": "030",
             "status": "delivered",
             "area": "kitchen",
             "source": "web",
             "platform": null,
             "name": "Jana Nováková",
             "fulfillment": "delivery",
             "express": false,
             "customer": {
              "name": "Jana Nováková",
              "phone": "+420777123456",
              "not_delivered_count": 0,
              "last_not_delivered_at": null
             },
             "delivery_address": {
              "street": "Jeseniova 1196/52",
              "city": "Praha 3",
              "location": {
               "lat": 50.0833,
               "lon": 14.4667
              }
             },
             "delivery_zone": {
              "id": "21",
              "name": "Vinohrady do 3 km"
             },
             "note": "3. patro, zvonek Nováková",
             "payment_method": "cash",
             "total": {
              "amount": 38600,
              "currency": "CZK"
             },
             "delivery_price": {
              "amount": 4900,
              "currency": "CZK"
             },
             "amount_due": {
              "amount": 38600,
              "currency": "CZK"
             },
             "paid_by": null,
             "created_at": "2027-01-15T11:50:40+01:00",
             "scheduled_for": null,
             "printed": true,
             "courier": {
              "id": "64",
              "name": "Tomáš Král"
             },
             "not_delivered": null,
             "items": [
              {
               "id": "52031",
               "product_id": "4571",
               "name": "Pizza Margherita",
               "kitchen_name": null,
               "note": "Nekrájet",
               "quantity": 1,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "315",
                "name": "Pizza"
               },
               "from_daily_menu": false,
               "station_id": "3",
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": {
                "name": "Ø32cm",
                "dish_name": "Pizza Margherita"
               },
               "unit_price": {
                "amount": 18900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": [
                {
                 "id": "52032",
                 "charge": null,
                 "product_id": "4602",
                 "name": "Extra sýr",
                 "kitchen_name": null,
                 "note": null,
                 "quantity": 1,
                 "kind": "full",
                 "status": "done",
                 "handed_out": false,
                 "part": null,
                 "size": null,
                 "unit_price": {
                  "amount": 3000,
                  "currency": "CZK"
                 },
                 "packaging_price": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "discount": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "gift": false,
                 "vat_rate": "12",
                 "removed_ingredients": []
                }
               ]
              },
              {
               "id": "52033",
               "product_id": "4593",
               "name": "Domácí limonáda 0,4 l",
               "kitchen_name": null,
               "note": null,
               "quantity": 2,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "320",
                "name": "Nápoje"
               },
               "from_daily_menu": false,
               "station_id": null,
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": null,
               "unit_price": {
                "amount": 5900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": []
              }
             ],
             "receipt": {
              "items": {
               "amount": 33700,
               "currency": "CZK"
              },
              "discounts": [],
              "delivery": {
               "amount": 4900,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "adjustment": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 38600,
               "currency": "CZK"
              },
              "to_pay": {
               "amount": 38600,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "12",
                "base": {
                 "amount": 34464,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 4136,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 38600,
                 "currency": "CZK"
                }
               }
              ],
              "document": {
               "title": "Účtenka",
               "number": "184226",
               "tax_document": "Zjednodušený daňový doklad"
              }
             }
            }
           ]
          },
          "x-summary-cs": "Doručeno, trasa hotová"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/delivery-routes/{route_id}/tickets/{ticket_id}/handover-payment": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/RouteId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "post": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "handoverTicketPayment",
    "summary": "Record the payment the courier took at the door",
    "x-summary-cs": "Zapsat platbu, kterou kurýr vybral u dveří",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "The courier took the payment for an order of the route – by card on the payment terminal (`method` `card`,\nwith `gateway_payment_id` of the terminal) or in cash. It works both ways: a cash order paid by card becomes\n`card_at_handover`, a `card_at_handover` order paid in cash becomes `cash`, and the shift close (`getKitchenShift`)\nmoves the takings between cash and card accordingly. The order then has `amount_due` 0 and `paid_by`.\n\nOnly for orders with `payment_method` `cash` or `card_at_handover` that have something to collect: paid in\nadvance (by card or online, at the register), meal vouchers, the company account and an invoice answer\n`409 payment_method_not_changeable`; an order already paid at the door `409 already_paid` with `paid_by` in\nthe problem; a cancelled order `409 ticket_cancelled`. `amount` must equal `amount_due` + `tip` – for an\norder without a part paid online that is `total` + `tip` (`422 amount_mismatch`). Send the time of the payment\nin `paid_at` – the phone may send it later from its queue; more than 5 minutes ahead of the server is refused.\nThe same payment sent again (the same `gateway_payment_id`, in cash the same `paid_at`) returns the ticket\nwithout writing anything, also after the 24 hours of `Idempotency-Key`; one terminal transaction cannot pay\ntwo orders (`422 validation_failed` with `duplicate`). The tip is recorded with the order. Same permissions as\n`markTicketDelivered`. Recording the payment does not deliver the order – mark it delivered as well.\n",
    "x-description-cs": "Kurýr vybral platbu za objednávku trasy – kartou na platebním terminálu (`method` `card`, s `gateway_payment_id`\nterminálu) nebo hotově. Funguje oběma směry: hotovostní objednávka zaplacená kartou se stane\n`card_at_handover`, objednávka `card_at_handover` zaplacená hotově se stane `cash` a uzávěrka (`getKitchenShift`)\npodle toho přesune tržbu mezi hotovostí a kartou. Objednávka pak má `amount_due` 0 a `paid_by`.\n\nJen u objednávek s `payment_method` `cash` nebo `card_at_handover`, u kterých je co vybrat: zaplacené předem\n(kartou nebo online, u pokladny), stravenky, účet podniku a faktura vrátí `409 payment_method_not_changeable`;\nobjednávka už zaplacená u dveří `409 already_paid` s `paid_by` v chybě; zrušená `409 ticket_cancelled`.\n`amount` se musí rovnat `amount_due` + `tip` – u objednávky bez části zaplacené online je to `total` + `tip`\n(`422 amount_mismatch`). Čas platby pošlete v `paid_at` – telefon ji může poslat později ze své fronty; víc než\n5 minut napřed proti serveru se odmítne. Stejná platba poslaná znovu (stejné `gateway_payment_id`, u hotovosti\nstejné `paid_at`) vrátí bon a nic nezapíše, i po 24 hodinách platnosti `Idempotency-Key`; jedna transakce\nterminálu nezaplatí dvě objednávky (`422 validation_failed` s `duplicate`). Spropitné se zapíše k objednávce.\nStejná oprávnění jako `markTicketDelivered`. Zápis platby objednávku nedoručí – označte ji i jako doručenou.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/HandoverPayment"
       },
       "examples": {
        "card": {
         "summary": "By card on the terminal with a tip",
         "value": {
          "method": "card",
          "amount": {
           "amount": 40600,
           "currency": "CZK"
          },
          "tip": {
           "amount": 2000,
           "currency": "CZK"
          },
          "gateway_payment_id": "teya-7f3a9c41",
          "card_brand": "visa",
          "card_last4": "4242",
          "paid_at": "2027-01-15T12:24:11+01:00"
         },
         "x-summary-cs": "Kartou na terminálu se spropitným"
        },
        "cash": {
         "summary": "The card failed, paid in cash",
         "value": {
          "method": "cash",
          "amount": {
           "amount": 38600,
           "currency": "CZK"
          },
          "tip": null,
          "paid_at": "2027-01-15T12:25:40+01:00"
         },
         "x-summary-cs": "Karta neprošla, zaplaceno hotově"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The ticket after the payment.",
      "x-description-cs": "Bon po zaplacení.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KitchenTicket"
        },
        "examples": {
         "paid": {
          "summary": "Paid by card at the door",
          "value": {
           "id": "77815",
           "order_id": "184226",
           "number": "030",
           "status": "out_for_delivery",
           "area": "kitchen",
           "source": "web",
           "platform": null,
           "name": "Jana Nováková",
           "fulfillment": "delivery",
           "express": false,
           "customer": {
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "not_delivered_count": 0,
            "last_not_delivered_at": null
           },
           "delivery_address": {
            "street": "Jeseniova 1196/52",
            "city": "Praha 3",
            "location": {
             "lat": 50.0833,
             "lon": 14.4667
            }
           },
           "delivery_zone": {
            "id": "21",
            "name": "Vinohrady do 3 km"
           },
           "note": "3. patro, zvonek Nováková",
           "payment_method": "card_at_handover",
           "total": {
            "amount": 38600,
            "currency": "CZK"
           },
           "delivery_price": {
            "amount": 4900,
            "currency": "CZK"
           },
           "amount_due": {
            "amount": 0,
            "currency": "CZK"
           },
           "paid_by": {
            "method": "card",
            "amount": {
             "amount": 40600,
             "currency": "CZK"
            },
            "tip": {
             "amount": 2000,
             "currency": "CZK"
            },
            "card_brand": "visa",
            "card_last4": "4242",
            "gateway_payment_id": "teya-7f3a9c41",
            "paid_at": "2027-01-15T12:24:11+01:00"
           },
           "created_at": "2027-01-15T11:50:40+01:00",
           "scheduled_for": null,
           "printed": true,
           "courier": {
            "id": "64",
            "name": "Tomáš Král"
           },
           "not_delivered": null,
           "items": [
            {
             "id": "52031",
             "product_id": "4571",
             "name": "Pizza Margherita",
             "kitchen_name": null,
             "note": "Nekrájet",
             "quantity": 1,
             "kind": "full",
             "charge": null,
             "course": 0,
             "category": {
              "id": "315",
              "name": "Pizza"
             },
             "from_daily_menu": false,
             "station_id": "3",
             "status": "done",
             "handed_out": false,
             "part": null,
             "size": {
              "name": "Ø32cm",
              "dish_name": "Pizza Margherita"
             },
             "unit_price": {
              "amount": 18900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [],
             "modifiers": [
              {
               "id": "52032",
               "charge": null,
               "product_id": "4602",
               "name": "Extra sýr",
               "kitchen_name": null,
               "note": null,
               "quantity": 1,
               "kind": "full",
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": null,
               "unit_price": {
                "amount": 3000,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": []
              }
             ]
            },
            {
             "id": "52033",
             "product_id": "4593",
             "name": "Domácí limonáda 0,4 l",
             "kitchen_name": null,
             "note": null,
             "quantity": 2,
             "kind": "full",
             "charge": null,
             "course": 0,
             "category": {
              "id": "320",
              "name": "Nápoje"
             },
             "from_daily_menu": false,
             "station_id": null,
             "status": "done",
             "handed_out": false,
             "part": null,
             "size": null,
             "unit_price": {
              "amount": 5900,
              "currency": "CZK"
             },
             "packaging_price": {
              "amount": 0,
              "currency": "CZK"
             },
             "discount": {
              "amount": 0,
              "currency": "CZK"
             },
             "gift": false,
             "vat_rate": "12",
             "removed_ingredients": [],
             "modifiers": []
            }
           ],
           "receipt": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "discounts": [],
            "delivery": {
             "amount": 4900,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "adjustment": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 38600,
             "currency": "CZK"
            },
            "to_pay": {
             "amount": 38600,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 34464,
               "currency": "CZK"
              },
              "vat": {
               "amount": 4136,
               "currency": "CZK"
              },
              "total": {
               "amount": 38600,
               "currency": "CZK"
              }
             }
            ],
            "document": {
             "title": "Účtenka",
             "number": "184226",
             "tax_document": "Zjednodušený daňový doklad"
            }
           }
          },
          "x-summary-cs": "Zaplaceno kartou u dveří"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "already_paid": {
          "summary": "Already paid",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#already_paid",
           "title": "Objednávka je už zaplacená",
           "status": 409,
           "code": "already_paid",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": {
            "method": "card",
            "amount": {
             "amount": 40600,
             "currency": "CZK"
            },
            "tip": {
             "amount": 2000,
             "currency": "CZK"
            },
            "card_brand": "visa",
            "card_last4": "4242",
            "gateway_payment_id": "teya-7f3a9c41",
            "paid_at": "2027-01-15T12:24:11+01:00"
           }
          },
          "x-summary-cs": "Už zaplaceno"
         },
         "payment_method_not_changeable": {
          "summary": "Paid in advance",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#payment_method_not_changeable",
           "title": "U této objednávky se u dveří nic nevybírá",
           "status": 409,
           "code": "payment_method_not_changeable",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Zaplaceno předem"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "amount_mismatch": {
          "summary": "The amount does not match",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#amount_mismatch",
           "title": "Částka nesedí s objednávkou",
           "status": 422,
           "code": "amount_mismatch",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Částka nesedí"
         }
        }
       }
      }
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/delivery-routes/{route_id}/tickets/{ticket_id}/not-delivered": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/RouteId"
    },
    {
     "$ref": "#/components/parameters/TicketId"
    }
   ],
   "post": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "markTicketNotDelivered",
    "summary": "Mark an order of the route not delivered, with the reason",
    "x-summary-cs": "Označit objednávku trasy jako nepřevzatou, s důvodem",
    "x-requires-device": true,
    "x-staff": "optional",
    "description": "The courier could not hand the order over – the customer was not there, refused it, did not pay, the address\ndoes not exist… The ticket becomes `not_delivered` with `not_delivered` (the reason, the note, the time, the\ncourier, the location and the calls as evidence of the attempt), no payment and no takings are recorded and\nno cash is expected from the courier for it (`getKitchenShift` shows it in `not_delivered`). The route is\ncompleted when every order is delivered, cancelled or not delivered. Applications that created the order get\n`order.status_changed` with `not_delivered`.\n\nThe restaurant then decides: writes it off (`cancelKitchenTicket` with `write_off` – no stock goes back, the\nfood is lost), sends it out again (`createDeliveryRoute`) or marks it delivered (`markTicketDelivered` – the\ncustomer picked it up, or the courier tapped by mistake). Until then it stays in the shift and the next shift.\n\n`reason` `other` needs `note` (`422 note_required`). A delivered order answers `409 ticket_already_delivered`,\na cancelled one `409 ticket_cancelled`, an order already paid at the door (`handoverTicketPayment`)\n`409 already_paid` – a paid order is settled by the restaurant. Orders paid in advance can be marked; the server\nreturns no money by itself. Marking the same order on the same route again keeps the first report. Same\npermissions as `markTicketDelivered`.\n",
    "x-description-cs": "Kurýr objednávku nemohl předat – zákazník nebyl doma, odmítl ji, nezaplatil, adresa neexistuje… Bon se stane\n`not_delivered` s `not_delivered` (důvod, poznámka, čas, kurýr, poloha a hovory jako doklad o pokusu),\nnezapíše se platba ani tržba a hotovost se za ni od kurýra nečeká (`getKitchenShift` ji ukazuje\nv `not_delivered`). Trasa se dokončí, když jsou všechny objednávky doručené, zrušené nebo nepřevzaté. Aplikace,\nkteré objednávku vytvořily, dostanou `order.status_changed` s `not_delivered`.\n\nProvozovna pak rozhodne: odepíše ji (`cancelKitchenTicket` s `write_off` – na sklad se nic nevrací, jídlo je\nztracené), pošle ji znovu (`createDeliveryRoute`), nebo ji označí jako doručenou (`markTicketDelivered` –\nzákazník si ji vyzvedl, nebo kurýr ťukl omylem). Do té doby zůstává ve směně i v té další.\n\n`reason` `other` potřebuje `note` (`422 note_required`). Doručená objednávka vrátí\n`409 ticket_already_delivered`, zrušená `409 ticket_cancelled`, objednávka už zaplacená u dveří\n(`handoverTicketPayment`) `409 already_paid` – zaplacenou objednávku řeší provozovna. Objednávky zaplacené\npředem označit jde; server sám žádné peníze nevrací. Opakované označení téže objednávky na téže trase nechá\nprvní hlášení. Stejná oprávnění jako `markTicketDelivered`.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/NotDeliveredReport"
       },
       "examples": {
        "absent": {
         "summary": "The customer could not be reached",
         "value": {
          "reason": "customer_absent",
          "note": "Zvonil jsem 2×, čekal 10 min, telefon nebere.",
          "attempted_at": "2027-01-15T12:27:02+01:00",
          "location": {
           "lat": 50.0834,
           "lon": 14.4668,
           "accuracy_m": 12
          },
          "call_attempts": 2
         },
         "x-summary-cs": "Zákazník nebyl k zastižení"
        },
        "other": {
         "summary": "Another reason with a note",
         "value": {
          "reason": "other",
          "note": "Vjezd do areálu je zavřený, ostraha nepustí.",
          "attempted_at": "2027-01-15T12:27:02+01:00"
         },
         "x-summary-cs": "Jiný důvod s poznámkou"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The route after the change.",
      "x-description-cs": "Trasa po změně.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeliveryRoute"
        },
        "examples": {
         "not_delivered": {
          "summary": "Not taken over, the route is done",
          "value": {
           "id": "3307",
           "courier": {
            "id": "64",
            "name": "Tomáš Král"
           },
           "status": "completed",
           "created_at": "2027-01-15T12:06:40+01:00",
           "completed_at": "2027-01-15T12:27:05+01:00",
           "tickets": [
            {
             "id": "77815",
             "order_id": "184226",
             "number": "030",
             "status": "not_delivered",
             "area": "kitchen",
             "source": "web",
             "platform": null,
             "name": "Jana Nováková",
             "fulfillment": "delivery",
             "express": false,
             "customer": {
              "name": "Jana Nováková",
              "phone": "+420777123456",
              "not_delivered_count": 1,
              "last_not_delivered_at": "2027-01-15T12:27:02+01:00"
             },
             "delivery_address": {
              "street": "Jeseniova 1196/52",
              "city": "Praha 3",
              "location": {
               "lat": 50.0833,
               "lon": 14.4667
              }
             },
             "delivery_zone": {
              "id": "21",
              "name": "Vinohrady do 3 km"
             },
             "note": "3. patro, zvonek Nováková",
             "payment_method": "cash",
             "total": {
              "amount": 38600,
              "currency": "CZK"
             },
             "delivery_price": {
              "amount": 4900,
              "currency": "CZK"
             },
             "amount_due": {
              "amount": 38600,
              "currency": "CZK"
             },
             "paid_by": null,
             "created_at": "2027-01-15T11:50:40+01:00",
             "scheduled_for": null,
             "printed": true,
             "courier": {
              "id": "64",
              "name": "Tomáš Král"
             },
             "not_delivered": {
              "reason": "customer_absent",
              "note": "Zvonil jsem 2×, čekal 10 min, telefon nebere.",
              "attempted_at": "2027-01-15T12:27:02+01:00",
              "employee": {
               "id": "64",
               "name": "Tomáš Král"
              },
              "location": {
               "lat": 50.0834,
               "lon": 14.4668,
               "accuracy_m": 12
              },
              "call_attempts": 2
             },
             "items": [
              {
               "id": "52031",
               "product_id": "4571",
               "name": "Pizza Margherita",
               "kitchen_name": null,
               "note": "Nekrájet",
               "quantity": 1,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "315",
                "name": "Pizza"
               },
               "from_daily_menu": false,
               "station_id": "3",
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": {
                "name": "Ø32cm",
                "dish_name": "Pizza Margherita"
               },
               "unit_price": {
                "amount": 18900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": [
                {
                 "id": "52032",
                 "charge": null,
                 "product_id": "4602",
                 "name": "Extra sýr",
                 "kitchen_name": null,
                 "note": null,
                 "quantity": 1,
                 "kind": "full",
                 "status": "done",
                 "handed_out": false,
                 "part": null,
                 "size": null,
                 "unit_price": {
                  "amount": 3000,
                  "currency": "CZK"
                 },
                 "packaging_price": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "discount": {
                  "amount": 0,
                  "currency": "CZK"
                 },
                 "gift": false,
                 "vat_rate": "12",
                 "removed_ingredients": []
                }
               ]
              },
              {
               "id": "52033",
               "product_id": "4593",
               "name": "Domácí limonáda 0,4 l",
               "kitchen_name": null,
               "note": null,
               "quantity": 2,
               "kind": "full",
               "charge": null,
               "course": 0,
               "category": {
                "id": "320",
                "name": "Nápoje"
               },
               "from_daily_menu": false,
               "station_id": null,
               "status": "done",
               "handed_out": false,
               "part": null,
               "size": null,
               "unit_price": {
                "amount": 5900,
                "currency": "CZK"
               },
               "packaging_price": {
                "amount": 0,
                "currency": "CZK"
               },
               "discount": {
                "amount": 0,
                "currency": "CZK"
               },
               "gift": false,
               "vat_rate": "12",
               "removed_ingredients": [],
               "modifiers": []
              }
             ],
             "receipt": {
              "items": {
               "amount": 33700,
               "currency": "CZK"
              },
              "discounts": [],
              "delivery": {
               "amount": 4900,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "adjustment": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 38600,
               "currency": "CZK"
              },
              "to_pay": {
               "amount": 38600,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "12",
                "base": {
                 "amount": 34464,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 4136,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 38600,
                 "currency": "CZK"
                }
               }
              ],
              "document": {
               "title": "Účtenka",
               "number": "184226",
               "tax_document": "Zjednodušený daňový doklad"
              }
             }
            }
           ]
          },
          "x-summary-cs": "Nepřevzato, trasa hotová"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "ticket_already_delivered": {
          "summary": "Already delivered",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#ticket_already_delivered",
           "title": "Objednávka je už doručená",
           "status": 409,
           "code": "ticket_already_delivered",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Už doručeno"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "note_required": {
          "summary": "The note is missing",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#note_required",
           "title": "K tomuto důvodu chybí poznámka",
           "status": 422,
           "code": "note_required",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chybí poznámka"
         }
        }
       }
      }
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/couriers/{employee_id}/telemetry": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/EmployeeId"
    }
   ],
   "post": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "postCourierTelemetry",
    "summary": "Send the courier's location and driving during the shift",
    "x-summary-cs": "Poslat polohu a jízdu kurýra během směny",
    "x-requires-device": true,
    "x-staff": "required",
    "x-idempotency": "body-id",
    "description": "The courier's phone sends what it measured since the last batch: points of the route (`samples` – location,\nspeed, heading, altitude and the peak acceleration), the harsh manoeuvres it recognised (`driving_events` –\nharsh braking, harsh acceleration and sharp turns, in g) and the state of the phone (`device` – battery,\nnetwork, location permission). The restaurant then sees its couriers live (`listCourierPositions`,\n`courier.position` events) and the driven track of every route with its summary (`getDeliveryRouteTrack`).\n\nSigned in on the phone must be the courier themself (`403 staff_role_missing`). Points are recorded only during\nthe courier's shift (`startCourierShift` to `endCourierShift`) and only when the restaurant turned courier\ntracking on in the administration, where it confirms it informed its employees. Otherwise the answer is `200`\nwith `mode` `off` and everything in `discarded` – stop measuring.\n\nThe answer says how to go on. `mode` `route` (the courier has an open route): send a batch every\n`send_every_s` (15 s) with a point every `sample_every_s` (5 s, or after 25 m). `shift` (on shift without\na route): a batch every 60 s. `off`: stop measuring – `off_reason` is `tracking_disabled`, `off_shift`, or\n`idle` (on shift without a route for over 3 hours, most likely a forgotten check-out); start again when the\ncourier gets a route or checks in again. A batch without points is fine for asking about the mode.\n`thresholds` are the limits of harsh manoeuvres in g the phone should use, `server_time` lets it correct its\nclock.\n\nWithout a signal keep the batches on the phone and send them later, oldest first. A batch sent again records\nnothing twice – points are told apart by the courier and `recorded_at` (`duplicates`), so no\n`Idempotency-Key` is needed. Points older than 24 hours, from before the shift began or more than 2 minutes\nahead of the server are dropped (`discarded`). Send `route_id` of the route the courier is driving until they\nare back in the restaurant – the ride back belongs to the route; without it the server uses the open route.\nPoints with an accuracy worse than 50 m are kept but count neither to the distance nor to the top speed.\nPoints and manoeuvres are kept for 14 days, then only the summary of the route stays. At most 300 points and\n50 manoeuvres in a batch. Not recorded in the audit log.\n",
    "x-description-cs": "Telefon kurýra posílá, co naměřil od minulé dávky: body trasy (`samples` – poloha, rychlost, směr, výška\na špička přetížení), prudké manévry, které poznal (`driving_events` – prudké brzdění, prudké zrychlení a ostré\nzatáčky, v g), a stav telefonu (`device` – baterie, síť, oprávnění k poloze). Provozovna pak vidí své kurýry\nživě (`listCourierPositions`, události `courier.position`) a projetou stopu každé trasy se souhrnem\n(`getDeliveryRouteTrack`).\n\nNa telefonu musí být přihlášený ten kurýr sám (`403 staff_role_missing`). Body se zapisují jen během směny\nkurýra (`startCourierShift` až `endCourierShift`) a jen když provozovna sledování kurýrů zapnula v administraci,\nkde potvrdí, že své zaměstnance informovala. Jinak odpověď `200` s `mode` `off` a vším v `discarded` – přestaňte\nměřit.\n\nOdpověď říká, jak pokračovat. `mode` `route` (kurýr má otevřenou trasu): dávku každých `send_every_s` (15 s)\ns bodem každých `sample_every_s` (5 s, nebo po 25 m). `shift` (na směně bez trasy): dávku každých 60 s. `off`:\npřestaňte měřit – `off_reason` je `tracking_disabled`, `off_shift`, nebo `idle` (na směně bez trasy přes\n3 hodiny, nejspíš zapomenuté odhlášení); znovu začněte, až kurýr dostane trasu nebo se znovu přihlásí na směnu.\nDávka bez bodů se hodí na dotaz, jaký je režim. `thresholds` jsou prahy prudkých manévrů v g, které má telefon\npoužít, `server_time` mu dovolí opravit hodiny.\n\nBez signálu nechte dávky v telefonu a pošlete je později, nejstarší první. Znovu poslaná dávka nic nezapíše\ndvakrát – body se rozliší podle kurýra a `recorded_at` (`duplicates`), takže `Idempotency-Key` není potřeba.\nBody starší než 24 hodin, z doby před začátkem směny nebo víc než 2 minuty napřed proti serveru se zahodí\n(`discarded`). Posílejte `route_id` trasy, kterou kurýr jede, dokud se nevrátí do provozovny – cesta zpět patří\nk trase; bez něj server použije otevřenou trasu. Body s přesností horší než 50 m se uloží, ale nepočítají se do\nvzdálenosti ani do nejvyšší rychlosti. Body a manévry se drží 14 dní, pak zůstane jen souhrn trasy. V dávce\nnejvýš 300 bodů a 50 manévrů. Nezapisuje se do auditního logu.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CourierTelemetryBatch"
       },
       "examples": {
        "route": {
         "summary": "A batch on a route",
         "value": {
          "samples": [
           {
            "recorded_at": "2027-01-15T12:15:21.040+01:00",
            "location": {
             "lat": 50.082311,
             "lon": 14.460402,
             "accuracy_m": 5
            },
            "speed_mps": 10.1,
            "heading_deg": 214,
            "altitude_m": 237,
            "accel_peak_g": 0.18,
            "route_id": "3307"
           },
           {
            "recorded_at": "2027-01-15T12:15:26.050+01:00",
            "location": {
             "lat": 50.082088,
             "lon": 14.460089,
             "accuracy_m": 5
            },
            "speed_mps": 6.3,
            "heading_deg": 213,
            "altitude_m": 236,
            "accel_peak_g": 0.52,
            "route_id": "3307"
           },
           {
            "recorded_at": "2027-01-15T12:15:31.060+01:00",
            "location": {
             "lat": 50.081902,
             "lon": 14.459811,
             "accuracy_m": 6
            },
            "speed_mps": 9.4,
            "heading_deg": 212,
            "altitude_m": 236,
            "accel_peak_g": 0.21,
            "route_id": "3307"
           }
          ],
          "driving_events": [
           {
            "type": "harsh_braking",
            "recorded_at": "2027-01-15T12:15:24.800+01:00",
            "value_g": 0.52,
            "duration_ms": 900,
            "speed_mps": 11.2,
            "location": {
             "lat": 50.082107,
             "lon": 14.460118,
             "accuracy_m": 5
            },
            "route_id": "3307"
           }
          ],
          "device": {
           "battery_pct": 64,
           "charging": false,
           "network": "cellular",
           "activity": "vehicle",
           "mock_location": false,
           "location_permission": "while_in_use",
           "power_save": false,
           "app_version": "26.11.3"
          }
         },
         "x-summary-cs": "Dávka na trase"
        },
        "mode": {
         "summary": "No points – only asking for the mode",
         "value": {
          "device": {
           "battery_pct": 64,
           "charging": false,
           "network": "cellular",
           "activity": "vehicle",
           "mock_location": false,
           "location_permission": "while_in_use",
           "power_save": false,
           "app_version": "26.11.3"
          }
         },
         "x-summary-cs": "Bez bodů – jen dotaz na režim"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "What was recorded and how to go on.",
      "x-description-cs": "Co se zapsalo a jak pokračovat.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CourierTelemetryResult"
        },
        "examples": {
         "route": {
          "summary": "Recorded, the next batch in 15 s",
          "value": {
           "accepted": 4,
           "duplicates": 0,
           "discarded": 0,
           "mode": "route",
           "off_reason": null,
           "send_every_s": 15,
           "sample_every_s": 5,
           "thresholds": {
            "harsh_braking_g": 0.4,
            "harsh_acceleration_g": 0.35,
            "sharp_turn_g": 0.45
           },
           "server_time": "2027-01-15T12:15:33+01:00"
          },
          "x-summary-cs": "Zapsáno, další dávka za 15 s"
         },
         "off": {
          "summary": "Tracking is off in the restaurant – stop measuring",
          "value": {
           "accepted": 0,
           "duplicates": 0,
           "discarded": 4,
           "mode": "off",
           "off_reason": "tracking_disabled",
           "send_every_s": null,
           "sample_every_s": null,
           "thresholds": {
            "harsh_braking_g": 0.4,
            "harsh_acceleration_g": 0.35,
            "sharp_turn_g": 0.45
           },
           "server_time": "2027-01-15T12:15:33+01:00"
          },
          "x-summary-cs": "Sledování v provozovně vypnuté – přestat měřit"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "description": "`insufficient_scope` or `customer_not_verified`; on Profirest's own devices also `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` and – on the\nregister – `manager_approval_required`.\n",
      "x-description-cs": "`insufficient_scope` nebo `customer_not_verified`; na vlastních zařízeních Profirestu také `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` a – na pokladně –\n`manager_approval_required`.\n",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "insufficient_scope": {
          "summary": "The token lacks the scope",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#insufficient_scope",
           "title": "Token nemá potřebné oprávnění",
           "status": 403,
           "code": "insufficient_scope",
           "detail": "Missing scope: orders:write",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Token nemá potřebné oprávnění"
         },
         "staff_role_missing": {
          "summary": "Only the courier sends their own location",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#staff_role_missing",
           "title": "Přihlášený zaměstnanec tohle nesmí",
           "status": 403,
           "code": "staff_role_missing",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Polohu posílá jen kurýr sám za sebe"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "503": {
      "$ref": "#/components/responses/ServiceUnavailable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/courier-positions": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "listCourierPositions",
    "summary": "Where the couriers on shift are",
    "x-summary-cs": "Kde jsou kurýři na směně",
    "x-staff": "optional",
    "description": "The last location of every courier on shift whose phone sends it (`postCourierTelemetry`), ordered by name:\nthe state, speed and heading, the open route with the orders left on it and the state of the phone. `state` is\n`moving`, `stopped`, `at_restaurant` (within 100 m of the restaurant) or `stale` – nothing from the phone for\nover 3 minutes (no signal, the phone is off or the application was closed); then show `received_at`. A courier\nwho checks out disappears from the list.\n\nChanges come live as `courier.position` events (at most one every 10 seconds per courier, only in the feed and\nthe stream, see `listEvents`) and `courier.shift_changed`. Load the list when you start and after you reconnect.\nThe courier's own phone (a device without `kitchen:read`) sees only the courier themself.\n",
    "x-description-cs": "Poslední poloha každého kurýra na směně, jehož telefon ji posílá (`postCourierTelemetry`), podle jména: stav,\nrychlost a směr, otevřená trasa se zbývajícími objednávkami a stav telefonu. `state` je `moving`, `stopped`,\n`at_restaurant` (do 100 m od provozovny), nebo `stale` – od telefonu přes 3 minuty nic (bez signálu, vypnutý\ntelefon nebo zavřená aplikace); pak ukažte `received_at`. Kurýr, který se odhlásí ze směny, ze seznamu zmizí.\n\nZměny chodí živě jako události `courier.position` (nejvýš jedna za 10 sekund na kurýra, jen v proudu, viz\n`listEvents`) a `courier.shift_changed`. Seznam načtěte při startu a po novém připojení. Telefon kurýra\n(zařízení bez `kitchen:read`) vidí jen kurýra samotného.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The couriers on shift with their location.",
      "x-description-cs": "Kurýři na směně s polohou.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CourierPositionList"
        },
        "examples": {
         "positions": {
          "summary": "Couriers on shift",
          "value": {
           "data": [
            {
             "employee": {
              "id": "64",
              "name": "Tomáš Král"
             },
             "state": "moving",
             "location": {
              "lat": 50.081902,
              "lon": 14.459811,
              "accuracy_m": 6
             },
             "speed_mps": 9.4,
             "heading_deg": 212,
             "altitude_m": 236,
             "recorded_at": "2027-01-15T12:15:31+01:00",
             "received_at": "2027-01-15T12:15:33+01:00",
             "route_id": "3307",
             "remaining_tickets": 1,
             "device": {
              "battery_pct": 64,
              "charging": false,
              "network": "cellular",
              "activity": "vehicle",
              "mock_location": false,
              "location_permission": "while_in_use",
              "power_save": false,
              "app_version": "26.11.3"
             }
            },
            {
             "employee": {
              "id": "68",
              "name": "Martin Beneš"
             },
             "state": "at_restaurant",
             "location": {
              "lat": 50.083412,
              "lon": 14.46679,
              "accuracy_m": 11
             },
             "speed_mps": 0.0,
             "heading_deg": null,
             "altitude_m": 241,
             "recorded_at": "2027-01-15T12:15:02+01:00",
             "received_at": "2027-01-15T12:15:04+01:00",
             "route_id": null,
             "remaining_tickets": 0,
             "device": {
              "battery_pct": 31,
              "charging": true,
              "network": "wifi",
              "activity": "still",
              "mock_location": false,
              "location_permission": "while_in_use",
              "power_save": false,
              "app_version": "26.11.3"
             }
            }
           ]
          },
          "x-summary-cs": "Kurýři na směně"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/delivery-routes/{route_id}/track": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/RouteId"
    }
   ],
   "get": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "getDeliveryRouteTrack",
    "summary": "The driven track of a route",
    "x-summary-cs": "Projetá stopa trasy",
    "x-staff": "optional",
    "description": "Where the courier drove on the route, from the points of `postCourierTelemetry`: points at least 10 m apart\n(at most 5 000), the harsh manoeuvres and the summary – distance, time moving, top and average speed while\nmoving and the number of harsh manoeuvres. The points and manoeuvres are kept for 14 days, then\n`points_expired` is `true` and only the summary stays. `summary` is `null` when the phone sent nothing for the\nroute. The courier's own phone sees only their routes.\n",
    "x-description-cs": "Kudy kurýr na trase jel, z bodů `postCourierTelemetry`: body aspoň 10 m od sebe (nejvýš 5 000), prudké manévry\na souhrn – vzdálenost, čas v jízdě, nejvyšší a průměrná rychlost za jízdy a počet prudkých manévrů. Body\na manévry se drží 14 dní, pak je `points_expired` `true` a zůstane jen souhrn. `summary` je `null`, když telefon\nk trase nic neposlal. Telefon kurýra vidí jen své trasy.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The track of the route.",
      "x-description-cs": "Stopa trasy.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeliveryRouteTrack"
        },
        "examples": {
         "track": {
          "summary": "The driven track of a route",
          "value": {
           "route_id": "3307",
           "courier": {
            "id": "64",
            "name": "Tomáš Král"
           },
           "summary": {
            "started_at": "2027-01-15T12:07:12+01:00",
            "ended_at": "2027-01-15T12:15:31+01:00",
            "distance_m": 2840,
            "moving_s": 412,
            "duration_s": 499,
            "max_speed_mps": 13.6,
            "avg_moving_speed_mps": 6.89,
            "points": 96,
            "harsh_braking": 1,
            "harsh_acceleration": 0,
            "sharp_turn": 0
           },
           "points_expired": false,
           "points": [
            {
             "recorded_at": "2027-01-15T12:07:12+01:00",
             "lat": 50.083412,
             "lon": 14.46679,
             "accuracy_m": 8,
             "speed_mps": 0.0,
             "heading_deg": null
            },
            {
             "recorded_at": "2027-01-15T12:15:26+01:00",
             "lat": 50.082088,
             "lon": 14.460089,
             "accuracy_m": 5,
             "speed_mps": 6.3,
             "heading_deg": 213
            },
            {
             "recorded_at": "2027-01-15T12:15:31+01:00",
             "lat": 50.081902,
             "lon": 14.459811,
             "accuracy_m": 6,
             "speed_mps": 9.4,
             "heading_deg": 212
            }
           ],
           "driving_events": [
            {
             "type": "harsh_braking",
             "recorded_at": "2027-01-15T12:15:24+01:00",
             "value_g": 0.52,
             "duration_ms": 900,
             "speed_mps": 11.2,
             "location": {
              "lat": 50.082107,
              "lon": 14.460118,
              "accuracy_m": 5
             }
            }
           ]
          },
          "x-summary-cs": "Projetá stopa trasy"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/address-suggestions": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Deliveries"
    ],
    "operationId": "suggestDeliveryAddresses",
    "summary": "Suggest delivery addresses",
    "x-summary-cs": "Našeptat doručovací adresy",
    "x-requires-device": true,
    "description": "Address search for an order taken on the phone, through the map service the administration uses (Mapy.cz). Only\naddresses inside a delivery zone of the restaurant come back, each with the zone a quote will use – for\napplications of the restaurant staff any active zone whatever its delivery hours (as in their quotes), for guest\napplications only zones delivering now; send `address` together with `location` as `delivery_address` of a\nquote. At most 8 addresses; at most 60 searches a\nminute per device (`429 rate_limited`). When the map service does not answer, the answer is\n`503 service_unavailable`.\n",
    "x-description-cs": "Hledání adresy pro objednávku přijatou po telefonu přes mapovou službu, kterou používá administrace (Mapy.cz).\nVrátí jen adresy uvnitř rozvozové zóny provozovny, každou se zónou, kterou použije kalkulace – pro aplikace\npersonálu jakoukoli aktivní zónu bez ohledu na časy rozvozu (jako v jejich kalkulacích), pro aplikace pro hosty\njen zóny, které teď rozvážejí; `address` spolu s `location` pošlete jako `delivery_address` kalkulace. Nejvýš 8 adres; nejvýš 60 hledání za minutu na zařízení\n(`429 rate_limited`). Když mapová služba neodpovídá, odpověď je `503 service_unavailable`.\n",
    "security": [
     {
      "oauth2": [
       "deliveries:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "query",
      "in": "query",
      "required": true,
      "description": "What the customer said – street and number, a place, a village.",
      "x-description-cs": "Co zákazník řekl – ulice a číslo, místo, obec.",
      "schema": {
       "type": "string",
       "minLength": 3,
       "maxLength": 100,
       "examples": [
        "Jeseniova 52"
       ]
      },
      "example": "Jeseniova 52"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Addresses the restaurant delivers to now.",
      "x-description-cs": "Adresy, kam provozovna teď rozváží.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AddressSuggestionList"
        },
        "examples": {
         "suggestions": {
          "summary": "Address suggestions",
          "value": {
           "data": [
            {
             "label": "Jeseniova 1196/52, Praha 3",
             "address": {
              "street": "Jeseniova",
              "house_number": "1196/52",
              "city": "Praha 3",
              "postal_code": "130 00",
              "country": "CZ"
             },
             "location": {
              "lat": 50.0833,
              "lon": 14.4667
             },
             "zone": {
              "id": "21",
              "name": "Vinohrady do 3 km",
              "fee": {
               "amount": 4900,
               "currency": "CZK"
              },
              "minimum_order": {
               "amount": 25000,
               "currency": "CZK"
              },
              "express_fee": {
               "amount": 4000,
               "currency": "CZK"
              }
             }
            }
           ]
          },
          "x-summary-cs": "Návrhy adres"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "$ref": "#/components/responses/ServiceUnavailable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/device-settings": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Device settings"
    ],
    "operationId": "getDeviceSettings",
    "summary": "Settings for the restaurant's devices",
    "x-summary-cs": "Nastavení pro zařízení provozovny",
    "description": "Everything set in the administration that a cash register, a kitchen display or another device of the restaurant\nneeds: the restaurant and the company on receipts (registration and VAT numbers, VAT payer), receipt layouts\n(Print layouts), predefined notes, printers and production stations of the split kitchen, rooms with tables\n(when the licence includes the table map), kitchen settings, the legacy EET 1.0 settings without the certificate\nitself (EET 2.0 is done by the server and has nothing to set on a device) and the features of the licence. Ask\nwith `If-None-Match`; an unchanged answer is `304`. No event tells about a change; ask again from time to time.\n",
    "x-description-cs": "Vše nastavené v administraci, co potřebuje pokladna, kuchyňský displej nebo jiné zařízení provozovny: provozovna\na firma na účtenkách (IČO, DIČ, plátce DPH), tiskové šablony (Tiskové sestavy), předdefinované poznámky, tiskárny\na výrobní stanoviště rozdělené kuchyně, místnosti se stoly (když licence obsahuje mapu provozovny), nastavení\nkuchyně, původní nastavení EET 1.0 bez samotného certifikátu (EET 2.0 eviduje server a na zařízení se nic\nnenastavuje) a funkce licence. Ptejte se s `If-None-Match`; nezměněná odpověď je `304`. Žádná událost o změně\nneinformuje; ptejte se občas znovu.\n",
    "security": [
     {
      "oauth2": [
       "settings:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The settings.",
      "x-description-cs": "Nastavení.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeviceSettings"
        },
        "examples": {
         "settings": {
          "summary": "Settings for devices",
          "value": {
           "restaurant": {
            "name": "Bistro U Lípy",
            "phone": "+420222333444",
            "website": "https://www.bistroulipy.cz",
            "address": {
             "street": "Vinohradská 1200/48",
             "city": "Praha 2",
             "postal_code": "120 00"
            },
            "location": {
             "lat": 50.0769,
             "lon": 14.4459
            },
            "currency": "CZK",
            "timezone": "Europe/Prague"
           },
           "company": {
            "name": "U Lípy gastro s.r.o.",
            "registration_number": "12345678",
            "vat_number": "CZ12345678",
            "vat_payer": true,
            "address": {
             "street": "Vinohradská 1200/48",
             "city": "Praha 2",
             "postal_code": "120 00"
            },
            "email": "ucetni@bistroulipy.cz"
           },
           "receipt_layouts": {
            "receipt": null,
            "takeaway": null
           },
           "predefined_notes": [
            {
             "id": "11",
             "text": "Bez cibule"
            },
            {
             "id": "12",
             "text": "Pálivé"
            },
            {
             "id": "13",
             "text": "S sebou"
            }
           ],
           "printers": [
            {
             "id": "5",
             "name": "Účtenky – bar",
             "sections": "all",
             "auto_print": false
            },
            {
             "id": "6",
             "name": "Bony – kuchyň",
             "sections": "kitchen",
             "auto_print": true
            }
           ],
           "kitchen_stations": [
            {
             "id": "2",
             "name": "Teplá kuchyně",
             "sections": "kitchen",
             "auto_print": false
            },
            {
             "id": "3",
             "name": "Pizza",
             "sections": "kitchen",
             "auto_print": false
            }
           ],
           "rooms": [
            {
             "id": "1",
             "name": "Restaurace",
             "width": 100,
             "height": 100,
             "tables": [
              {
               "id": "4",
               "name": "Stůl 4",
               "kind": "table",
               "code": "K7M2Q9XB",
               "left": 12,
               "top": 20,
               "width": 14,
               "height": 10
              },
              {
               "id": "7",
               "name": "Stůl 7",
               "kind": "table",
               "code": "3HFD8R2W",
               "left": 52,
               "top": 20,
               "width": 14,
               "height": 10
              },
              {
               "id": "30",
               "name": "Bar",
               "kind": "item",
               "code": null,
               "left": 80,
               "top": 70,
               "width": 18,
               "height": 25
              }
             ]
            }
           ],
           "kitchen": {
            "portion_mode": "local",
            "extra_ticket": false,
            "redirect_restaurant_id": null,
            "ready_sms": true
           },
           "eet": {
            "enabled": true,
            "premises_id": "273",
            "certificate_valid_to": "2029-12-31T23:59:59+01:00"
           },
           "features": {
            "kitchen": true,
            "multiple_cash_registers": true,
            "multiple_kitchen_devices": true,
            "other_devices": true,
            "attendance": true,
            "reservations": false,
            "lodging": false,
            "daily_menu": true,
            "table_map": true,
            "customer_database": true
           },
           "paid_until": "2027-12-31T23:59:59+01:00",
           "table_ordering": {
            "enabled": true,
            "confirm_mode": "first",
            "empty_table": "staff",
            "join_code_enabled": true,
            "max_quantity": 10,
            "expire_minutes": 10,
            "respect_opening_hours": true,
            "category_ids": [
             "320"
            ],
            "note_max_length": 32,
            "wifi_ssid": "U Lípy – hosté"
           },
           "pos": {
            "receipt_cancel_by": "staff",
            "takeaway_only": false,
            "calculator": {
             "enabled": true,
             "keys": [
              {
               "id": "17",
               "name": "Pečivo",
               "vat_rate": "12",
               "color": "#119b2d",
               "position": 1
              },
              {
               "id": "18",
               "name": "Zboží",
               "vat_rate": "21",
               "color": "#5b4ac0",
               "position": 2
              }
             ]
            }
           }
          },
          "x-summary-cs": "Nastavení pro zařízení"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/customer-directory": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Customer directory"
    ],
    "operationId": "searchCustomerDirectory",
    "summary": "Find customers by phone or name",
    "x-summary-cs": "Najít zákazníky podle telefonu nebo jména",
    "x-requires-device": true,
    "description": "For an order taken on the phone. Customers of the whole account – the same people the administration shows in\nCustomers – whose phone number starts with `phone` or whose name contains `name`, each with one of their\ndelivery addresses: one result per customer and address, at most 10. Addresses with a location come first, then\nregistered customers, then the addresses added last. A customer without any address comes once with\n`address: null`. Send at least 2 digits of `phone` or 2 characters of `name`. One device searches at most\n600 times an hour (`429 rate_limited` with `Retry-After` until the next hour).\n",
    "x-description-cs": "Pro objednávku přijatou po telefonu. Zákazníci celého účtu – titíž, které administrace ukazuje v Zákaznících –,\njejichž telefon začíná na `phone` nebo jejichž jméno obsahuje `name`, každý s jednou ze svých doručovacích adres:\njeden výsledek na zákazníka a adresu, nejvýš 10. Napřed adresy s polohou, pak registrovaní zákazníci, pak naposledy\npřidané adresy. Zákazník bez adresy přijde jednou s `address: null`. Pošlete aspoň 2 číslice `phone` nebo 2 znaky\n`name`. Jedno zařízení hledá nejvýš 600krát za hodinu (`429 rate_limited` s `Retry-After` do další hodiny).\n",
    "security": [
     {
      "oauth2": [
       "directory:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "phone",
      "in": "query",
      "description": "Beginning of the phone number. Spaces and the prefix `+420` or `00420` are ignored.",
      "x-description-cs": "Začátek telefonního čísla. Mezery a předvolba `+420` nebo `00420` se nepočítají.",
      "schema": {
       "type": "string",
       "maxLength": 20,
       "examples": [
        "777 12"
       ]
      },
      "example": "777 12"
     },
     {
      "name": "name",
      "in": "query",
      "description": "Part of the customer's name, or the beginning of their e-shop login.",
      "x-description-cs": "Část jména zákazníka nebo začátek jeho přihlašovacího jména do e-shopu.",
      "schema": {
       "type": "string",
       "maxLength": 64,
       "examples": [
        "Nováková"
       ]
      }
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Matching customers with their addresses.",
      "x-description-cs": "Nalezení zákazníci s adresami.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CustomerDirectoryList"
        },
        "examples": {
         "found": {
          "summary": "A customer found",
          "value": {
           "data": [
            {
             "customer": {
              "id": "90321",
              "name": "Jana Nováková",
              "phone": "+420777123456",
              "registered": true,
              "points": 120,
              "orders": 14
             },
             "address": {
              "id": "40417",
              "street": "Jeseniova 1196/52",
              "city": "Praha 3",
              "location": {
               "lat": 50.0833,
               "lon": 14.4667
              }
             }
            }
           ]
          },
          "x-summary-cs": "Nalezený zákazník"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/calls": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Customer directory"
    ],
    "operationId": "reportCall",
    "summary": "Report an incoming call",
    "x-summary-cs": "Nahlásit příchozí hovor",
    "x-requires-device": true,
    "x-idempotency": "none",
    "description": "The restaurant's phone reports a call. The answer tells who is calling – the customer, their number of orders and\nthe address of their last delivery from this restaurant – and the kitchen displays of the restaurant get the\nevent `call.received`. A number the account does not know yet is added to its customers, as today, so that the\nscreens which still read calls the old way show it as well. No `Idempotency-Key`: reporting the same call again\nonly reports it again.\n",
    "x-description-cs": "Telefon provozovny hlásí hovor. Odpověď řekne, kdo volá – zákazníka, počet jeho objednávek a adresu posledního\nrozvozu z této provozovny – a kuchyňské displeje provozovny dostanou událost `call.received`. Číslo, které účet\nještě nezná, se jako dnes přidá mezi zákazníky, aby ho ukázaly i obrazovky, které hovory čtou postaru. Bez\n`Idempotency-Key`: nové nahlášení téhož hovoru ho jen nahlásí znovu.\n",
    "security": [
     {
      "oauth2": [
       "calls:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CallReport"
       },
       "examples": {
        "incoming": {
         "summary": "An incoming call",
         "value": {
          "phone": "+420777123456",
          "kind": "incoming"
         },
         "x-summary-cs": "Příchozí hovor"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Who is calling.",
      "x-description-cs": "Kdo volá.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/IncomingCall"
        },
        "examples": {
         "call": {
          "summary": "A call from a known customer",
          "value": {
           "phone": "+420777123456",
           "kind": "incoming",
           "received_at": "2027-01-15T11:36:48+01:00",
           "customer": {
            "id": "90321",
            "name": "Jana Nováková",
            "phone": "+420777123456",
            "registered": true,
            "points": 120,
            "orders": 14
           },
           "last_address": {
            "id": "40417",
            "street": "Jeseniova 1196/52",
            "city": "Praha 3",
            "location": {
             "lat": 50.0833,
             "lon": 14.4667
            }
           }
          },
          "x-summary-cs": "Hovor se známým zákazníkem"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/calls/latest": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Customer directory"
    ],
    "operationId": "getLatestCall",
    "summary": "The call of the last 45 seconds",
    "x-summary-cs": "Hovor posledních 45 sekund",
    "x-requires-device": true,
    "description": "The latest call reported in the last 45 seconds, as the kitchen display shows it today next to a new order;\n`call: null` when there is none. Like today it covers the calls of the whole account, including those reported\nby the older applications. Calls reported through `POST …/calls` also come as `call.received` to the devices of\ntheir restaurant; calls reported by the older applications do not.\n",
    "x-description-cs": "Poslední hovor nahlášený za posledních 45 sekund, jak ho dnes kuchyňský displej ukazuje u nové objednávky;\n`call: null`, když žádný není. Jako dnes zahrnuje hovory celého účtu včetně těch, které nahlásily starší aplikace.\nHovory nahlášené přes `POST …/calls` přicházejí zařízením jejich provozovny i jako `call.received`; hovory ze\nstarších aplikací ne.\n",
    "security": [
     {
      "oauth2": [
       "directory:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The latest call, or `null`.",
      "x-description-cs": "Poslední hovor, nebo `null`.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LatestCall"
        },
        "examples": {
         "latest": {
          "summary": "The latest call",
          "value": {
           "call": {
            "phone": "+420777123456",
            "kind": "incoming",
            "received_at": "2027-01-15T11:36:48+01:00",
            "customer": {
             "id": "90321",
             "name": "Jana Nováková",
             "phone": "+420777123456",
             "registered": true,
             "points": 120,
             "orders": 14
            },
            "last_address": {
             "id": "40417",
             "street": "Jeseniova 1196/52",
             "city": "Praha 3",
             "location": {
              "lat": 50.0833,
              "lon": 14.4667
             }
            }
           }
          },
          "x-summary-cs": "Poslední hovor"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/external-refs/{object_type}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/ObjectType"
    }
   ],
   "get": {
    "tags": [
     "External references"
    ],
    "operationId": "listExternalRefs",
    "summary": "Find objects by your ID",
    "x-summary-cs": "Najít objekty podle vašeho ID",
    "description": "Your IDs and metadata on objects of this type. Filter by `external_id` to translate your ID to ours. Needs the\nscope that allows reading the object type (for example `orders:read` for orders).\n",
    "x-description-cs": "Vaše ID a metadata u objektů tohoto typu. Filtrem `external_id` převedete své ID na naše. Vyžaduje oprávnění\nke čtení daného typu objektu (například `orders:read` u objednávek).\n",
    "security": [
     {
      "oauth2": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/ExternalIdFilter"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of references.",
      "x-description-cs": "Stránka vazeb.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ExternalRefPage"
        },
        "examples": {
         "list": {
          "summary": "Own IDs of orders",
          "value": {
           "data": [
            {
             "object_type": "order",
             "object_id": "184223",
             "external_id": "A-2027-000123",
             "metadata": {
              "branch": "praha-3"
             },
             "updated_at": "2027-01-15T11:43:05+01:00"
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Vlastní ID objednávek"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/external-refs/{object_type}/{object_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/ObjectType"
    },
    {
     "name": "object_id",
     "in": "path",
     "required": true,
     "schema": {
      "$ref": "#/components/schemas/Id"
     },
     "example": "184223"
    }
   ],
   "get": {
    "tags": [
     "External references"
    ],
    "operationId": "getExternalRef",
    "summary": "Your ID and metadata of one object",
    "x-summary-cs": "Vaše ID a metadata jednoho objektu",
    "description": "Needs the scope that allows reading the object type. Objects your connection cannot see answer 404.",
    "x-description-cs": "Vyžaduje oprávnění ke čtení daného typu objektu. Objekty, které vaše připojení nevidí, vrátí 404.",
    "security": [
     {
      "oauth2": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The reference (`external_id` may be `null` and `metadata` empty).",
      "x-description-cs": "Vazba (`external_id` může být `null` a `metadata` prázdná).",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ExternalRef"
        },
        "examples": {
         "ref": {
          "summary": "The own ID of an order",
          "value": {
           "object_type": "order",
           "object_id": "184223",
           "external_id": "A-2027-000123",
           "metadata": {
            "branch": "praha-3"
           },
           "updated_at": "2027-01-15T11:43:05+01:00"
          },
          "x-summary-cs": "Vlastní ID objednávky"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "put": {
    "tags": [
     "External references"
    ],
    "operationId": "putExternalRef",
    "summary": "Set your ID and metadata",
    "x-summary-cs": "Nastavit vaše ID a metadata",
    "description": "Sets your `external_id` and replaces your `metadata` on an object your connection can see (for example a product\nof the catalog) – a restaurant, category, product, order or customer; other objects cannot carry a reference.\nCategories and products count as visible when they are on the web (\"W\"), add-ons and daily menu products\nincluded; those offered only in the `pos` or `kitchen` channel answer `404`. Idempotent by itself. Send\n`If-Match` when several of your processes may write the same reference. An `external_id` already used on\nanother object of the same type answers `409 external_id_conflict`\nwith `existing_id`. Needs the read scope of the type; orders and customers also need `orders:write` or\n`customers:write` (setting and removing).\n",
    "x-description-cs": "Nastaví vaše `external_id` a nahradí vaše `metadata` u objektu, který vaše připojení vidí (například produktu ze\nsortimentu) – u provozovny, kategorie, produktu, objednávky nebo zákazníka; jiné objekty vazbu nést nemohou.\nKategorie a produkty jsou vidět, když jsou na webu („W“), včetně příloh a produktů denního menu; ty, které se\nnabízejí jen v kanálu `pos` nebo `kitchen`, vrátí `404`. Je idempotentní sám od sebe. Když stejnou vazbu může\nzapisovat víc vašich procesů, pošlete `If-Match`. `external_id` použité u jiného objektu stejného typu vrátí\n`409 external_id_conflict`\ns `existing_id`. Vyžaduje oprávnění ke čtení typu; u objednávek a zákazníků navíc `orders:write` nebo\n`customers:write` (nastavení i odebrání).\n",
    "security": [
     {
      "oauth2": []
     }
    ],
    "parameters": [
     {
      "name": "If-Match",
      "in": "header",
      "required": false,
      "description": "Optional `ETag` of the reference you read.",
      "x-description-cs": "Nepovinný `ETag` vazby, kterou jste načetli.",
      "schema": {
       "type": "string"
      }
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ExternalRefUpdate"
       },
       "examples": {
        "set": {
         "summary": "Setting the own ID and metadata",
         "value": {
          "external_id": "A-2027-000123",
          "metadata": {
           "branch": "praha-3"
          }
         },
         "x-summary-cs": "Nastavit vlastní ID a metadata"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The reference.",
      "x-description-cs": "Vazba.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ExternalRef"
        },
        "examples": {
         "ref": {
          "summary": "Stored",
          "value": {
           "object_type": "order",
           "object_id": "184223",
           "external_id": "A-2027-000123",
           "metadata": {
            "branch": "praha-3"
           },
           "updated_at": "2027-01-15T11:43:05+01:00"
          },
          "x-summary-cs": "Uloženo"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "external_id_conflict": {
          "summary": "Another object already has the own ID",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#external_id_conflict",
           "title": "Toto external_id už má jiný objekt",
           "status": 409,
           "code": "external_id_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": "184101",
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Vlastní ID už má jiný objekt"
         }
        }
       }
      }
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "delete": {
    "tags": [
     "External references"
    ],
    "operationId": "deleteExternalRef",
    "summary": "Remove your ID and metadata",
    "x-summary-cs": "Odebrat vaše ID a metadata",
    "description": "Removes only your reference. The object itself is not touched. Scopes as for setting it.",
    "x-description-cs": "Odebere jen vaši vazbu. Samotného objektu se nedotkne. Oprávnění jako u nastavení.",
    "security": [
     {
      "oauth2": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Removed, or there was nothing to remove.",
      "x-description-cs": "Odebráno, nebo nebylo co odebrat."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/receipts/preview": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Receipts"
    ],
    "operationId": "previewReceipt",
    "summary": "Price a receipt before payment",
    "x-summary-cs": "Spočítat účtenku před placením",
    "x-requires-device": true,
    "x-staff": "optional",
    "x-idempotency": "none",
    "description": "Prices the items exactly as `createReceipt` will: the register catalog at `issued_at` (now when left out), the\nhalf and employee prices, discounts, VAT and the amount due in cash rounded to whole crowns. Nothing is saved.\nCall it while online before you take the payment; then send the receipt with the same prices.\n",
    "x-description-cs": "Spočítá položky přesně jako `createReceipt`: sortiment pokladny v `issued_at` (bez něj teď), cenu půlky\na pro zaměstnance, slevy, DPH a částku k placení v hotovosti zaokrouhlenou na celé koruny. Nic se neukládá.\nVolejte ho online před přijetím platby; účtenku pak pošlete se stejnými cenami.\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReceiptPreviewRequest"
       },
       "examples": {
        "table": {
         "summary": "A table's bill before paying",
         "value": {
          "order_type": "dine_in",
          "items": [
           {
            "product_id": "4567",
            "quantity": 1,
            "course": 1
           },
           {
            "product_id": "4590",
            "quantity": 2
           }
          ]
         },
         "x-summary-cs": "Účet stolu před placením"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The priced receipt.",
      "x-description-cs": "Spočítaná účtenka.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReceiptPreview"
        },
        "examples": {
         "preview": {
          "summary": "The computed receipt",
          "value": {
           "lines": [
            {
             "id": "1",
             "type": "product",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": 1,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "note": null,
             "course": 1,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             },
             "voucher_code": null
            },
            {
             "id": "2",
             "type": "product",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": 2,
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "21",
             "add_ons": [],
             "note": null,
             "course": 0,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             },
             "voucher_code": null
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": 11405,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2395,
               "currency": "CZK"
              },
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": 17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2132,
               "currency": "CZK"
              },
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             }
            ]
           },
           "price_differences": [],
           "cash_amount_due": {
            "amount": 33700,
            "currency": "CZK"
           },
           "eet_recorded": true
          },
          "x-summary-cs": "Spočítaná účtenka"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/receipts": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Receipts"
    ],
    "operationId": "listReceipts",
    "summary": "List receipts",
    "x-summary-cs": "Seznam účtenek",
    "x-requires-device": true,
    "description": "Receipts and cancellation documents that registers of the restaurant issued through this API, the last received\nfirst (an offline receipt sent later comes before older ones). By default only those of the calling device.\nSales recorded elsewhere – by registers on API v1 or in the administration – are not here.\n",
    "x-description-cs": "Účtenky a storno doklady, které pokladny provozovny vystavily přes toto API, naposledy přijaté první (offline\núčtenka poslaná později přijde před staršími). Bez filtru jen účtenky volajícího zařízení. Tržby zapsané jinde –\npokladnami na API v1 nebo v administraci – tu nejsou.\n",
    "security": [
     {
      "oauth2": [
       "receipts:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "device",
      "in": "query",
      "required": false,
      "description": "`this` – the calling device (default), `all` – every register of the restaurant that issues receipts through this API.",
      "x-description-cs": "`this` – volající zařízení (výchozí), `all` – všechny pokladny provozovny, které vystavují účtenky přes toto API.",
      "schema": {
       "type": "string",
       "enum": [
        "this",
        "all"
       ],
       "default": "this"
      },
      "example": "this"
     },
     {
      "name": "shift",
      "in": "query",
      "required": false,
      "description": "`open` – only receipts not closed by a shift close yet; `any` (default) – closed ones too.",
      "x-description-cs": "`open` – jen účtenky, které ještě neuzavřela uzávěrka; `any` (výchozí) – i uzavřené.",
      "schema": {
       "type": "string",
       "enum": [
        "open",
        "any"
       ],
       "default": "any"
      },
      "example": "open"
     },
     {
      "name": "shift_id",
      "in": "query",
      "required": false,
      "description": "Only the receipts of this shift close (`PosShiftClose.id`, `listPosShifts`) – also those of other devices it\nclosed and the API v1 documents it took over (`legacy_receipt_ids`). Without `device` of every device. An\nunknown ID answers `422` with `not_found`. Since 26.11.26.\n",
      "x-description-cs": "Jen účtenky této uzávěrky (`PosShiftClose.id`, `listPosShifts`) – i dalších zařízení, která uzavřela,\na doklady z API v1, které převzala (`legacy_receipt_ids`). Bez `device` všech zařízení. Neznámé ID odpoví\n`422` s `not_found`. Od 26.11.26.\n",
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     },
     {
      "name": "since",
      "in": "query",
      "required": false,
      "description": "Issued at or after this instant.",
      "x-description-cs": "Vystavené v tomto okamžiku nebo později.",
      "schema": {
       "$ref": "#/components/schemas/Timestamp"
      }
     },
     {
      "name": "until",
      "in": "query",
      "required": false,
      "description": "Issued before this instant.",
      "x-description-cs": "Vystavené před tímto okamžikem.",
      "schema": {
       "$ref": "#/components/schemas/Timestamp"
      }
     },
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "One page of receipts.",
      "x-description-cs": "Jedna stránka účtenek.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ReceiptPage"
        },
        "examples": {
         "open_shift": {
          "summary": "Receipts of the open shift",
          "value": {
           "data": [
            {
             "id": "01a318f0-a0c0-7296-bee5-5e43065310d7",
             "restaurant_id": "123",
             "device_id": "512",
             "number": 1002,
             "kind": "sale",
             "status": "issued",
             "issued_at": "2027-01-15T12:47:05+01:00",
             "received_at": "2027-01-15T12:47:06+01:00",
             "offline": false,
             "issued_by": {
              "id": "58",
              "name": "Jana Dvořáková"
             },
             "approved_by": null,
             "table_name": "Stůl 7",
             "order_type": "dine_in",
             "customer_id": null,
             "note": null,
             "lines": [
              {
               "id": "1",
               "type": "product",
               "product_id": "4567",
               "name": "Svíčková na smetaně, houskový knedlík",
               "variant": "full",
               "quantity": 1,
               "unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "catalog_unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "price_source": "catalog",
               "at_employee_price": false,
               "packaging_unit_price": null,
               "vat_rate": "12",
               "add_ons": [],
               "note": null,
               "course": 1,
               "total": {
                "amount": 19900,
                "currency": "CZK"
               },
               "voucher_code": null
              },
              {
               "id": "2",
               "type": "product",
               "product_id": "4590",
               "name": "Pivo 12° 0,5 l",
               "variant": "full",
               "quantity": 2,
               "unit_price": {
                "amount": 6900,
                "currency": "CZK"
               },
               "catalog_unit_price": {
                "amount": 6900,
                "currency": "CZK"
               },
               "price_source": "catalog",
               "at_employee_price": false,
               "packaging_unit_price": null,
               "vat_rate": "21",
               "add_ons": [],
               "note": null,
               "course": 0,
               "total": {
                "amount": 13800,
                "currency": "CZK"
               },
               "voucher_code": null
              }
             ],
             "discounts": [],
             "totals": {
              "items": {
               "amount": 33700,
               "currency": "CZK"
              },
              "charges": {
               "amount": 0,
               "currency": "CZK"
              },
              "discounts": {
               "amount": 0,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 33700,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "21",
                "base": {
                 "amount": 11405,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 2395,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 13800,
                 "currency": "CZK"
                }
               },
               {
                "rate": "12",
                "base": {
                 "amount": 17768,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 2132,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 19900,
                 "currency": "CZK"
                }
               }
              ]
             },
             "payments": [
              {
               "id": "1",
               "method": "card",
               "amount": {
                "amount": 33700,
                "currency": "CZK"
               },
               "tip": {
                "amount": 3300,
                "currency": "CZK"
               },
               "tendered": null,
               "change": null,
               "voucher_code": null,
               "reference": null,
               "terminal": {
                "provider": "csob",
                "transaction_id": "0011245580",
                "card_number_masked": "**** **** **** 4821",
                "auth_code": "A7K2Q9"
               }
              }
             ],
             "tips": {
              "amount": 3300,
              "currency": "CZK"
             },
             "price_differences": [],
             "kitchen_number": null,
             "cancels": null,
             "cancelled_by": null,
             "eet": {
              "status": "accepted",
              "total": {
               "amount": 33700,
               "currency": "CZK"
              },
              "prepaid_issued": null,
              "prepaid_used": null,
              "register_id": "POS-512",
              "sequence": "1002",
              "unit_id": "273",
              "sold_at": "2027-01-15T12:47:05+01:00",
              "pok": "0c94d2b7-1e6a-4f3b-8d25-7a9e1c3f5b80-03",
              "environment": "production",
              "error": null,
              "warnings": [],
              "deadline_at": "2027-01-17T12:47:05+01:00"
             },
             "shift_closed_at": null
            },
            {
             "id": "01a318f0-a0c0-750d-8c36-65b69d55462d",
             "restaurant_id": "123",
             "device_id": "512",
             "number": 1001,
             "kind": "sale",
             "status": "issued",
             "issued_at": "2027-01-15T12:03:18+01:00",
             "received_at": "2027-01-15T12:03:19+01:00",
             "offline": false,
             "issued_by": {
              "id": "58",
              "name": "Jana Dvořáková"
             },
             "approved_by": null,
             "table_name": "Stůl 4",
             "order_type": "dine_in",
             "customer_id": null,
             "note": null,
             "lines": [
              {
               "id": "1",
               "type": "product",
               "product_id": "4567",
               "name": "Svíčková na smetaně, houskový knedlík",
               "variant": "full",
               "quantity": 1,
               "unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "catalog_unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "price_source": "catalog",
               "at_employee_price": false,
               "packaging_unit_price": null,
               "vat_rate": "12",
               "add_ons": [],
               "note": null,
               "course": 1,
               "total": {
                "amount": 19900,
                "currency": "CZK"
               },
               "voucher_code": null
              },
              {
               "id": "2",
               "type": "product",
               "product_id": "4590",
               "name": "Pivo 12° 0,5 l",
               "variant": "full",
               "quantity": 2,
               "unit_price": {
                "amount": 6900,
                "currency": "CZK"
               },
               "catalog_unit_price": {
                "amount": 6900,
                "currency": "CZK"
               },
               "price_source": "catalog",
               "at_employee_price": false,
               "packaging_unit_price": null,
               "vat_rate": "21",
               "add_ons": [],
               "note": null,
               "course": 0,
               "total": {
                "amount": 13800,
                "currency": "CZK"
               },
               "voucher_code": null
              }
             ],
             "discounts": [],
             "totals": {
              "items": {
               "amount": 33700,
               "currency": "CZK"
              },
              "charges": {
               "amount": 0,
               "currency": "CZK"
              },
              "discounts": {
               "amount": 0,
               "currency": "CZK"
              },
              "rounding": {
               "amount": 0,
               "currency": "CZK"
              },
              "total": {
               "amount": 33700,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "21",
                "base": {
                 "amount": 11405,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 2395,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 13800,
                 "currency": "CZK"
                }
               },
               {
                "rate": "12",
                "base": {
                 "amount": 17768,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 2132,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 19900,
                 "currency": "CZK"
                }
               }
              ]
             },
             "payments": [
              {
               "id": "1",
               "method": "cash",
               "amount": {
                "amount": 33700,
                "currency": "CZK"
               },
               "tip": {
                "amount": 0,
                "currency": "CZK"
               },
               "tendered": {
                "amount": 40000,
                "currency": "CZK"
               },
               "change": {
                "amount": 6300,
                "currency": "CZK"
               },
               "voucher_code": null,
               "reference": null,
               "terminal": null
              }
             ],
             "tips": {
              "amount": 0,
              "currency": "CZK"
             },
             "price_differences": [],
             "kitchen_number": null,
             "cancels": null,
             "cancelled_by": null,
             "eet": {
              "status": "accepted",
              "total": {
               "amount": 33700,
               "currency": "CZK"
              },
              "prepaid_issued": null,
              "prepaid_used": null,
              "register_id": "POS-512",
              "sequence": "1001",
              "unit_id": "273",
              "sold_at": "2027-01-15T12:03:18+01:00",
              "pok": "6a1f0c2e-58b3-4d7e-9a41-0f2c7b9d3e5a-03",
              "environment": "production",
              "error": null,
              "warnings": [],
              "deadline_at": "2027-01-17T12:03:18+01:00"
             },
             "shift_closed_at": null
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Účtenky otevřené směny"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     }
    }
   },
   "post": {
    "tags": [
     "Receipts"
    ],
    "operationId": "createReceipt",
    "summary": "Issue a receipt",
    "x-summary-cs": "Vystavit účtenku",
    "x-requires-device": true,
    "x-staff": "optional",
    "x-idempotency": "body-id",
    "description": "A paid receipt. The server prices it, saves it the same way as today's register – as an order of the\nadministration, so the reports, shift closes and exports show it – takes portions and stock, sells and redeems\nvouchers, awards loyalty points and records the sale in EET 2.0.\n\n**Split payments.** The order in the administration keeps one payment method – the one with the largest amount,\ngift vouchers not counted – so the statistics by payment method, the order detail, the Excel, Pohoda and Money\nexports, the tips in the shift close detail and `KitchenTicket.payment_method` show the whole receipt under that\nmethod. The split stays in the receipt (`payments`), in `getPosShift` and in the totals by payment method of the\nshift close. A gift voucher payment is shown in the administration and on the receipt copy with its code masked\n(`ABC-***`).\n\n`id` is your UUID made on the device when the receipt was paid. Sending the same `id` again never creates a\nsecond receipt: you get the first one with `200` (`409 receipt_id_conflict` when the `id` belongs to another\ndevice or number). Send receipts recorded offline later with `offline: true`. A receipt may be up to 7 days old;\none recorded offline is accepted up to 62 days (a register without network over holidays) – then without\ntaking portions and with a note in the action timeline of the administration, because the sale must be recorded\nanyway.\n\n**Who.** The employee signed in on the device (`Profirest-Staff-Token`) with the `pos` or `pos_manager` role.\nWithout a session only an offline receipt is accepted, with `issued_by_id`.\n\n**Prices.** Leave `unit_price` out to take the catalog price at `issued_at`. A different price is accepted only\nfrom a register manager (signed in, `manager_credential`, or `approved_by_id` on an offline receipt) and on a\nreceipt recorded offline or sent more than 10 minutes late – the customer paid what the register showed and\nthe difference is listed in `price_differences`. Otherwise `409 price_changed`: reload the catalog. Manual\ndiscounts and open items need a manager (`403 manager_approval_required`); automatic discounts anybody.\nA voucher sold below its value needs a manager verified now (signed in or `manager_credential`) –\n`approved_by_id` of an offline receipt is not enough. `approved_by_id` and `issued_by_id` are only what the\ndevice says (nobody\nchecked a PIN): an offline receipt with prices other than the catalog, a voucher sale, or manual discounts and\nopen items approved this way is listed in the action timeline of the administration.\n\n**Money.** The payments add up to `totals.total`. With cash, the part paid in cash (the total minus the other\npayments) may be rounded to whole CZK – exactly by that rounding, or not at all; any other difference is\n`payment_amount_mismatch` (the rounding is outside VAT). A tip goes with a cash or card payment and is not part of\nthe total.\n\n**EET 2.0.** When the restaurant records sales, the server signs and sends them – the device needs no\ncertificate. The recorded amount is the cash, card and meal voucher payments with their tips plus the voucher\npayments; vouchers sold are prepaid amounts up to the cash, card and meal voucher payments (tips included). Company\naccount and invoice payments are not recorded (a voucher sold on an invoice neither). The\nresponse carries the EET status; a `pending` sale is sent again automatically until the tax administration\naccepts it – the legal deadline is 48 hours (`eet.deadline_at`); after an outage longer than that it is still\nsent, late.\n",
    "x-description-cs": "Zaplacená účtenka. Server ji spočítá, uloží stejně jako dnešní pokladna – jako objednávku v administraci, takže ji\nukážou přehledy, uzávěrky i exporty –, odečte porce a sklad, prodá a uplatní vouchery, připíše věrnostní body\na zaeviduje tržbu do EET 2.0.\n\n**Dělená platba.** Objednávka v administraci si drží jeden způsob platby – ten s největší částkou, dárkové\nvouchery se nepočítají –, takže statistiky podle platby, detail objednávky, exporty do Excelu, Pohody a Money,\ndýško v detailu uzávěrky i `KitchenTicket.payment_method` ukážou celou účtenku pod tímto způsobem. Rozdělení\nzůstává v účtence (`payments`), v `getPosShift` a v součtech uzávěrky podle způsobu platby. Platba dárkovým\nvoucherem se v administraci a na kopii účtenky ukazuje se zamaskovaným kódem (`ABC-***`).\n\n`id` je vaše UUID vytvořené na zařízení ve chvíli zaplacení. Opakované odeslání stejného `id` nikdy nevytvoří\ndruhou účtenku: dostanete první s `200` (`409 receipt_id_conflict`, když `id` patří jinému zařízení nebo\nčíslu). Účtenky pořízené offline pošlete později s `offline: true`. Účtenka smí být nejvýš 7 dní stará; pořízená\noffline se přijme až do 62 dní (pokladna přes svátky bez sítě) – pak bez odečtení porcí a s upozorněním v Časové\nose akcí v administraci, protože tržba se musí zaevidovat i tak.\n\n**Kdo.** Zaměstnanec přihlášený na zařízení (`Profirest-Staff-Token`) s rolí `pos` nebo `pos_manager`. Bez\nrelace se přijme jen offline účtenka s `issued_by_id`.\n\n**Ceny.** Bez `unit_price` platí cena ze sortimentu v `issued_at`. Jinou cenu server přijme jen od vedoucího\npokladny (přihlášený, `manager_credential`, nebo `approved_by_id` u offline účtenky) a u účtenky pořízené\noffline nebo poslané o víc než 10 minut později – zákazník zaplatil, co ukázala pokladna, a rozdíl je\nv `price_differences`. Jinak `409 price_changed`: načtěte sortiment znovu. Ruční sleva a položka s vlastní\ncenou potřebují vedoucího (`403 manager_approval_required`); automatickou slevu smí kdokoli. Voucher pod\njeho hodnotou prodá jen vedoucí ověřený teď (přihlášený nebo `manager_credential`) – `approved_by_id` offline\núčtenky nestačí. `approved_by_id` a `issued_by_id` jsou jen údaj zařízení (PIN nikdo neověřil): offline účtenka\ns jinou cenou než ceník, s prodejem voucheru nebo s ruční slevou a vlastní položkou schválenou takto se\nukáže v Časové ose akcí v administraci.\n\n**Peníze.** Platby dávají dohromady `totals.total`. Část placenou hotově (celkem bez ostatních plateb) jde\nzaokrouhlit na celé koruny – přesně o to zaokrouhlení, nebo vůbec; jiný rozdíl je `payment_amount_mismatch`\n(zaokrouhlení je mimo DPH). Dýško patří k platbě hotově nebo kartou a do celkové částky se nepočítá.\n\n**EET 2.0.** Když provozovna eviduje tržby, server je podepíše a odešle – zařízení certifikát nepotřebuje.\nEvidovaná tržba jsou platby hotově, kartou a stravenkami s dýškem a platby vouchery; prodané vouchery jsou\nplatby určené k čerpání do výše plateb hotově, kartou a stravenkami (včetně dýška). Platby na firemní účet a na\nfakturu se neevidují (ani voucher prodaný na fakturu). Odpověď nese stav EET; tržba ve\nstavu `pending` se odesílá znovu sama, dokud ji finanční správa nepřijme – zákonná lhůta je 48 hodin\n(`eet.deadline_at`); po delším výpadku se odešle i tak, pozdě.\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReceiptCreate"
       },
       "examples": {
        "cash": {
         "summary": "Cash, 400 CZK for 337 CZK",
         "value": {
          "id": "01a318f0-a0c0-750d-8c36-65b69d55462d",
          "number": 1001,
          "issued_at": "2027-01-15T12:03:18+01:00",
          "table_name": "Stůl 4",
          "order_type": "dine_in",
          "tab_id": "01a318f0-a0c0-7834-8f31-7973aa8bb418",
          "tab_version": 3,
          "items": [
           {
            "product_id": "4567",
            "quantity": 1,
            "course": 1
           },
           {
            "product_id": "4590",
            "quantity": 2
           }
          ],
          "payments": [
           {
            "method": "cash",
            "amount": {
             "amount": 33700,
             "currency": "CZK"
            },
            "tendered": {
             "amount": 40000,
             "currency": "CZK"
            }
           }
          ]
         },
         "x-summary-cs": "Hotově, 400 Kč na 337 Kč"
        },
        "card": {
         "summary": "By card with a tip from the terminal",
         "value": {
          "id": "01a318f0-a0c0-7296-bee5-5e43065310d7",
          "number": 1002,
          "issued_at": "2027-01-15T12:47:05+01:00",
          "table_name": "Stůl 7",
          "items": [
           {
            "product_id": "4567",
            "quantity": 1,
            "course": 1
           },
           {
            "product_id": "4590",
            "quantity": 2
           }
          ],
          "payments": [
           {
            "method": "card",
            "amount": {
             "amount": 33700,
             "currency": "CZK"
            },
            "tip": {
             "amount": 3300,
             "currency": "CZK"
            },
            "tip_source": "terminal_confirmed",
            "terminal": {
             "provider": "csob",
             "transaction_id": "0011245580",
             "card_number_masked": "**** **** **** 4821",
             "auth_code": "A7K2Q9",
             "response_code": "00"
            }
           }
          ]
         },
         "x-summary-cs": "Kartou se spropitným z terminálu"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "This `id` was already issued; the first receipt.",
      "x-description-cs": "Toto `id` už bylo vystavené; první účtenka.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Receipt"
        },
        "examples": {
         "duplicate": {
          "summary": "The same id again – already issued",
          "value": {
           "id": "01a318f0-a0c0-750d-8c36-65b69d55462d",
           "restaurant_id": "123",
           "device_id": "512",
           "number": 1001,
           "kind": "sale",
           "status": "issued",
           "issued_at": "2027-01-15T12:03:18+01:00",
           "received_at": "2027-01-15T12:03:19+01:00",
           "offline": false,
           "issued_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "approved_by": null,
           "table_name": "Stůl 4",
           "order_type": "dine_in",
           "customer_id": null,
           "note": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": 1,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "note": null,
             "course": 1,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             },
             "voucher_code": null
            },
            {
             "id": "2",
             "type": "product",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": 2,
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "21",
             "add_ons": [],
             "note": null,
             "course": 0,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             },
             "voucher_code": null
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": 11405,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2395,
               "currency": "CZK"
              },
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": 17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2132,
               "currency": "CZK"
              },
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "1",
             "method": "cash",
             "amount": {
              "amount": 33700,
              "currency": "CZK"
             },
             "tip": {
              "amount": 0,
              "currency": "CZK"
             },
             "tendered": {
              "amount": 40000,
              "currency": "CZK"
             },
             "change": {
              "amount": 6300,
              "currency": "CZK"
             },
             "voucher_code": null,
             "reference": null,
             "terminal": null
            }
           ],
           "tips": {
            "amount": 0,
            "currency": "CZK"
           },
           "price_differences": [],
           "kitchen_number": null,
           "cancels": null,
           "cancelled_by": null,
           "eet": {
            "status": "accepted",
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "prepaid_issued": null,
            "prepaid_used": null,
            "register_id": "POS-512",
            "sequence": "1001",
            "unit_id": "273",
            "sold_at": "2027-01-15T12:03:18+01:00",
            "pok": "6a1f0c2e-58b3-4d7e-9a41-0f2c7b9d3e5a-03",
            "environment": "production",
            "error": null,
            "warnings": [],
            "deadline_at": "2027-01-17T12:03:18+01:00"
           },
           "shift_closed_at": null
          },
          "x-summary-cs": "Stejné id podruhé – už vystavená"
         }
        }
       }
      }
     },
     "201": {
      "description": "Issued.",
      "x-description-cs": "Vystaveno.",
      "headers": {
       "Location": {
        "$ref": "#/components/headers/Location"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Receipt"
        },
        "examples": {
         "cash": {
          "summary": "An issued receipt with EET 2.0",
          "value": {
           "id": "01a318f0-a0c0-750d-8c36-65b69d55462d",
           "restaurant_id": "123",
           "device_id": "512",
           "number": 1001,
           "kind": "sale",
           "status": "issued",
           "issued_at": "2027-01-15T12:03:18+01:00",
           "received_at": "2027-01-15T12:03:19+01:00",
           "offline": false,
           "issued_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "approved_by": null,
           "table_name": "Stůl 4",
           "order_type": "dine_in",
           "customer_id": null,
           "note": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": 1,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "note": null,
             "course": 1,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             },
             "voucher_code": null
            },
            {
             "id": "2",
             "type": "product",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": 2,
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "21",
             "add_ons": [],
             "note": null,
             "course": 0,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             },
             "voucher_code": null
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": 11405,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2395,
               "currency": "CZK"
              },
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": 17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2132,
               "currency": "CZK"
              },
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "1",
             "method": "cash",
             "amount": {
              "amount": 33700,
              "currency": "CZK"
             },
             "tip": {
              "amount": 0,
              "currency": "CZK"
             },
             "tendered": {
              "amount": 40000,
              "currency": "CZK"
             },
             "change": {
              "amount": 6300,
              "currency": "CZK"
             },
             "voucher_code": null,
             "reference": null,
             "terminal": null
            }
           ],
           "tips": {
            "amount": 0,
            "currency": "CZK"
           },
           "price_differences": [],
           "kitchen_number": null,
           "cancels": null,
           "cancelled_by": null,
           "eet": {
            "status": "accepted",
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "prepaid_issued": null,
            "prepaid_used": null,
            "register_id": "POS-512",
            "sequence": "1001",
            "unit_id": "273",
            "sold_at": "2027-01-15T12:03:18+01:00",
            "pok": "6a1f0c2e-58b3-4d7e-9a41-0f2c7b9d3e5a-03",
            "environment": "production",
            "error": null,
            "warnings": [],
            "deadline_at": "2027-01-17T12:03:18+01:00"
           },
           "shift_closed_at": null
          },
          "x-summary-cs": "Vystavená účtenka s EET 2.0"
         },
         "card": {
          "summary": "Paid by card with a tip",
          "value": {
           "id": "01a318f0-a0c0-7296-bee5-5e43065310d7",
           "restaurant_id": "123",
           "device_id": "512",
           "number": 1002,
           "kind": "sale",
           "status": "issued",
           "issued_at": "2027-01-15T12:47:05+01:00",
           "received_at": "2027-01-15T12:47:06+01:00",
           "offline": false,
           "issued_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "approved_by": null,
           "table_name": "Stůl 7",
           "order_type": "dine_in",
           "customer_id": null,
           "note": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": 1,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "note": null,
             "course": 1,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             },
             "voucher_code": null
            },
            {
             "id": "2",
             "type": "product",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": 2,
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "21",
             "add_ons": [],
             "note": null,
             "course": 0,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             },
             "voucher_code": null
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": 11405,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2395,
               "currency": "CZK"
              },
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": 17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2132,
               "currency": "CZK"
              },
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "1",
             "method": "card",
             "amount": {
              "amount": 33700,
              "currency": "CZK"
             },
             "tip": {
              "amount": 3300,
              "currency": "CZK"
             },
             "tendered": null,
             "change": null,
             "voucher_code": null,
             "reference": null,
             "terminal": {
              "provider": "csob",
              "transaction_id": "0011245580",
              "card_number_masked": "**** **** **** 4821",
              "auth_code": "A7K2Q9"
             }
            }
           ],
           "tips": {
            "amount": 3300,
            "currency": "CZK"
           },
           "price_differences": [],
           "kitchen_number": null,
           "cancels": null,
           "cancelled_by": null,
           "eet": {
            "status": "accepted",
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "prepaid_issued": null,
            "prepaid_used": null,
            "register_id": "POS-512",
            "sequence": "1002",
            "unit_id": "273",
            "sold_at": "2027-01-15T12:47:05+01:00",
            "pok": "0c94d2b7-1e6a-4f3b-8d25-7a9e1c3f5b80-03",
            "environment": "production",
            "error": null,
            "warnings": [],
            "deadline_at": "2027-01-17T12:47:05+01:00"
           },
           "shift_closed_at": null
          },
          "x-summary-cs": "Placeno kartou se spropitným"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "receipt_id_conflict": {
          "summary": "Another receipt has the id (another device or number)",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#receipt_id_conflict",
           "title": "Toto id už má jiná účtenka",
           "status": 409,
           "code": "receipt_id_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Toto id už má jiná účtenka (jiné zařízení nebo číslo)"
         },
         "receipt_number_conflict": {
          "summary": "Another receipt of the device has the number",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#receipt_number_conflict",
           "title": "Toto číslo účtenky zařízení už použilo",
           "status": 409,
           "code": "receipt_number_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": "01a318f0-a0c0-750d-8c36-65b69d55462d",
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Číslo z počítadla zařízení už má jiná účtenka"
         },
         "price_changed": {
          "summary": "The prices changed meanwhile",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#price_changed",
           "title": "Cena se změnila; načtěte sortiment znovu",
           "status": 409,
           "code": "price_changed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/product_id",
             "code": "price_changed",
             "message": "Cena se změnila na 209,00 Kč."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Ceny se mezitím změnily"
         }
        }
       }
      }
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/receipts/{receipt_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReceiptId"
    }
   ],
   "get": {
    "tags": [
     "Receipts"
    ],
    "operationId": "getReceipt",
    "summary": "Get a receipt",
    "x-summary-cs": "Detail účtenky",
    "x-requires-device": true,
    "description": "One receipt or cancellation document that any register of the restaurant issued through this API, with the\ncurrent EET status. Receipts of registers on API v1 answer `404`.\n",
    "x-description-cs": "Jedna účtenka nebo storno doklad, které kterákoli pokladna provozovny vystavila přes toto API, s aktuálním stavem\nEET. Účtenky pokladen na API v1 vrátí `404`.\n",
    "security": [
     {
      "oauth2": [
       "receipts:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The receipt.",
      "x-description-cs": "Účtenka.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Receipt"
        },
        "examples": {
         "receipt": {
          "summary": "A receipt",
          "value": {
           "id": "01a318f0-a0c0-750d-8c36-65b69d55462d",
           "restaurant_id": "123",
           "device_id": "512",
           "number": 1001,
           "kind": "sale",
           "status": "issued",
           "issued_at": "2027-01-15T12:03:18+01:00",
           "received_at": "2027-01-15T12:03:19+01:00",
           "offline": false,
           "issued_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "approved_by": null,
           "table_name": "Stůl 4",
           "order_type": "dine_in",
           "customer_id": null,
           "note": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": 1,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "note": null,
             "course": 1,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             },
             "voucher_code": null
            },
            {
             "id": "2",
             "type": "product",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": 2,
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "21",
             "add_ons": [],
             "note": null,
             "course": 0,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             },
             "voucher_code": null
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": 11405,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2395,
               "currency": "CZK"
              },
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": 17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2132,
               "currency": "CZK"
              },
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "1",
             "method": "cash",
             "amount": {
              "amount": 33700,
              "currency": "CZK"
             },
             "tip": {
              "amount": 0,
              "currency": "CZK"
             },
             "tendered": {
              "amount": 40000,
              "currency": "CZK"
             },
             "change": {
              "amount": 6300,
              "currency": "CZK"
             },
             "voucher_code": null,
             "reference": null,
             "terminal": null
            }
           ],
           "tips": {
            "amount": 0,
            "currency": "CZK"
           },
           "price_differences": [],
           "kitchen_number": null,
           "cancels": null,
           "cancelled_by": null,
           "eet": {
            "status": "accepted",
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "prepaid_issued": null,
            "prepaid_used": null,
            "register_id": "POS-512",
            "sequence": "1001",
            "unit_id": "273",
            "sold_at": "2027-01-15T12:03:18+01:00",
            "pok": "6a1f0c2e-58b3-4d7e-9a41-0f2c7b9d3e5a-03",
            "environment": "production",
            "error": null,
            "warnings": [],
            "deadline_at": "2027-01-17T12:03:18+01:00"
           },
           "shift_closed_at": null
          },
          "x-summary-cs": "Účtenka"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/receipts/{receipt_id}/storno": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReceiptId"
    }
   ],
   "post": {
    "tags": [
     "Receipts"
    ],
    "operationId": "cancelReceipt",
    "summary": "Cancel a receipt",
    "x-summary-cs": "Stornovat účtenku",
    "x-requires-device": true,
    "x-staff": "required",
    "x-idempotency": "body-id",
    "description": "A cancellation document with negative amounts, like today's register: the sale is reversed in the reports,\nvouchers paid with go back to the vouchers, vouchers sold become ready for sale again (only when nothing was\nused from them), loyalty points are taken back, and with `restock` (default) the stock and portions return.\nEET 2.0 records the negative sale at the time of the cancellation.\n\nWho may cancel is set by the restaurant (`getDeviceSettings`, `pos.receipt_cancel_by`). `staff` (default, as\nin API v1): any employee with the `pos` role, the manager's PIN in `manager_credential` is only recorded.\n`manager`: only a register manager – signed in with `pos_manager`, or the manager's PIN or card in\n`manager_credential` (`403 manager_approval_required`). A receipt is cancelled once\n(`409 receipt_already_cancelled`) and the cancellation belongs to the open shift of this device even when the\noriginal receipt is in a closed shift. `id` is your UUID of the cancellation document; the same `id` again\nreturns it with `200`.\n",
    "x-description-cs": "Storno doklad se zápornými částkami jako na dnešní pokladně: tržba se v přehledech odečte, vouchery, kterými\nse platilo, se vrátí na vouchery, prodané vouchery jsou znovu k prodeji (jen když se z nich nic nepoužilo),\nvěrnostní body se odečtou a s `restock` (výchozí) se vrátí sklad i porce. EET 2.0 zaeviduje zápornou tržbu\nv čase storna.\n\nKdo smí stornovat, nastavuje provozovna (`getDeviceSettings`, `pos.receipt_cancel_by`). `staff` (výchozí, jako\nv API v1): kdokoli s rolí `pos`, PIN vedoucího v `manager_credential` se jen zapíše. `manager`: jen vedoucí\npokladny – přihlášený s `pos_manager`, nebo jeho PIN či čip v `manager_credential`\n(`403 manager_approval_required`). Účtenka se stornuje jednou (`409 receipt_already_cancelled`) a storno patří\ndo otevřené směny tohoto zařízení, i když původní účtenka je v uzavřené směně. `id` je vaše UUID storno\ndokladu; stejné `id` znovu ho vrátí s `200`.\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReceiptCancel"
       },
       "examples": {
        "storno": {
         "summary": "A cancellation by the manager",
         "value": {
          "id": "01a318f0-a0c0-70e0-bba9-8720b58925a1",
          "number": 1003,
          "reason": "Chybně namarkováno – patří ke stolu 5",
          "restock": true
         },
         "x-summary-cs": "Storno vedoucím"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "This `id` was already used for the cancellation; the cancellation document.",
      "x-description-cs": "Toto `id` už storno má; storno doklad.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Receipt"
        },
        "examples": {
         "duplicate": {
          "summary": "The same id again",
          "value": {
           "id": "01a318f0-a0c0-70e0-bba9-8720b58925a1",
           "restaurant_id": "123",
           "device_id": "512",
           "number": 1003,
           "kind": "storno",
           "status": "issued",
           "issued_at": "2027-01-15T12:10:44+01:00",
           "received_at": "2027-01-15T12:10:44+01:00",
           "offline": false,
           "issued_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "approved_by": null,
           "table_name": "Stůl 4",
           "order_type": "dine_in",
           "customer_id": null,
           "note": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": -1,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "note": null,
             "course": 1,
             "total": {
              "amount": -19900,
              "currency": "CZK"
             },
             "voucher_code": null
            },
            {
             "id": "2",
             "type": "product",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": -2,
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "21",
             "add_ons": [],
             "note": null,
             "course": 0,
             "total": {
              "amount": -13800,
              "currency": "CZK"
             },
             "voucher_code": null
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": -33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": -33700,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": -11405,
               "currency": "CZK"
              },
              "vat": {
               "amount": -2395,
               "currency": "CZK"
              },
              "total": {
               "amount": -13800,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": -17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": -2132,
               "currency": "CZK"
              },
              "total": {
               "amount": -19900,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "1",
             "method": "cash",
             "amount": {
              "amount": -33700,
              "currency": "CZK"
             },
             "tip": {
              "amount": 0,
              "currency": "CZK"
             },
             "tendered": null,
             "change": null,
             "voucher_code": null,
             "reference": null,
             "terminal": null
            }
           ],
           "tips": {
            "amount": 0,
            "currency": "CZK"
           },
           "price_differences": [],
           "kitchen_number": null,
           "cancels": "01a318f0-a0c0-750d-8c36-65b69d55462d",
           "cancelled_by": null,
           "eet": {
            "status": "accepted",
            "total": {
             "amount": -33700,
             "currency": "CZK"
            },
            "prepaid_issued": null,
            "prepaid_used": null,
            "register_id": "POS-512",
            "sequence": "1003",
            "unit_id": "273",
            "sold_at": "2027-01-15T12:10:44+01:00",
            "pok": "3d7b1a90-6c2e-4f85-b1d3-9e0a7c5f2b46-03",
            "environment": "production",
            "error": null,
            "warnings": [],
            "deadline_at": "2027-01-17T12:10:44+01:00"
           },
           "shift_closed_at": null
          },
          "x-summary-cs": "Stejné id podruhé"
         }
        }
       }
      }
     },
     "201": {
      "description": "Cancelled; the cancellation document.",
      "x-description-cs": "Stornováno; storno doklad.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Receipt"
        },
        "examples": {
         "storno": {
          "summary": "A cancellation document with negative amounts",
          "value": {
           "id": "01a318f0-a0c0-70e0-bba9-8720b58925a1",
           "restaurant_id": "123",
           "device_id": "512",
           "number": 1003,
           "kind": "storno",
           "status": "issued",
           "issued_at": "2027-01-15T12:10:44+01:00",
           "received_at": "2027-01-15T12:10:44+01:00",
           "offline": false,
           "issued_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "approved_by": null,
           "table_name": "Stůl 4",
           "order_type": "dine_in",
           "customer_id": null,
           "note": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": -1,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "note": null,
             "course": 1,
             "total": {
              "amount": -19900,
              "currency": "CZK"
             },
             "voucher_code": null
            },
            {
             "id": "2",
             "type": "product",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": -2,
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "21",
             "add_ons": [],
             "note": null,
             "course": 0,
             "total": {
              "amount": -13800,
              "currency": "CZK"
             },
             "voucher_code": null
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": -33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": -33700,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": -11405,
               "currency": "CZK"
              },
              "vat": {
               "amount": -2395,
               "currency": "CZK"
              },
              "total": {
               "amount": -13800,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": -17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": -2132,
               "currency": "CZK"
              },
              "total": {
               "amount": -19900,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "1",
             "method": "cash",
             "amount": {
              "amount": -33700,
              "currency": "CZK"
             },
             "tip": {
              "amount": 0,
              "currency": "CZK"
             },
             "tendered": null,
             "change": null,
             "voucher_code": null,
             "reference": null,
             "terminal": null
            }
           ],
           "tips": {
            "amount": 0,
            "currency": "CZK"
           },
           "price_differences": [],
           "kitchen_number": null,
           "cancels": "01a318f0-a0c0-750d-8c36-65b69d55462d",
           "cancelled_by": null,
           "eet": {
            "status": "accepted",
            "total": {
             "amount": -33700,
             "currency": "CZK"
            },
            "prepaid_issued": null,
            "prepaid_used": null,
            "register_id": "POS-512",
            "sequence": "1003",
            "unit_id": "273",
            "sold_at": "2027-01-15T12:10:44+01:00",
            "pok": "3d7b1a90-6c2e-4f85-b1d3-9e0a7c5f2b46-03",
            "environment": "production",
            "error": null,
            "warnings": [],
            "deadline_at": "2027-01-17T12:10:44+01:00"
           },
           "shift_closed_at": null
          },
          "x-summary-cs": "Storno doklad se zápornými částkami"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "description": "`insufficient_scope` or `customer_not_verified`; on Profirest's own devices also `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` and – on the\nregister – `manager_approval_required`.\n",
      "x-description-cs": "`insufficient_scope` nebo `customer_not_verified`; na vlastních zařízeních Profirestu také `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` a – na pokladně –\n`manager_approval_required`.\n",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "insufficient_scope": {
          "summary": "The token lacks the scope",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#insufficient_scope",
           "title": "Token nemá potřebné oprávnění",
           "status": 403,
           "code": "insufficient_scope",
           "detail": "Missing scope: orders:write",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Token nemá potřebné oprávnění"
         },
         "manager_approval_required": {
          "summary": "A manager is needed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#manager_approval_required",
           "title": "Tohle musí schválit vedoucí pokladny",
           "status": 403,
           "code": "manager_approval_required",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Je potřeba vedoucí"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "receipt_already_cancelled": {
          "summary": "The receipt is already cancelled",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#receipt_already_cancelled",
           "title": "Účtenka už je stornovaná",
           "status": 409,
           "code": "receipt_already_cancelled",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Účtenka už je stornovaná"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/receipts/{receipt_id}/payment-change": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/ReceiptId"
    }
   ],
   "post": {
    "tags": [
     "Receipts"
    ],
    "operationId": "changeReceiptPayment",
    "summary": "Change the payment of a receipt",
    "x-summary-cs": "Změnit platbu účtenky",
    "x-requires-device": true,
    "x-staff": "required",
    "x-idempotency": "body-id",
    "description": "Changes how an issued receipt was paid, without a cancellation and a new receipt – for example when the\nemployee chose cash but the customer paid by card. The receipt keeps its `id`, number, items, total and\nrounding; only `payments` change, and the shift totals, the cash book, the administration and the reports\nfollow at once. The response is the receipt after the change.\n\nOnly payments in cash, by meal vouchers, to a company account and by invoice change. Card payments and gift\nvoucher payments stay as they are and are not sent: a change from a card would be a refund to the card, which\na register cannot make yet, and a gift voucher returns only with a cancellation (`cancelReceipt`). Send in\n`payments` what paid the rest instead – `cash`, `card` (with `terminal`), `meal_voucher`, `company_account` or\n`invoice` (no `voucher`). The new payments must add up to the same amount and the same tip as the payments\nbeing changed (`422 payment_amount_mismatch`); the tip only moves with the payment. A receipt rounded for\ncash keeps its rounding only with a cash payment of the same part – otherwise cancel it and issue a new one.\nA receipt paid only by card or gift voucher answers `409 receipt_payment_not_changeable`.\n\nUntil the shift close of the receipt (`409 pos_shift_closed` afterwards – the cash was already counted; the\nadministration can still change it). A cancelled receipt does not change (`409 receipt_already_cancelled`),\nnor does a cancellation document. Who may change a payment is set by the restaurant as for a cancellation\n(`getDeviceSettings`, `pos.receipt_cancel_by`; `403 manager_approval_required`). The change goes to the\nTimeline of the administration and an event `receipt.updated` follows.\n\nEET 2.0: cash, card and meal voucher payments record the same sale, so a change among them sends nothing.\nWhen the recorded amount changes (for example cash → invoice), the server sends a negative sale of the former\namount and a new sale, both at the time of the change, under the number of the receipt; `eet` of the receipt\nthen shows the new sale. `id` is your UUID of the change; the same `id` again returns the receipt with `200`\nand changes nothing. Payments equal to the current ones change nothing either.\n",
    "x-description-cs": "Změní, jak se vydaná účtenka zaplatila, bez storna a nové účtenky – třeba když obsluha zvolila hotovost, ale\nzákazník platil kartou. Účtenka si nechá `id`, číslo, položky, celkovou částku i zaokrouhlení; mění se jen\n`payments` a hned se přizpůsobí součty směny, pokladní kniha, administrace i přehledy. Odpověď je účtenka po\nzměně.\n\nMění se jen platby hotově, stravenkami, na firemní účet a fakturou. Platby kartou a dárkovým voucherem\nzůstávají, jak jsou, a neposílají se: změna z karty by byla vrácení peněz na kartu, které pokladna zatím\nneumí, a dárkový voucher vrátí jen storno (`cancelReceipt`). V `payments` pošlete, čím se místo nich zaplatil\nzbytek – `cash`, `card` (s `terminal`), `meal_voucher`, `company_account` nebo `invoice` (ne `voucher`). Nové\nplatby musí dát stejnou částku a stejné dýško jako měněné platby (`422 payment_amount_mismatch`); dýško se jen\npřesune s platbou. Účtenka zaokrouhlená na hotovost si zaokrouhlení nechá jen s platbou hotově za stejnou\nčást – jinak ji stornujte a vystavte novou. Účtenka zaplacená jen kartou nebo dárkovým voucherem vrátí\n`409 receipt_payment_not_changeable`.\n\nJen do uzávěrky směny účtenky (potom `409 pos_shift_closed` – hotovost už je spočítaná; administrace ji změnit\nmůže). Stornovaná účtenka se nemění (`409 receipt_already_cancelled`), storno doklad také ne. Kdo smí platbu\nzměnit, nastavuje provozovna stejně jako u storna (`getDeviceSettings`, `pos.receipt_cancel_by`;\n`403 manager_approval_required`). Změna se zapíše do Časové osy administrace a přijde událost `receipt.updated`.\n\nEET 2.0: platby hotově, kartou a stravenkami evidují stejnou tržbu, takže změna mezi nimi nic neposílá. Když se\nevidovaná částka změní (např. hotově → faktura), server pošle zápornou tržbu dosavadní částky a novou tržbu,\nobě v čase změny, pod číslem účtenky; `eet` účtenky pak ukazuje novou tržbu. `id` je vaše UUID změny; stejné\n`id` znovu vrátí účtenku s `200` a nic nezmění. Platby stejné jako dosavadní také nic nezmění.\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ReceiptPaymentChange"
       },
       "examples": {
        "card": {
         "summary": "The employee chose cash, the customer paid by card",
         "value": {
          "id": "01a318f0-a0c0-7b2e-b422-5663a54604b9",
          "reason": "Omylem hotově, platil kartou",
          "payments": [
           {
            "method": "card",
            "amount": {
             "amount": 33700,
             "currency": "CZK"
            },
            "terminal": {
             "provider": "csob",
             "transaction_id": "0011245611",
             "card_number_masked": "**** **** **** 1187",
             "auth_code": "B3M8T1",
             "response_code": "00"
            }
           }
          ]
         },
         "x-summary-cs": "Obsluha zvolila hotovost, zákazník platil kartou"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The receipt after the change (or unchanged, when this `id` was already used or the payments are the same).",
      "x-description-cs": "Účtenka po změně (nebo beze změny, když toto `id` už změna má nebo jsou platby stejné).",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Receipt"
        },
        "examples": {
         "card": {
          "summary": "The receipt paid by card",
          "value": {
           "id": "01a318f0-a0c0-750d-8c36-65b69d55462d",
           "restaurant_id": "123",
           "device_id": "512",
           "number": 1001,
           "kind": "sale",
           "status": "issued",
           "issued_at": "2027-01-15T12:03:18+01:00",
           "received_at": "2027-01-15T12:03:19+01:00",
           "offline": false,
           "issued_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "approved_by": null,
           "table_name": "Stůl 4",
           "order_type": "dine_in",
           "customer_id": null,
           "note": null,
           "lines": [
            {
             "id": "1",
             "type": "product",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": 1,
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "12",
             "add_ons": [],
             "note": null,
             "course": 1,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             },
             "voucher_code": null
            },
            {
             "id": "2",
             "type": "product",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": 2,
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "catalog_unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "price_source": "catalog",
             "at_employee_price": false,
             "packaging_unit_price": null,
             "vat_rate": "21",
             "add_ons": [],
             "note": null,
             "course": 0,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             },
             "voucher_code": null
            }
           ],
           "discounts": [],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "charges": {
             "amount": 0,
             "currency": "CZK"
            },
            "discounts": {
             "amount": 0,
             "currency": "CZK"
            },
            "rounding": {
             "amount": 0,
             "currency": "CZK"
            },
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": 11405,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2395,
               "currency": "CZK"
              },
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": 17768,
               "currency": "CZK"
              },
              "vat": {
               "amount": 2132,
               "currency": "CZK"
              },
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             }
            ]
           },
           "payments": [
            {
             "id": "1",
             "method": "card",
             "amount": {
              "amount": 33700,
              "currency": "CZK"
             },
             "tip": {
              "amount": 0,
              "currency": "CZK"
             },
             "tendered": null,
             "change": null,
             "voucher_code": null,
             "reference": null,
             "terminal": {
              "provider": "csob",
              "transaction_id": "0011245611",
              "card_number_masked": "**** **** **** 1187",
              "auth_code": "B3M8T1"
             }
            }
           ],
           "tips": {
            "amount": 0,
            "currency": "CZK"
           },
           "price_differences": [],
           "kitchen_number": null,
           "cancels": null,
           "cancelled_by": null,
           "eet": {
            "status": "accepted",
            "total": {
             "amount": 33700,
             "currency": "CZK"
            },
            "prepaid_issued": null,
            "prepaid_used": null,
            "register_id": "POS-512",
            "sequence": "1001",
            "unit_id": "273",
            "sold_at": "2027-01-15T12:03:18+01:00",
            "pok": "6a1f0c2e-58b3-4d7e-9a41-0f2c7b9d3e5a-03",
            "environment": "production",
            "error": null,
            "warnings": [],
            "deadline_at": "2027-01-17T12:03:18+01:00"
           },
           "shift_closed_at": null
          },
          "x-summary-cs": "Účtenka zaplacená kartou"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "receipt_payment_not_changeable": {
          "summary": "The receipt is paid only by card",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#receipt_payment_not_changeable",
           "title": "Platbu této účtenky změnit nejde",
           "status": 409,
           "code": "receipt_payment_not_changeable",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Účtenka je zaplacená jen kartou"
         },
         "pos_shift_closed": {
          "summary": "The shift of the receipt is closed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#pos_shift_closed",
           "title": "Směna účtenky je už uzavřená",
           "status": 409,
           "code": "pos_shift_closed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Směna účtenky je uzavřená"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "payment_amount_mismatch": {
          "summary": "The new payments add up to another amount",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#payment_amount_mismatch",
           "title": "Platby neodpovídají částce k úhradě",
           "status": 422,
           "code": "payment_amount_mismatch",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Nové platby dávají jinou částku"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/pos-shift": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Receipts"
    ],
    "operationId": "getPosShift",
    "summary": "The open shift of this device",
    "x-summary-cs": "Otevřená směna tohoto zařízení",
    "x-requires-device": true,
    "description": "Totals of the receipts and cancellation documents this device issued through this API since its last shift close,\ncomputed by the server, and the cash movements it recorded (`cash_movements`). With `devices` the summary covers\nthe open shifts of more devices of the restaurant – for example a waiter's phone, before the manager closes them\ntogether (`device_ids` of the close). `by_device` and `by_employee` split it per device and per employee who\nissued the receipts: the cash payments and cash tips of an employee are what they hand over. A cancellation counts on the device that issued it, also when the original receipt was\nissued elsewhere. Sales of other devices and of registers on API v1 are not included; only `open_tabs` covers the\nwhole restaurant.\n",
    "x-description-cs": "Součty účtenek a storno dokladů, které toto zařízení vystavilo přes toto API od své poslední uzávěrky, spočítané\nserverem, a pohyby hotovosti, které zapsalo (`cash_movements`). S `devices` souhrn pokryje otevřené směny víc\nzařízení provozovny – třeba telefonu číšníka, než je vedoucí uzavře spolu (`device_ids` uzávěrky). `by_device`\na `by_employee` ho rozdělí po zařízeních a po zaměstnancích, kteří účtenky vystavili: platby hotově a dýško\nv hotovosti zaměstnance jsou to, co odvádí. Storno se počítá zařízení, které ho vystavilo, i když původní účtenka vznikla jinde. Tržby jiných\nzařízení a pokladen na API v1 tu nejsou; celou provozovnu zahrnuje jen `open_tabs`.\n",
    "security": [
     {
      "oauth2": [
       "receipts:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "devices",
      "in": "query",
      "required": false,
      "description": "More devices of the restaurant: `all` (every device with an open shift – receipts or cash movements without\na close) or their IDs separated by commas. This device is always included.\n",
      "x-description-cs": "Další zařízení provozovny: `all` (každé zařízení s otevřenou směnou – účtenky nebo pohyby hotovosti bez\nuzávěrky) nebo jejich ID oddělená čárkou. Toto zařízení je v souhrnu vždy.\n",
      "schema": {
       "type": "string",
       "pattern": "^(all|[1-9][0-9]{0,9}(,[1-9][0-9]{0,9}){0,49})$"
      }
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The open shift.",
      "x-description-cs": "Otevřená směna.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PosShiftSummary"
        },
        "examples": {
         "open": {
          "summary": "The open shift of the register",
          "value": {
           "device_id": "512",
           "opened_at": "2027-01-15T09:55:30+01:00",
           "receipts": {
            "sales": 148,
            "storno": 1
           },
           "totals": {
            "sales": {
             "amount": 4815600,
             "currency": "CZK"
            },
            "storno": {
             "amount": -33700,
             "currency": "CZK"
            },
            "net": {
             "amount": 4781900,
             "currency": "CZK"
            }
           },
           "payments": [
            {
             "method": "cash",
             "amount": {
              "amount": 2069700,
              "currency": "CZK"
             },
             "tips": {
              "amount": 0,
              "currency": "CZK"
             },
             "count": 71
            },
            {
             "method": "card",
             "amount": {
              "amount": 2632500,
              "currency": "CZK"
             },
             "tips": {
              "amount": 21300,
              "currency": "CZK"
             },
             "count": 75
            },
            {
             "method": "meal_voucher",
             "amount": {
              "amount": 79700,
              "currency": "CZK"
             },
             "tips": {
              "amount": 0,
              "currency": "CZK"
             },
             "count": 2
            }
           ],
           "tips": {
            "amount": 21300,
            "currency": "CZK"
           },
           "vat": [
            {
             "rate": "21",
             "base": {
              "amount": 1049256,
              "currency": "CZK"
             },
             "vat": {
              "amount": 220344,
              "currency": "CZK"
             },
             "total": {
              "amount": 1269600,
              "currency": "CZK"
             }
            },
            {
             "rate": "12",
             "base": {
              "amount": 3135982,
              "currency": "CZK"
             },
             "vat": {
              "amount": 376318,
              "currency": "CZK"
             },
             "total": {
              "amount": 3512300,
              "currency": "CZK"
             }
            }
           ],
           "vouchers": {
            "sold": {
             "amount": 100000,
             "currency": "CZK"
            },
            "redeemed": {
             "amount": 50000,
             "currency": "CZK"
            }
           },
           "eet": {
            "pending": 0,
            "rejected": 0
           },
           "open_tabs": {
            "count": 1,
            "total": {
             "amount": 33700,
             "currency": "CZK"
            }
           },
           "cash_movements": {
            "count": 3,
            "deposits": {
             "amount": 200000,
             "currency": "CZK"
            },
            "incomes": {
             "amount": 0,
             "currency": "CZK"
            },
            "withdrawals": {
             "amount": 1500000,
             "currency": "CZK"
            },
            "expenses": {
             "amount": 35000,
             "currency": "CZK"
            },
            "net": {
             "amount": -1335000,
             "currency": "CZK"
            }
           },
           "device_ids": [
            "512"
           ],
           "by_device": [
            {
             "device_id": "512",
             "name": "Pokladna u baru",
             "receipts": {
              "sales": 148,
              "storno": 1
             },
             "net": {
              "amount": 4781900,
              "currency": "CZK"
             },
             "payments": [
              {
               "method": "cash",
               "amount": {
                "amount": 2069700,
                "currency": "CZK"
               },
               "tips": {
                "amount": 0,
                "currency": "CZK"
               },
               "count": 71
              },
              {
               "method": "card",
               "amount": {
                "amount": 2632500,
                "currency": "CZK"
               },
               "tips": {
                "amount": 21300,
                "currency": "CZK"
               },
               "count": 75
              },
              {
               "method": "meal_voucher",
               "amount": {
                "amount": 79700,
                "currency": "CZK"
               },
               "tips": {
                "amount": 0,
                "currency": "CZK"
               },
               "count": 2
              }
             ]
            }
           ],
           "by_employee": [
            {
             "employee": {
              "id": "58",
              "name": "Jana Dvořáková"
             },
             "receipts": {
              "sales": 96,
              "storno": 1
             },
             "net": {
              "amount": 3115600,
              "currency": "CZK"
             },
             "payments": [
              {
               "method": "cash",
               "amount": {
                "amount": 1324700,
                "currency": "CZK"
               },
               "tips": {
                "amount": 0,
                "currency": "CZK"
               },
               "count": 45
              },
              {
               "method": "card",
               "amount": {
                "amount": 1711200,
                "currency": "CZK"
               },
               "tips": {
                "amount": 15800,
                "currency": "CZK"
               },
               "count": 50
              },
              {
               "method": "meal_voucher",
               "amount": {
                "amount": 79700,
                "currency": "CZK"
               },
               "tips": {
                "amount": 0,
                "currency": "CZK"
               },
               "count": 2
              }
             ]
            },
            {
             "employee": {
              "id": "61",
              "name": "Petr Novák"
             },
             "receipts": {
              "sales": 52,
              "storno": 0
             },
             "net": {
              "amount": 1666300,
              "currency": "CZK"
             },
             "payments": [
              {
               "method": "cash",
               "amount": {
                "amount": 745000,
                "currency": "CZK"
               },
               "tips": {
                "amount": 0,
                "currency": "CZK"
               },
               "count": 26
              },
              {
               "method": "card",
               "amount": {
                "amount": 921300,
                "currency": "CZK"
               },
               "tips": {
                "amount": 5500,
                "currency": "CZK"
               },
               "count": 25
              }
             ]
            }
           ]
          },
          "x-summary-cs": "Otevřená směna pokladny"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/pos-shift/close": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Receipts"
    ],
    "operationId": "closePosShift",
    "summary": "Close the shift of this device",
    "x-summary-cs": "Uzávěrka tohoto zařízení",
    "x-requires-device": true,
    "x-staff": "required",
    "x-idempotency": "body-id",
    "description": "Closes the open shift of this device with the totals computed by the server and saves it as a shift close in\nthe administration. With `counted_cash` the response shows the difference against the expected cash (cash\npayments, cash tips and the cash movements of this device). With `device_ids` one close covers the open shifts of\nmore devices of the restaurant (a waiter's phone, a second register) – only a register manager, signed in or with\ntheir PIN or card in `manager_credential`; the expected cash then covers all of them. `id` is your UUID of the close; the same `id` again returns it with `200`. A shift\nwithout receipts cannot be closed (`409 pos_shift_empty`). Tabs still open in the restaurant are in\n`summary.open_tabs` – read `GET …/pos-shift` first and let the employee settle them; the close stores their\ntotal as not paid. Like a close of today's register, it also takes in the item cancellations of tables (pieces\nremoved from tabs after they went to the kitchen) of the whole restaurant that no close has taken yet, from any\nregister.\n",
    "x-description-cs": "Uzavře otevřenou směnu tohoto zařízení se součty spočítanými serverem a uloží ji jako uzávěrku v administraci.\nS `counted_cash` odpověď ukáže rozdíl proti očekávané hotovosti (platby hotově, dýško v hotovosti a pohyby\nhotovosti zařízení). S `device_ids` jedna uzávěrka pokryje otevřené směny víc zařízení provozovny (telefon\nčíšníka, druhou pokladnu) – jen vedoucí pokladny, přihlášený nebo svým PINem či čipem v `manager_credential`;\nočekávaná hotovost pak zahrne všechna. `id` je\nvaše UUID uzávěrky; stejné `id` znovu ji vrátí s `200`. Směnu bez účtenek uzavřít nejde (`409 pos_shift_empty`).\nÚčty stolů, které jsou v provozovně ještě otevřené, jsou v `summary.open_tabs` – načtěte nejdřív\n`GET …/pos-shift` a nechte zaměstnance je vyřídit; uzávěrka uloží jejich součet jako nezaplacený. Stejně jako\nuzávěrka dnešní pokladny zahrne i storna položek stolů (kusy odebrané z účtů poté, co šly do kuchyně) celé\nprovozovny, které ještě žádná uzávěrka nezahrnula, z kterékoli pokladny.\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PosShiftCloseRequest"
       },
       "examples": {
        "close": {
         "summary": "Closing with the cash counted",
         "value": {
          "id": "01a318f0-a0c0-7ce8-9a4a-c5d2d2497f33",
          "counted_cash": {
           "amount": 734300,
           "currency": "CZK"
          },
          "note": "Chybí 4 Kč."
         },
         "x-summary-cs": "Uzávěrka s přepočítanou hotovostí"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "This `id` was already used; the close.",
      "x-description-cs": "Toto `id` už uzávěrka má; uzávěrka.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PosShiftClose"
        },
        "examples": {
         "default": {
          "value": {
           "id": "01a318f0-a0c0-7031-8216-27bad8f984d8",
           "device_id": "512",
           "closed_at": "2027-01-15T22:15:40+01:00",
           "closed_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "summary": {
            "device_id": "512",
            "opened_at": "2027-01-15T11:48:02+01:00",
            "receipts": {
             "sales": 1,
             "storno": 1
            },
            "totals": {
             "sales": {
              "amount": 10000,
              "currency": "CZK"
             },
             "storno": {
              "amount": 10000,
              "currency": "CZK"
             },
             "net": {
              "amount": 10000,
              "currency": "CZK"
             }
            },
            "payments": [
             {
              "method": "cash",
              "amount": {
               "amount": 10000,
               "currency": "CZK"
              },
              "tips": {
               "amount": 10000,
               "currency": "CZK"
              },
              "count": 1
             }
            ],
            "tips": {
             "amount": 10000,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "12",
              "base": {
               "amount": 10000,
               "currency": "CZK"
              },
              "vat": {
               "amount": 10000,
               "currency": "CZK"
              },
              "total": {
               "amount": 10000,
               "currency": "CZK"
              }
             }
            ],
            "vouchers": {
             "sold": {
              "amount": 10000,
              "currency": "CZK"
             },
             "redeemed": {
              "amount": 10000,
              "currency": "CZK"
             }
            },
            "eet": {
             "pending": 1,
             "rejected": 1
            },
            "open_tabs": {
             "count": 1,
             "total": {
              "amount": 10000,
              "currency": "CZK"
             }
            },
            "cash_movements": {
             "count": 1,
             "deposits": {
              "amount": 10000,
              "currency": "CZK"
             },
             "incomes": {
              "amount": 10000,
              "currency": "CZK"
             },
             "withdrawals": {
              "amount": 10000,
              "currency": "CZK"
             },
             "expenses": {
              "amount": 10000,
              "currency": "CZK"
             },
             "net": {
              "amount": 10000,
              "currency": "CZK"
             }
            },
            "device_ids": [
             "20330"
            ],
            "by_device": [
             {
              "device_id": "512",
              "name": "Pokladna u baru",
              "receipts": {
               "sales": 1,
               "storno": 1
              },
              "net": {
               "amount": 10000,
               "currency": "CZK"
              },
              "payments": [
               {
                "method": "cash",
                "amount": {
                 "amount": 10000,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 10000,
                 "currency": "CZK"
                },
                "count": 1
               }
              ]
             }
            ],
            "by_employee": [
             {
              "employee": {
               "id": "58",
               "name": "Jana Dvořáková"
              },
              "receipts": {
               "sales": 1,
               "storno": 1
              },
              "net": {
               "amount": 10000,
               "currency": "CZK"
              },
              "payments": [
               {
                "method": "cash",
                "amount": {
                 "amount": 10000,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 10000,
                 "currency": "CZK"
                },
                "count": 1
               }
              ]
             }
            ]
           },
           "cash_expected": {
            "amount": 10000,
            "currency": "CZK"
           },
           "counted_cash": {
            "amount": 10000,
            "currency": "CZK"
           },
           "cash_difference": {
            "amount": 10000,
            "currency": "CZK"
           },
           "note": null
          }
         }
        }
       }
      }
     },
     "201": {
      "description": "Closed.",
      "x-description-cs": "Uzavřeno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PosShiftClose"
        },
        "examples": {
         "closed": {
          "summary": "The closed shift",
          "value": {
           "id": "01a318f0-a0c0-7ce8-9a4a-c5d2d2497f33",
           "device_id": "512",
           "closed_at": "2027-01-15T22:15:40+01:00",
           "closed_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "summary": {
            "device_id": "512",
            "opened_at": "2027-01-15T09:55:30+01:00",
            "receipts": {
             "sales": 148,
             "storno": 1
            },
            "totals": {
             "sales": {
              "amount": 4815600,
              "currency": "CZK"
             },
             "storno": {
              "amount": -33700,
              "currency": "CZK"
             },
             "net": {
              "amount": 4781900,
              "currency": "CZK"
             }
            },
            "payments": [
             {
              "method": "cash",
              "amount": {
               "amount": 2069700,
               "currency": "CZK"
              },
              "tips": {
               "amount": 0,
               "currency": "CZK"
              },
              "count": 71
             },
             {
              "method": "card",
              "amount": {
               "amount": 2632500,
               "currency": "CZK"
              },
              "tips": {
               "amount": 21300,
               "currency": "CZK"
              },
              "count": 75
             },
             {
              "method": "meal_voucher",
              "amount": {
               "amount": 79700,
               "currency": "CZK"
              },
              "tips": {
               "amount": 0,
               "currency": "CZK"
              },
              "count": 2
             }
            ],
            "tips": {
             "amount": 21300,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": 1049256,
               "currency": "CZK"
              },
              "vat": {
               "amount": 220344,
               "currency": "CZK"
              },
              "total": {
               "amount": 1269600,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": 3135982,
               "currency": "CZK"
              },
              "vat": {
               "amount": 376318,
               "currency": "CZK"
              },
              "total": {
               "amount": 3512300,
               "currency": "CZK"
              }
             }
            ],
            "vouchers": {
             "sold": {
              "amount": 100000,
              "currency": "CZK"
             },
             "redeemed": {
              "amount": 50000,
              "currency": "CZK"
             }
            },
            "eet": {
             "pending": 0,
             "rejected": 0
            },
            "open_tabs": {
             "count": 1,
             "total": {
              "amount": 33700,
              "currency": "CZK"
             }
            },
            "cash_movements": {
             "count": 3,
             "deposits": {
              "amount": 200000,
              "currency": "CZK"
             },
             "incomes": {
              "amount": 0,
              "currency": "CZK"
             },
             "withdrawals": {
              "amount": 1500000,
              "currency": "CZK"
             },
             "expenses": {
              "amount": 35000,
              "currency": "CZK"
             },
             "net": {
              "amount": -1335000,
              "currency": "CZK"
             }
            },
            "device_ids": [
             "512"
            ],
            "by_device": [
             {
              "device_id": "512",
              "name": "Pokladna u baru",
              "receipts": {
               "sales": 148,
               "storno": 1
              },
              "net": {
               "amount": 4781900,
               "currency": "CZK"
              },
              "payments": [
               {
                "method": "cash",
                "amount": {
                 "amount": 2069700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 71
               },
               {
                "method": "card",
                "amount": {
                 "amount": 2632500,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 21300,
                 "currency": "CZK"
                },
                "count": 75
               },
               {
                "method": "meal_voucher",
                "amount": {
                 "amount": 79700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 2
               }
              ]
             }
            ],
            "by_employee": [
             {
              "employee": {
               "id": "58",
               "name": "Jana Dvořáková"
              },
              "receipts": {
               "sales": 96,
               "storno": 1
              },
              "net": {
               "amount": 3115600,
               "currency": "CZK"
              },
              "payments": [
               {
                "method": "cash",
                "amount": {
                 "amount": 1324700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 45
               },
               {
                "method": "card",
                "amount": {
                 "amount": 1711200,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 15800,
                 "currency": "CZK"
                },
                "count": 50
               },
               {
                "method": "meal_voucher",
                "amount": {
                 "amount": 79700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 2
               }
              ]
             },
             {
              "employee": {
               "id": "61",
               "name": "Petr Novák"
              },
              "receipts": {
               "sales": 52,
               "storno": 0
              },
              "net": {
               "amount": 1666300,
               "currency": "CZK"
              },
              "payments": [
               {
                "method": "cash",
                "amount": {
                 "amount": 745000,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 26
               },
               {
                "method": "card",
                "amount": {
                 "amount": 921300,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 5500,
                 "currency": "CZK"
                },
                "count": 25
               }
              ]
             }
            ]
           },
           "cash_expected": {
            "amount": 734700,
            "currency": "CZK"
           },
           "counted_cash": {
            "amount": 734300,
            "currency": "CZK"
           },
           "cash_difference": {
            "amount": -400,
            "currency": "CZK"
           },
           "note": "Chybí 4 Kč."
          },
          "x-summary-cs": "Uzavřená směna"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "pos_shift_empty": {
          "summary": "There is nothing in the shift",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#pos_shift_empty",
           "title": "Ve směně není co uzavřít",
           "status": 409,
           "code": "pos_shift_empty",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Ve směně nic není"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/pos-shifts": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Receipts"
    ],
    "operationId": "listPosShifts",
    "summary": "List closed shifts",
    "x-summary-cs": "Seznam uzavřených směn",
    "x-requires-device": true,
    "description": "Shift closes of the restaurant exactly as `closePosShift` returned them – what the server summed, also the API v1\ndocuments taken over by `legacy_receipt_ids` – the last closed first. By default only the closes made on the\ncalling device; `device=all` for every device. The receipts of one close are in `listReceipts?shift_id=`.\nSince 26.11.26.\n",
    "x-description-cs": "Uzávěrky provozovny přesně tak, jak je vrátil `closePosShift` – co server sečetl, i s doklady z API v1\npřevzatými přes `legacy_receipt_ids` – naposledy uzavřené první. Bez filtru jen uzávěrky provedené na volajícím\nzařízení; `device=all` všech zařízení. Účtenky jedné uzávěrky jsou v `listReceipts?shift_id=`. Od 26.11.26.\n",
    "security": [
     {
      "oauth2": [
       "receipts:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "device",
      "in": "query",
      "required": false,
      "description": "`this` – closes made on the calling device (default), `all` – of every device of the restaurant.",
      "x-description-cs": "`this` – uzávěrky provedené na volajícím zařízení (výchozí), `all` – všech zařízení provozovny.",
      "schema": {
       "type": "string",
       "enum": [
        "this",
        "all"
       ],
       "default": "this"
      },
      "example": "this"
     },
     {
      "name": "since",
      "in": "query",
      "required": false,
      "description": "Closed at or after this instant.",
      "x-description-cs": "Uzavřené v tomto okamžiku nebo později.",
      "schema": {
       "$ref": "#/components/schemas/Timestamp"
      }
     },
     {
      "name": "until",
      "in": "query",
      "required": false,
      "description": "Closed before this instant.",
      "x-description-cs": "Uzavřené před tímto okamžikem.",
      "schema": {
       "$ref": "#/components/schemas/Timestamp"
      }
     },
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "One page of shift closes.",
      "x-description-cs": "Jedna stránka uzávěrek.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PosShiftClosePage"
        },
        "examples": {
         "closed": {
          "summary": "The closes of this register",
          "value": {
           "data": [
            {
             "id": "01a318f0-a0c0-7ce8-9a4a-c5d2d2497f33",
             "device_id": "512",
             "closed_at": "2027-01-15T22:15:40+01:00",
             "closed_by": {
              "id": "61",
              "name": "Petr Novák"
             },
             "summary": {
              "device_id": "512",
              "opened_at": "2027-01-15T09:55:30+01:00",
              "receipts": {
               "sales": 148,
               "storno": 1
              },
              "totals": {
               "sales": {
                "amount": 4815600,
                "currency": "CZK"
               },
               "storno": {
                "amount": -33700,
                "currency": "CZK"
               },
               "net": {
                "amount": 4781900,
                "currency": "CZK"
               }
              },
              "payments": [
               {
                "method": "cash",
                "amount": {
                 "amount": 2069700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 71
               },
               {
                "method": "card",
                "amount": {
                 "amount": 2632500,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 21300,
                 "currency": "CZK"
                },
                "count": 75
               },
               {
                "method": "meal_voucher",
                "amount": {
                 "amount": 79700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 2
               }
              ],
              "tips": {
               "amount": 21300,
               "currency": "CZK"
              },
              "vat": [
               {
                "rate": "21",
                "base": {
                 "amount": 1049256,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 220344,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 1269600,
                 "currency": "CZK"
                }
               },
               {
                "rate": "12",
                "base": {
                 "amount": 3135982,
                 "currency": "CZK"
                },
                "vat": {
                 "amount": 376318,
                 "currency": "CZK"
                },
                "total": {
                 "amount": 3512300,
                 "currency": "CZK"
                }
               }
              ],
              "vouchers": {
               "sold": {
                "amount": 100000,
                "currency": "CZK"
               },
               "redeemed": {
                "amount": 50000,
                "currency": "CZK"
               }
              },
              "eet": {
               "pending": 0,
               "rejected": 0
              },
              "open_tabs": {
               "count": 1,
               "total": {
                "amount": 33700,
                "currency": "CZK"
               }
              },
              "cash_movements": {
               "count": 3,
               "deposits": {
                "amount": 200000,
                "currency": "CZK"
               },
               "incomes": {
                "amount": 0,
                "currency": "CZK"
               },
               "withdrawals": {
                "amount": 1500000,
                "currency": "CZK"
               },
               "expenses": {
                "amount": 35000,
                "currency": "CZK"
               },
               "net": {
                "amount": -1335000,
                "currency": "CZK"
               }
              },
              "device_ids": [
               "512"
              ],
              "by_device": [
               {
                "device_id": "512",
                "name": "Pokladna u baru",
                "receipts": {
                 "sales": 148,
                 "storno": 1
                },
                "net": {
                 "amount": 4781900,
                 "currency": "CZK"
                },
                "payments": [
                 {
                  "method": "cash",
                  "amount": {
                   "amount": 2069700,
                   "currency": "CZK"
                  },
                  "tips": {
                   "amount": 0,
                   "currency": "CZK"
                  },
                  "count": 71
                 },
                 {
                  "method": "card",
                  "amount": {
                   "amount": 2632500,
                   "currency": "CZK"
                  },
                  "tips": {
                   "amount": 21300,
                   "currency": "CZK"
                  },
                  "count": 75
                 },
                 {
                  "method": "meal_voucher",
                  "amount": {
                   "amount": 79700,
                   "currency": "CZK"
                  },
                  "tips": {
                   "amount": 0,
                   "currency": "CZK"
                  },
                  "count": 2
                 }
                ]
               }
              ],
              "by_employee": [
               {
                "employee": {
                 "id": "58",
                 "name": "Jana Dvořáková"
                },
                "receipts": {
                 "sales": 96,
                 "storno": 1
                },
                "net": {
                 "amount": 3115600,
                 "currency": "CZK"
                },
                "payments": [
                 {
                  "method": "cash",
                  "amount": {
                   "amount": 1324700,
                   "currency": "CZK"
                  },
                  "tips": {
                   "amount": 0,
                   "currency": "CZK"
                  },
                  "count": 45
                 },
                 {
                  "method": "card",
                  "amount": {
                   "amount": 1711200,
                   "currency": "CZK"
                  },
                  "tips": {
                   "amount": 15800,
                   "currency": "CZK"
                  },
                  "count": 50
                 },
                 {
                  "method": "meal_voucher",
                  "amount": {
                   "amount": 79700,
                   "currency": "CZK"
                  },
                  "tips": {
                   "amount": 0,
                   "currency": "CZK"
                  },
                  "count": 2
                 }
                ]
               },
               {
                "employee": {
                 "id": "61",
                 "name": "Petr Novák"
                },
                "receipts": {
                 "sales": 52,
                 "storno": 0
                },
                "net": {
                 "amount": 1666300,
                 "currency": "CZK"
                },
                "payments": [
                 {
                  "method": "cash",
                  "amount": {
                   "amount": 745000,
                   "currency": "CZK"
                  },
                  "tips": {
                   "amount": 0,
                   "currency": "CZK"
                  },
                  "count": 26
                 },
                 {
                  "method": "card",
                  "amount": {
                   "amount": 921300,
                   "currency": "CZK"
                  },
                  "tips": {
                   "amount": 5500,
                   "currency": "CZK"
                  },
                  "count": 25
                 }
                ]
               }
              ]
             },
             "cash_expected": {
              "amount": 734700,
              "currency": "CZK"
             },
             "counted_cash": {
              "amount": 734300,
              "currency": "CZK"
             },
             "cash_difference": {
              "amount": -400,
              "currency": "CZK"
             },
             "note": "Chybí 4 Kč."
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Uzávěrky této pokladny"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/pos-shifts/{shift_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "shift_id",
     "in": "path",
     "required": true,
     "description": "`PosShiftClose.id` – the UUID the device sent in `closePosShift`.",
     "x-description-cs": "`PosShiftClose.id` – UUID, které zařízení poslalo v `closePosShift`.",
     "schema": {
      "type": "string",
      "format": "uuid"
     },
     "example": "01a318f0-a0c0-7ce8-9a4a-c5d2d2497f33"
    }
   ],
   "get": {
    "tags": [
     "Receipts"
    ],
    "operationId": "getPosShiftClose",
    "summary": "A closed shift",
    "x-summary-cs": "Uzavřená směna",
    "x-requires-device": true,
    "description": "One shift close of the restaurant, made on any of its devices, exactly as `closePosShift` returned it.\nSince 26.11.26.\n",
    "x-description-cs": "Jedna uzávěrka provozovny, provedená na kterémkoli jejím zařízení, přesně tak, jak ji vrátil `closePosShift`.\nOd 26.11.26.\n",
    "security": [
     {
      "oauth2": [
       "receipts:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The shift close.",
      "x-description-cs": "Uzávěrka.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PosShiftClose"
        },
        "examples": {
         "closed": {
          "summary": "The closed shift",
          "value": {
           "id": "01a318f0-a0c0-7ce8-9a4a-c5d2d2497f33",
           "device_id": "512",
           "closed_at": "2027-01-15T22:15:40+01:00",
           "closed_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "summary": {
            "device_id": "512",
            "opened_at": "2027-01-15T09:55:30+01:00",
            "receipts": {
             "sales": 148,
             "storno": 1
            },
            "totals": {
             "sales": {
              "amount": 4815600,
              "currency": "CZK"
             },
             "storno": {
              "amount": -33700,
              "currency": "CZK"
             },
             "net": {
              "amount": 4781900,
              "currency": "CZK"
             }
            },
            "payments": [
             {
              "method": "cash",
              "amount": {
               "amount": 2069700,
               "currency": "CZK"
              },
              "tips": {
               "amount": 0,
               "currency": "CZK"
              },
              "count": 71
             },
             {
              "method": "card",
              "amount": {
               "amount": 2632500,
               "currency": "CZK"
              },
              "tips": {
               "amount": 21300,
               "currency": "CZK"
              },
              "count": 75
             },
             {
              "method": "meal_voucher",
              "amount": {
               "amount": 79700,
               "currency": "CZK"
              },
              "tips": {
               "amount": 0,
               "currency": "CZK"
              },
              "count": 2
             }
            ],
            "tips": {
             "amount": 21300,
             "currency": "CZK"
            },
            "vat": [
             {
              "rate": "21",
              "base": {
               "amount": 1049256,
               "currency": "CZK"
              },
              "vat": {
               "amount": 220344,
               "currency": "CZK"
              },
              "total": {
               "amount": 1269600,
               "currency": "CZK"
              }
             },
             {
              "rate": "12",
              "base": {
               "amount": 3135982,
               "currency": "CZK"
              },
              "vat": {
               "amount": 376318,
               "currency": "CZK"
              },
              "total": {
               "amount": 3512300,
               "currency": "CZK"
              }
             }
            ],
            "vouchers": {
             "sold": {
              "amount": 100000,
              "currency": "CZK"
             },
             "redeemed": {
              "amount": 50000,
              "currency": "CZK"
             }
            },
            "eet": {
             "pending": 0,
             "rejected": 0
            },
            "open_tabs": {
             "count": 1,
             "total": {
              "amount": 33700,
              "currency": "CZK"
             }
            },
            "cash_movements": {
             "count": 3,
             "deposits": {
              "amount": 200000,
              "currency": "CZK"
             },
             "incomes": {
              "amount": 0,
              "currency": "CZK"
             },
             "withdrawals": {
              "amount": 1500000,
              "currency": "CZK"
             },
             "expenses": {
              "amount": 35000,
              "currency": "CZK"
             },
             "net": {
              "amount": -1335000,
              "currency": "CZK"
             }
            },
            "device_ids": [
             "512"
            ],
            "by_device": [
             {
              "device_id": "512",
              "name": "Pokladna u baru",
              "receipts": {
               "sales": 148,
               "storno": 1
              },
              "net": {
               "amount": 4781900,
               "currency": "CZK"
              },
              "payments": [
               {
                "method": "cash",
                "amount": {
                 "amount": 2069700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 71
               },
               {
                "method": "card",
                "amount": {
                 "amount": 2632500,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 21300,
                 "currency": "CZK"
                },
                "count": 75
               },
               {
                "method": "meal_voucher",
                "amount": {
                 "amount": 79700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 2
               }
              ]
             }
            ],
            "by_employee": [
             {
              "employee": {
               "id": "58",
               "name": "Jana Dvořáková"
              },
              "receipts": {
               "sales": 96,
               "storno": 1
              },
              "net": {
               "amount": 3115600,
               "currency": "CZK"
              },
              "payments": [
               {
                "method": "cash",
                "amount": {
                 "amount": 1324700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 45
               },
               {
                "method": "card",
                "amount": {
                 "amount": 1711200,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 15800,
                 "currency": "CZK"
                },
                "count": 50
               },
               {
                "method": "meal_voucher",
                "amount": {
                 "amount": 79700,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 2
               }
              ]
             },
             {
              "employee": {
               "id": "61",
               "name": "Petr Novák"
              },
              "receipts": {
               "sales": 52,
               "storno": 0
              },
              "net": {
               "amount": 1666300,
               "currency": "CZK"
              },
              "payments": [
               {
                "method": "cash",
                "amount": {
                 "amount": 745000,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 0,
                 "currency": "CZK"
                },
                "count": 26
               },
               {
                "method": "card",
                "amount": {
                 "amount": 921300,
                 "currency": "CZK"
                },
                "tips": {
                 "amount": 5500,
                 "currency": "CZK"
                },
                "count": 25
               }
              ]
             }
            ]
           },
           "cash_expected": {
            "amount": 734700,
            "currency": "CZK"
           },
           "counted_cash": {
            "amount": 734300,
            "currency": "CZK"
           },
           "cash_difference": {
            "amount": -400,
            "currency": "CZK"
           },
           "note": "Chybí 4 Kč."
          },
          "x-summary-cs": "Uzavřená směna"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/cash-movements": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Receipts"
    ],
    "operationId": "createCashMovement",
    "summary": "Record a deposit, a withdrawal or an expense of cash",
    "x-summary-cs": "Zapsat vklad, výběr nebo výdaj hotovosti",
    "x-requires-device": true,
    "x-staff": "required",
    "x-idempotency": "body-id",
    "description": "Records money that went into or out of the drawer without a receipt into the restaurant's cash book – the same\nbook the administration keeps (Statistics → Cash book) and exports to the Cash agenda of Pohoda: `deposit`\n(change for the shift, a top-up), `income` (other cash received), `withdrawal` (taken to the bank or to the\nowner), `expense` (paid from the drawer – shopping, a supplier) and `opening` (the opening balance that starts\nthe book, once per restaurant). The amount is always positive; the kind gives the direction. A withdrawal, an\nexpense and the opening balance are recorded by a register manager – signed in with `pos_manager`, or with\ntheir PIN or card in `manager_credential`. Every movement except the opening balance needs a `note` saying what\nit was for.\n\nThe cash book is kept for the restaurant, not for the device: it counts the cash receipts of all registers by\nitself. The movements this device recorded since its last close are in `GET …/pos-shift` (`cash_movements`)\nand in the expected cash of `POST …/pos-shift/close`. A movement is not a sale and does not go to EET. The book\nmust have started (`409 cash_book_not_started`); `occurred_at` may be up to 7 days back (a register catching up\nafter an outage), never before the opening balance. `id` is your UUID of the movement; the same `id` again\nreturns it with `200`. A movement recorded by mistake is deleted in the administration.\n",
    "x-description-cs": "Zapíše peníze, které přišly do kasy nebo z ní odešly mimo účtenky, do pokladní knihy provozovny – téže, kterou\nvede administrace (Statistiky → Pokladní kniha) a exportuje do agendy Pokladna v Pohodě: `deposit` (vklad –\ndrobné na směnu, doplnění), `income` (jiný příjem hotovosti), `withdrawal` (výběr – odvod do banky, předání\nmajiteli), `expense` (výdaj z kasy – nákup, platba dodavateli) a `opening` (počáteční stav, kterým kniha\nzačíná, jednou za provozovnu). Částka je vždy kladná, směr dává druh. Výběr, výdaj a počáteční stav zapisuje\nvedoucí pokladny – přihlášený s `pos_manager`, nebo svým PINem či čipem v `manager_credential`. Každý pohyb\nkromě počátečního stavu potřebuje `note`, o co šlo.\n\nPokladní kniha se vede za provozovnu, ne za zařízení: hotovost za účtenky všech pokladen počítá sama. Pohyby,\nkteré toto zařízení zapsalo od své poslední uzávěrky, jsou v `GET …/pos-shift` (`cash_movements`) a v očekávané\nhotovosti `POST …/pos-shift/close`. Pohyb není tržba a do EET nejde. Kniha musí mít počáteční stav\n(`409 cash_book_not_started`); `occurred_at` smí být až 7 dní zpátky (pokladna dohání výpadek), nikdy před\npočátečním stavem. `id` je vaše UUID pohybu; stejné `id` znovu ho vrátí s `200`. Pohyb zapsaný omylem se maže\nv administraci.\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CashMovementInput"
       },
       "examples": {
        "withdrawal": {
         "summary": "Money to the bank – the manager signed in",
         "value": {
          "id": "01a318f0-a0c0-7f0d-91ef-e936a0196e90",
          "kind": "withdrawal",
          "amount": {
           "amount": 1500000,
           "currency": "CZK"
          },
          "note": "Odvod tržby do banky",
          "document": null,
          "occurred_at": null,
          "manager_credential": null
         },
         "x-summary-cs": "Odvod do banky – přihlášený vedoucí"
        },
        "expense": {
         "summary": "A purchase from the drawer approved with the manager's PIN",
         "value": {
          "id": "01a318f0-a0c0-75b8-b868-9f9ca22f3945",
          "kind": "expense",
          "amount": {
           "amount": 35000,
           "currency": "CZK"
          },
          "note": "Citrony a máta – Albert",
          "document": "P-2231",
          "occurred_at": null,
          "manager_credential": {
           "method": "pin",
           "secret": "4831",
           "employee_id": null
          }
         },
         "x-summary-cs": "Nákup z kasy se schválením PINem vedoucího"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "This `id` was already used; the movement.",
      "x-description-cs": "Toto `id` už pohyb má; pohyb.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CashMovement"
        },
        "examples": {
         "duplicate": {
          "summary": "The same id again",
          "value": {
           "id": "01a318f0-a0c0-7f0d-91ef-e936a0196e90",
           "number": "8812",
           "kind": "withdrawal",
           "amount": {
            "amount": 1500000,
            "currency": "CZK"
           },
           "note": "Odvod tržby do banky",
           "document": null,
           "occurred_at": "2027-01-15T16:05:12+01:00",
           "recorded_at": "2027-01-15T16:05:12+01:00",
           "recorded_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "approved_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "device_id": "512"
          },
          "x-summary-cs": "Stejné id podruhé"
         }
        }
       }
      }
     },
     "201": {
      "description": "Recorded in the cash book.",
      "x-description-cs": "Zapsáno do pokladní knihy.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CashMovement"
        },
        "examples": {
         "withdrawal": {
          "summary": "A withdrawal recorded in the cash book",
          "value": {
           "id": "01a318f0-a0c0-7f0d-91ef-e936a0196e90",
           "number": "8812",
           "kind": "withdrawal",
           "amount": {
            "amount": 1500000,
            "currency": "CZK"
           },
           "note": "Odvod tržby do banky",
           "document": null,
           "occurred_at": "2027-01-15T16:05:12+01:00",
           "recorded_at": "2027-01-15T16:05:12+01:00",
           "recorded_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "approved_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "device_id": "512"
          },
          "x-summary-cs": "Výběr zapsaný do pokladní knihy"
         },
         "expense": {
          "summary": "An expense approved by the manager",
          "value": {
           "id": "01a318f0-a0c0-75b8-b868-9f9ca22f3945",
           "number": "8813",
           "kind": "expense",
           "amount": {
            "amount": 35000,
            "currency": "CZK"
           },
           "note": "Citrony a máta – Albert",
           "document": "P-2231",
           "occurred_at": "2027-01-15T17:40:05+01:00",
           "recorded_at": "2027-01-15T17:40:05+01:00",
           "recorded_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "approved_by": {
            "id": "61",
            "name": "Petr Novák"
           },
           "device_id": "512"
          },
          "x-summary-cs": "Výdaj schválený vedoucím"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "description": "`insufficient_scope` or `customer_not_verified`; on Profirest's own devices also `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` and – on the\nregister – `manager_approval_required`.\n",
      "x-description-cs": "`insufficient_scope` nebo `customer_not_verified`; na vlastních zařízeních Profirestu také `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` a – na pokladně –\n`manager_approval_required`.\n",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "insufficient_scope": {
          "summary": "The token lacks the scope",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#insufficient_scope",
           "title": "Token nemá potřebné oprávnění",
           "status": 403,
           "code": "insufficient_scope",
           "detail": "Missing scope: orders:write",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Token nemá potřebné oprávnění"
         },
         "manager_approval_required": {
          "summary": "A withdrawal without a manager",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#manager_approval_required",
           "title": "Tohle musí schválit vedoucí pokladny",
           "status": 403,
           "code": "manager_approval_required",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Výběr bez vedoucího"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "cash_book_not_started": {
          "summary": "A book without an opening balance",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#cash_book_not_started",
           "title": "Pokladní kniha ještě nezačala",
           "status": 409,
           "code": "cash_book_not_started",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Kniha bez počátečního stavu"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/cash-book": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Restaurants"
    ],
    "operationId": "getCashBook",
    "summary": "Cash book",
    "x-summary-cs": "Pokladní kniha",
    "description": "The cash book of the restaurant for the days, as Statistics → Cash book in the administration shows it: the\ncash at the start and the end of every day and now, the cash receipts and cash tips of the day (counted from the\norders paid in cash – card payment at handover not, kitchen tickets before payment not) and the movements\nrecorded by hand – deposits, withdrawals, expenses, other income, the opening balance and the differences found\nby cash checks – from the administration and from registers (`createCashMovement`). Deleted movements stay in\nthe list with `deleted_at` and do not count. Before the opening balance the book has no balance (`null`).\n",
    "x-description-cs": "Pokladní kniha provozovny za zadané dny tak, jak ji ukazuje Statistiky → Pokladní kniha v administraci: hotovost\nna začátku a na konci každého dne i teď, hotovost za účtenky a dýško v hotovosti za den (počítá se z objednávek\nplacených hotově – karta při převzetí ne, bon do kuchyně před zaplacením ne) a ručně zapsané pohyby – vklady,\nvýběry, výdaje, jiné příjmy, počáteční stav a rozdíly zjištěné kontrolou pokladny – z administrace i z pokladen\n(`createCashMovement`). Smazané pohyby zůstávají v seznamu s `deleted_at` a nepočítají se. Před počátečním\nstavem kniha stav nemá (`null`).\n",
    "security": [
     {
      "oauth2": [
       "reports:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "date_from",
      "in": "query",
      "required": true,
      "description": "First day.",
      "x-description-cs": "První den.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "name": "date_to",
      "in": "query",
      "required": true,
      "description": "Last day; at most 92 days in one request.",
      "x-description-cs": "Poslední den; nejvýš 92 dní v jednom požadavku.",
      "schema": {
       "$ref": "#/components/schemas/LocalDate"
      },
      "example": "2027-01-15"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The cash book.",
      "x-description-cs": "Pokladní kniha.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CashBook"
        },
        "examples": {
         "day": {
          "summary": "The cash book of a day",
          "value": {
           "date_from": "2027-01-15",
           "date_to": "2027-01-15",
           "opening": {
            "amount": {
             "amount": 500000,
             "currency": "CZK"
            },
            "occurred_at": "2027-01-04T08:00:00+01:00"
           },
           "balance_start": {
            "amount": 1230000,
            "currency": "CZK"
           },
           "balance_end": {
            "amount": 1964300,
            "currency": "CZK"
           },
           "balance_now": {
            "amount": 1964300,
            "currency": "CZK"
           },
           "days": [
            {
             "date": "2027-01-15",
             "start": {
              "amount": 1230000,
              "currency": "CZK"
             },
             "cash_receipts": {
              "amount": 2069700,
              "currency": "CZK"
             },
             "receipts_count": 71,
             "cash_tips": {
              "amount": 0,
              "currency": "CZK"
             },
             "income": {
              "amount": 200000,
              "currency": "CZK"
             },
             "outgoings": {
              "amount": 1535000,
              "currency": "CZK"
             },
             "differences": {
              "amount": -400,
              "currency": "CZK"
             },
             "end": {
              "amount": 1964300,
              "currency": "CZK"
             }
            }
           ],
           "movements": [
            {
             "number": "8811",
             "kind": "deposit",
             "amount": {
              "amount": 200000,
              "currency": "CZK"
             },
             "note": "Drobné na směnu",
             "document": null,
             "occurred_at": "2027-01-15T09:50:00+01:00",
             "recorded_by": "Jana Dvořáková (Pokladna u baru)",
             "device_id": "512",
             "pos_movement_id": "01a318f0-a0c0-74d7-8b0b-b661d43046eb",
             "deleted_at": null,
             "deleted_by": null
            },
            {
             "number": "8812",
             "kind": "withdrawal",
             "amount": {
              "amount": -1500000,
              "currency": "CZK"
             },
             "note": "Odvod tržby do banky",
             "document": null,
             "occurred_at": "2027-01-15T16:05:12+01:00",
             "recorded_by": "Petr Novák (Pokladna u baru)",
             "device_id": "512",
             "pos_movement_id": "01a318f0-a0c0-7f0d-91ef-e936a0196e90",
             "deleted_at": null,
             "deleted_by": null
            },
            {
             "number": "8813",
             "kind": "expense",
             "amount": {
              "amount": -35000,
              "currency": "CZK"
             },
             "note": "Citrony a máta – Albert",
             "document": "P-2231",
             "occurred_at": "2027-01-15T17:40:05+01:00",
             "recorded_by": "Jana Dvořáková (Pokladna u baru), schválil Petr Novák",
             "device_id": "512",
             "pos_movement_id": "01a318f0-a0c0-75b8-b868-9f9ca22f3945",
             "deleted_at": null,
             "deleted_by": null
            },
            {
             "number": "8815",
             "kind": "difference",
             "amount": {
              "amount": -400,
              "currency": "CZK"
             },
             "note": "Kontrola pokladny: spočítáno 19 643 Kč, očekáváno 19 647 Kč – chybí 4 Kč",
             "document": null,
             "occurred_at": "2027-01-15T22:20:00+01:00",
             "recorded_by": "Petr Novák",
             "device_id": null,
             "pos_movement_id": null,
             "deleted_at": null,
             "deleted_by": null
            }
           ]
          },
          "x-summary-cs": "Pokladní kniha dne"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/tabs": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Receipts"
    ],
    "operationId": "listTabs",
    "summary": "Open tabs of the restaurant",
    "x-summary-cs": "Otevřené účty stolů provozovny",
    "x-requires-device": true,
    "description": "All open tabs of the restaurant, from every register and waiter app, so that any device can continue a table.\nPoll with `If-None-Match` (an unchanged list costs almost nothing) or follow the `tab.updated` and `tab.closed`\nevents.\n",
    "x-description-cs": "Všechny otevřené účty stolů provozovny ze všech pokladen a číšníků, takže stůl může převzít kterékoli zařízení.\nPtejte se s `If-None-Match` (nezměněný seznam skoro nic nestojí), nebo sledujte události `tab.updated`\na `tab.closed`.\n",
    "security": [
     {
      "oauth2": [
       "receipts:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "Open tabs.",
      "x-description-cs": "Otevřené účty.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TabList"
        },
        "examples": {
         "open": {
          "summary": "Open table tabs",
          "value": {
           "data": [
            {
             "id": "01a318f0-a0c0-7834-8f31-7973aa8bb418",
             "restaurant_id": "123",
             "table_name": "Stůl 4",
             "note": null,
             "opened_at": "2027-01-15T11:48:02+01:00",
             "opened_by": {
              "id": "58",
              "name": "Jana Dvořáková"
             },
             "updated_by": {
              "id": "58",
              "name": "Jana Dvořáková"
             },
             "lines": [
              {
               "id": "l-1",
               "product_id": "4567",
               "name": "Svíčková na smetaně, houskový knedlík",
               "variant": "full",
               "quantity": 1,
               "ordered_at": "2027-01-15T11:51:40+01:00",
               "unit_price": {
                "amount": 19900,
                "currency": "CZK"
               },
               "add_ons": [],
               "removed_ingredients": [],
               "note": null,
               "course": 1,
               "sent_to_kitchen": true,
               "total": {
                "amount": 19900,
                "currency": "CZK"
               }
              },
              {
               "id": "l-2",
               "product_id": "4590",
               "name": "Pivo 12° 0,5 l",
               "variant": "full",
               "quantity": 2,
               "ordered_at": "2027-01-15T11:49:15+01:00",
               "unit_price": {
                "amount": 6900,
                "currency": "CZK"
               },
               "add_ons": [],
               "removed_ingredients": [],
               "note": null,
               "course": 0,
               "sent_to_kitchen": false,
               "total": {
                "amount": 13800,
                "currency": "CZK"
               }
              }
             ],
             "totals": {
              "items": {
               "amount": 33700,
               "currency": "CZK"
              },
              "total": {
               "amount": 33700,
               "currency": "CZK"
              }
             },
             "version": 3,
             "status": "open",
             "updated_at": "2027-01-15T11:51:40+01:00",
             "device_id": "512",
             "closed_at": null,
             "receipt_id": null
            }
           ]
          },
          "x-summary-cs": "Otevřené účty stolů"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/tabs/{tab_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/TabId"
    }
   ],
   "get": {
    "tags": [
     "Receipts"
    ],
    "operationId": "getTab",
    "summary": "Get a tab",
    "x-summary-cs": "Detail účtu stolu",
    "x-requires-device": true,
    "description": "An open or closed tab with its `ETag` (the version).",
    "x-description-cs": "Otevřený nebo uzavřený účet stolu s `ETag` (verzí).",
    "security": [
     {
      "oauth2": [
       "receipts:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The tab.",
      "x-description-cs": "Účet stolu.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Tab"
        },
        "examples": {
         "tab": {
          "summary": "A table tab",
          "value": {
           "id": "01a318f0-a0c0-7834-8f31-7973aa8bb418",
           "restaurant_id": "123",
           "table_name": "Stůl 4",
           "note": null,
           "opened_at": "2027-01-15T11:48:02+01:00",
           "opened_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "updated_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "lines": [
            {
             "id": "l-1",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": 1,
             "ordered_at": "2027-01-15T11:51:40+01:00",
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "add_ons": [],
             "removed_ingredients": [],
             "note": null,
             "course": 1,
             "sent_to_kitchen": true,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             }
            },
            {
             "id": "l-2",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": 2,
             "ordered_at": "2027-01-15T11:49:15+01:00",
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "add_ons": [],
             "removed_ingredients": [],
             "note": null,
             "course": 0,
             "sent_to_kitchen": false,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             }
            }
           ],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "total": {
             "amount": 33700,
             "currency": "CZK"
            }
           },
           "version": 3,
           "status": "open",
           "updated_at": "2027-01-15T11:51:40+01:00",
           "device_id": "512",
           "closed_at": null,
           "receipt_id": null
          },
          "x-summary-cs": "Účet stolu"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "put": {
    "tags": [
     "Receipts"
    ],
    "operationId": "putTab",
    "summary": "Open or change a tab",
    "x-summary-cs": "Otevřít nebo změnit účet stolu",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "Sends the whole state of the tab: its table and all its items. Without `If-Match` a new tab is opened (`201`).\nTo change an open tab send `If-Match` with the `ETag` you read (`428 precondition_required` without it); when\nanother device changed it meanwhile you get `412 precondition_failed` – read it again, merge and send again.\nA closed tab cannot be changed (`409 tab_closed`).\n\nPrices are shown from the register catalog now; the receipt prices the items again when paid\n(`createReceipt` with `tab_id` closes the tab). Every change of quantities is written to the table log of the\nadministration in the same words as today's register (added, removed, closed), so the owner keeps seeing\nwhat happened at each table; a changed note, course, table name or `sent_to_kitchen` is not logged.\n",
    "x-description-cs": "Pošle celý stav účtu: stůl a všechny položky. Bez `If-Match` se otevře nový účet (`201`). Při změně\notevřeného účtu pošlete `If-Match` s načteným `ETag` (bez něj `428 precondition_required`); když ho mezitím\nzměnilo jiné zařízení, dostanete `412 precondition_failed` – načtěte ho znovu, sloučte a pošlete znovu.\nUzavřený účet měnit nejde (`409 tab_closed`).\n\nCeny jsou ze sortimentu pokladny v tuto chvíli jen pro zobrazení; účtenka položky při placení spočítá znovu\n(`createReceipt` s `tab_id` účet uzavře). Každá změna množství se zapíše do logu stolů v administraci stejnými\nvětami jako dnešní pokladna (přidáno, odebráno, uzavřeno), takže majitel dál vidí, co se u kterého stolu dělo;\nzměna poznámky, chodu, názvu stolu nebo `sent_to_kitchen` se nezapisuje.\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfMatchOptional"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TabInput"
       },
       "examples": {
        "tab": {
         "summary": "The whole tab of a table",
         "value": {
          "table_name": "Stůl 4",
          "items": [
           {
            "id": "l-1",
            "product_id": "4567",
            "quantity": 1,
            "course": 1,
            "sent_to_kitchen": true
           },
           {
            "id": "l-2",
            "product_id": "4590",
            "quantity": 2
           }
          ]
         },
         "x-summary-cs": "Celý účet stolu"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Changed.",
      "x-description-cs": "Změněno.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Tab"
        },
        "examples": {
         "updated": {
          "summary": "The stored tab",
          "value": {
           "id": "01a318f0-a0c0-7834-8f31-7973aa8bb418",
           "restaurant_id": "123",
           "table_name": "Stůl 4",
           "note": null,
           "opened_at": "2027-01-15T11:48:02+01:00",
           "opened_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "updated_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "lines": [
            {
             "id": "l-1",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": 1,
             "ordered_at": "2027-01-15T11:51:40+01:00",
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "add_ons": [],
             "removed_ingredients": [],
             "note": null,
             "course": 1,
             "sent_to_kitchen": true,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             }
            },
            {
             "id": "l-2",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": 2,
             "ordered_at": "2027-01-15T11:49:15+01:00",
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "add_ons": [],
             "removed_ingredients": [],
             "note": null,
             "course": 0,
             "sent_to_kitchen": false,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             }
            }
           ],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "total": {
             "amount": 33700,
             "currency": "CZK"
            }
           },
           "version": 3,
           "status": "open",
           "updated_at": "2027-01-15T11:51:40+01:00",
           "device_id": "512",
           "closed_at": null,
           "receipt_id": null
          },
          "x-summary-cs": "Uložený účet"
         }
        }
       }
      }
     },
     "201": {
      "description": "Opened.",
      "x-description-cs": "Otevřeno.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Tab"
        },
        "examples": {
         "created": {
          "summary": "A new tab",
          "value": {
           "id": "01a318f0-a0c0-7834-8f31-7973aa8bb418",
           "restaurant_id": "123",
           "table_name": "Stůl 4",
           "note": null,
           "opened_at": "2027-01-15T11:48:02+01:00",
           "opened_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "updated_by": {
            "id": "58",
            "name": "Jana Dvořáková"
           },
           "lines": [
            {
             "id": "l-1",
             "product_id": "4567",
             "name": "Svíčková na smetaně, houskový knedlík",
             "variant": "full",
             "quantity": 1,
             "ordered_at": "2027-01-15T11:51:40+01:00",
             "unit_price": {
              "amount": 19900,
              "currency": "CZK"
             },
             "add_ons": [],
             "removed_ingredients": [],
             "note": null,
             "course": 1,
             "sent_to_kitchen": true,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             }
            },
            {
             "id": "l-2",
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "variant": "full",
             "quantity": 2,
             "ordered_at": "2027-01-15T11:49:15+01:00",
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "add_ons": [],
             "removed_ingredients": [],
             "note": null,
             "course": 0,
             "sent_to_kitchen": false,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             }
            }
           ],
           "totals": {
            "items": {
             "amount": 33700,
             "currency": "CZK"
            },
            "total": {
             "amount": 33700,
             "currency": "CZK"
            }
           },
           "version": 1,
           "status": "open",
           "updated_at": "2027-01-15T11:51:40+01:00",
           "device_id": "512",
           "closed_at": null,
           "receipt_id": null
          },
          "x-summary-cs": "Nový účet"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "description": "`precondition_failed`: the object changed since you read it. Read it again and retry.",
      "x-description-cs": "`precondition_failed`: záznam se od načtení změnil. Načtěte ho znovu a zkuste to znovu.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "precondition_failed": {
          "summary": "Another device changed the tab meanwhile",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#precondition_failed",
           "title": "Záznam se mezitím změnil",
           "status": 412,
           "code": "precondition_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Účet mezitím změnilo jiné zařízení"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "428": {
      "$ref": "#/components/responses/PreconditionRequired"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   },
   "delete": {
    "tags": [
     "Receipts"
    ],
    "operationId": "closeTab",
    "summary": "Close a tab without a receipt",
    "x-summary-cs": "Uzavřít účet stolu bez účtenky",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "Closes a tab that will not be paid – a cancelled table. Lines still on the tab count as cancelled: those already\nsent to the kitchen are written as item cancellations, the same as removing them with `putTab`, and the table log\nof the administration records the close with the optional `reason`. To move items to another tab use\n`moveTabLines` first (moved lines are no cancellation). A paid tab is closed by `createReceipt` with `tab_id`.\nNo kitchen ticket is cancelled; the lines stay in the closed tab (`getTab`).\n",
    "x-description-cs": "Uzavře účet, který se platit nebude – zrušený stůl. Řádky, které na účtu zůstaly, se počítají jako zrušené: ty,\nkteré už šly do kuchyně, se zapíšou jako storna položek stejně jako při odebrání přes `putTab` a log stolů\nv administraci zapíše uzavření s nepovinným `reason`. Položky na jiný účet nejdřív přesuňte přes `moveTabLines`\n(přesunuté řádky storno nejsou). Zaplacený účet uzavře `createReceipt` s `tab_id`. Žádný kuchyňský bon se\nneruší; řádky zůstanou v uzavřeném účtu (`getTab`).\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfMatch"
     },
     {
      "name": "reason",
      "in": "query",
      "required": false,
      "description": "Why the tab closes without payment, for the table log of the administration.",
      "x-description-cs": "Proč se účet zavírá bez placení – do logu stolů v administraci.",
      "schema": {
       "type": "string",
       "maxLength": 200
      }
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "204": {
      "description": "Closed.",
      "x-description-cs": "Uzavřeno."
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "$ref": "#/components/responses/PreconditionFailed"
     },
     "428": {
      "$ref": "#/components/responses/PreconditionRequired"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/tabs/{tab_id}/moves": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/TabId"
    }
   ],
   "post": {
    "tags": [
     "Receipts"
    ],
    "operationId": "moveTabLines",
    "summary": "Move lines to another tab",
    "x-summary-cs": "Přesunout položky na jiný účet",
    "x-requires-device": true,
    "x-staff": "required",
    "description": "Moves lines, or part of their quantity, from this tab to another one in one step – guests moving to another\ntable, or a split bill (move the part being paid to a new tab and pay it with `createReceipt`). The moved pieces\nkeep their price, add-ons, note, course, `sent_to_kitchen` and `ordered_at`; nothing is priced again, so a daily\nmenu moves even after its time. A move is no cancellation.\n\nThe target is an open tab of the restaurant – send its `version` in `target_version` (`412 precondition_failed`\nwhen it changed) – or a new UUID you generate, which opens a tab with `target_table_name`. Send `If-Match` with\nthe `ETag` of this tab. A tab left without lines is closed (`tab.closed`). Both tabs get a new version, the table\nlog of the administration records the move and `tab.updated` goes out. When the target tab already has a line\nwith the same ID, send another `target_line_id`.\n",
    "x-description-cs": "Přesune řádky nebo jejich část z tohoto účtu na jiný v jednom kroku – hosté se přesadí k jinému stolu, nebo se\núčet dělí (placenou část přesuňte na nový účet a zaplaťte ji přes `createReceipt`). Přesunuté kusy si nesou cenu,\npřílohy, poznámku, chod, `sent_to_kitchen` i `ordered_at`; nic se znovu neoceňuje, takže se přesune i denní menu\npo svém čase. Přesun není storno.\n\nCílem je otevřený účet provozovny – pošlete jeho `version` v `target_version` (`412 precondition_failed`, když\nse změnil) – nebo nové UUID, které vytvoříte, a otevře se účet s `target_table_name`. Pošlete `If-Match` s `ETag`\ntohoto účtu. Účet, na kterém nic nezůstane, se uzavře (`tab.closed`). Oba účty dostanou novou verzi, log stolů\nv administraci přesun zapíše a odejde `tab.updated`. Když cílový účet už řádek se stejným ID má, pošlete jiné\n`target_line_id`.\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfMatch"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TabMoveInput"
       },
       "examples": {
        "split": {
         "summary": "The beer to a new tab (split bill)",
         "value": {
          "target_tab_id": "01a318f0-a0c0-7b5f-897a-975233c4fa9d",
          "target_table_name": "Stůl 4 – Petr",
          "lines": [
           {
            "line_id": "l-2",
            "quantity": 2
           }
          ]
         },
         "x-summary-cs": "Pivo na nový účet (dělení účtu)"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Moved; both tabs after the move.",
      "x-description-cs": "Přesunuto; oba účty po přesunu.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TabMove"
        },
        "examples": {
         "moved": {
          "summary": "Both tabs after the move",
          "value": {
           "source": {
            "id": "01a318f0-a0c0-7834-8f31-7973aa8bb418",
            "restaurant_id": "123",
            "table_name": "Stůl 4",
            "note": null,
            "opened_at": "2027-01-15T11:48:02+01:00",
            "opened_by": {
             "id": "58",
             "name": "Jana Dvořáková"
            },
            "updated_by": {
             "id": "58",
             "name": "Jana Dvořáková"
            },
            "lines": [
             {
              "id": "l-1",
              "product_id": "4567",
              "name": "Svíčková na smetaně, houskový knedlík",
              "variant": "full",
              "quantity": 1,
              "ordered_at": "2027-01-15T11:51:40+01:00",
              "unit_price": {
               "amount": 19900,
               "currency": "CZK"
              },
              "add_ons": [],
              "removed_ingredients": [],
              "note": null,
              "course": 1,
              "sent_to_kitchen": true,
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             }
            ],
            "totals": {
             "items": {
              "amount": 19900,
              "currency": "CZK"
             },
             "total": {
              "amount": 19900,
              "currency": "CZK"
             }
            },
            "version": 4,
            "status": "open",
            "updated_at": "2027-01-15T11:55:10+01:00",
            "device_id": "512",
            "closed_at": null,
            "receipt_id": null
           },
           "target": {
            "id": "01a318f0-a0c0-7b5f-897a-975233c4fa9d",
            "restaurant_id": "123",
            "table_name": "Stůl 4 – Petr",
            "note": null,
            "opened_at": "2027-01-15T11:55:10+01:00",
            "opened_by": {
             "id": "58",
             "name": "Jana Dvořáková"
            },
            "updated_by": {
             "id": "58",
             "name": "Jana Dvořáková"
            },
            "lines": [
             {
              "id": "l-2",
              "product_id": "4590",
              "name": "Pivo 12° 0,5 l",
              "variant": "full",
              "quantity": 2,
              "ordered_at": "2027-01-15T11:49:15+01:00",
              "unit_price": {
               "amount": 6900,
               "currency": "CZK"
              },
              "add_ons": [],
              "removed_ingredients": [],
              "note": null,
              "course": 0,
              "sent_to_kitchen": false,
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             }
            ],
            "totals": {
             "items": {
              "amount": 13800,
              "currency": "CZK"
             },
             "total": {
              "amount": 13800,
              "currency": "CZK"
             }
            },
            "version": 1,
            "status": "open",
            "updated_at": "2027-01-15T11:55:10+01:00",
            "device_id": "512",
            "closed_at": null,
            "receipt_id": null
           }
          },
          "x-summary-cs": "Oba účty po přesunu"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "412": {
      "description": "`precondition_failed`: the object changed since you read it. Read it again and retry.",
      "x-description-cs": "`precondition_failed`: záznam se od načtení změnil. Načtěte ho znovu a zkuste to znovu.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "precondition_failed": {
          "summary": "Another device changed the target tab meanwhile",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#precondition_failed",
           "title": "Záznam se mezitím změnil",
           "status": 412,
           "code": "precondition_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Cílový účet mezitím změnilo jiné zařízení"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "428": {
      "$ref": "#/components/responses/PreconditionRequired"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/pos-activity": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Receipts"
    ],
    "operationId": "createPosActivity",
    "summary": "Send the register's activity log",
    "x-summary-cs": "Poslat deník akcí pokladny",
    "x-requires-device": true,
    "x-staff": "optional",
    "x-idempotency": "body-id",
    "description": "Actions done on the register that are not documents – opening the cash drawer, printing a copy, signing in,\nmoving items between tables… – as text for the administration's bar activity timeline, as from today's register.\nIt only records the text and changes nothing: moving items between tables, for example, is done by two `putTab`\ncalls – the target tab with the items, then the source tab without them and with their IDs in `moved_line_ids` –\nwhich are two separate steps, not one atomic move. Send the actions in batches, also later after working\noffline; every item has your UUID, so a batch sent twice writes nothing twice (`duplicates`). An employee who\ndoes not work at the restaurant rejects the whole batch (`422`).\n",
    "x-description-cs": "Akce na pokladně, které nejsou doklady – otevření zásuvky, tisk kopie, přihlášení, přesun položek mezi stoly… –\njako text pro Časovou osu akcí (bar) v administraci, stejně jako z dnešní pokladny. Jen zapíše text a nic nemění:\npřesun položek mezi stoly se třeba dělá dvěma voláními `putTab` – cílový účet s položkami, pak zdrojový účet bez\nnich a s jejich ID v `moved_line_ids` –, což jsou dva samostatné kroky, ne jeden nedělitelný přesun. Akce\nposílejte po dávkách, i později po práci offline; každá položka má vaše UUID, takže dvakrát poslaná dávka nic\nnezapíše dvakrát (`duplicates`). Zaměstnanec, který v provozovně nepracuje, odmítne celou dávku (`422`).\n",
    "security": [
     {
      "oauth2": [
       "receipts:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PosActivityBatch"
       },
       "examples": {
        "drawer": {
         "summary": "The drawer opened without a sale",
         "value": {
          "items": [
           {
            "id": "01a318f0-a0c0-7c1f-beee-4d0eed82b7a2",
            "employee_id": "58",
            "occurred_at": "2027-01-15T12:15:02+01:00",
            "action": "Otevřena zásuvka bez prodeje"
           }
          ]
         },
         "x-summary-cs": "Otevřená zásuvka bez prodeje"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "How many items were written and how many were already there.",
      "x-description-cs": "Kolik položek se zapsalo a kolik už tam bylo.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PosActivityResult"
        },
        "examples": {
         "stored": {
          "summary": "Stored",
          "value": {
           "created": 1,
           "duplicates": 0
          },
          "x-summary-cs": "Zapsáno"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/stock-taking/items": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Stock"
    ],
    "operationId": "listStockTakingItems",
    "summary": "Items to count in a stock taking",
    "x-summary-cs": "Položky k inventuře",
    "x-requires-device": true,
    "description": "The warehouse items the administration marks for counting at the bar (on the registers) or in the kitchen, with\nthe quantity the stock expects now – the list for a stock taking on the device. Items hidden for this\nrestaurant are left out.\n\nWhen `weighing` is set, an opened package can be weighed instead of estimated: its quantity is\n`pack_content × (weight − empty_weight_g) / (full_weight_g − empty_weight_g)`. `tolerance_percent` is the\ndifference the restaurant still accepts (`0` = not set); show larger differences to the employee before\nsending.\n\nSorted by ID; group the items by `category` yourself.\n",
    "x-description-cs": "Skladové položky, které má administrace označené k inventuře na baru (na pokladnách) nebo v kuchyni, s množstvím,\nkteré teď očekává sklad – seznam pro inventuru na zařízení. Položky skryté pro tuto provozovnu chybí.\n\nKdyž je vyplněné `weighing`, otevřené balení jde zvážit místo odhadu: jeho množství je\n`pack_content × (váha − empty_weight_g) / (full_weight_g − empty_weight_g)`. `tolerance_percent` je rozdíl, který\nprovozovna ještě snese (`0` = nenastaveno); větší rozdíly ukažte zaměstnanci před odesláním.\n\nSeřazeno podle ID; podle `category` si položky seskupte sami.\n",
    "security": [
     {
      "oauth2": [
       "stock:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "area",
      "in": "query",
      "required": false,
      "description": "`bar` – items counted on the registers (default), `kitchen` – items counted in the kitchen.",
      "x-description-cs": "`bar` – položky, které se počítají na pokladnách (výchozí), `kitchen` – položky, které se počítají v kuchyni.",
      "schema": {
       "type": "string",
       "enum": [
        "bar",
        "kitchen"
       ],
       "default": "bar"
      },
      "example": "bar"
     },
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "One page of the items.",
      "x-description-cs": "Jedna stránka položek.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StockTakingItemPage"
        },
        "examples": {
         "items": {
          "summary": "Items to count",
          "value": {
           "data": [
            {
             "warehouse_item_id": "880",
             "name": "Pivo 12° – sud 50 l",
             "category": {
              "id": "41",
              "name": "Pivo"
             },
             "unit": "l",
             "ean": null,
             "expected_quantity": 37.5,
             "tolerance_percent": 2,
             "weighing": null
            },
            {
             "warehouse_item_id": "884",
             "name": "Rum tmavý 0,7 l",
             "category": {
              "id": "43",
              "name": "Lihoviny"
             },
             "unit": "l",
             "ean": "8594001021345",
             "expected_quantity": 2.1,
             "tolerance_percent": 0,
             "weighing": {
              "pack_content": 0.7,
              "full_weight_g": 1250,
              "empty_weight_g": 550
             }
            },
            {
             "warehouse_item_id": "887",
             "name": "Citrony",
             "category": {
              "id": "45",
              "name": "Ovoce"
             },
             "unit": "kg",
             "ean": null,
             "expected_quantity": 3.2,
             "tolerance_percent": 5,
             "weighing": null
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Položky k inventuře"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/stock-takings": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Stock"
    ],
    "operationId": "createStockTaking",
    "summary": "Record a stock taking",
    "x-summary-cs": "Zapsat inventuru",
    "x-requires-device": true,
    "x-staff": "required",
    "x-idempotency": "body-id",
    "description": "The counted quantities of a finished stock taking, in one request. The server compares them with the stock,\nrecords the stock taking in the administration (Warehouse → Stock taking) under the signed-in employee and sets\nthe stock to the counted quantities, with the differences in the stock movements as a stock taking – unless the\nrestaurant has *Do not set the stock from stock takings* switched on; then the stock taking is only recorded\n(`stock_updated: false`). Items you do not send stay as they are.\n\nAt the bar it is done by an employee with a register role (`pos`, `pos_manager`), in the kitchen by one with a\nkitchen role (`kitchen`, `kitchen_manager`). Send every item at most once.\n\n`id` is your UUID of the stock taking made on the device; the same `id` again returns the stock taking with\n`200` (`409 stock_taking_id_conflict` when the `id` belongs to another device).\n",
    "x-description-cs": "Napočítaná množství dokončené inventury v jednom požadavku. Server je porovná se stavem skladu, zapíše inventuru\ndo administrace (Sklad → Inventury) na přihlášeného zaměstnance a nastaví sklad na napočítaná množství; rozdíly\nzapíše do pohybů skladu jako inventuru – pokud provozovna nemá zapnuté *Nenastavovat sklad dle inventur*; pak se\ninventura jen zapíše (`stock_updated: false`). Položky, které nepošlete, zůstanou, jak jsou.\n\nNa baru ji dělá zaměstnanec s rolí na pokladně (`pos`, `pos_manager`), v kuchyni zaměstnanec s rolí v kuchyni\n(`kitchen`, `kitchen_manager`). Každou položku pošlete nejvýš jednou.\n\n`id` je vaše UUID inventury vytvořené na zařízení; stejné `id` znovu vrátí inventuru s `200`\n(`409 stock_taking_id_conflict`, když `id` patří jinému zařízení).\n",
    "security": [
     {
      "oauth2": [
       "stock:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/StockTakingCreate"
       },
       "examples": {
        "bar": {
         "summary": "Stock taking of the bar",
         "value": {
          "id": "01a318f0-a0c0-7f96-b81b-51428f522956",
          "area": "bar",
          "note": "Měsíční inventura baru",
          "items": [
           {
            "warehouse_item_id": "880",
            "quantity": 36.0
           },
           {
            "warehouse_item_id": "884",
            "quantity": 1.96
           },
           {
            "warehouse_item_id": "887",
            "quantity": 3.2
           }
          ]
         },
         "x-summary-cs": "Inventura baru"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "This `id` was already sent; the stock taking.",
      "x-description-cs": "Toto `id` už bylo poslané; inventura.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StockTaking"
        },
        "examples": {
         "duplicate": {
          "summary": "The same id again",
          "value": {
           "id": "01a318f0-a0c0-7f96-b81b-51428f522956",
           "number": "INV-2027-003",
           "area": "bar",
           "created_at": "2027-01-15T22:31:10+01:00",
           "employee": {
            "id": "61",
            "name": "Petr Novák"
           },
           "note": "Měsíční inventura baru",
           "stock_updated": true,
           "items": [
            {
             "warehouse_item_id": "880",
             "name": "Pivo 12° – sud 50 l",
             "unit": "l",
             "expected_quantity": 37.5,
             "counted_quantity": 36.0,
             "difference": -1.5,
             "difference_value": {
              "amount": -6300,
              "currency": "CZK"
             }
            },
            {
             "warehouse_item_id": "884",
             "name": "Rum tmavý 0,7 l",
             "unit": "l",
             "expected_quantity": 2.1,
             "counted_quantity": 1.96,
             "difference": -0.14,
             "difference_value": {
              "amount": -4200,
              "currency": "CZK"
             }
            },
            {
             "warehouse_item_id": "887",
             "name": "Citrony",
             "unit": "kg",
             "expected_quantity": 3.2,
             "counted_quantity": 3.2,
             "difference": 0.0,
             "difference_value": {
              "amount": 0,
              "currency": "CZK"
             }
            }
           ],
           "difference_value": {
            "amount": -10500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Stejné id podruhé"
         }
        }
       }
      }
     },
     "201": {
      "description": "Recorded.",
      "x-description-cs": "Zapsáno.",
      "headers": {
       "Location": {
        "$ref": "#/components/headers/Location"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StockTaking"
        },
        "examples": {
         "created": {
          "summary": "Stored, the stock is set",
          "value": {
           "id": "01a318f0-a0c0-7f96-b81b-51428f522956",
           "number": "INV-2027-003",
           "area": "bar",
           "created_at": "2027-01-15T22:31:10+01:00",
           "employee": {
            "id": "61",
            "name": "Petr Novák"
           },
           "note": "Měsíční inventura baru",
           "stock_updated": true,
           "items": [
            {
             "warehouse_item_id": "880",
             "name": "Pivo 12° – sud 50 l",
             "unit": "l",
             "expected_quantity": 37.5,
             "counted_quantity": 36.0,
             "difference": -1.5,
             "difference_value": {
              "amount": -6300,
              "currency": "CZK"
             }
            },
            {
             "warehouse_item_id": "884",
             "name": "Rum tmavý 0,7 l",
             "unit": "l",
             "expected_quantity": 2.1,
             "counted_quantity": 1.96,
             "difference": -0.14,
             "difference_value": {
              "amount": -4200,
              "currency": "CZK"
             }
            },
            {
             "warehouse_item_id": "887",
             "name": "Citrony",
             "unit": "kg",
             "expected_quantity": 3.2,
             "counted_quantity": 3.2,
             "difference": 0.0,
             "difference_value": {
              "amount": 0,
              "currency": "CZK"
             }
            }
           ],
           "difference_value": {
            "amount": -10500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Inventura zapsaná, sklad nastavený"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/stock-takings/{stock_taking_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/StockTakingId"
    }
   ],
   "get": {
    "tags": [
     "Stock"
    ],
    "operationId": "getStockTaking",
    "summary": "Get a stock taking",
    "x-summary-cs": "Detail inventury",
    "x-requires-device": true,
    "description": "One stock taking recorded through the API, with the expected and the counted quantities.",
    "x-description-cs": "Jedna inventura zapsaná přes API s očekávaným a napočítaným množstvím.",
    "security": [
     {
      "oauth2": [
       "stock:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The stock taking.",
      "x-description-cs": "Inventura.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/StockTaking"
        },
        "examples": {
         "stock_taking": {
          "summary": "A stock taking",
          "value": {
           "id": "01a318f0-a0c0-7f96-b81b-51428f522956",
           "number": "INV-2027-003",
           "area": "bar",
           "created_at": "2027-01-15T22:31:10+01:00",
           "employee": {
            "id": "61",
            "name": "Petr Novák"
           },
           "note": "Měsíční inventura baru",
           "stock_updated": true,
           "items": [
            {
             "warehouse_item_id": "880",
             "name": "Pivo 12° – sud 50 l",
             "unit": "l",
             "expected_quantity": 37.5,
             "counted_quantity": 36.0,
             "difference": -1.5,
             "difference_value": {
              "amount": -6300,
              "currency": "CZK"
             }
            },
            {
             "warehouse_item_id": "884",
             "name": "Rum tmavý 0,7 l",
             "unit": "l",
             "expected_quantity": 2.1,
             "counted_quantity": 1.96,
             "difference": -0.14,
             "difference_value": {
              "amount": -4200,
              "currency": "CZK"
             }
            },
            {
             "warehouse_item_id": "887",
             "name": "Citrony",
             "unit": "kg",
             "expected_quantity": 3.2,
             "counted_quantity": 3.2,
             "difference": 0.0,
             "difference_value": {
              "amount": 0,
              "currency": "CZK"
             }
            }
           ],
           "difference_value": {
            "amount": -10500,
            "currency": "CZK"
           }
          },
          "x-summary-cs": "Inventura"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/backups": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Backups"
    ],
    "operationId": "listBackups",
    "summary": "List backups",
    "x-summary-cs": "Seznam záloh",
    "x-requires-device": true,
    "description": "Backups of the restaurant's registers, newest first – including those uploaded by registers on API v1\n(`legacy: true`). Only backups the server can hand out are listed: one whose file it cannot find is left out\n(`getBackup` and `downloadBackup` answer `404` for it). For uploads through this API the server keeps the last 64 automatic, 10 manual and 30 closure\nbackups of each device; older ones of the device disappear with its next upload of the same type, so such a\nregister never pushes out the backups of the others. A register on API v1 still cleans up per restaurant: its\nupload keeps the newest 64, 10 or 30 backups of that type of the whole restaurant and can delete older ones of\nany device, also those uploaded through this API. An automatic backup is accepted at most once in 10 minutes per\ndevice (`429`). Backups of type `other` come from old versions of the app and are kept.\n\nBefore restoring check `db_version` (and `app_version`): a backup of an older or a newer local database may\nneed a conversion in the app.\n",
    "x-description-cs": "Zálohy pokladen provozovny od nejnovější – i ty, které nahrály pokladny na API v1 (`legacy: true`). V seznamu\njsou jen zálohy, které server umí vydat: záloha, jejíž soubor nenajde, se vynechá (`getBackup` i `downloadBackup`\npro ni vrátí `404`). U záloh\nnahraných přes toto API server drží posledních 64 automatických, 10 ručních a 30 záloh po uzávěrce každého\nzařízení; starší zálohy zařízení zmizí s jeho dalším nahráním stejného typu, takže taková pokladna nikdy\nnevytlačí zálohy ostatních. Pokladna na API v1 ale uklízí po provozovně: její nahrání ponechá nejnovějších 64,\n10 nebo 30 záloh daného typu celé provozovny a může smazat starší zálohy kteréhokoli zařízení, i nahrané přes\ntoto API. Automatickou zálohu server přijme nejvýš jednou za 10 minut od jednoho zařízení (`429`). Zálohy typu\n`other` pocházejí ze starých verzí aplikace a zůstávají.\n\nPřed obnovou zkontrolujte `db_version` (a `app_version`): záloha starší nebo novější místní databáze může\nv aplikaci potřebovat převod.\n",
    "security": [
     {
      "oauth2": [
       "backups:read"
      ]
     }
    ],
    "parameters": [
     {
      "name": "type",
      "in": "query",
      "required": false,
      "description": "Only backups of this type.",
      "x-description-cs": "Jen zálohy tohoto typu.",
      "schema": {
       "type": "string",
       "enum": [
        "automatic",
        "manual",
        "closure",
        "other"
       ]
      },
      "example": "closure"
     },
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "One page of backups.",
      "x-description-cs": "Jedna stránka záloh.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/BackupPage"
        },
        "examples": {
         "list": {
          "summary": "Register backups",
          "value": {
           "data": [
            {
             "id": "4410",
             "type": "closure",
             "created_at": "2027-01-15T22:16:05+01:00",
             "size_bytes": 4718592,
             "app_version": "3.4.1",
             "db_version": "112",
             "device_name": "Pokladna u baru",
             "this_device": true,
             "legacy": false
            }
           ],
           "next_cursor": null
          },
          "x-summary-cs": "Zálohy pokladny"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     }
    }
   },
   "post": {
    "tags": [
     "Backups"
    ],
    "operationId": "createBackup",
    "summary": "Upload a backup",
    "x-summary-cs": "Nahrát zálohu",
    "x-requires-device": true,
    "description": "Uploads a ZIP archive with the register's local database: the file itself is the body\n(`Content-Type: application/zip`), at most 50 MB. The server stores it for the restaurant and removes the oldest\nbackups of the same type over the limit (see `listBackups`).\n\n`type`: `automatic` – a periodic backup, `manual` – an employee asked for it, `closure` – after the shift\nclosure. A body that is not a ZIP archive answers `422 validation_failed` (`/body`); when the storage is not\navailable, `503 service_unavailable` – keep the backup and try again later.\n",
    "x-description-cs": "Nahraje archiv ZIP s místní databází pokladny: tělem je samotný soubor (`Content-Type: application/zip`),\nnejvýš 50 MB. Server ho uloží k provozovně a nejstarší zálohy stejného typu nad limit smaže (viz `listBackups`).\n\n`type`: `automatic` – pravidelná záloha, `manual` – požádal o ni zaměstnanec, `closure` – po uzávěrce směny.\nTělo, které není archiv ZIP, vrátí `422 validation_failed` (`/body`); když úložiště není dostupné,\n`503 service_unavailable` – zálohu si nechte a zkuste to později.\n",
    "security": [
     {
      "oauth2": [
       "backups:write"
      ]
     }
    ],
    "parameters": [
     {
      "name": "type",
      "in": "query",
      "required": true,
      "description": "Why the backup was made.",
      "x-description-cs": "Proč záloha vznikla.",
      "schema": {
       "type": "string",
       "enum": [
        "automatic",
        "manual",
        "closure"
       ]
      },
      "example": "closure"
     },
     {
      "name": "app_version",
      "in": "query",
      "required": false,
      "description": "Version of the app that made the backup.",
      "x-description-cs": "Verze aplikace, která zálohu vytvořila.",
      "schema": {
       "type": "string",
       "minLength": 1,
       "maxLength": 16,
       "pattern": "^[0-9A-Za-z._+-]+$"
      },
      "example": "3.4.1"
     },
     {
      "name": "db_version",
      "in": "query",
      "required": false,
      "description": "Version of the local database in the backup.",
      "x-description-cs": "Verze místní databáze v záloze.",
      "schema": {
       "type": "string",
       "minLength": 1,
       "maxLength": 16,
       "pattern": "^[0-9A-Za-z._+-]+$"
      },
      "example": "112"
     },
     {
      "$ref": "#/components/parameters/IdempotencyKey"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "x-max-bytes": 52428800,
     "content": {
      "application/zip": {
       "schema": {
        "type": "string",
        "format": "binary"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The backup is stored.",
      "x-description-cs": "Záloha je uložená.",
      "headers": {
       "Location": {
        "$ref": "#/components/headers/Location"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Backup"
        },
        "examples": {
         "stored": {
          "summary": "The backup is stored",
          "value": {
           "id": "4410",
           "type": "closure",
           "created_at": "2027-01-15T22:16:05+01:00",
           "size_bytes": 4718592,
           "app_version": "3.4.1",
           "db_version": "112",
           "device_name": "Pokladna u baru",
           "this_device": true,
           "legacy": false
          },
          "x-summary-cs": "Záloha uložená"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "$ref": "#/components/responses/Conflict"
     },
     "413": {
      "description": "`payload_too_large`: the body is larger than the operation allows.",
      "x-description-cs": "`payload_too_large`: tělo je větší, než operace dovolí.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "payload_too_large": {
          "summary": "The backup is too large",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#payload_too_large",
           "title": "Požadavek je příliš velký",
           "status": 413,
           "code": "payload_too_large",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Záloha je moc velká"
         }
        }
       }
      }
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "$ref": "#/components/responses/ServiceUnavailable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/backups/{backup_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/BackupId"
    }
   ],
   "get": {
    "tags": [
     "Backups"
    ],
    "operationId": "getBackup",
    "summary": "Get a backup",
    "x-summary-cs": "Detail zálohy",
    "x-requires-device": true,
    "description": "Details of one backup of the restaurant; the archive itself is at `…/content`.",
    "x-description-cs": "Údaje o jedné záloze provozovny; samotný archiv je na `…/content`.",
    "security": [
     {
      "oauth2": [
       "backups:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The backup.",
      "x-description-cs": "Záloha.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Backup"
        },
        "examples": {
         "backup": {
          "summary": "A backup",
          "value": {
           "id": "4410",
           "type": "closure",
           "created_at": "2027-01-15T22:16:05+01:00",
           "size_bytes": 4718592,
           "app_version": "3.4.1",
           "db_version": "112",
           "device_name": "Pokladna u baru",
           "this_device": true,
           "legacy": false
          },
          "x-summary-cs": "Záloha"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/backups/{backup_id}/content": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "$ref": "#/components/parameters/BackupId"
    }
   ],
   "get": {
    "tags": [
     "Backups"
    ],
    "operationId": "downloadBackup",
    "summary": "Download a backup",
    "x-summary-cs": "Stáhnout zálohu",
    "x-requires-device": true,
    "description": "The ZIP archive of the backup, as the register uploaded it. A backup whose file is no longer stored answers\n`404 not_found`. The archive holds the restaurant's data – do not keep it outside the device.\n",
    "x-description-cs": "Archiv ZIP zálohy tak, jak ho pokladna nahrála. Záloha, jejíž soubor už není uložený, vrátí `404 not_found`.\nArchiv obsahuje data provozovny – mimo zařízení ho neuchovávejte.\n",
    "security": [
     {
      "oauth2": [
       "backups:read"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The archive.",
      "x-description-cs": "Archiv.",
      "headers": {
       "Content-Disposition": {
        "description": "`attachment; filename=\"profirest-backup-{id}.zip\"`",
        "x-description-cs": "`attachment; filename=\"profirest-backup-{id}.zip\"`",
        "schema": {
         "type": "string"
        }
       },
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/zip": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/device-logs": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Diagnostics"
    ],
    "operationId": "createDeviceLogs",
    "summary": "Send device logs",
    "x-summary-cs": "Poslat logy zařízení",
    "x-requires-device": true,
    "x-idempotency": "none",
    "deprecated": true,
    "description": "**Deprecated (26.10.6):** log records no longer go to the database line by line. Keep the log on the device,\nreport errors at once with `reportDeviceError` and upload the whole log only when asked (`checkInDevice`,\n`putLogUploadPart`). The operation still works for older apps and will be removed later.\n\nA batch of the device's log records for Profirest support (at most 500 records, the body at most 1 MB). The\nserver always keeps warnings and errors; `debug` and `info` only while Profirest support has detailed logging on\nfor the restaurant – `min_level` in the answer (`warning`, or `debug` then) says what is kept now; records below\nit are accepted and dropped, so the device need not send them. At most 20,000 records a day are kept from one\ndevice; over that the batch is accepted and dropped (`stored` is lower than `received`). Records are kept for\n2 days after they happened (`logged_at`). Never put passwords, PINs or tokens in the messages; tokens of this API\nare masked anyway.\n\nSending a batch again stores it again – logs are diagnostics, a duplicate does no harm, so no\n`Idempotency-Key`.\n",
    "x-description-cs": "**Zastaralé (26.10.6):** záznamy logu už nejdou do databáze po řádcích. Log nechte na zařízení, chyby hlaste hned\npřes `reportDeviceError` a celý log nahrajte jen na vyžádání (`checkInDevice`, `putLogUploadPart`). Operace\nstarším aplikacím dál funguje a později se odstraní.\n\nDávka záznamů logu zařízení pro podporu Profirestu (nejvýš 500 záznamů, tělo nejvýš 1 MB). Varování a chyby\nserver ukládá vždy, `debug` a `info` jen dokud má podpora Profirestu u provozovny zapnuté podrobné logování –\n`min_level` v odpovědi (`warning`, nebo tehdy `debug`) říká, co se teď ukládá; nižší záznamy se přijmou\na zahodí, takže je zařízení posílat nemusí. Z jednoho zařízení se za den uloží nejvýš 20 000 záznamů; nad to se\ndávka přijme a zahodí (`stored` je menší než `received`). Záznamy se drží 2 dny od chvíle, kdy se staly\n(`logged_at`). Do zpráv nikdy nedávejte hesla, PINy ani tokeny; tokeny tohoto API se stejně zamaskují.\n\nOpakované odeslání dávku uloží znovu – logy jsou diagnostika a duplicita nevadí, proto bez `Idempotency-Key`.\n",
    "security": [
     {
      "oauth2": [
       "diagnostics:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeviceLogBatch"
       },
       "examples": {
        "logs": {
         "summary": "Warnings and errors from a register",
         "value": {
          "events": [
           {
            "level": "warning",
            "logged_at": "2027-01-15T12:01:07+01:00",
            "message": "Tiskárna Účtenky – bar neodpovídá (192.168.1.40).",
            "tag": "printer",
            "employee_name": "Jana Dvořáková"
           },
           {
            "level": "error",
            "logged_at": "2027-01-15T12:01:09+01:00",
            "message": "Tisk účtenky 1001 selhal: timeout.",
            "tag": "printer",
            "employee_name": "Jana Dvořáková"
           },
           {
            "level": "debug",
            "logged_at": "2027-01-15T12:01:10+01:00",
            "message": "Opakuji tisk.",
            "tag": "printer"
           }
          ]
         },
         "x-summary-cs": "Varování a chyby z pokladny"
        }
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "The batch is processed.",
      "x-description-cs": "Dávka je zpracovaná.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeviceLogResult"
        },
        "examples": {
         "accepted": {
          "summary": "Accepted, the debug record skipped",
          "value": {
           "received": 3,
           "stored": 2,
           "min_level": "info"
          },
          "x-summary-cs": "Přijato, ladicí záznam vynechán"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/bug-reports": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Diagnostics"
    ],
    "operationId": "createBugReport",
    "summary": "Report a bug",
    "x-summary-cs": "Nahlásit chybu",
    "x-requires-device": true,
    "x-idempotency": "body-id",
    "description": "A bug report from the device's user for Profirest support, with the recent log records the device attaches.\nThe report goes to support by e-mail, together with what the device sent to `device-logs` in the last hour.\n\n`code` is made by the device and shown to the user, who can quote it on the phone; the same code from the same\ndevice is recorded once (`200` with the first report). At most 10 reports an hour from one device, then\n`429 rate_limited`.\n",
    "x-description-cs": "Hlášení chyby od uživatele zařízení pro podporu Profirestu s nedávnými záznamy logu, které zařízení přiloží.\nHlášení jde podpoře e-mailem spolu s tím, co zařízení za poslední hodinu poslalo do `device-logs`.\n\n`code` vymýšlí zařízení a ukazuje ho uživateli, který ho může nadiktovat do telefonu; stejný kód ze stejného\nzařízení se zapíše jednou (`200` s prvním hlášením). Z jednoho zařízení nejvýš 10 hlášení za hodinu, pak\n`429 rate_limited`.\n",
    "security": [
     {
      "oauth2": [
       "diagnostics:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/BugReportCreate"
       },
       "examples": {
        "report": {
         "summary": "A bug report from a register",
         "value": {
          "code": "PK7-3QD9",
          "description": "Po zaplacení kartou se nevytiskla účtenka.",
          "employee_name": "Jana Dvořáková",
          "app_version": "3.4.1",
          "db_version": "112",
          "os_version": "Android 13",
          "device_model": "Sunmi T2s",
          "logs": [
           {
            "level": "error",
            "logged_at": "2027-01-15T12:01:09+01:00",
            "message": "Tisk účtenky 1001 selhal: timeout.",
            "tag": "printer"
           }
          ]
         },
         "x-summary-cs": "Hlášení chyby z pokladny"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The report is recorded and sent to support.",
      "x-description-cs": "Hlášení je zapsané a odeslané podpoře.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/BugReport"
        },
        "examples": {
         "received": {
          "summary": "The report is received",
          "value": {
           "code": "PK7-3QD9",
           "received_at": "2027-01-15T12:02:15+01:00",
           "logs_attached": 1
          },
          "x-summary-cs": "Hlášení přijaté"
         }
        }
       }
      }
     },
     "200": {
      "description": "A report with this code from this device was already recorded.",
      "x-description-cs": "Hlášení s tímto kódem z tohoto zařízení už je zapsané.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/BugReport"
        },
        "examples": {
         "duplicate": {
          "summary": "The same code again",
          "value": {
           "code": "PK7-3QD9",
           "received_at": "2027-01-15T12:02:15+01:00",
           "logs_attached": 1
          },
          "x-summary-cs": "Stejný kód podruhé"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/device-checkin": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Diagnostics"
    ],
    "operationId": "checkInDevice",
    "summary": "Check the device in",
    "x-summary-cs": "Přihlásit stav zařízení",
    "x-requires-device": true,
    "x-idempotency": "none",
    "description": "The device says it is alive and in what state, and picks up commands – about 500 bytes every 60 seconds from\nthe register, every 5 minutes from a waiter's phone with its own token and internet. The body is the state of\nthe device now: versions, network, the queues waiting to be sent (receipts, payments, print jobs), the last\nbackup, the devices connected to it (`peers` – waiters' phones that talk to the register over the local\nnetwork and have no token of their own), free `counters` (polls, broadcasts, errors – whatever the app counts),\nthe size of its own log store and the results of the commands from the last answer. Logs themselves stay on the\ndevice; the server gets them only on request (see below) and errors at once (`reportDeviceError`).\n\nThe answer carries `commands` to carry out. `upload_logs` – Profirest support or the restaurant asked for\nlogs: for every target in `uploads` upload the log of that device for the period `from`–`to` with the token of\nthe target (`putLogUploadPart`, `completeLogUpload`); the register hands the targets of its peers to them over\nthe local network, a target the device cannot serve ends with `abortLogUpload`. `live_logs` – send warnings too\nand more context with every error until `until`. `ping` – just answer. Every command is handed over once, only\n`upload_logs` comes again (with the same tokens) while one of its targets has sent nothing for 15 minutes; report\nwhat happened in `command_results` of the next check-in (`done`, `failed`, `unsupported`) – an app that does not\nknow a type reports `unsupported`. While a command waits, every answer of this API to the device\ncarries the header `Profirest-Commands: pending` – check in at once instead of waiting for the next minute.\n\nFrom the state the server derives alerts for the restaurant and for Profirest support (a receipt not sent for\n30 minutes, a payment waiting 10 minutes, a print job stuck 15 minutes, no backup for 3 days, a register silent\nfor 5 minutes in opening hours, a peer disconnected for 15 minutes) – the administration shows them under\nDevices. `server_time` in the answer lets the device compute its clock offset for the timestamps in its log\n(`server_offset_ms` of the log header); `next_in_seconds` says when to check in next.\n\nSending the same state again does no harm – no `Idempotency-Key`.\n",
    "x-description-cs": "Zařízení říká, že žije a v jakém je stavu, a vyzvedne si příkazy – asi 500 bajtů každých 60 sekund z kasy,\nkaždých 5 minut z telefonu číšníka s vlastním tokenem a internetem. Tělo je stav zařízení teď: verze, síť,\nfronty čekající na odeslání (účtenky, platby, tisk), poslední záloha, zařízení k němu připojená (`peers` –\ntelefony číšníků, které s kasou mluví po místní síti a vlastní token nemají), volná `counters` (dotazy,\nbroadcasty, chyby – co aplikace počítá), velikost vlastního úložiště logů a výsledky příkazů z minulé odpovědi.\nLogy samotné zůstávají na zařízení; server je dostane jen na vyžádání (níž) a chyby hned (`reportDeviceError`).\n\nOdpověď nese `commands` k vyřízení. `upload_logs` – podpora Profirestu nebo provozovna si vyžádala logy: pro\nkaždý cíl v `uploads` nahrajte log toho zařízení za období `from`–`to` s tokenem cíle (`putLogUploadPart`,\n`completeLogUpload`); kasa cíle svých číšníků předá po místní síti, cíl, který zařízení obsloužit nemůže, skončí\npřes `abortLogUpload`. `live_logs` – posílejte i varování a ke každé chybě víc kontextu až do `until`. `ping` –\njen odpovědět. Každý příkaz se předá jednou, jen `upload_logs` přijde znovu (se stejnými tokeny), dokud některý\njeho cíl 15 minut nic neposlal; co se s příkazem stalo, hlaste v `command_results` dalšího check-inu (`done`,\n`failed`, `unsupported`) – aplikace, která typ nezná, hlásí `unsupported`. Dokud příkaz čeká, nese\nkaždá odpověď tohoto API zařízení hlavičku `Profirest-Commands: pending` – přihlaste stav hned, nečekejte na\ndalší minutu.\n\nZe stavu server odvozuje upozornění pro provozovnu a podporu Profirestu (účtenka neodeslaná 30 minut, platba\nčekající 10 minut, tisk visící 15 minut, záloha starší 3 dnů, kasa mlčící 5 minut v otevírací době, číšník\nodpojený 15 minut) – administrace je ukazuje u Zařízení. `server_time` v odpovědi dá zařízení posun hodin pro\nčasy v jeho logu (`server_offset_ms` hlavičky logu); `next_in_seconds` říká, kdy přihlásit stav příště.\n\nStejný stav poslaný znovu neškodí – bez `Idempotency-Key`.\n",
    "security": [
     {
      "oauth2": [
       "diagnostics:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeviceCheckIn"
       },
       "examples": {
        "alive": {
         "summary": "The register is alive, Jana connected, Petr not",
         "value": {
          "role": "register",
          "app_version": "26.10.3",
          "os_version": "Android 13",
          "device_model": "Sunmi T2s",
          "sent_at": "2027-01-15T12:01:00+01:00",
          "uptime_seconds": 41820,
          "battery": {
           "percent": 100,
           "charging": true
          },
          "network": {
           "type": "wifi",
           "ip": "192.168.1.57",
           "signal_dbm": -58
          },
          "queues": {
           "receipts": {
            "count": 0,
            "oldest_at": null
           },
           "payments": {
            "count": 1,
            "oldest_at": "2027-01-15T11:58:40+01:00"
           },
           "print_jobs": {
            "count": 0,
            "oldest_at": null
           }
          },
          "last_backup_at": "2027-01-15T03:00:12+01:00",
          "last_sync_at": "2027-01-15T12:00:48+01:00",
          "log_store": {
           "segments": 2016,
           "bytes": 22806528,
           "oldest_at": "2027-01-01T12:00:00+01:00",
           "errors_today": 1
          },
          "counters": {
           "polls": 3312,
           "broadcasts": 148,
           "errors": 1,
           "socket_reconnects": 2
          },
          "peers": [
           {
            "key": "9bb5f040",
            "name": "Jana",
            "role": "waiter",
            "app_version": "26.10.3",
            "connected": true,
            "last_seen_at": "2027-01-15T12:00:58+01:00",
            "log_store": true
           },
           {
            "key": "c17d02aa",
            "name": "Petr",
            "role": "waiter",
            "app_version": "26.10.3",
            "connected": false,
            "last_seen_at": "2027-01-15T11:20:03+01:00",
            "log_store": true
           }
          ],
          "command_results": [
           {
            "command_id": "c-5d10b9",
            "status": "done",
            "message": null
           }
          ]
         },
         "x-summary-cs": "Kasa žije, Jana připojená, Petr ne"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The state is recorded; `commands` to carry out.",
      "x-description-cs": "Stav je zapsaný; `commands` k vyřízení.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeviceCheckInResult"
        },
        "examples": {
         "command": {
          "summary": "A command: upload 24 h of logs from the register and Jana",
          "value": {
           "server_time": "2027-01-15T12:01:00+01:00",
           "api_target": {
            "target": "v2",
            "base_url": "https://api.mujprofirest.cz/v2"
           },
           "next_in_seconds": 60,
           "commands": [
            {
             "id": "c-8f2c1a",
             "type": "upload_logs",
             "created_at": "2027-01-15T12:00:35+01:00",
             "expires_at": "2027-01-16T12:00:35+01:00",
             "upload_logs": {
              "request_id": "3105",
              "reason": "karta stržena, stůl 11",
              "from": "2027-01-14T12:00:00+01:00",
              "to": "2027-01-15T12:00:00+01:00",
              "detail": "full",
              "uploads": [
               {
                "upload_id": "7742",
                "peer_key": null,
                "token": "pfl_6Y0Bl8pbgLgDKJGhWSHjW3CGQWKaO2bukl9Z2gxAUPA",
                "upload_url": "https://api.mujprofirest.cz/v2/log-uploads/7742",
                "max_part_bytes": 4194304,
                "expires_at": "2027-01-16T12:00:35+01:00"
               },
               {
                "upload_id": "7743",
                "peer_key": "9bb5f040",
                "token": "pfl_kUeD_3Y4izx2yb8cvfgBkOe-ZP05gv7dvaNvonfEzvg",
                "upload_url": "https://api.mujprofirest.cz/v2/log-uploads/7743",
                "max_part_bytes": 4194304,
                "expires_at": "2027-01-16T12:00:35+01:00"
               }
              ]
             },
             "live_logs": null
            }
           ]
          },
          "x-summary-cs": "Příkaz: nahrát 24 h logů z kasy i od Jany"
         },
         "quiet": {
          "summary": "Nothing to do",
          "value": {
           "server_time": "2027-01-15T12:01:00+01:00",
           "api_target": {
            "target": "v2",
            "base_url": "https://api.mujprofirest.cz/v2"
           },
           "next_in_seconds": 60,
           "commands": []
          },
          "x-summary-cs": "Nic k vyřízení"
         },
         "to_v1": {
          "summary": "The restaurant goes back to API v1",
          "value": {
           "server_time": "2027-01-15T12:01:00+01:00",
           "api_target": {
            "target": "v1",
            "base_url": "https://api.mujprofirest.cz/v2"
           },
           "next_in_seconds": 60,
           "commands": []
          },
          "x-summary-cs": "Provozovna se vrací na API v1"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/device-errors": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "post": {
    "tags": [
     "Diagnostics"
    ],
    "operationId": "reportDeviceError",
    "summary": "Report an error at once",
    "x-summary-cs": "Nahlásit chybu hned",
    "x-requires-device": true,
    "x-idempotency": "body-id",
    "description": "One error (or, in live mode, a warning) from the device's log as it happens, with the log lines before it\n(`context`, about 30 lines, oldest first) – about 3 kB. The server keeps it as a file for 90 days and shows it\nin the administration (Devices → Errors) and to Profirest support; the register reports the errors of its\npeers too (`peer_key`). Of one error the server keeps at most 16 kB of the newest context lines and 16 kB of\n`stack`, and at most 1 MB of such files a day from one device – over that it records the error without them. Mask secrets on the device before sending (PINs, tokens, card numbers); tokens of this\nAPI are masked anyway.\n\n`id` is a UUID made on the device: the same `id` from the same device is recorded once (`200` with the first\nrecord). At most 60 reports an hour from one device, then `429 rate_limited` – keep the rest on the device,\nsupport can ask for the full log. `code` is from the app's own catalog (`SOCK.timeout`, `PAY.pending`,\n`UI.crash` …), `area` the part of the app, `refs` the IDs that were valid at the time (shift, tab, payment\nattempt, request) – the same IDs on the register and on the waiter's phone tell the story together.\n",
    "x-description-cs": "Jedna chyba (v živém režimu i varování) z logu zařízení hned, jak se stane, s řádky logu před ní (`context`,\nasi 30 řádků, od nejstaršího) – kolem 3 kB. Server ji drží jako soubor 90 dní a ukazuje v administraci\n(Zařízení → Chyby) a podpoře Profirestu; kasa hlásí i chyby svých číšníků (`peer_key`). Z jedné chyby server\ndrží nejvýš 16 kB nejnovějších řádků kontextu a 16 kB `stack` a z jednoho zařízení nejvýš 1 MB takových souborů\nza den – nad to chybu zapíše bez nich. Tajemství maskujte na\nzařízení před odesláním (PINy, tokeny, čísla karet); tokeny tohoto API se zamaskují tak jako tak.\n\n`id` je UUID vytvořené na zařízení: stejné `id` z téhož zařízení se zapíše jednou (`200` s prvním záznamem).\nZ jednoho zařízení nejvýš 60 hlášení za hodinu, pak `429 rate_limited` – zbytek nechte na zařízení, podpora si\nmůže vyžádat celý log. `code` je z vlastního číselníku aplikace (`SOCK.timeout`, `PAY.pending`, `UI.crash` …),\n`area` část aplikace, `refs` ID platná v tu chvíli (směna, účet, pokus o platbu, požadavek) – stejná ID na kase\ni u číšníka skládají příběh dohromady.\n",
    "security": [
     {
      "oauth2": [
       "diagnostics:write"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/DeviceErrorCreate"
       },
       "examples": {
        "timeout": {
         "summary": "Jana's payment with no answer from the register",
         "value": {
          "id": "01a318f0-a0c0-7b57-8364-1e6fc225f5ce",
          "occurred_at": "2027-01-15T11:56:17+01:00",
          "level": "error",
          "code": "SOCK.timeout",
          "area": "SOCK",
          "event": "req.timeout",
          "message": "Pay bez odpovědi 20 s (b7e1)",
          "peer_key": "9bb5f040",
          "employee_name": "Jana",
          "app_version": "26.10.3",
          "refs": {
           "session": "s-3f9a",
           "tab": "o-7c21",
           "payment": "p-8f2c",
           "request": "b7e1",
           "broadcast": null
          },
          "context": [
           "{\"t\":\"11:55:36.920\",\"seq\":48200,\"l\":\"I\",\"a\":\"UI\",\"e\":\"tap\",\"sess\":\"s-3f9a\",\"ord\":\"o-7c21\",\"intent\":\"PayCard\",\"sum\":25000}",
           "{\"t\":\"11:55:57.703\",\"seq\":48204,\"l\":\"I\",\"a\":\"PAY\",\"e\":\"terminal.ok\",\"pay\":\"p-8f2c\",\"auth\":\"1dc15286\",\"pan\":\"****4821\",\"ms\":20742}",
           "{\"t\":\"11:55:57.750\",\"seq\":48206,\"l\":\"I\",\"a\":\"SOCK\",\"e\":\"req.send\",\"ord\":\"o-7c21\",\"pay\":\"p-8f2c\",\"rid\":\"b7e1\",\"op\":\"Pay\",\"kb\":1.9}",
           "{\"t\":\"11:56:16.004\",\"seq\":48208,\"l\":\"I\",\"a\":\"ENV\",\"e\":\"net.change\",\"from\":\"wifi\",\"to\":\"lte\",\"ip\":\"10.21.4.88\"}"
          ],
          "stack": null
         },
         "x-summary-cs": "Platba u Jany bez odpovědi kasy"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The error is recorded.",
      "x-description-cs": "Chyba je zapsaná.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeviceErrorResult"
        },
        "examples": {
         "recorded": {
          "summary": "Recorded",
          "value": {
           "id": "90115",
           "received_at": "2027-01-15T11:56:18+01:00"
          },
          "x-summary-cs": "Zapsáno"
         }
        }
       }
      }
     },
     "200": {
      "description": "An error with this `id` from this device was already recorded.",
      "x-description-cs": "Chyba s tímto `id` z tohoto zařízení už je zapsaná.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeviceErrorResult"
        },
        "examples": {
         "duplicate": {
          "summary": "The same id again",
          "value": {
           "id": "90115",
           "received_at": "2027-01-15T11:56:18+01:00"
          },
          "x-summary-cs": "Stejné id podruhé"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "description": "`rate_limited` (requests of the connection or device), or a limit of the operation – `staff_locked`, `voucher_attempts_exceeded`, `verification_resend_too_early`, `sms_quota_exceeded`; see `code`. Wait `Retry-After` seconds.",
      "x-description-cs": "`rate_limited` (požadavky připojení nebo zařízení), nebo limit operace – `staff_locked`, `voucher_attempts_exceeded`, `verification_resend_too_early`, `sms_quota_exceeded`; viz `code`. Počkejte `Retry-After` sekund.",
      "headers": {
       "Retry-After": {
        "$ref": "#/components/headers/RetryAfter"
       }
      },
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "rate_limited": {
          "summary": "More than 60 reports an hour",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#rate_limited",
           "title": "Příliš mnoho požadavků",
           "status": 429,
           "code": "rate_limited",
           "detail": "Z jednoho zařízení nejvýš 60 hlášení za hodinu.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Víc než 60 hlášení za hodinu"
         }
        }
       }
      }
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/log-uploads/{upload_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/UploadId"
    }
   ],
   "get": {
    "tags": [
     "Diagnostics"
    ],
    "operationId": "getLogUpload",
    "summary": "State of a log upload",
    "x-summary-cs": "Stav nahrávání logu",
    "description": "Where one target of an `upload_logs` command stands: which parts the server has (`parts_received`) and whether\nthe upload is still open. After an interruption read it and send only the missing parts. The token of the\ntarget (`pfl_…` from the command) is the `Authorization: Bearer` – no device token, so a waiter's phone without\na token of its own uploads too.\n",
    "x-description-cs": "Jak je na tom jeden cíl příkazu `upload_logs`: které části server má (`parts_received`) a jestli je nahrávání\nještě otevřené. Po přerušení ho přečtěte a pošlete jen chybějící části. Token cíle (`pfl_…` z příkazu) je\n`Authorization: Bearer` – žádný token zařízení, takže nahrává i telefon číšníka bez vlastního tokenu.\n",
    "security": [
     {
      "logUpload": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The upload.",
      "x-description-cs": "Nahrávání.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LogUploadStatus"
        },
        "examples": {
         "partial": {
          "summary": "Two parts arrived, the upload is open",
          "value": {
           "id": "7742",
           "request_id": "3105",
           "status": "uploading",
           "parts_received": [
            1,
            2
           ],
           "parts_expected": null,
           "bytes": 3145728,
           "from": "2027-01-14T12:00:00+01:00",
           "to": "2027-01-15T12:00:00+01:00",
           "detail": "full",
           "max_part_bytes": 4194304,
           "expires_at": "2027-01-16T12:00:35+01:00"
          },
          "x-summary-cs": "Dvě části došly, nahrávání otevřené"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/log-uploads/{upload_id}/parts/{part}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/UploadId"
    },
    {
     "name": "part",
     "in": "path",
     "required": true,
     "description": "Number of the part, from 1 in order.",
     "x-description-cs": "Číslo části, od 1 po pořadí.",
     "schema": {
      "type": "integer",
      "minimum": 1,
      "maximum": 500
     },
     "example": 3
    }
   ],
   "put": {
    "tags": [
     "Diagnostics"
    ],
    "operationId": "putLogUploadPart",
    "summary": "Upload a part of the log",
    "x-summary-cs": "Nahrát část logu",
    "description": "One part of the log file: the body is gzip (`Content-Type: application/gzip`), at most 4 MB, with whole lines\nof NDJSON – the server joins the parts in order into one gzip file without unpacking (gzip members concatenate),\nso every part is a complete gzip stream of its own. Parts of 1–2 MB go well over a slow line; an interrupted\nupload continues with the next part, a part sent again replaces the earlier one. Upload outside the queue of\norders and payments and pause it while the staff pays.\n\nOne upload holds at most 200 MB, all uploads of one request together 500 MB – over that `413 payload_too_large`\n(ask for a shorter period or only the trace). When the server's storage is nearly full it answers\n`503 service_unavailable` with `Retry-After`; keep the log and try later. Requests for the same upload run one\nat a time – one that waits too long answers `409 conflict` with `Retry-After`.\n\nThe token of the target (`pfl_…`) is the `Authorization: Bearer`. A finished or expired upload answers\n`409 upload_closed`.\n",
    "x-description-cs": "Jedna část souboru logu: tělem je gzip (`Content-Type: application/gzip`), nejvýš 4 MB, s celými řádky NDJSON\n– server části po pořadí spojí do jednoho souboru gzip bez rozbalení (členy gzipu se dají zřetězit), takže každá\nčást je sama o sobě úplný proud gzip. Části po 1–2 MB projdou i pomalou linkou; přerušené nahrávání pokračuje\ndalší částí, část poslaná znovu nahradí tu dřívější. Nahrávejte mimo frontu objednávek a plateb a během placení\nnahrávání pozastavte.\n\nJedno nahrávání má nejvýš 200 MB, všechna nahrávání jedné žádosti dohromady 500 MB – nad to\n`413 payload_too_large` (vyžádejte kratší období nebo jen stopu). Když je úložiště serveru skoro plné, odpoví\n`503 service_unavailable` s `Retry-After`; log si nechte a zkuste to později. Požadavky na totéž nahrávání běží\njeden po druhém – ten, který čeká příliš dlouho, odpoví `409 conflict` s `Retry-After`.\n\nToken cíle (`pfl_…`) je `Authorization: Bearer`. Dokončené nebo prošlé nahrávání odpoví `409 upload_closed`.\n",
    "security": [
     {
      "logUpload": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "x-max-bytes": 4194304,
     "content": {
      "application/gzip": {
       "schema": {
        "type": "string",
        "format": "binary"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The part is stored.",
      "x-description-cs": "Část je uložená.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LogUploadStatus"
        },
        "examples": {
         "stored": {
          "summary": "The third part is stored",
          "value": {
           "id": "7742",
           "request_id": "3105",
           "status": "uploading",
           "parts_received": [
            1,
            2,
            3
           ],
           "parts_expected": null,
           "bytes": 4718592,
           "from": "2027-01-14T12:00:00+01:00",
           "to": "2027-01-15T12:00:00+01:00",
           "detail": "full",
           "max_part_bytes": 4194304,
           "expires_at": "2027-01-16T12:00:35+01:00"
          },
          "x-summary-cs": "Třetí část uložená"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "upload_closed": {
          "summary": "The upload is finished or expired",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#upload_closed",
           "title": "Nahrávání logu je dokončené nebo prošlé",
           "status": 409,
           "code": "upload_closed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Nahrávání je dokončené nebo prošlé"
         }
        }
       }
      }
     },
     "413": {
      "description": "`payload_too_large`: the body is larger than the operation allows.",
      "x-description-cs": "`payload_too_large`: tělo je větší, než operace dovolí.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "payload_too_large": {
          "summary": "The part is over 4 MB",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#payload_too_large",
           "title": "Požadavek je příliš velký",
           "status": 413,
           "code": "payload_too_large",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Část je větší než 4 MB"
         }
        }
       }
      }
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "$ref": "#/components/responses/ServiceUnavailable"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     }
    }
   }
  },
  "/log-uploads/{upload_id}/complete": {
   "parameters": [
    {
     "$ref": "#/components/parameters/UploadId"
    }
   ],
   "post": {
    "tags": [
     "Diagnostics"
    ],
    "operationId": "completeLogUpload",
    "summary": "Finish the log upload",
    "x-summary-cs": "Dokončit nahrávání logu",
    "x-idempotency": "none",
    "description": "All parts are there: `parts` says how many, the server joins them and closes the upload (`status` `done`).\nA missing part answers `422 upload_incomplete` with the numbers in `detail` – send them and complete again.\n`lines`, `from` and `to` describe what the file holds (shown to support). Completing a finished upload again\njust answers its state.\n",
    "x-description-cs": "Všechny části jsou tam: `parts` říká kolik, server je spojí a nahrávání uzavře (`status` `done`). Chybějící část\nodpoví `422 upload_incomplete` s čísly v `detail` – pošlete je a dokončete znovu. `lines`, `from` a `to`\npopisují, co soubor nese (ukáže se podpoře). Dokončení už hotového nahrávání jen odpoví jeho stav.\n",
    "security": [
     {
      "logUpload": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LogUploadComplete"
       },
       "examples": {
        "done": {
         "summary": "Three parts, 184,210 lines",
         "value": {
          "parts": 3,
          "lines": 184210,
          "from": "2027-01-14T12:00:00+01:00",
          "to": "2027-01-15T11:59:58+01:00",
          "sha256": null
         },
         "x-summary-cs": "Tři části, 184 210 řádků"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The upload is complete.",
      "x-description-cs": "Nahrávání je dokončené.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LogUploadStatus"
        },
        "examples": {
         "complete": {
          "summary": "The file is joined, the upload is done",
          "value": {
           "id": "7742",
           "request_id": "3105",
           "status": "done",
           "parts_received": [
            1,
            2,
            3
           ],
           "parts_expected": 3,
           "bytes": 4718592,
           "from": "2027-01-14T12:00:00+01:00",
           "to": "2027-01-15T12:00:00+01:00",
           "detail": "full",
           "max_part_bytes": 4194304,
           "expires_at": "2027-01-16T12:00:35+01:00"
          },
          "x-summary-cs": "Soubor spojený, nahrávání hotové"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "upload_closed": {
          "summary": "The upload was withdrawn",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#upload_closed",
           "title": "Nahrávání logu je dokončené nebo prošlé",
           "status": 409,
           "code": "upload_closed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Nahrávání je stažené"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "upload_incomplete": {
          "summary": "The second part is missing",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#upload_incomplete",
           "title": "Části nahrávání logu chybí",
           "status": 422,
           "code": "upload_incomplete",
           "detail": "Missing parts: 2",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chybí druhá část"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/log-uploads/{upload_id}/abort": {
   "parameters": [
    {
     "$ref": "#/components/parameters/UploadId"
    }
   ],
   "post": {
    "tags": [
     "Diagnostics"
    ],
    "operationId": "abortLogUpload",
    "summary": "Give the log upload up",
    "x-summary-cs": "Vzdát nahrávání logu",
    "x-idempotency": "none",
    "description": "The device cannot serve this target: `reason` `unsupported` (the app has no log store), `no_data` (nothing for\nthe period – the log store is shorter, the device was off), `failed` (an error the device cannot get past,\nsay what in `message`) or `declined`. The upload closes with that status and support sees why. Parts already\nsent are discarded.\n",
    "x-description-cs": "Zařízení tento cíl obsloužit nemůže: `reason` `unsupported` (aplikace úložiště logů nemá), `no_data` (za období\nnic není – úložiště je kratší, zařízení bylo vypnuté), `failed` (chyba, přes kterou se zařízení nedostane, co\npřesně řekne `message`) nebo `declined`. Nahrávání se uzavře s tím stavem a podpora vidí proč. Už poslané části\nse zahodí.\n",
    "security": [
     {
      "logUpload": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LogUploadAbort"
       },
       "examples": {
        "no_data": {
         "summary": "The waiter's log store reaches only 6 hours back",
         "value": {
          "reason": "no_data",
          "message": "Úložiště začíná 15. 1. 06:10, žádaný začátek je 14. 1. 12:00."
         },
         "x-summary-cs": "Úložiště číšníka sahá jen 6 hodin zpět"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The upload is closed.",
      "x-description-cs": "Nahrávání je uzavřené.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/LogUploadStatus"
        },
        "examples": {
         "closed": {
          "summary": "The upload is closed with no data",
          "value": {
           "id": "7743",
           "request_id": "3105",
           "status": "no_data",
           "parts_received": [],
           "parts_expected": null,
           "bytes": 0,
           "from": "2027-01-14T12:00:00+01:00",
           "to": "2027-01-15T12:00:00+01:00",
           "detail": "full",
           "max_part_bytes": 4194304,
           "expires_at": "2027-01-16T12:00:35+01:00"
          },
          "x-summary-cs": "Nahrávání uzavřené bez dat"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "upload_closed": {
          "summary": "The upload is already finished",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#upload_closed",
           "title": "Nahrávání logu je dokončené nebo prošlé",
           "status": 409,
           "code": "upload_closed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Nahrávání už je dokončené"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/events": {
   "get": {
    "tags": [
     "Events"
    ],
    "operationId": "listEvents",
    "summary": "Change feed",
    "x-summary-cs": "Proud změn",
    "description": "Events of your connection in the order they were written (`sequence`), after the given cursor. This is the\nsource of truth: webhooks only tell you that something new is here; `streamEvents` gives the same events live,\nwith the same cursor, without polling. You get only the event types your\nscopes allow: `order.*` needs `orders:read`, `catalog.changed`, `availability.changed` and `promotions.changed`\nneed `catalog:read`,\n`restaurant.changed` needs `restaurants:read`, `attendance.updated` needs `attendance:read`, `kitchen.*` needs\n`kitchen:read`, `call.*` needs `directory:read`, `receipt.*`, `pos_shift.*` and `tab.*` need `receipts:read`,\n`sale.*` and `shift.*` need `reports:read`, `table.*` needs `table:sync`, `reservation.*` needs\n`reservations:read`, `courier.*` needs `deliveries:read`; `grant.*` always comes.\n\nWithout `cursor` the feed starts at the current end (no old events, just a cursor to continue from). Events\nappear in the feed a few seconds after the change, never before an event with a lower `sequence`, so the cursor\nnever skips one. They are kept for 30 days (`courier.position` only for 24 hours – it is a live location, reload\n`listCourierPositions`); an older cursor answers `410 cursor_expired`, then reload the state\nyou need and start again without a cursor. An empty page returns a cursor at the same position, refreshed – a\nfeed you keep reading never expires, even when nothing happens for weeks.\n",
    "x-description-cs": "Události vašeho připojení v pořadí zápisu (`sequence`), po zadaném kurzoru. Toto je zdroj pravdy: webhooky\njen říkají, že je tu něco nového; `streamEvents` dává tytéž události živě, se stejným kurzorem a bez dotazování.\nDostanete jen typy událostí, které vaše oprávnění dovolují: `order.*`\nvyžaduje `orders:read`, `catalog.changed`, `availability.changed` a `promotions.changed` vyžadují `catalog:read`,\n`restaurant.changed`\nvyžaduje `restaurants:read`, `attendance.updated` vyžaduje `attendance:read`, `kitchen.*` vyžaduje\n`kitchen:read`, `call.*` vyžaduje `directory:read`, `receipt.*`, `pos_shift.*` a `tab.*` vyžadují\n`receipts:read`, `sale.*` a `shift.*` vyžadují `reports:read`, `table.*` vyžaduje `table:sync`, `reservation.*`\nvyžaduje `reservations:read`, `courier.*` vyžaduje `deliveries:read`; `grant.*` přijde vždy.\n\nBez `cursor` začíná proud na aktuálním konci (žádné staré události, jen kurzor, od kterého pokračovat).\nUdálosti se v proudu objeví pár sekund po změně, nikdy před událostí s nižším `sequence`, takže kurzor žádnou\nnepřeskočí. Drží se 30 dní (`courier.position` jen 24 hodin – je to živá poloha, načtěte znovu\n`listCourierPositions`); starší kurzor vrátí `410 cursor_expired`, pak si potřebný stav načtěte znovu\na začněte bez kurzoru. Prázdná stránka vrátí kurzor na stejném místě, obnovený – proud, který čtete, nikdy\nnevyprší, ani když se týdny nic neděje.\n",
    "security": [
     {
      "oauth2": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "$ref": "#/components/parameters/Limit"
     },
     {
      "name": "restaurant_id",
      "in": "query",
      "required": false,
      "description": "Only events of this restaurant.",
      "x-description-cs": "Jen události této provozovny.",
      "schema": {
       "$ref": "#/components/schemas/Id"
      },
      "example": "123"
     },
     {
      "name": "types",
      "in": "query",
      "required": false,
      "description": "Comma-separated event types, for example `order.status_changed,catalog.changed`, or whole groups such as\n`order.*` (every type that starts with `order.`), the same as `streamEvents`. Another form answers `422`\nwith `invalid_format`; a well-formed type that does not exist or that your scopes do not allow simply matches\nnothing.\n",
      "x-description-cs": "Typy událostí oddělené čárkou, například `order.status_changed,catalog.changed`, nebo celé skupiny jako\n`order.*` (všechny typy začínající `order.`) stejně jako `streamEvents`. Jiný tvar vrátí `422`\ns `invalid_format`; správně zapsaný typ, který neexistuje nebo který vaše oprávnění nedovolují, prostě nic\nnenajde.\n",
      "schema": {
       "type": "string",
       "maxLength": 500
      }
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "A page of events.",
      "x-description-cs": "Stránka událostí.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/EventPage"
        },
        "examples": {
         "events": {
          "summary": "New events since the cursor",
          "value": {
           "data": [
            {
             "id": "910551",
             "api_version": "2",
             "sequence": 910551,
             "type": "order.created",
             "occurred_at": "2027-01-15T11:42:31+01:00",
             "connection_id": "2208",
             "account_id": "7",
             "restaurant_id": "123",
             "data": {
              "id": "184223",
              "restaurant_id": "123",
              "kitchen_number": "027",
              "status": "received",
              "status_changed_at": "2027-01-15T11:42:31+01:00",
              "created_at": "2027-01-15T11:42:31+01:00",
              "payment_deadline": null,
              "fulfillment": {
               "type": "pickup",
               "speed": "standard",
               "asap": true,
               "time": null,
               "estimated_at": "2027-01-15T12:05:00+01:00"
              },
              "customer": {
               "customer_id": null,
               "name": "Jana Nováková",
               "phone": "+420777123456",
               "email": "jana.novakova@example.cz"
              },
              "delivery": null,
              "lines": [
               {
                "id": "1",
                "type": "product",
                "product_id": "4567",
                "name": "Svíčková na smetaně, houskový knedlík",
                "quantity": 2,
                "base_unit_price": {
                 "amount": 19900,
                 "currency": "CZK"
                },
                "unit_price": {
                 "amount": 19900,
                 "currency": "CZK"
                },
                "packaging_unit_price": null,
                "vat_rate": "12",
                "add_ons": [],
                "options": [],
                "parts": null,
                "removed_ingredients": [],
                "note": null,
                "total": {
                 "amount": 39800,
                 "currency": "CZK"
                },
                "gift_of": null
               }
              ],
              "charges": [],
              "discounts": [],
              "totals": {
               "items": {
                "amount": 39800,
                "currency": "CZK"
               },
               "charges": {
                "amount": 0,
                "currency": "CZK"
               },
               "discounts": {
                "amount": 0,
                "currency": "CZK"
               },
               "rounding": {
                "amount": 0,
                "currency": "CZK"
               },
               "total": {
                "amount": 39800,
                "currency": "CZK"
               },
               "vat": [
                {
                 "rate": "12",
                 "base": {
                  "amount": 35536,
                  "currency": "CZK"
                 },
                 "vat": {
                  "amount": 4264,
                  "currency": "CZK"
                 },
                 "total": {
                  "amount": 39800,
                  "currency": "CZK"
                 }
                }
               ]
              },
              "payments": [
               {
                "id": "301877",
                "method": "cash",
                "status": "unpaid",
                "amount": {
                 "amount": 39800,
                 "currency": "CZK"
                },
                "provider": null,
                "reference": null,
                "voucher_code": null,
                "forfeited": null
               }
              ],
              "amount_to_collect": {
               "amount": 39800,
               "currency": "CZK"
              },
              "loyalty_points_earned": null,
              "note": null,
              "cancellation": null,
              "external_id": "A-2027-000123",
              "metadata": {
               "branch": "praha-3"
              }
             }
            },
            {
             "id": "910563",
             "api_version": "2",
             "sequence": 910563,
             "type": "order.status_changed",
             "occurred_at": "2027-01-15T11:44:02+01:00",
             "connection_id": "2208",
             "account_id": "7",
             "restaurant_id": "123",
             "data": {
              "id": "184223",
              "restaurant_id": "123",
              "kitchen_number": "027",
              "status": "preparing",
              "status_changed_at": "2027-01-15T11:44:02+01:00",
              "created_at": "2027-01-15T11:42:31+01:00",
              "payment_deadline": null,
              "fulfillment": {
               "type": "pickup",
               "speed": "standard",
               "asap": true,
               "time": null,
               "estimated_at": "2027-01-15T12:05:00+01:00"
              },
              "customer": {
               "customer_id": null,
               "name": "Jana Nováková",
               "phone": "+420777123456",
               "email": "jana.novakova@example.cz"
              },
              "delivery": null,
              "lines": [
               {
                "id": "1",
                "type": "product",
                "product_id": "4567",
                "name": "Svíčková na smetaně, houskový knedlík",
                "quantity": 2,
                "base_unit_price": {
                 "amount": 19900,
                 "currency": "CZK"
                },
                "unit_price": {
                 "amount": 19900,
                 "currency": "CZK"
                },
                "packaging_unit_price": null,
                "vat_rate": "12",
                "add_ons": [],
                "options": [],
                "parts": null,
                "removed_ingredients": [],
                "note": null,
                "total": {
                 "amount": 39800,
                 "currency": "CZK"
                },
                "gift_of": null
               }
              ],
              "charges": [],
              "discounts": [],
              "totals": {
               "items": {
                "amount": 39800,
                "currency": "CZK"
               },
               "charges": {
                "amount": 0,
                "currency": "CZK"
               },
               "discounts": {
                "amount": 0,
                "currency": "CZK"
               },
               "rounding": {
                "amount": 0,
                "currency": "CZK"
               },
               "total": {
                "amount": 39800,
                "currency": "CZK"
               },
               "vat": [
                {
                 "rate": "12",
                 "base": {
                  "amount": 35536,
                  "currency": "CZK"
                 },
                 "vat": {
                  "amount": 4264,
                  "currency": "CZK"
                 },
                 "total": {
                  "amount": 39800,
                  "currency": "CZK"
                 }
                }
               ]
              },
              "payments": [
               {
                "id": "301877",
                "method": "cash",
                "status": "unpaid",
                "amount": {
                 "amount": 39800,
                 "currency": "CZK"
                },
                "provider": null,
                "reference": null,
                "voucher_code": null,
                "forfeited": null
               }
              ],
              "amount_to_collect": {
               "amount": 39800,
               "currency": "CZK"
              },
              "loyalty_points_earned": null,
              "note": null,
              "cancellation": null,
              "external_id": "A-2027-000123",
              "metadata": {
               "branch": "praha-3"
              }
             }
            },
            {
             "id": "910570",
             "api_version": "2",
             "sequence": 910570,
             "type": "availability.changed",
             "occurred_at": "2027-01-15T11:45:10+01:00",
             "connection_id": "2208",
             "account_id": "7",
             "restaurant_id": "123",
             "data": {
              "restaurant_id": "123"
             }
            }
           ],
           "next_cursor": "eyJzZXEiOjkxMDU3MH0"
          },
          "x-summary-cs": "Nové události od kurzoru"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "410": {
      "description": "`cursor_expired`: the cursor was issued more than 30 days ago – events since then may be gone.",
      "x-description-cs": "`cursor_expired`: kurzor byl vydán před víc než 30 dny – události od té doby už mohou být pryč.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "cursor_expired": {
          "summary": "The cursor is too old",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#cursor_expired",
           "title": "Kurzor vypršel",
           "status": 410,
           "code": "cursor_expired",
           "detail": "Načtěte stav znovu a pokračujte bez kurzoru.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Kurzor je moc starý"
         }
        }
       }
      }
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/events/stream": {
   "get": {
    "tags": [
     "Events"
    ],
    "operationId": "streamEvents",
    "summary": "Change feed live (Server-Sent Events)",
    "x-summary-cs": "Proud změn živě (Server-Sent Events)",
    "x-stream": "sse",
    "description": "The same events as `listEvents` – the same order, the same scopes and the same delay of a few seconds after the\nchange – pushed over one long-lived response `text/event-stream` instead of polling. Use it where you wait for\nchanges: kitchen displays, registers, integrations on a server.\n\nEvery event is one message: `event:` is the event type, `data:` the `Event` as JSON on one line and `id:` the\ncursor after this event – the same cursor as `next_cursor` of `listEvents`. After a disconnection connect again\nwith the last `id` in the header `Last-Event-ID` (or as `?cursor=`) and nothing is skipped; you can switch\nbetween the stream and `listEvents` at any time with the same cursor. Without a cursor the stream starts at the\ncurrent end. The first message is `ready` (`StreamReady`; its `id` is the cursor of the current position), then\nthe events; a comment `: ping` comes after 25 seconds without a message.\n\nThe stream ends by itself; then connect again. The message `closing` (`StreamClosing`) tells why: `max_age`\n(after 30 minutes – reconnect at once), `token_expired` and `token_revoked` (refresh the access token first),\n`restart` (a new version of the service – reconnect in 1–10 seconds at random), `forbidden` (the connection no\nlonger has the restaurant of `restaurant_id` – do not repeat the same request). Without `closing` (a network\nfailure) reconnect with a pause growing from 1 second to 1 minute.\n\nThe access token goes only in the header `Authorization`, never in the URL. The browser's `EventSource` cannot\nsend it – read the stream with `fetch` (`watchEvents` of `profirest-api.js` does it). At most 3 streams for one\ndevice or one token and 200 for one connection, over that `429`. When the stream is not available (`503` with\n`Retry-After`, or `stream_url` of `getApiRoot` is `null`), poll `listEvents` and try the stream again later.\n",
    "x-description-cs": "Tytéž události jako `listEvents` – stejné pořadí, stejná oprávnění a stejné zpoždění pár sekund po změně –\nposílané jednou dlouhou odpovědí `text/event-stream` místo dotazování. Hodí se všude, kde se čeká na změny:\nkuchyňské displeje, pokladny, integrace na serveru.\n\nKaždá událost je jedna zpráva: `event:` je typ události, `data:` `Event` jako JSON na jednom řádku a `id:` kurzor\nza touto událostí – stejný kurzor jako `next_cursor` z `listEvents`. Po výpadku se připojte znovu s posledním `id`\nv hlavičce `Last-Event-ID` (nebo jako `?cursor=`) a nic se nepřeskočí; mezi proudem a `listEvents` jde kdykoli\npřecházet se stejným kurzorem. Bez kurzoru začne proud na aktuálním konci. První zpráva je `ready`\n(`StreamReady`; její `id` je kurzor aktuálního místa), pak chodí události; po 25 sekundách bez zprávy přijde\nkomentář `: ping`.\n\nProud končí sám; pak se připojte znovu. Zpráva `closing` (`StreamClosing`) říká proč: `max_age` (po 30 minutách\n– připojit hned), `token_expired` a `token_revoked` (nejdřív obnovit access token), `restart` (nová verze služby\n– znovu za 1–10 sekund náhodně), `forbidden` (připojení už nemá provozovnu z `restaurant_id` – stejný požadavek\nneopakovat). Bez `closing` (výpadek sítě) se připojujte znovu s pauzou rostoucí od 1 sekundy do 1 minuty.\n\nAccess token patří jen do hlavičky `Authorization`, nikdy do adresy. Prohlížečový `EventSource` ho poslat neumí –\nproud čtěte přes `fetch` (dělá to `watchEvents` z `profirest-api.js`). Nejvýš 3 proudy na jedno zařízení nebo\njeden token a 200 na jedno připojení, nad to `429`. Když proud není k dispozici (`503` s `Retry-After`, nebo\n`stream_url` z `getApiRoot` je `null`), ptejte se přes `listEvents` a o proud se pokuste znovu později.\n",
    "security": [
     {
      "oauth2": []
     }
    ],
    "parameters": [
     {
      "name": "Last-Event-ID",
      "in": "header",
      "required": false,
      "description": "The `id` of the last message you processed (a cursor). Takes precedence over `cursor`.",
      "x-description-cs": "`id` poslední zprávy, kterou jste zpracovali (kurzor). Má přednost před `cursor`.",
      "schema": {
       "type": "string",
       "maxLength": 512
      }
     },
     {
      "$ref": "#/components/parameters/Cursor"
     },
     {
      "name": "restaurant_id",
      "in": "query",
      "required": false,
      "description": "Only events of this restaurant.",
      "x-description-cs": "Jen události této provozovny.",
      "schema": {
       "$ref": "#/components/schemas/Id"
      },
      "example": "123"
     },
     {
      "name": "types",
      "in": "query",
      "required": false,
      "description": "Comma-separated event types or groups such as `order.*`, the same as in `listEvents`.",
      "x-description-cs": "Typy událostí oddělené čárkou nebo skupiny jako `order.*`, stejně jako v `listEvents`.",
      "schema": {
       "type": "string",
       "maxLength": 500
      },
      "example": "order.*,kitchen.*"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The stream: `ready` (`StreamReady`), then one message for every event (`event:` the type, `data:` the\n`Event`, `id:` the cursor), comments `: ping`, at the end possibly `closing` (`StreamClosing`).\n",
      "x-description-cs": "Proud: `ready` (`StreamReady`), pak jedna zpráva za každou událost (`event:` typ, `data:` `Event`, `id:`\nkurzor), komentáře `: ping`, na konci případně `closing` (`StreamClosing`).\n",
      "x-sse-messages": {
       "ready": {
        "$ref": "#/components/schemas/StreamReady"
       },
       "closing": {
        "$ref": "#/components/schemas/StreamClosing"
       },
       "event": {
        "$ref": "#/components/schemas/Event"
       }
      },
      "content": {
       "text/event-stream": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "410": {
      "description": "`cursor_expired`: the cursor was issued more than 30 days ago – events since then may be gone.",
      "x-description-cs": "`cursor_expired`: kurzor byl vydán před víc než 30 dny – události od té doby už mohou být pryč.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "cursor_expired": {
          "summary": "The cursor is too old",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#cursor_expired",
           "title": "Kurzor vypršel",
           "status": 410,
           "code": "cursor_expired",
           "detail": "Načtěte stav znovu a pokračujte bez kurzoru.",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Kurzor je moc starý"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "$ref": "#/components/responses/StreamUnavailable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     }
    }
   }
  },
  "/table/sessions": {
   "post": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "startTableSession",
    "summary": "Join a table by the code from its QR",
    "x-summary-cs": "Připojit se ke stolu kódem z QR",
    "x-idempotency": "none",
    "description": "The backup path of ordering from the table, for a phone that cannot reach the main register of the restaurant\nover its Wi-Fi. The guest app sends the code of the table from the QR code (`table_code`) and gets a token of\nthis phone at this table. The main register decides about everything: requests reach it through the cloud, so\n`ordering.blocked_reason` is `connecting` until the register takes the phone over (usually within seconds).\n\nSend the token as `Authorization: Bearer pfg_…` with the other operations of this tag. It works for nothing\nelse, for at most 12 hours and only until the visit of the table ends (`410 visit_ended`). When the app already\nhas a token of the same table, send it too: the same phone gets a new token instead of becoming another phone.\nCall this operation only after the guest scanned the QR code (or tapped „start again“), never on its own after\n`visit_ended` – a phone left open must not join the next party at the table.\n\n`table_not_found` – no table has this code; `ordering_disabled` – the restaurant does not take orders from the\ntable. At most 20 requests a minute from one address.\n",
    "x-description-cs": "Záložní cesta objednávání od stolu pro telefon, který se k hlavní kase podniku nedostane přes jeho Wi-Fi.\nAplikace hosta pošle kód stolu z QR kódu (`table_code`) a dostane token tohoto telefonu u tohoto stolu.\nO všem rozhoduje hlavní kasa: požadavky k ní jdou přes cloud, proto je `ordering.blocked_reason` `connecting`,\ndokud si kasa telefon nepřevezme (obvykle během pár sekund).\n\nToken posílejte jako `Authorization: Bearer pfg_…` u ostatních operací této skupiny. Na nic jiného nejde, platí\nnejvýš 12 hodin a jen do konce návštěvy stolu (`410 visit_ended`). Když aplikace už má token téhož stolu,\npošlete ho také: týž telefon dostane nový token, místo aby z něj byl další telefon. Tuto operaci volejte jen\npoté, co host naskenoval QR kód (nebo klepl na „začít znovu“), nikdy sama po `visit_ended` – telefon nechaný\notevřený se nesmí přidat k další skupině u stolu.\n\n`table_not_found` – žádný stůl nemá tento kód; `ordering_disabled` – podnik objednávky od stolu nebere.\nNejvýš 20 požadavků za minutu z jedné adresy.\n",
    "security": [
     {},
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TableSessionStart"
       },
       "examples": {
        "scan": {
         "summary": "A guest scanned the QR code on the table",
         "value": {
          "table_code": "K7M2Q9XB"
         },
         "x-summary-cs": "Host naskenoval QR na stole"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "A new phone at the table.",
      "x-description-cs": "Nový telefon u stolu.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableSessionCreated"
        },
        "examples": {
         "new": {
          "summary": "A new phone – the register has not taken it over yet",
          "value": {
           "token": "pfg_NP6O2CxGkkaev4zBkA30OFr-zMN58zpbrnEsJ1g3hgA",
           "expires_at": "2027-01-16T06:30:05+01:00",
           "session": {
            "path": "cloud",
            "restaurant": {
             "name": "Bistro U Lípy"
            },
            "table": {
             "id": "5012",
             "name": "Stůl 5",
             "room": "Zahrádka"
            },
            "visit": null,
            "device": {
             "id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
             "nickname": "Host",
             "verified": false,
             "verified_by": null,
             "join_locked": false,
             "join_attempts_left": 5
            },
            "ordering": {
             "enabled": true,
             "paused": false,
             "can_order": false,
             "blocked_reason": "connecting",
             "confirm_mode": "first",
             "needs_confirmation": true,
             "max_quantity": 10,
             "note_max_length": 32,
             "empty_table": "staff"
            },
            "join": {
             "enabled": true,
             "code": null
            },
            "calls": []
           }
          },
          "x-summary-cs": "Nový telefon – kasa si ho ještě nepřevzala"
         }
        }
       }
      }
     },
     "200": {
      "description": "The same phone (the token you sent) with a new token; the old one stops working.",
      "x-description-cs": "Týž telefon (token, který jste poslali) s novým tokenem; starý přestane platit.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableSessionCreated"
        },
        "examples": {
         "again": {
          "summary": "The same phone after a new scan",
          "value": {
           "token": "pfg_NP6O2CxGkkaev4zBkA30OFr-zMN58zpbrnEsJ1g3hgA",
           "expires_at": "2027-01-16T06:30:05+01:00",
           "session": {
            "path": "cloud",
            "restaurant": {
             "name": "Bistro U Lípy"
            },
            "table": {
             "id": "5012",
             "name": "Stůl 5",
             "room": "Zahrádka"
            },
            "visit": {
             "id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
             "state": "open",
             "tab_open": true,
             "opened_at": "2027-01-15T18:05:12+01:00",
             "closed_at": null
            },
            "device": {
             "id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
             "nickname": "Host 2",
             "verified": true,
             "verified_by": "join_code",
             "join_locked": false,
             "join_attempts_left": 5
            },
            "ordering": {
             "enabled": true,
             "paused": false,
             "can_order": true,
             "blocked_reason": null,
             "confirm_mode": "first",
             "needs_confirmation": false,
             "max_quantity": 10,
             "note_max_length": 32,
             "empty_table": "staff"
            },
            "join": {
             "enabled": true,
             "code": "4821"
            },
            "calls": []
           }
          },
          "x-summary-cs": "Týž telefon po novém skenu"
         }
        }
       }
      }
     },
     "404": {
      "description": "`table_not_found`: no table has this code.",
      "x-description-cs": "`table_not_found`: žádný stůl nemá tento kód.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "table_not_found": {
          "summary": "The code belongs to no table",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#table_not_found",
           "title": "Žádný stůl nemá tento kód",
           "status": 404,
           "code": "table_not_found",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Kód nepatří žádnému stolu"
         }
        }
       }
      }
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "ordering_disabled": {
          "summary": "The restaurant takes no orders from the table",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#ordering_disabled",
           "title": "Provozovna teď nepřijímá objednávky",
           "status": 422,
           "code": "ordering_disabled",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Podnik objednávky od stolu nebere"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/table/session": {
   "get": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "getTableSession",
    "summary": "The table as this phone sees it",
    "x-summary-cs": "Stůl, jak ho vidí tento telefon",
    "description": "The restaurant and the table, the visit of the table (`null` until the main register takes the phone over), this\nphone, whether and how it can order now (`ordering`), the code for friends at the table (only for a verified\nphone) and the open calls of this phone. Read it again after every action and every 10 seconds while the app is\nopen; `ordering.can_order` and `blocked_reason` say what to show.\n",
    "x-description-cs": "Provozovna a stůl, návštěva stolu (`null`, dokud si telefon nepřevezme hlavní kasa), tento telefon, jestli\na jak teď jde objednat (`ordering`), kód pro kamarády u stolu (jen ověřenému telefonu) a otevřená volání tohoto\ntelefonu. Čtěte znovu po každé akci a každých 10 sekund, dokud je aplikace otevřená; `ordering.can_order`\na `blocked_reason` říkají, co ukázat.\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The table.",
      "x-description-cs": "Stůl.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableSession"
        },
        "examples": {
         "verified": {
          "summary": "A verified phone at an open tab",
          "value": {
           "path": "cloud",
           "restaurant": {
            "name": "Bistro U Lípy"
           },
           "table": {
            "id": "5012",
            "name": "Stůl 5",
            "room": "Zahrádka"
           },
           "visit": {
            "id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
            "state": "open",
            "tab_open": true,
            "opened_at": "2027-01-15T18:05:12+01:00",
            "closed_at": null
           },
           "device": {
            "id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
            "nickname": "Host 2",
            "verified": true,
            "verified_by": "join_code",
            "join_locked": false,
            "join_attempts_left": 5
           },
           "ordering": {
            "enabled": true,
            "paused": false,
            "can_order": true,
            "blocked_reason": null,
            "confirm_mode": "first",
            "needs_confirmation": false,
            "max_quantity": 10,
            "note_max_length": 32,
            "empty_table": "staff"
           },
           "join": {
            "enabled": true,
            "code": "4821"
           },
           "calls": []
          },
          "x-summary-cs": "Ověřený telefon u otevřeného účtu"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "410": {
      "description": "`visit_ended`: the visit of the table ended (paid, or the staff ended it) and the token of the phone with it. Do not start a new session by yourself – only after a new scan of the QR code.",
      "x-description-cs": "`visit_ended`: návštěva stolu skončila (zaplaceno, nebo ji ukončila obsluha) a s ní token telefonu. Novou relaci nezakládejte sami – až po novém naskenování QR kódu.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "visit_ended": {
          "summary": "The tab was paid – the visit ended",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#visit_ended",
           "title": "Návštěva stolu skončila",
           "status": 410,
           "code": "visit_ended",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Účet se zaplatil – návštěva skončila"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/table/session/join": {
   "post": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "joinTable",
    "summary": "Join the party with the code from a friend",
    "x-summary-cs": "Přidat se ke skupině kódem od kamaráda",
    "x-idempotency": "none",
    "description": "The four digits a verified phone at the table shows (`TableSession.join.code`). The main register checks the\ncode and answers through the cloud: the answer is `202` with a request; read it with `getTableRequest` until\n`status` is `done` (the phone is verified – it sees the tab and its orders need not wait for the staff) or\n`failed` (`error.code`: `join_code_invalid` with `attempts_left`, `join_locked`, `join_not_available`).\nAfter 5 wrong codes the phone is locked until the staff unlocks it. Every attempt counts – send the next one\nonly after the previous one is decided.\n\n`join_not_available` – the restaurant does not use codes from friends; `join_locked` – this phone is locked;\n`restaurant_offline` – the main register is not connected, try again later or ask the staff.\n",
    "x-description-cs": "Čtyři číslice, které ukazuje ověřený telefon u stolu (`TableSession.join.code`). Kód ověří hlavní kasa\na odpoví přes cloud: odpověď je `202` se žádostí; čtěte ji přes `getTableRequest`, dokud `status` není `done`\n(telefon je ověřený – vidí účet a jeho objednávky nemusí čekat na obsluhu) nebo `failed` (`error.code`:\n`join_code_invalid` s `attempts_left`, `join_locked`, `join_not_available`). Po 5 špatných kódech se telefon\nzamkne, dokud ho obsluha neodemkne. Počítá se každý pokus – další pošlete, až bude předchozí rozhodnutý.\n\n`join_not_available` – podnik kód od kamaráda nepoužívá; `join_locked` – tento telefon je zamčený;\n`restaurant_offline` – hlavní kasa není připojená, zkuste to později nebo požádejte obsluhu.\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TableJoinInput"
       },
       "examples": {
        "code": {
         "summary": "The code from a friend at the table",
         "value": {
          "code": "4821"
         },
         "x-summary-cs": "Kód od kamaráda u stolu"
        }
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Handed over to the main register; read the result with `getTableRequest`.",
      "x-description-cs": "Předáno hlavní kase; výsledek čtěte přes `getTableRequest`.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableRequest"
        },
        "examples": {
         "queued": {
          "summary": "Handed over to the register",
          "value": {
           "id": "88231",
           "kind": "join_requested",
           "status": "queued",
           "result": null,
           "error": null
          },
          "x-summary-cs": "Předáno kase"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "join_not_available": {
          "summary": "The restaurant does not use codes from friends",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#join_not_available",
           "title": "Přidání kódem není k dispozici",
           "status": 409,
           "code": "join_not_available",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Podnik kód od kamaráda nepoužívá"
         }
        }
       }
      }
     },
     "410": {
      "$ref": "#/components/responses/VisitEnded"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "423": {
      "description": "`join_locked`: this phone entered a wrong code from a friend too many times. The staff unlocks it.",
      "x-description-cs": "`join_locked`: tento telefon zadal špatný kód od kamaráda příliš mnohokrát. Odemkne ho obsluha.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "join_locked": {
          "summary": "The phone entered a wrong code five times",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#join_locked",
           "title": "Příliš mnoho špatných kódů",
           "status": 423,
           "code": "join_locked",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Telefon zadal pětkrát špatný kód"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "description": "`restaurant_offline`: the main register of the restaurant is not connected, so nobody would take the request over. Try again after `Retry-After` seconds, or ask the staff.",
      "x-description-cs": "`restaurant_offline`: hlavní kasa podniku není připojená, takže by žádost nikdo nepřevzal. Zkuste to znovu za `Retry-After` sekund, nebo požádejte obsluhu.",
      "headers": {
       "Retry-After": {
        "$ref": "#/components/headers/RetryAfter"
       }
      },
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "restaurant_offline": {
          "summary": "The main register is not connected",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#restaurant_offline",
           "title": "Hlavní kasa podniku není připojená",
           "status": 503,
           "code": "restaurant_offline",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Hlavní kasa není připojená"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/table/requests/{request_id}": {
   "get": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "getTableRequest",
    "summary": "The answer of the main register to a request of this phone",
    "x-summary-cs": "Odpověď hlavní kasy na žádost tohoto telefonu",
    "description": "A request this phone made through the cloud (`joinTable`, `cancelTableOrder`, `cancelTableCall`). `queued`\n– the main register has not decided yet; read again in 2 seconds. `done` or `failed` is final.\n",
    "x-description-cs": "Žádost, kterou tento telefon poslal přes cloud (`joinTable`, `cancelTableOrder`, `cancelTableCall`). `queued`\n– hlavní kasa ještě nerozhodla; čtěte znovu za 2 sekundy. `done` nebo `failed` je konečné.\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "name": "request_id",
      "in": "path",
      "required": true,
      "description": "`TableRequest.id`. Requests of other phones answer 404.",
      "x-description-cs": "`TableRequest.id`. Žádosti jiných telefonů vrátí 404.",
      "schema": {
       "$ref": "#/components/schemas/Id"
      },
      "example": "88231"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The request.",
      "x-description-cs": "Žádost.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableRequest"
        },
        "examples": {
         "failed": {
          "summary": "A wrong code, 3 attempts left",
          "value": {
           "id": "88231",
           "kind": "join_requested",
           "status": "failed",
           "result": null,
           "error": {
            "code": "join_code_invalid",
            "detail": "Kód nesedí. Zbývají 3 pokusy.",
            "attempts_left": 3
           }
          },
          "x-summary-cs": "Špatný kód, zbývají 3 pokusy"
         },
         "done": {
          "summary": "The phone is verified",
          "value": {
           "id": "88231",
           "kind": "join_requested",
           "status": "done",
           "result": {},
           "error": null
          },
          "x-summary-cs": "Telefon je ověřený"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "410": {
      "$ref": "#/components/responses/VisitEnded"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/table/menu": {
   "get": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "getTableMenu",
    "summary": "What the guest can order from the table",
    "x-summary-cs": "Co si host může objednat od stolu",
    "description": "Products of the categories the restaurant allows for ordering from the table, with the prices of the register.\n`available: false` – sold out now; show it, but do not let the guest add it. `age_restricted` – the staff checks\nthe age when serving. Read it with `If-None-Match`; it changes when the restaurant changes its catalog.\n",
    "x-description-cs": "Produkty kategorií, které podnik pro objednávky od stolu povolil, s cenami pokladny. `available: false` – teď\nvyprodané; ukažte ho, ale nedovolte ho přidat. `age_restricted` – věk kontroluje obsluha při podání. Čtěte\ns `If-None-Match`; mění se, když podnik změní sortiment.\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/IfNoneMatch"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The menu.",
      "x-description-cs": "Menu.",
      "headers": {
       "ETag": {
        "$ref": "#/components/headers/ETag"
       }
      },
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableMenu"
        },
        "examples": {
         "menu": {
          "summary": "Drinks for ordering from the table",
          "value": {
           "currency": "CZK",
           "generated_at": "2027-01-15T18:30:00+01:00",
           "categories": [
            {
             "id": "320",
             "name": "Nápoje",
             "position": 1
            }
           ],
           "products": [
            {
             "id": "4590",
             "category_id": "320",
             "name": "Pivo 12° 0,5 l",
             "description": null,
             "image_url": null,
             "price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "weight": 500,
             "allergens": [],
             "add_ons": [],
             "removable_ingredients": [],
             "available": true,
             "age_restricted": true,
             "position": 1
            },
            {
             "id": "4593",
             "category_id": "320",
             "name": "Domácí limonáda 0,4 l",
             "description": "Bezová s citronem",
             "image_url": null,
             "price": {
              "amount": 5900,
              "currency": "CZK"
             },
             "weight": 400,
             "allergens": [],
             "add_ons": [],
             "removable_ingredients": [],
             "available": false,
             "age_restricted": false,
             "position": 2
            }
           ],
           "allergens": []
          },
          "x-summary-cs": "Nápoje pro objednávky od stolu"
         }
        }
       }
      }
     },
     "304": {
      "$ref": "#/components/responses/NotModified"
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "410": {
      "$ref": "#/components/responses/VisitEnded"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/table/orders": {
   "get": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "listTableOrders",
    "summary": "Orders of this phone",
    "x-summary-cs": "Objednávky tohoto telefonu",
    "description": "The orders this phone sent at this table, newest first (at most 50), with their state as the main register\nreports it. Orders of other phones are not here; a verified phone sees the whole tab in `getTableTab`.\n",
    "x-description-cs": "Objednávky, které tento telefon u tohoto stolu poslal, od nejnovější (nejvýš 50), se stavem, jak ho hlásí\nhlavní kasa. Objednávky jiných telefonů tu nejsou; ověřený telefon vidí celý účet v `getTableTab`.\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The orders.",
      "x-description-cs": "Objednávky.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableOrderList"
        },
        "examples": {
         "orders": {
          "summary": "Orders of the phone",
          "value": {
           "data": [
            {
             "id": "01a318f0-a0c0-7516-945b-bc3f72c5aa49",
             "visit_id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
             "device_id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
             "device_nickname": "Host 2",
             "from_verified_device": true,
             "status": "accepted",
             "reason_code": null,
             "reason": null,
             "lines": [
              {
               "product_id": "4590",
               "name": "Pivo 12° 0,5 l",
               "quantity": 2,
               "add_ons": [],
               "removed_ingredients": [],
               "unit_price": {
                "amount": 6900,
                "currency": "CZK"
               },
               "total": {
                "amount": 13800,
                "currency": "CZK"
               }
              }
             ],
             "note": "Bez pěny, prosím",
             "total": {
              "amount": 13800,
              "currency": "CZK"
             },
             "created_at": "2027-01-15T18:32:05+01:00",
             "decided_at": "2027-01-15T18:32:09+01:00"
            }
           ]
          },
          "x-summary-cs": "Objednávky telefonu"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "410": {
      "$ref": "#/components/responses/VisitEnded"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   },
   "post": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "createTableOrder",
    "summary": "Send an order to the table",
    "x-summary-cs": "Poslat objednávku na stůl",
    "x-idempotency": "body-id",
    "description": "`id` is a UUID the app makes when the guest taps „order“; keep it when you repeat the request (also over the\nother path – the main register knows it). The same `id` with the same body returns the order with `200`; with\nanother body `422 idempotency_key_mismatch`.\n\nThe cloud only checks what the guest can fix at once (the product is in the menu and not sold out, at most\n`max_quantity` pieces) and hands the order to the main register: it comes back `202` with `status` `submitted`.\nThe register decides by the rules of the restaurant – `pending_confirmation` (waits for the staff), `accepted`,\nor `rejected` with `reason_code` and `reason`. Read `listTableOrders` every 5 seconds until the order leaves\n`submitted` and `pending_confirmation`. An order the register does not take over within the waiting time of the\nrestaurant becomes `expired`.\n\n`ordering_disabled`, `ordering_paused` – the restaurant does not take orders from the table now (calling the\nstaff works); `product_not_orderable`, `product_unavailable`, `validation_failed` – see `errors`;\n`too_many_pending_orders` – 3 orders of this phone still wait for the staff; `restaurant_offline` – the main\nregister is not connected.\n",
    "x-description-cs": "`id` je UUID, které aplikace vytvoří, když host klepne na „objednat“; při opakování ho zachovejte (i přes druhou\ncestu – hlavní kasa ho zná). Stejné `id` se stejným tělem vrátí objednávku s `200`; s jiným tělem\n`422 idempotency_key_mismatch`.\n\nCloud kontroluje jen to, co host může hned opravit (produkt je v menu a není vyprodaný, nejvýš `max_quantity`\nkusů), a objednávku předá hlavní kase: vrátí se `202` se `status` `submitted`. Kasa rozhodne podle pravidel\npodniku – `pending_confirmation` (čeká na obsluhu), `accepted`, nebo `rejected` s `reason_code` a `reason`.\nČtěte `listTableOrders` každých 5 sekund, dokud objednávka neopustí `submitted` a `pending_confirmation`.\nObjednávka, kterou si kasa nepřevezme do čekací doby podniku, skončí jako `expired`.\n\n`ordering_disabled`, `ordering_paused` – podnik teď objednávky od stolu nebere (zavolat obsluhu jde);\n`product_not_orderable`, `product_unavailable`, `validation_failed` – viz `errors`; `too_many_pending_orders`\n– na obsluhu čekají 3 objednávky tohoto telefonu; `restaurant_offline` – hlavní kasa není připojená.\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TableOrderCreate"
       },
       "examples": {
        "beer": {
         "summary": "Two beers",
         "value": {
          "id": "01a318f0-a0c0-7516-945b-bc3f72c5aa49",
          "lines": [
           {
            "product_id": "4590",
            "quantity": 2
           }
          ],
          "note": "Bez pěny, prosím"
         },
         "x-summary-cs": "Dvě piva"
        }
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Handed over to the main register (`status` `submitted`).",
      "x-description-cs": "Předáno hlavní kase (`status` `submitted`).",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableOrder"
        },
        "examples": {
         "submitted": {
          "summary": "Handed over to the main register",
          "value": {
           "id": "01a318f0-a0c0-7516-945b-bc3f72c5aa49",
           "visit_id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
           "device_id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
           "device_nickname": "Host 2",
           "from_verified_device": true,
           "status": "submitted",
           "reason_code": null,
           "reason": null,
           "lines": [
            {
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "quantity": 2,
             "add_ons": [],
             "removed_ingredients": [],
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "total": {
              "amount": 13800,
              "currency": "CZK"
             }
            }
           ],
           "note": "Bez pěny, prosím",
           "total": {
            "amount": 13800,
            "currency": "CZK"
           },
           "created_at": "2027-01-15T18:32:05+01:00",
           "decided_at": null
          },
          "x-summary-cs": "Předáno hlavní kase"
         }
        }
       }
      }
     },
     "200": {
      "description": "This `id` was already sent; the order as it is now.",
      "x-description-cs": "Toto `id` už bylo odeslané; objednávka, jak je teď.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableOrder"
        },
        "examples": {
         "again": {
          "summary": "The same id again",
          "value": {
           "id": "01a318f0-a0c0-7516-945b-bc3f72c5aa49",
           "visit_id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
           "device_id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
           "device_nickname": "Host 2",
           "from_verified_device": true,
           "status": "accepted",
           "reason_code": null,
           "reason": null,
           "lines": [
            {
             "product_id": "4590",
             "name": "Pivo 12° 0,5 l",
             "quantity": 2,
             "add_ons": [],
             "removed_ingredients": [],
             "unit_price": {
              "amount": 6900,
              "currency": "CZK"
             },
             "total": {
              "amount": 13800,
              "currency": "CZK"
             }
            }
           ],
           "note": "Bez pěny, prosím",
           "total": {
            "amount": 13800,
            "currency": "CZK"
           },
           "created_at": "2027-01-15T18:32:05+01:00",
           "decided_at": "2027-01-15T18:32:09+01:00"
          },
          "x-summary-cs": "Stejné id podruhé"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "too_many_pending_orders": {
          "summary": "3 orders of the phone wait for the staff",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#too_many_pending_orders",
           "title": "Na obsluhu čeká příliš mnoho objednávek",
           "status": 409,
           "code": "too_many_pending_orders",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Na obsluhu čekají 3 objednávky telefonu"
         }
        }
       }
      }
     },
     "410": {
      "$ref": "#/components/responses/VisitEnded"
     },
     "422": {
      "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
      "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "validation_failed": {
          "summary": "Field errors",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
           "title": "Neplatná data",
           "status": 422,
           "code": "validation_failed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/items/0/quantity",
             "code": "too_small",
             "message": "Množství musí být aspoň 1."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Chyby u polí"
         },
         "product_not_orderable": {
          "summary": "The product is not in the menu for the table",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#product_not_orderable",
           "title": "Tento produkt nejde objednat od stolu",
           "status": 422,
           "code": "product_not_orderable",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [
            {
             "pointer": "/lines/0/product_id",
             "code": "product_not_orderable",
             "message": "Tento produkt nejde objednat od stolu."
            }
           ],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Produkt není v menu pro stůl"
         },
         "ordering_paused": {
          "summary": "The staff paused orders",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#ordering_paused",
           "title": "Objednávky od stolu jsou pozastavené",
           "status": 422,
           "code": "ordering_paused",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Obsluha objednávky pozastavila"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "description": "`restaurant_offline`: the main register of the restaurant is not connected, so nobody would take the request over. Try again after `Retry-After` seconds, or ask the staff.",
      "x-description-cs": "`restaurant_offline`: hlavní kasa podniku není připojená, takže by žádost nikdo nepřevzal. Zkuste to znovu za `Retry-After` sekund, nebo požádejte obsluhu.",
      "headers": {
       "Retry-After": {
        "$ref": "#/components/headers/RetryAfter"
       }
      },
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "restaurant_offline": {
          "summary": "The main register is not connected",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#restaurant_offline",
           "title": "Hlavní kasa podniku není připojená",
           "status": 503,
           "code": "restaurant_offline",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Hlavní kasa není připojená"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/table/orders/{order_id}/cancel": {
   "post": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "cancelTableOrder",
    "summary": "Ask to cancel an order that still waits for the staff",
    "x-summary-cs": "Požádat o zrušení objednávky, která ještě čeká na obsluhu",
    "x-idempotency": "none",
    "description": "Only an order in `submitted` or `pending_confirmation` (`order_not_cancellable` otherwise). The main register\ndecides: read the answer with `getTableRequest` – `done` (the order is `cancelled`) or `failed` with\n`order_not_cancellable` (the staff accepted it meanwhile).\n",
    "x-description-cs": "Jen objednávka ve stavu `submitted` nebo `pending_confirmation` (jinak `order_not_cancellable`). Rozhodne\nhlavní kasa: odpověď čtěte přes `getTableRequest` – `done` (objednávka je `cancelled`) nebo `failed`\ns `order_not_cancellable` (obsluha ji mezitím přijala).\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "name": "order_id",
      "in": "path",
      "required": true,
      "description": "`TableOrder.id` of this phone; orders of other phones answer 404.",
      "x-description-cs": "`TableOrder.id` tohoto telefonu; objednávky jiných telefonů vrátí 404.",
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "example": "01a318f0-a0c0-7516-945b-bc3f72c5aa49"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "202": {
      "description": "Handed over to the main register.",
      "x-description-cs": "Předáno hlavní kase.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableRequest"
        },
        "examples": {
         "queued": {
          "summary": "Handed over to the register",
          "value": {
           "id": "88240",
           "kind": "order_cancel_requested",
           "status": "queued",
           "result": null,
           "error": null
          },
          "x-summary-cs": "Předáno kase"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "order_not_cancellable": {
          "summary": "The staff already accepted the order",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#order_not_cancellable",
           "title": "Objednávku už nelze zrušit",
           "status": 409,
           "code": "order_not_cancellable",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Obsluha objednávku už přijala"
         }
        }
       }
      }
     },
     "410": {
      "$ref": "#/components/responses/VisitEnded"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "$ref": "#/components/responses/RestaurantOffline"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/table/calls": {
   "post": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "createTableCall",
    "summary": "Call the staff to the table",
    "x-summary-cs": "Zavolat obsluhu ke stolu",
    "x-idempotency": "none",
    "description": "`waiter` – come to the table; `bill` – the guest wants to pay (at the staff, payment by phone is not part of\nthis). Works also while orders are paused. While a call of the same kind of this phone is still open, you get\nthat one with `200` instead of a second one. The call reaches the bar display through the main register:\n`submitted` until the register takes it over, then `open`, `acknowledged` when the staff confirms it.\n",
    "x-description-cs": "`waiter` – přijďte ke stolu; `bill` – host chce platit (u obsluhy, platba mobilem sem nepatří). Funguje\ni při pozastavených objednávkách. Dokud je volání stejného druhu z tohoto telefonu otevřené, dostanete místo\ndruhého to první s `200`. Volání dojde na displej baru přes hlavní kasu: `submitted`, dokud si ho kasa\nnepřevezme, pak `open`, `acknowledged`, když ho obsluha potvrdí.\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TableCallCreate"
       },
       "examples": {
        "waiter": {
         "summary": "Call the staff",
         "value": {
          "kind": "waiter"
         },
         "x-summary-cs": "Zavolat obsluhu"
        }
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Handed over to the main register.",
      "x-description-cs": "Předáno hlavní kase.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableCall"
        },
        "examples": {
         "submitted": {
          "summary": "Handed over to the main register",
          "value": {
           "id": "01a318f0-a0c0-77c0-8511-eded33db3ed0",
           "kind": "waiter",
           "status": "submitted",
           "created_at": "2027-01-15T18:40:02+01:00",
           "acknowledged_at": null
          },
          "x-summary-cs": "Předáno hlavní kase"
         }
        }
       }
      }
     },
     "200": {
      "description": "A call of this kind is already open; that call.",
      "x-description-cs": "Volání tohoto druhu už je otevřené; to volání.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableCall"
        },
        "examples": {
         "open": {
          "summary": "The call is already open",
          "value": {
           "id": "01a318f0-a0c0-77c0-8511-eded33db3ed0",
           "kind": "waiter",
           "status": "open",
           "created_at": "2027-01-15T18:40:02+01:00",
           "acknowledged_at": null
          },
          "x-summary-cs": "Volání už je otevřené"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "410": {
      "$ref": "#/components/responses/VisitEnded"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "$ref": "#/components/responses/RestaurantOffline"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     }
    }
   }
  },
  "/table/calls/{call_id}/cancel": {
   "post": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "cancelTableCall",
    "summary": "Ask to cancel a call",
    "x-summary-cs": "Požádat o zrušení volání",
    "x-idempotency": "none",
    "description": "The main register cancels the call; read the answer with `getTableRequest`.",
    "x-description-cs": "Volání zruší hlavní kasa; odpověď čtěte přes `getTableRequest`.",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "name": "call_id",
      "in": "path",
      "required": true,
      "description": "`TableCall.id` of this phone; calls of other phones answer 404.",
      "x-description-cs": "`TableCall.id` tohoto telefonu; volání jiných telefonů vrátí 404.",
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "example": "01a318f0-a0c0-77c0-8511-eded33db3ed0"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "202": {
      "description": "Handed over to the main register.",
      "x-description-cs": "Předáno hlavní kase.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableRequest"
        },
        "examples": {
         "queued": {
          "summary": "Handed over to the register",
          "value": {
           "id": "88245",
           "kind": "call_cancel_requested",
           "status": "queued",
           "result": null,
           "error": null
          },
          "x-summary-cs": "Předáno kase"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "410": {
      "$ref": "#/components/responses/VisitEnded"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "$ref": "#/components/responses/RestaurantOffline"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/table/tab": {
   "get": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "getTableTab",
    "summary": "The tab of the table",
    "x-summary-cs": "Účet stolu",
    "description": "Everything on the tab of the table, also what the staff entered and what other phones ordered – only for a\nverified phone (`device_not_verified` otherwise). As the main register last sent it; `404` while the table has\nno tab.\n",
    "x-description-cs": "Všechno na účtu stolu, i to, co namarkovala obsluha a co objednaly jiné telefony – jen pro ověřený telefon\n(jinak `device_not_verified`). Tak, jak ho naposledy poslala hlavní kasa; `404`, dokud stůl účet nemá.\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The tab.",
      "x-description-cs": "Účet.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableTab"
        },
        "examples": {
         "tab": {
          "summary": "The tab for a verified phone",
          "value": {
           "visit_id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
           "items": [
            {
             "name": "Svíčková na smetaně, houskový knedlík",
             "quantity": 1,
             "total": {
              "amount": 19900,
              "currency": "CZK"
             },
             "by": null
            },
            {
             "name": "Pivo 12° 0,5 l",
             "quantity": 2,
             "total": {
              "amount": 13800,
              "currency": "CZK"
             },
             "by": "Host 2"
            }
           ],
           "total": {
            "amount": 33700,
            "currency": "CZK"
           },
           "updated_at": "2027-01-15T18:32:09+01:00"
          },
          "x-summary-cs": "Účet stolu pro ověřený telefon"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "description": "`insufficient_scope` or `customer_not_verified`; on Profirest's own devices also `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` and – on the\nregister – `manager_approval_required`.\n",
      "x-description-cs": "`insufficient_scope` nebo `customer_not_verified`; na vlastních zařízeních Profirestu také `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` a – na pokladně –\n`manager_approval_required`.\n",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "insufficient_scope": {
          "summary": "The token lacks the scope",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#insufficient_scope",
           "title": "Token nemá potřebné oprávnění",
           "status": 403,
           "code": "insufficient_scope",
           "detail": "Missing scope: orders:write",
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Token nemá potřebné oprávnění"
         },
         "device_not_verified": {
          "summary": "The phone is not verified yet",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#device_not_verified",
           "title": "Telefon u stolu není ověřený",
           "status": 403,
           "code": "device_not_verified",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Telefon ještě není ověřený"
         }
        }
       }
      }
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "410": {
      "$ref": "#/components/responses/VisitEnded"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/table/events": {
   "get": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "streamTableEvents",
    "summary": "Live updates of the phone at the table (Server-Sent Events)",
    "x-summary-cs": "Upozornění na změny pro telefon u stolu (Server-Sent Events)",
    "x-stream": "sse",
    "description": "The same as the events of the main register's local API: a long-lived response `text/event-stream` whose messages\ntell only what changed (`TableGuestEvent` – the type and an ID), never how; the app then reads the state with GET\n(`getTableSession`, `listTableOrders`, `getTableTab`). Types: `session` (the phone, the visit or ordering changed –\nthe code from a friend accepted, ordering paused, the register online again), `orders` (an order of this phone,\n`id` is the order), `calls` (a call of this phone, `id` is the call), `tab` (the tab of the table), `visit_ended`\n(the last message – then the stream closes and the token no longer works). The phone gets only messages of itself\nand of its visit, within about a second after the change.\n\nA comment `: ping` comes after 25 seconds without a message; the stream lasts at most 10 minutes, then connect\nagain. At most 2 streams for one phone – a third one closes the oldest. The token goes in the header\n`Authorization`; `EventSource` cannot send headers, read the stream with `fetch`. When the stream is not\navailable (`503`, a network failure), refresh with GET every 5 seconds while something is pending and every\n30 seconds otherwise, as with the main register.\n",
    "x-description-cs": "Stejné jako události místního API hlavní kasy: dlouhá odpověď `text/event-stream`, jejíž zprávy říkají jen, co se\nzměnilo (`TableGuestEvent` – typ a ID), nikdy jak; stav si aplikace pak načte GETem (`getTableSession`,\n`listTableOrders`, `getTableTab`). Typy: `session` (změnil se telefon, návštěva nebo objednávání – přijatý kód od\nkamaráda, pozastavené objednávky, kasa zase online), `orders` (objednávka tohoto telefonu, `id` je objednávka),\n`calls` (volání tohoto telefonu, `id` je volání), `tab` (účet stolu), `visit_ended` (poslední zpráva – pak se proud\nzavře a token přestane platit). Telefon dostává jen zprávy o sobě a své návštěvě, zhruba do sekundy po změně.\n\nPo 25 sekundách bez zprávy přijde komentář `: ping`; proud trvá nejvýš 10 minut, pak se připojte znovu. Nejvýš\n2 proudy na jeden telefon – třetí zavře nejstarší. Token patří do hlavičky `Authorization`; `EventSource`\nhlavičky neumí, proud čtěte přes `fetch`. Když proud není k dispozici (`503`, výpadek sítě), načítejte stav GETem\nkaždých 5 sekund, dokud něco čeká, jinak každých 30 sekund – stejně jako u hlavní kasy.\n",
    "security": [
     {
      "tableGuest": []
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The stream of `TableGuestEvent` messages (`event:` the type, `data:` the JSON) and comments `: ping`.",
      "x-description-cs": "Proud zpráv `TableGuestEvent` (`event:` typ, `data:` JSON) a komentářů `: ping`.",
      "x-sse-messages": {
       "event": {
        "$ref": "#/components/schemas/TableGuestEvent"
       }
      },
      "content": {
       "text/event-stream": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "410": {
      "description": "`visit_ended`: the visit of the table ended (paid, or the staff ended it) and the token of the phone with it. Do not start a new session by yourself – only after a new scan of the QR code.",
      "x-description-cs": "`visit_ended`: návštěva stolu skončila (zaplaceno, nebo ji ukončila obsluha) a s ní token telefonu. Novou relaci nezakládejte sami – až po novém naskenování QR kódu.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "visit_ended": {
          "summary": "The visit of the table ended",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#visit_ended",
           "title": "Návštěva stolu skončila",
           "status": 410,
           "code": "visit_ended",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Návštěva stolu skončila"
         }
        }
       }
      }
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     },
     "503": {
      "$ref": "#/components/responses/StreamUnavailable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/table/heartbeat": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "put": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "putTableHeartbeat",
    "summary": "The main register is alive",
    "x-summary-cs": "Hlavní kasa žije",
    "x-requires-device": true,
    "description": "Only the main register of the restaurant (the device that serves ordering from the table on the restaurant's\nWi-Fi). Send it every 30 seconds while ordering from the table is on, and at once when the pause changes. For\n90 seconds after the last one the cloud takes the register as online (`online_seconds`); after that guests on\nthe backup path get `restaurant_offline`. `local` is the address of the register's local API (for support and\nthe administration), `paused` the pause of new orders.\n\n`inbox_pending` – requests of guests waiting in the inbox: read them with `listTableInbox` at once. The event\n`table.inbox_received` announces a new one sooner.\n\nOne restaurant has one main register: while one device sends heartbeats, another gets\n`409 main_device_conflict` (show it to the staff – two registers must not both take orders from tables). It can\ntake over 90 seconds after the last heartbeat of the first one.\n",
    "x-description-cs": "Jen hlavní kasa provozovny (zařízení, které obsluhuje objednávky od stolu po Wi-Fi podniku). Posílejte ho každých\n30 sekund, dokud je objednávání od stolu zapnuté, a hned při změně pauzy. 90 sekund po posledním bere cloud kasu\njako online (`online_seconds`); potom hosté na záložní cestě dostanou `restaurant_offline`. `local` je adresa\nmístního API kasy (pro podporu a administraci), `paused` pauza nových objednávek.\n\n`inbox_pending` – žádosti hostů čekající ve schránce: hned si je přečtěte přes `listTableInbox`. Novou dřív\nohlásí událost `table.inbox_received`.\n\nProvozovna má jednu hlavní kasu: dokud heartbeat posílá jedno zařízení, jiné dostane `409 main_device_conflict`\n(ukažte to obsluze – dvě kasy nesmí obě brát objednávky od stolů). Převzít může 90 sekund po posledním\nheartbeatu té první.\n",
    "security": [
     {
      "oauth2": [
       "table:sync"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TableHeartbeatInput"
       },
       "examples": {
        "alive": {
         "summary": "The main register is alive",
         "value": {
          "paused": false,
          "local": {
           "host": "profirest-123.local",
           "port": 8080,
           "ip": "192.168.50.10"
          },
          "app_version": "3.5.0",
          "guest_app_version": "1.0.0"
         },
         "x-summary-cs": "Hlavní kasa žije"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Recorded.",
      "x-description-cs": "Zapsáno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableHeartbeat"
        },
        "examples": {
         "recorded": {
          "summary": "One request waits in the inbox",
          "value": {
           "server_time": "2027-01-15T18:32:06+01:00",
           "inbox_pending": 1,
           "online_seconds": 90
          },
          "x-summary-cs": "Jedna žádost čeká ve schránce"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "main_device_conflict": {
          "summary": "Another device is the main register",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#main_device_conflict",
           "title": "Hlavní kasou je jiné zařízení",
           "status": 409,
           "code": "main_device_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Hlavní kasou je jiné zařízení"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/table/inbox": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "get": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "listTableInbox",
    "summary": "Requests of guests on the backup path",
    "x-summary-cs": "Žádosti hostů ze záložní cesty",
    "x-requires-device": true,
    "description": "Requests of guests who reached the cloud instead of the register, oldest first (at most 100). Handle every one\nwith the same code as the same request on the local API and send the result with `completeTableInboxItem`; an\nitem stays here until then. `kind` and `payload`:\n\n- `session_started` – a new phone at the table: `{device_id, table_id, table_code}`; the result `{visit_id,\n  nickname}` (`visit_id` `null` while the table has no visit), or `failed` (`ordering_disabled`).\n- `join_requested` – `{device_id, code}`; `done` verifies the phone, `failed` with `join_code_invalid` (and\n  `attempts_left`), `join_locked` or `join_not_available`.\n- `order_submitted` – `{device_id, order}` (`order` as the phone sent it, `TableOrderCreate`); the result\n  `{order}` with the order as the register decided it, or `failed` with the reason (the order becomes\n  `rejected`).\n- `order_cancel_requested` – `{device_id, order_id}`; the result `{order}`, or `failed` with\n  `order_not_cancellable`.\n- `call_requested` – `{device_id, call: {id, kind}}`; the result `{call}`.\n- `call_cancel_requested` – `{device_id, call_id}`; the result `{call}`.\n- `staff_action` – a decision of the staff from the web kitchen display: `{action, order_id, call_id, device_id,\n  reason, employee}` with `action` `accept_order`, `reject_order`, `acknowledge_call` or `unlock_device`; the\n  result `{}` or `{order}` / `{call}`.\n\nA request older than the waiting time of the restaurant (`expire_minutes`) is not handed out: the cloud ends an\nold `order_submitted` as `expired` by itself, so an order sent during an outage never reaches the kitchen late.\n",
    "x-description-cs": "Žádosti hostů, které se místo ke kase dostaly do cloudu, od nejstarší (nejvýš 100). Každou zpracujte stejným\nkódem jako stejný požadavek na místním API a výsledek pošlete přes `completeTableInboxItem`; do té doby tu\npoložka zůstane. `kind` a `payload`:\n\n- `session_started` – nový telefon u stolu: `{device_id, table_id, table_code}`; výsledek `{visit_id,\n  nickname}` (`visit_id` `null`, dokud stůl nemá návštěvu), nebo `failed` (`ordering_disabled`).\n- `join_requested` – `{device_id, code}`; `done` telefon ověří, `failed` s `join_code_invalid` (a\n  `attempts_left`), `join_locked` nebo `join_not_available`.\n- `order_submitted` – `{device_id, order}` (`order`, jak ho poslal telefon, `TableOrderCreate`); výsledek\n  `{order}` s objednávkou, jak o ní kasa rozhodla, nebo `failed` s důvodem (objednávka bude `rejected`).\n- `order_cancel_requested` – `{device_id, order_id}`; výsledek `{order}`, nebo `failed`\n  s `order_not_cancellable`.\n- `call_requested` – `{device_id, call: {id, kind}}`; výsledek `{call}`.\n- `call_cancel_requested` – `{device_id, call_id}`; výsledek `{call}`.\n- `staff_action` – rozhodnutí obsluhy z webového kuchyňského displeje: `{action, order_id, call_id, device_id,\n  reason, employee}` s `action` `accept_order`, `reject_order`, `acknowledge_call` nebo `unlock_device`;\n  výsledek `{}` nebo `{order}` / `{call}`.\n\nŽádost starší než čekací doba podniku (`expire_minutes`) se nevydá: starou `order_submitted` cloud sám ukončí\njako `expired`, takže objednávka poslaná během výpadku nikdy nedojde do kuchyně pozdě.\n",
    "security": [
     {
      "oauth2": [
       "table:sync"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "responses": {
     "200": {
      "description": "The waiting requests.",
      "x-description-cs": "Čekající žádosti.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableInboxPage"
        },
        "examples": {
         "order": {
          "summary": "An order from mobile data",
          "value": {
           "data": [
            {
             "id": "88230",
             "kind": "order_submitted",
             "created_at": "2027-01-15T18:32:05+01:00",
             "device_id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
             "ref_id": "01a318f0-a0c0-7516-945b-bc3f72c5aa49",
             "payload": {
              "device_id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
              "order": {
               "id": "01a318f0-a0c0-7516-945b-bc3f72c5aa49",
               "lines": [
                {
                 "product_id": "4590",
                 "quantity": 2
                }
               ],
               "note": "Bez pěny, prosím"
              }
             }
            }
           ]
          },
          "x-summary-cs": "Objednávka z mobilních dat"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/table/inbox/{item_id}": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "item_id",
     "in": "path",
     "required": true,
     "description": "`TableInboxItem.id`.",
     "x-description-cs": "`TableInboxItem.id`.",
     "schema": {
      "$ref": "#/components/schemas/Id"
     },
     "example": "88230"
    }
   ],
   "put": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "completeTableInboxItem",
    "summary": "The result of a request of a guest",
    "x-summary-cs": "Výsledek žádosti hosta",
    "x-requires-device": true,
    "description": "`done` with `result`, or `failed` with `error` (the code and the sentence for the guest, see\n`listTableInbox`). The guest sees it at once, and the order, the call or the phone in the cloud change with it;\nwhat the result does not say (later states, the tab) send with `putTableState`. Sending the same result again is\nfine (a lost answer); another result for a decided item is `409 inbox_item_conflict`.\n",
    "x-description-cs": "`done` s `result`, nebo `failed` s `error` (kód a věta pro hosta, viz `listTableInbox`). Host ho uvidí hned\na podle něj se změní objednávka, volání nebo telefon v cloudu; co z výsledku nejde poznat (pozdější stavy,\núčet), pošlete přes `putTableState`. Stejný výsledek poslat znovu je v pořádku (ztracená odpověď); jiný\nvýsledek k rozhodnuté položce je `409 inbox_item_conflict`.\n",
    "security": [
     {
      "oauth2": [
       "table:sync"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TableInboxResultInput"
       },
       "examples": {
        "accepted": {
         "summary": "The register accepted the order",
         "value": {
          "status": "done",
          "result": {
           "order": {
            "id": "01a318f0-a0c0-7516-945b-bc3f72c5aa49",
            "table_id": "5012",
            "visit_id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
            "device_id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
            "device_nickname": "Host 2",
            "from_verified_device": true,
            "status": "accepted",
            "reason_code": null,
            "reason": null,
            "lines": [
             {
              "product_id": "4590",
              "name": "Pivo 12° 0,5 l",
              "quantity": 2,
              "add_ons": [],
              "unit_price": {
               "amount": 6900,
               "currency": "CZK"
              },
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             }
            ],
            "note": "Bez pěny, prosím",
            "total": {
             "amount": 13800,
             "currency": "CZK"
            },
            "created_at": "2027-01-15T18:32:05+01:00",
            "decided_at": "2027-01-15T18:32:09+01:00",
            "version": 3
           }
          }
         },
         "x-summary-cs": "Kasa objednávku přijala"
        },
        "wrong_code": {
         "summary": "A wrong code from a friend",
         "value": {
          "status": "failed",
          "error": {
           "code": "join_code_invalid",
           "detail": "Kód nesedí. Zbývají 3 pokusy.",
           "attempts_left": 3
          }
         },
         "x-summary-cs": "Špatný kód od kamaráda"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Recorded.",
      "x-description-cs": "Zapsáno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableInboxCompletion"
        },
        "examples": {
         "done": {
          "summary": "Recorded",
          "value": {
           "id": "88230",
           "kind": "order_submitted",
           "status": "done",
           "error_code": null,
           "done_at": "2027-01-15T18:32:09+01:00"
          },
          "x-summary-cs": "Zapsáno"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "inbox_item_conflict": {
          "summary": "The item already has another result",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#inbox_item_conflict",
           "title": "Žádost už je rozhodnutá jinak",
           "status": 409,
           "code": "inbox_item_conflict",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Položka už má jiný výsledek"
         }
        }
       }
      }
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/table/state": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    }
   ],
   "put": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "putTableState",
    "summary": "Mirror the state of tables from the main register",
    "x-summary-cs": "Zrcadlo stavu stolů z hlavní kasy",
    "x-requires-device": true,
    "description": "The main register is the source of truth. After every change send the changed visits, phones, orders and calls –\nof the local path too, so the cloud shows them to guests on the backup path, on the web kitchen display and in the\nadministration. Every object carries its `version` (a number growing with every change on the register): the\ncloud keeps the higher one and skips an older or equal one, so a repeated or late batch after an outage changes\nnothing. Objects of tables of other restaurants are skipped (`skipped`).\n\nA visit with `state` `closed` ends the tokens of its phones on the backup path (`visit_ended`); a phone with\n`revoked: true` too. `tab` is the tab of the table for verified phones (`getTableTab`).\n",
    "x-description-cs": "Zdrojem pravdy je hlavní kasa. Po každé změně pošlete změněné návštěvy, telefony, objednávky a volání – i z místní\ncesty, aby je cloud ukázal hostům na záložní cestě, na webovém kuchyňském displeji a v administraci. Každý objekt\nnese svou `version` (číslo, které na kase roste s každou změnou): cloud si nechá vyšší a starší nebo stejnou\npřeskočí, takže opakovaná nebo opožděná dávka po výpadku nic nezmění. Objekty stolů jiných provozoven se\npřeskočí (`skipped`).\n\nNávštěva se `state` `closed` ukončí tokeny svých telefonů na záložní cestě (`visit_ended`); telefon\ns `revoked: true` také. `tab` je účet stolu pro ověřené telefony (`getTableTab`).\n",
    "security": [
     {
      "oauth2": [
       "table:sync"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TableStateInput"
       },
       "examples": {
        "changes": {
         "summary": "Changes after an order was accepted",
         "value": {
          "visits": [
           {
            "id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
            "table_id": "5012",
            "state": "open",
            "tab_open": true,
            "join_code": "4821",
            "opened_at": "2027-01-15T18:05:12+01:00",
            "closed_at": null,
            "version": 7,
            "tab": {
             "items": [
              {
               "name": "Svíčková na smetaně, houskový knedlík",
               "quantity": 1,
               "total": {
                "amount": 19900,
                "currency": "CZK"
               },
               "by": null
              },
              {
               "name": "Pivo 12° 0,5 l",
               "quantity": 2,
               "total": {
                "amount": 13800,
                "currency": "CZK"
               },
               "by": "Host 2"
              }
             ],
             "total": {
              "amount": 33700,
              "currency": "CZK"
             },
             "updated_at": "2027-01-15T18:32:09+01:00"
            }
           }
          ],
          "devices": [
           {
            "id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
            "table_id": "5012",
            "visit_id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
            "path": "cloud",
            "nickname": "Host 2",
            "verified": true,
            "verified_by": "join_code",
            "join_locked": false,
            "join_attempts_left": 5,
            "last_seen_at": "2027-01-15T18:32:05+01:00",
            "revoked": false,
            "version": 4
           }
          ],
          "orders": [
           {
            "id": "01a318f0-a0c0-7516-945b-bc3f72c5aa49",
            "table_id": "5012",
            "visit_id": "01a318f0-a0c0-7d36-b16d-7337a1727025",
            "device_id": "01a318f0-a0c0-71ce-b4fd-cd42250394f5",
            "device_nickname": "Host 2",
            "from_verified_device": true,
            "status": "accepted",
            "reason_code": null,
            "reason": null,
            "lines": [
             {
              "product_id": "4590",
              "name": "Pivo 12° 0,5 l",
              "quantity": 2,
              "add_ons": [],
              "unit_price": {
               "amount": 6900,
               "currency": "CZK"
              },
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             }
            ],
            "note": "Bez pěny, prosím",
            "total": {
             "amount": 13800,
             "currency": "CZK"
            },
            "created_at": "2027-01-15T18:32:05+01:00",
            "decided_at": "2027-01-15T18:32:09+01:00",
            "version": 3
           }
          ],
          "calls": []
         },
         "x-summary-cs": "Změny po přijetí objednávky"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Recorded.",
      "x-description-cs": "Zapsáno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableStateResult"
        },
        "examples": {
         "applied": {
          "summary": "Recorded",
          "value": {
           "applied": 3,
           "skipped": 0
          },
          "x-summary-cs": "Zapsáno"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  },
  "/restaurants/{restaurant_id}/table/orders/{order_id}/apply": {
   "parameters": [
    {
     "$ref": "#/components/parameters/RestaurantId"
    },
    {
     "name": "order_id",
     "in": "path",
     "required": true,
     "description": "`TableOrder.id` – the UUID the phone gave the order.",
     "x-description-cs": "`TableOrder.id` – UUID, které objednávce dal telefon.",
     "schema": {
      "type": "string",
      "format": "uuid"
     },
     "example": "01a318f0-a0c0-7516-945b-bc3f72c5aa49"
    }
   ],
   "post": {
    "tags": [
     "Table ordering"
    ],
    "operationId": "applyTableOrder",
    "summary": "Write an accepted order from the table to the tab and the kitchen",
    "x-summary-cs": "Zapsat přijatou objednávku od stolu na účet a do kuchyně",
    "x-requires-device": true,
    "x-staff": "optional",
    "x-idempotency": "body-id",
    "description": "When the main register accepts an order from the table (the staff on the register or the bar display, or by the\nrules of the restaurant without the staff), it adds its lines to the tab of the table with this operation, not\nwith `putTab` – no employee needs to be signed in on the register, and the lines are only added, so no\n`If-Match` is needed. `tab_id` is the tab of the visit; a new UUID opens a new tab with `table_name`. With\n`kitchen` the server also makes the kitchen ticket of the given lines (as `createKitchenTicket`) and marks them\nsent to the kitchen.\n\n`accepted_by_id` is the employee who accepted the order (on the bar display it is the employee signed in there);\n`null` when the rules accepted it. The tab and its log then show `updated_by` with `id` `0` and the name of the\nphone. With a staff session in `Profirest-Staff-Token` its employee is used.\n\nThe order ID in the path makes it idempotent: the same order again returns the tab with `200` and writes\nnothing; other lines for the same order are `409 conflict`. `tab_closed` – the tab was paid or closed\nmeanwhile: end the order as `cancelled` and tell the staff.\n",
    "x-description-cs": "Když hlavní kasa přijme objednávku od stolu (obsluha na kase nebo na displeji baru, nebo podle pravidel podniku\nbez obsluhy), přidá její řádky na účet stolu touto operací, ne přes `putTab` – na kase nemusí být přihlášený\nzaměstnanec a řádky se jen přidávají, takže není potřeba `If-Match`. `tab_id` je účet návštěvy; nové UUID\notevře nový účet s `table_name`. S `kitchen` server udělá i kuchyňský bon zadaných řádků (jako\n`createKitchenTicket`) a označí je jako poslané do kuchyně.\n\n`accepted_by_id` je zaměstnanec, který objednávku přijal (na displeji baru ten, kdo je tam přihlášený); `null`,\nkdyž ji přijala pravidla. Účet a jeho log pak ukážou `updated_by` s `id` `0` a jménem telefonu. S relací\nzaměstnance v `Profirest-Staff-Token` se použije její zaměstnanec.\n\nID objednávky v adrese ji dělá idempotentní: stejná objednávka znovu vrátí účet s `200` a nic nezapíše; jiné\nřádky pro stejnou objednávku jsou `409 conflict`. `tab_closed` – účet se mezitím zaplatil nebo uzavřel:\nukončete objednávku jako `cancelled` a řekněte to obsluze.\n",
    "security": [
     {
      "oauth2": [
       "table:sync"
      ]
     }
    ],
    "parameters": [
     {
      "$ref": "#/components/parameters/StaffToken"
     },
     {
      "$ref": "#/components/parameters/AcceptLanguage"
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TableOrderApplyInput"
       },
       "examples": {
        "bar": {
         "summary": "Beer to the tab, the ticket only at the bar",
         "value": {
          "tab_id": "01a318f0-a0c0-7772-90b9-6b2ebc3017f8",
          "table_name": "Stůl 5",
          "accepted_by_id": "58",
          "device_nickname": "Host 2",
          "lines": [
           {
            "id": "t-1",
            "product_id": "4590",
            "quantity": 2,
            "note": "Bez pěny, prosím"
           }
          ],
          "kitchen": null
         },
         "x-summary-cs": "Pivo na účet, bon jen na baru"
        },
        "kitchen": {
         "summary": "A meal accepted by the rules, also to the kitchen",
         "value": {
          "tab_id": "01a318f0-a0c0-7772-90b9-6b2ebc3017f8",
          "table_name": "Stůl 5",
          "accepted_by_id": null,
          "device_nickname": "Host 2",
          "lines": [
           {
            "id": "t-2",
            "product_id": "4567",
            "quantity": 1,
            "course": 1
           }
          ],
          "kitchen": {
           "ticket_id": "01a318f0-a0c0-73f6-b301-b2ca7599b305",
           "line_ids": [
            "t-2"
           ],
           "note": "Od stolu – Host 2"
          }
         },
         "x-summary-cs": "Jídlo přijaté pravidly i do kuchyně"
        }
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "Written.",
      "x-description-cs": "Zapsáno.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableOrderApplied"
        },
        "examples": {
         "written": {
          "summary": "Written to the tab",
          "value": {
           "tab": {
            "id": "01a318f0-a0c0-7772-90b9-6b2ebc3017f8",
            "restaurant_id": "123",
            "table_name": "Stůl 5",
            "note": null,
            "opened_at": "2027-01-15T11:48:02+01:00",
            "opened_by": {
             "id": "58",
             "name": "Jana Dvořáková"
            },
            "updated_by": {
             "id": "58",
             "name": "Jana Dvořáková"
            },
            "lines": [
             {
              "id": "l-1",
              "product_id": "4567",
              "name": "Svíčková na smetaně, houskový knedlík",
              "variant": "full",
              "quantity": 1,
              "ordered_at": "2027-01-15T11:51:40+01:00",
              "unit_price": {
               "amount": 19900,
               "currency": "CZK"
              },
              "add_ons": [],
              "removed_ingredients": [],
              "note": null,
              "course": 1,
              "sent_to_kitchen": true,
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             },
             {
              "id": "l-2",
              "product_id": "4590",
              "name": "Pivo 12° 0,5 l",
              "variant": "full",
              "quantity": 2,
              "ordered_at": "2027-01-15T11:49:15+01:00",
              "unit_price": {
               "amount": 6900,
               "currency": "CZK"
              },
              "add_ons": [],
              "removed_ingredients": [],
              "note": null,
              "course": 0,
              "sent_to_kitchen": false,
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             },
             {
              "id": "t-1",
              "product_id": "4590",
              "name": "Pivo 12° 0,5 l",
              "variant": "full",
              "quantity": 2,
              "ordered_at": "2027-01-15T18:32:09+01:00",
              "unit_price": {
               "amount": 6900,
               "currency": "CZK"
              },
              "add_ons": [],
              "removed_ingredients": [],
              "note": "Bez pěny, prosím",
              "course": 0,
              "sent_to_kitchen": false,
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             }
            ],
            "totals": {
             "items": {
              "amount": 47500,
              "currency": "CZK"
             },
             "total": {
              "amount": 47500,
              "currency": "CZK"
             }
            },
            "version": 4,
            "status": "open",
            "updated_at": "2027-01-15T18:32:09+01:00",
            "device_id": "512",
            "closed_at": null,
            "receipt_id": null
           },
           "kitchen_ticket": null
          },
          "x-summary-cs": "Zapsáno na účet"
         }
        }
       }
      }
     },
     "200": {
      "description": "This order was already written; the tab as it is now.",
      "x-description-cs": "Tato objednávka už je zapsaná; účet, jak je teď.",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TableOrderApplied"
        },
        "examples": {
         "again": {
          "summary": "The same order again",
          "value": {
           "tab": {
            "id": "01a318f0-a0c0-7772-90b9-6b2ebc3017f8",
            "restaurant_id": "123",
            "table_name": "Stůl 5",
            "note": null,
            "opened_at": "2027-01-15T11:48:02+01:00",
            "opened_by": {
             "id": "58",
             "name": "Jana Dvořáková"
            },
            "updated_by": {
             "id": "58",
             "name": "Jana Dvořáková"
            },
            "lines": [
             {
              "id": "l-1",
              "product_id": "4567",
              "name": "Svíčková na smetaně, houskový knedlík",
              "variant": "full",
              "quantity": 1,
              "ordered_at": "2027-01-15T11:51:40+01:00",
              "unit_price": {
               "amount": 19900,
               "currency": "CZK"
              },
              "add_ons": [],
              "removed_ingredients": [],
              "note": null,
              "course": 1,
              "sent_to_kitchen": true,
              "total": {
               "amount": 19900,
               "currency": "CZK"
              }
             },
             {
              "id": "l-2",
              "product_id": "4590",
              "name": "Pivo 12° 0,5 l",
              "variant": "full",
              "quantity": 2,
              "ordered_at": "2027-01-15T11:49:15+01:00",
              "unit_price": {
               "amount": 6900,
               "currency": "CZK"
              },
              "add_ons": [],
              "removed_ingredients": [],
              "note": null,
              "course": 0,
              "sent_to_kitchen": false,
              "total": {
               "amount": 13800,
               "currency": "CZK"
              }
             }
            ],
            "totals": {
             "items": {
              "amount": 33700,
              "currency": "CZK"
             },
             "total": {
              "amount": 33700,
              "currency": "CZK"
             }
            },
            "version": 3,
            "status": "open",
            "updated_at": "2027-01-15T11:51:40+01:00",
            "device_id": "512",
            "closed_at": null,
            "receipt_id": null
           },
           "kitchen_ticket": null
          },
          "x-summary-cs": "Stejná objednávka podruhé"
         }
        }
       }
      }
     },
     "401": {
      "$ref": "#/components/responses/Unauthorized"
     },
     "403": {
      "$ref": "#/components/responses/Forbidden"
     },
     "404": {
      "$ref": "#/components/responses/NotFound"
     },
     "409": {
      "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
      "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
      "content": {
       "application/problem+json": {
        "schema": {
         "$ref": "#/components/schemas/Problem"
        },
        "examples": {
         "idempotency_in_progress": {
          "summary": "The same Idempotency-Key is still being processed",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
           "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
           "status": 409,
           "code": "idempotency_in_progress",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
         },
         "tab_closed": {
          "summary": "The tab was paid meanwhile",
          "value": {
           "type": "https://api.mujprofirest.cz/v2/docs/errors#tab_closed",
           "title": "Účet stolu je už uzavřený",
           "status": 409,
           "code": "tab_closed",
           "detail": null,
           "instance": null,
           "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
           "errors": [],
           "existing_id": null,
           "candidates": [],
           "paid_by": null
          },
          "x-summary-cs": "Účet se mezitím zaplatil"
         }
        }
       }
      }
     },
     "422": {
      "$ref": "#/components/responses/Unprocessable"
     },
     "400": {
      "$ref": "#/components/responses/BadRequest"
     },
     "406": {
      "$ref": "#/components/responses/NotAcceptable"
     },
     "413": {
      "$ref": "#/components/responses/PayloadTooLarge"
     },
     "415": {
      "$ref": "#/components/responses/UnsupportedMediaType"
     },
     "429": {
      "$ref": "#/components/responses/TooManyRequests"
     }
    }
   }
  }
 },
 "webhooks": {
  "event": {
   "post": {
    "summary": "Event delivery",
    "x-summary-cs": "Doručení události",
    "description": "Profirest sends each event of every connection of your client to the webhook URL registered for the client. The\nbody is the same `Event` object as in `GET /events`; `connection_id` tells which connection it belongs to.\nEvents are filtered by the connection's scopes and restaurants just like the feed. When the owner revokes the\nconnection, only `grant.revoked` is delivered; deliveries still waiting for a retry are dropped.\n\nAuthentication is the signature, not a token. Headers follow Standard Webhooks: `webhook-id` (the event ID, the\nsame in every attempt; use it to drop duplicates), `webhook-timestamp` (Unix seconds of this attempt) and\n`webhook-signature` (`v1,<base64 HMAC-SHA256 of \"{webhook-id}.{webhook-timestamp}.{body}\">`; during a secret\nrotation several signatures separated by spaces). Reject a message whose timestamp is more than 5 minutes\nfrom your clock.\n\nAnswer with any 2xx within 10 seconds. Otherwise the delivery is retried after 1 min, 5 min, 30 min, 2 h and\n12 h, each time signed anew. Deliveries may arrive out of order and more than once; `sequence` and\n`GET /events` give the order.\n\nThe URL must be HTTPS on a public address. Redirects are not followed, and a host that resolves to a private,\nloopback, link-local or reserved address (also one of several) gets no delivery – the attempt fails with\nthat reason.\n",
    "x-description-cs": "Profirest pošle každou událost každého připojení vašeho klienta na webhookovou adresu registrovanou u klienta.\nTělo je stejný objekt `Event` jako v `GET /events`; `connection_id` říká, ke kterému připojení patří. Události se\nfiltrují podle oprávnění a provozoven připojení stejně jako v proudu. Když majitel připojení zruší, doručí se už\njen `grant.revoked`; doručení, která čekají na další pokus, se zahodí.\n\nOvěřuje se podpisem, ne tokenem. Hlavičky odpovídají Standard Webhooks: `webhook-id` (ID události, stejné\nv každém pokusu; podle něj zahazujte duplicity), `webhook-timestamp` (Unix sekundy tohoto pokusu)\na `webhook-signature` (`v1,<base64 HMAC-SHA256 z \"{webhook-id}.{webhook-timestamp}.{tělo}\">`; při výměně\ntajemství několik podpisů oddělených mezerou). Zprávu s časem vzdáleným od vašich hodin o víc než 5 minut\nodmítněte.\n\nOdpovězte jakýmkoli 2xx do 10 sekund. Jinak se doručení opakuje po 1 min, 5 min, 30 min, 2 h a 12 h, pokaždé\ns novým podpisem. Zprávy mohou dorazit v jiném pořadí i víckrát; pořadí dává `sequence` a `GET /events`.\n\nAdresa musí být HTTPS na veřejné adrese. Přesměrování se nesleduje a na jméno, které se přeloží do soukromé,\nmístní, link-local nebo vyhrazené sítě (i jen jednou z více adres), se nedoručí – pokus selže s tímto důvodem.\n",
    "security": [],
    "parameters": [
     {
      "name": "webhook-id",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string"
      }
     },
     {
      "name": "webhook-timestamp",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "pattern": "^[0-9]+$"
      }
     },
     {
      "name": "webhook-signature",
      "in": "header",
      "required": true,
      "schema": {
       "type": "string",
       "examples": [
        "v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4="
       ]
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/Event"
       }
      }
     }
    },
    "responses": {
     "2XX": {
      "description": "Received.",
      "x-description-cs": "Přijato."
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "oauth2": {
    "type": "oauth2",
    "description": "OAuth 2.0 authorization code with PKCE (S256). The endpoints live outside `/v2`.",
    "x-description-cs": "OAuth 2.0 authorization code s PKCE (S256). Endpointy leží mimo `/v2`.",
    "flows": {
     "authorizationCode": {
      "authorizationUrl": "https://api.mujprofirest.cz/oauth/authorize",
      "tokenUrl": "https://api.mujprofirest.cz/oauth/token",
      "refreshUrl": "https://api.mujprofirest.cz/oauth/token",
      "scopes": {
       "restaurants:read": "See restaurant details, opening hours, order hours, delivery zones and orderable times.",
       "catalog:read": "See categories, products, prices and availability.",
       "availability:write": "Change how many portions of products are left and mark products sold out.",
       "opening_hours:write": "Change the regular weekly opening hours of the restaurant.",
       "orders:write": "Price baskets, send orders to the kitchen, confirm payments and cancel orders.",
       "orders:read": "See orders created by this connection.",
       "customers:read": "See customers linked by this connection.",
       "customers:write": "Link, change and remove customers and verify their phone numbers.",
       "loyalty:read": "See loyalty points of verified customers.",
       "vouchers:redeem": "Check and redeem gift vouchers.",
       "accounting:read": "Download accounting exports of takings and shift closes (Pohoda, Money), including buyers on invoices.",
       "reports:read": "See shift closes, sales documents of all sources, reports of takings (by day, payment, product, employee, tips) and the cash book – with names of employees, without customer contacts.",
       "staff:read": "See the restaurant's employees and their roles, never their PINs.",
       "staff:authenticate": "Sign employees in on the device with their PIN or card.",
       "attendance:read": "See who is at work and who is on a break, and the signed-in employee's shifts and requests for time off.",
       "attendance:punch": "Record arrivals, departures and breaks of employees, and requests for time off of the signed-in employee.",
       "kitchen:read": "See all orders in the kitchen with their items, notes and delivery details.",
       "kitchen:write": "Move orders through the kitchen, confirm printed tickets and cancel orders.",
       "deliveries:read": "See couriers and delivery routes with the addresses and phone numbers of customers, and search delivery addresses.",
       "deliveries:write": "Plan delivery routes, check couriers in and out of the shift and mark orders delivered.",
       "settings:read": "See the restaurant's settings for devices – company details, receipt layouts, printers and tables.",
       "queue:read": "See order numbers for a screen for customers – no names, no items.",
       "directory:read": "Find the account's customers by phone or name with their addresses, and see incoming calls.",
       "calls:write": "Report calls to the restaurant's phone.",
       "receipts:read": "See receipts of the restaurant's registers with payments and the EET status, open tabs of tables and the shift of the device.",
       "receipts:write": "Issue and cancel receipts, open and change tabs of tables, send their tickets to the kitchen, close the shift of the device and record deposits, withdrawals and expenses of cash into the cash book.",
       "stock:read": "See the warehouse items to count with the quantities the stock expects, and stock takings made on devices.",
       "stock:write": "Record stock takings that set the stock.",
       "backups:read": "See and download backups of the restaurant's registers.",
       "backups:write": "Upload backups of the register's local database.",
       "diagnostics:write": "Send logs and bug reports of the device to Profirest support.",
       "table:sync": "Take over requests of guests ordering from the table and mirror the tables of the main register to the cloud.",
       "reservations:read": "See reservations of tables and services with the guests' contacts, the reservation rules, services, free times and which tables are free now.",
       "reservations:write": "Create, change, confirm, seat and cancel reservations of tables and services.",
       "lodging:read": "See the guests staying now (room, name, dates) and the accounts of their rooms.",
       "lodging:write": "Charge bills to the account of a room.",
       "housekeeping:read": "See the cleaning tasks of rooms and their faults – without guest data.",
       "housekeeping:write": "Tick cleaning tasks off and report and fix faults of rooms.",
       "guest_passes:check": "Check QR codes of staying guests at the wellness, breakfast or car park and record their entries – room and what the guest may use, no names.",
       "lodging_desk:read": "The reception of a hotel: see the rooms, the occupancy plan and every stay with the guests' contacts, their identity documents and the history of the stay.",
       "lodging_desk:write": "The reception of a hotel: create, change, move, check in, check out and cancel stays, register guests and settle the account of the room."
      },
      "x-first-party-scopes": [
       "staff:read",
       "staff:authenticate",
       "attendance:read",
       "attendance:punch",
       "kitchen:read",
       "kitchen:write",
       "deliveries:read",
       "deliveries:write",
       "settings:read",
       "queue:read",
       "directory:read",
       "calls:write",
       "receipts:read",
       "receipts:write",
       "stock:read",
       "stock:write",
       "backups:read",
       "backups:write",
       "diagnostics:write",
       "table:sync",
       "lodging_desk:read",
       "lodging_desk:write"
      ],
      "x-scopes-cs": {
       "restaurants:read": "Vidět údaje o provozovnách, otevírací dobu, příjem objednávek, rozvozové zóny a časy, na které lze objednat.",
       "catalog:read": "Vidět kategorie, produkty, ceny a dostupnost.",
       "availability:write": "Měnit zbývající porce produktů a označovat produkty jako vyprodané.",
       "opening_hours:write": "Měnit běžnou týdenní otevírací dobu provozovny.",
       "orders:write": "Počítat košíky, posílat objednávky do kuchyně, potvrzovat platby a rušit objednávky.",
       "orders:read": "Vidět objednávky vytvořené tímto připojením.",
       "customers:read": "Vidět zákazníky propojené tímto připojením.",
       "customers:write": "Propojovat, měnit a odebírat zákazníky a ověřovat jejich telefony.",
       "loyalty:read": "Vidět věrnostní body ověřených zákazníků.",
       "vouchers:redeem": "Ověřovat a uplatňovat dárkové vouchery.",
       "accounting:read": "Stahovat účetní exporty tržeb a uzávěrek (Pohoda, Money) včetně odběratelů na fakturách.",
       "reports:read": "Vidět uzávěrky, doklady prodeje ze všech zdrojů, přehledy tržeb (po dnech, platbách, produktech, zaměstnancích, dýška) a pokladní knihu – se jmény zaměstnanců, bez kontaktů zákazníků.",
       "staff:read": "Vidět zaměstnance provozovny a jejich role, nikdy jejich PINy.",
       "staff:authenticate": "Přihlašovat zaměstnance na zařízení PINem nebo čipem.",
       "attendance:read": "Vidět, kdo je v práci a kdo má přestávku, a směny a žádosti o volno přihlášeného zaměstnance.",
       "attendance:punch": "Zapisovat příchody, odchody a přestávky zaměstnanců a žádosti o volno přihlášeného zaměstnance.",
       "kitchen:read": "Vidět všechny objednávky v kuchyni s položkami, poznámkami a údaji pro rozvoz.",
       "kitchen:write": "Posouvat objednávky v kuchyni, potvrzovat vytištěné bony a rušit objednávky.",
       "deliveries:read": "Vidět kurýry a rozvozové trasy s adresami a telefony zákazníků a vyhledávat doručovací adresy.",
       "deliveries:write": "Plánovat rozvozové trasy, přihlašovat kurýry na směnu a označovat doručené objednávky.",
       "settings:read": "Vidět nastavení provozovny pro zařízení – údaje firmy, tiskové šablony, tiskárny a stoly.",
       "queue:read": "Vidět čísla objednávek pro obrazovku hostů – bez jmen a bez položek.",
       "directory:read": "Hledat zákazníky účtu podle telefonu nebo jména s jejich adresami a vidět příchozí hovory.",
       "calls:write": "Hlásit hovory na telefon provozovny.",
       "receipts:read": "Vidět účtenky pokladen provozovny s platbami a stavem EET, otevřené účty stolů a směnu zařízení.",
       "receipts:write": "Vystavovat a stornovat účtenky, otevírat a měnit účty stolů, posílat jejich bony do kuchyně, uzavírat směnu zařízení a zapisovat vklady, výběry a výdaje hotovosti do pokladní knihy.",
       "stock:read": "Vidět skladové položky k inventuře s množstvím, které očekává sklad, a inventury ze zařízení.",
       "stock:write": "Zapisovat inventury, které nastaví stav skladu.",
       "backups:read": "Vidět a stahovat zálohy pokladen provozovny.",
       "backups:write": "Nahrávat zálohy místní databáze pokladny.",
       "diagnostics:write": "Posílat logy a hlášení chyb zařízení podpoře Profirestu.",
       "table:sync": "Přebírat žádosti hostů, kteří objednávají od stolu, a zrcadlit stoly hlavní kasy do cloudu.",
       "reservations:read": "Vidět rezervace stolů a služeb s kontakty hostů, pravidla rezervací, služby, volné časy a které stoly jsou teď volné.",
       "reservations:write": "Zakládat, měnit, potvrzovat, usazovat a rušit rezervace stolů a služeb.",
       "lodging:read": "Vidět právě ubytované hosty (pokoj, jméno, termín) a účty jejich pokojů.",
       "lodging:write": "Zapisovat útraty na účet pokoje.",
       "housekeeping:read": "Vidět úkoly úklidu pokojů a jejich závady – bez údajů hostů.",
       "housekeeping:write": "Odškrtávat úkoly úklidu a hlásit a opravovat závady pokojů.",
       "guest_passes:check": "Ověřovat QR kódy ubytovaných hostů u wellness, snídaní nebo parkoviště a zapisovat jejich vstupy – pokoj a co host smí, bez jmen.",
       "lodging_desk:read": "Recepce hotelu: vidět pokoje, plán obsazenosti a každý pobyt s kontakty hostů, jejich doklady totožnosti a historií pobytu.",
       "lodging_desk:write": "Recepce hotelu: zakládat, měnit, přesouvat, ubytovávat, odhlašovat a rušit pobyty, zapisovat hosty a vyúčtovat účet pokoje."
      }
     }
    }
   },
   "clientBasic": {
    "type": "http",
    "scheme": "basic",
    "description": "`client_id` as user name and `client_secret` as password. Only for the OAuth endpoints.",
    "x-description-cs": "`client_id` jako jméno a `client_secret` jako heslo. Jen pro OAuth endpointy."
   },
   "tableGuest": {
    "type": "http",
    "scheme": "bearer",
    "description": "The token of a guest's phone at a table (`pfg_…`) from `startTableSession`. Only for the operations of ordering\nfrom the table (`/table/…`); at most 12 hours and until the visit of the table ends.\n",
    "x-description-cs": "Token telefonu hosta u stolu (`pfg_…`) ze `startTableSession`. Jen pro operace objednávání od stolu\n(`/table/…`); nejvýš 12 hodin a do konce návštěvy stolu.\n"
   },
   "logUpload": {
    "type": "http",
    "scheme": "bearer",
    "description": "The token of one target of an `upload_logs` command (`pfl_…`, `LogUploadTarget.token`) from `checkInDevice`.\nOnly for the operations of that upload (`/log-uploads/{upload_id}/…`) and only until it is finished or the\nrequest expires (24 hours). No token of the device is needed, so a waiter's phone without one uploads too.\n",
    "x-description-cs": "Token jednoho cíle příkazu `upload_logs` (`pfl_…`, `LogUploadTarget.token`) z `checkInDevice`. Jen pro operace\ntoho nahrávání (`/log-uploads/{upload_id}/…`) a jen do jeho dokončení nebo vypršení žádosti (24 hodin). Token\nzařízení není potřeba, takže nahrává i telefon číšníka bez vlastního tokenu.\n"
   }
  },
  "parameters": {
   "RestaurantId": {
    "name": "restaurant_id",
    "in": "path",
    "required": true,
    "description": "ID of a restaurant granted to your connection. Other IDs answer 404.",
    "x-description-cs": "ID provozovny, ke které má vaše připojení přístup. Jiná ID vrátí 404.",
    "schema": {
     "$ref": "#/components/schemas/Id"
    },
    "example": "123"
   },
   "RevenueSegment": {
    "name": "segment",
    "in": "query",
    "required": false,
    "description": "Only one kind of revenue: `food` – food and drinks (the register, the web shop with food, delivery, the\nplatforms), `lodging` – documents of stays (the stay, services and bills charged to the room), `tickets` –\ntickets (the web shop and the box office). Default all.\n",
    "x-description-cs": "Jen jeden druh tržby: `food` – jídlo a pití (pokladna, e-shop s jídlem, rozvoz, platformy), `lodging` – doklady\nza pobyt (ubytování, služby a útrata zapsaná na pokoj), `tickets` – vstupenky (e-shop a prodej u vchodu).\nVýchozí všechno.\n",
    "schema": {
     "type": "string",
     "enum": [
      "food",
      "lodging",
      "tickets"
     ]
    }
   },
   "OrderId": {
    "name": "order_id",
    "in": "path",
    "required": true,
    "description": "ID of an order your connection created at this restaurant (`Order.id`). Other IDs answer 404.",
    "x-description-cs": "ID objednávky, kterou vaše připojení vytvořilo na této provozovně (`Order.id`). Jiná ID vrátí 404.",
    "schema": {
     "$ref": "#/components/schemas/Id"
    },
    "example": "184223"
   },
   "CustomerId": {
    "name": "customer_id",
    "in": "path",
    "required": true,
    "description": "Our ID of the customer link, as returned by `POST /customers`.",
    "x-description-cs": "Naše ID propojení zákazníka, jak ho vrátil `POST /customers`.",
    "schema": {
     "$ref": "#/components/schemas/Id"
    },
    "example": "90321"
   },
   "ObjectType": {
    "name": "object_type",
    "in": "path",
    "required": true,
    "description": "Type of the object that carries your reference.",
    "x-description-cs": "Typ objektu, ke kterému patří vaše vazba.",
    "schema": {
     "type": "string",
     "enum": [
      "restaurant",
      "category",
      "product",
      "order",
      "customer"
     ]
    },
    "example": "order"
   },
   "Cursor": {
    "name": "cursor",
    "in": "query",
    "required": false,
    "description": "Value of `next_cursor` from the previous page. Opaque; never build it yourself.",
    "x-description-cs": "Hodnota `next_cursor` z předchozí stránky. Neprůhledná; nikdy ji neskládejte sami.",
    "schema": {
     "type": "string",
     "maxLength": 512
    },
    "example": "eyJzZXEiOjkxMDU1MH0"
   },
   "Limit": {
    "name": "limit",
    "in": "query",
    "required": false,
    "description": "Page size.",
    "x-description-cs": "Velikost stránky.",
    "schema": {
     "type": "integer",
     "minimum": 1,
     "maximum": 100,
     "default": 50
    },
    "example": 20
   },
   "IdempotencyKey": {
    "name": "Idempotency-Key",
    "in": "header",
    "required": true,
    "description": "Unique key of this request, ideally a UUID. Retrying with the same key and the same body returns the stored\nresult. The same key with a different body answers `422 idempotency_key_mismatch`; while the first request is\nstill running `409 idempotency_in_progress`. Only final results (2xx and 4xx) are stored, for 24 hours; keys are\nscoped to your connection, the method and the path.\n",
    "x-description-cs": "Jedinečný klíč tohoto požadavku, ideálně UUID. Opakování se stejným klíčem a stejným tělem vrátí uložený\nvýsledek. Stejný klíč s jiným tělem vrátí `422 idempotency_key_mismatch`; dokud první požadavek běží,\n`409 idempotency_in_progress`. Ukládají se jen konečné výsledky (2xx a 4xx), na 24 hodin; klíče platí v rámci\nvašeho připojení, metody a cesty.\n",
    "schema": {
     "type": "string",
     "minLength": 8,
     "maxLength": 255,
     "examples": [
      "018f3c2e-7b1a-7c4e-9d2f-3a5b6c7d8e9f"
     ]
    }
   },
   "IfNoneMatch": {
    "name": "If-None-Match",
    "in": "header",
    "required": false,
    "description": "ETag from a previous response. When nothing changed the answer is `304 Not Modified` without a body.",
    "x-description-cs": "ETag z předchozí odpovědi. Když se nic nezměnilo, odpověď je `304 Not Modified` bez těla.",
    "schema": {
     "type": "string"
    }
   },
   "IfMatch": {
    "name": "If-Match",
    "in": "header",
    "required": true,
    "description": "`ETag` of the version you read. When the object changed meanwhile the answer is `412 precondition_failed`.",
    "x-description-cs": "`ETag` verze, kterou jste načetli. Když se záznam mezitím změnil, odpověď je `412 precondition_failed`.",
    "schema": {
     "type": "string"
    }
   },
   "StayIfMatch": {
    "name": "If-Match",
    "in": "header",
    "required": false,
    "description": "`ETag` of the stay you read (`getStay`); when it changed meanwhile the answer is `412 precondition_failed`.",
    "x-description-cs": "`ETag` načteného pobytu (`getStay`); když se mezitím změnil, odpověď je `412 precondition_failed`.",
    "schema": {
     "type": "string"
    }
   },
   "AcceptLanguage": {
    "name": "Accept-Language",
    "in": "header",
    "required": false,
    "description": "Language of error titles. `cs` (default) or `en`.",
    "x-description-cs": "Jazyk názvů chyb. `cs` (výchozí) nebo `en`.",
    "schema": {
     "type": "string",
     "examples": [
      "en",
      "cs"
     ]
    }
   },
   "EmployeeId": {
    "name": "employee_id",
    "in": "path",
    "required": true,
    "description": "ID of an employee of the restaurant. Other IDs answer 404.",
    "x-description-cs": "ID zaměstnance provozovny. Jiná ID vrátí 404.",
    "schema": {
     "$ref": "#/components/schemas/Id"
    },
    "example": "64"
   },
   "RouteId": {
    "name": "route_id",
    "in": "path",
    "required": true,
    "description": "ID of a delivery route of the restaurant. Other IDs answer 404.",
    "x-description-cs": "ID rozvozové trasy provozovny. Jiná ID vrátí 404.",
    "schema": {
     "$ref": "#/components/schemas/Id"
    },
    "example": "3307"
   },
   "StationId": {
    "name": "station_id",
    "in": "path",
    "required": true,
    "description": "ID of an active production station of the restaurant (`DeviceSettings.kitchen_stations`). Others answer 404.",
    "x-description-cs": "ID aktivního výrobního stanoviště provozovny (`DeviceSettings.kitchen_stations`). Jiná vrátí 404.",
    "schema": {
     "$ref": "#/components/schemas/Id"
    },
    "example": "2"
   },
   "TicketId": {
    "name": "ticket_id",
    "in": "path",
    "required": true,
    "description": "ID of a kitchen ticket of the restaurant. Other IDs answer 404.",
    "x-description-cs": "ID kuchyňského bonu provozovny. Jiná ID vrátí 404.",
    "schema": {
     "$ref": "#/components/schemas/Id"
    },
    "example": "77812"
   },
   "ReceiptId": {
    "name": "receipt_id",
    "in": "path",
    "required": true,
    "description": "The UUID of a receipt of the restaurant (made on the device). Other IDs answer 404.",
    "x-description-cs": "UUID účtenky provozovny (vzniklo na zařízení). Jiná ID vrátí 404.",
    "schema": {
     "type": "string",
     "maxLength": 64
    },
    "example": "01a318f0-a0c0-750d-8c36-65b69d55462d"
   },
   "TabId": {
    "name": "tab_id",
    "in": "path",
    "required": true,
    "description": "Your UUID of the tab (made on the device that opened it).",
    "x-description-cs": "Vaše UUID účtu stolu (vzniklo na zařízení, které ho otevřelo).",
    "schema": {
     "type": "string",
     "maxLength": 64
    },
    "example": "01a318f0-a0c0-7834-8f31-7973aa8bb418"
   },
   "ReservationId": {
    "name": "reservation_id",
    "in": "path",
    "required": true,
    "description": "ID of a reservation of the restaurant, or its `uuid`. Other IDs answer 404.",
    "x-description-cs": "ID rezervace provozovny, nebo její `uuid`. Jiná ID vrátí 404.",
    "schema": {
     "type": "string",
     "maxLength": 64
    },
    "example": "5120"
   },
   "WaitlistId": {
    "name": "waitlist_id",
    "in": "path",
    "required": true,
    "description": "ID of an entry of the waiting list of the restaurant. Other IDs answer 404.",
    "x-description-cs": "ID záznamu čekací listiny provozovny. Jiná ID vrátí 404.",
    "schema": {
     "type": "string",
     "maxLength": 20
    },
    "example": "88"
   },
   "RoomId": {
    "name": "room_id",
    "in": "path",
    "required": true,
    "description": "ID of a room of the restaurant (`HousekeepingRoom.id`). Other IDs answer 404.",
    "x-description-cs": "ID pokoje provozovny (`HousekeepingRoom.id`). Jiná ID vrátí 404.",
    "schema": {
     "type": "string",
     "maxLength": 20
    },
    "example": "104"
   },
   "IssueId": {
    "name": "issue_id",
    "in": "path",
    "required": true,
    "description": "ID of a fault of the restaurant (`RoomIssue.id`). Other IDs answer 404.",
    "x-description-cs": "ID závady provozovny (`RoomIssue.id`). Jiná ID vrátí 404.",
    "schema": {
     "type": "string",
     "maxLength": 20
    },
    "example": "57"
   },
   "StayId": {
    "name": "stay_id",
    "in": "path",
    "required": true,
    "description": "ID of a stay of the restaurant (`InHouseStay.id`). Other IDs answer 404.",
    "x-description-cs": "ID pobytu provozovny (`InHouseStay.id`). Jiná ID vrátí 404.",
    "schema": {
     "type": "string",
     "maxLength": 20
    },
    "example": "197"
   },
   "ReservationIfMatch": {
    "name": "If-Match",
    "in": "header",
    "required": false,
    "description": "`ETag` of the reservation you read; when it changed meanwhile the answer is `412 precondition_failed`.",
    "x-description-cs": "`ETag` načtené rezervace; když se mezitím změnila, odpověď je `412 precondition_failed`.",
    "schema": {
     "type": "string"
    }
   },
   "StockTakingId": {
    "name": "stock_taking_id",
    "in": "path",
    "required": true,
    "description": "The UUID of a stock taking of the restaurant (made on the device). Other IDs answer 404.",
    "x-description-cs": "UUID inventury provozovny (vzniklo na zařízení). Jiná ID vrátí 404.",
    "schema": {
     "type": "string",
     "maxLength": 64
    },
    "example": "01a318f0-a0c0-7f96-b81b-51428f522956"
   },
   "BackupId": {
    "name": "backup_id",
    "in": "path",
    "required": true,
    "description": "ID of a backup of the restaurant. Other IDs answer 404.",
    "x-description-cs": "ID zálohy provozovny. Jiná ID vrátí 404.",
    "schema": {
     "type": "string",
     "maxLength": 64
    },
    "example": "4410"
   },
   "UploadId": {
    "name": "upload_id",
    "in": "path",
    "required": true,
    "description": "ID of a log upload (`LogUploadTarget.upload_id`). The token in `Authorization` must belong to it, otherwise 404.",
    "x-description-cs": "ID nahrávání logu (`LogUploadTarget.upload_id`). Token v `Authorization` k němu musí patřit, jinak 404.",
    "schema": {
     "type": "string",
     "maxLength": 64
    },
    "example": "7742"
   },
   "IfMatchOptional": {
    "name": "If-Match",
    "in": "header",
    "required": false,
    "description": "`ETag` of the version you read. Required to change an existing tab; leave it out to create a new one.",
    "x-description-cs": "`ETag` verze, kterou jste načetli. Povinný při změně existujícího účtu; bez něj se zakládá nový.",
    "schema": {
     "type": "string"
    }
   },
   "StaffToken": {
    "name": "Profirest-Staff-Token",
    "in": "header",
    "required": false,
    "description": "Token from `POST /restaurants/{restaurant_id}/staff-sessions` – the employee working on this device.",
    "x-description-cs": "Token z `POST /restaurants/{restaurant_id}/staff-sessions` – zaměstnanec, který na zařízení pracuje.",
    "schema": {
     "type": "string",
     "maxLength": 128
    }
   },
   "ExternalIdFilter": {
    "name": "external_id",
    "in": "query",
    "required": false,
    "description": "Only objects that carry this `external_id` of your connection.",
    "x-description-cs": "Jen objekty s tímto `external_id` vašeho připojení.",
    "schema": {
     "$ref": "#/components/schemas/ExternalId"
    },
    "example": "A-2027-000123"
   }
  },
  "headers": {
   "ETag": {
    "description": "Version of the representation. Send it back in `If-None-Match` or `If-Match`.",
    "x-description-cs": "Verze obsahu. Pošlete ji zpět v `If-None-Match` nebo `If-Match`.",
    "schema": {
     "type": "string"
    }
   },
   "Location": {
    "description": "URL of the created resource.",
    "x-description-cs": "Adresa vytvořeného záznamu.",
    "schema": {
     "type": "string",
     "format": "uri-reference"
    }
   },
   "RetryAfter": {
    "description": "Seconds to wait before retrying.",
    "x-description-cs": "Kolik sekund počkat před dalším pokusem.",
    "schema": {
     "type": "integer"
    }
   }
  },
  "responses": {
   "NotModified": {
    "description": "Nothing changed since the ETag you sent.",
    "x-description-cs": "Od zaslaného ETagu se nic nezměnilo.",
    "headers": {
     "ETag": {
      "$ref": "#/components/headers/ETag"
     }
    }
   },
   "BadRequest": {
    "description": "`malformed_request` or `idempotency_key_missing`.",
    "x-description-cs": "`malformed_request` nebo `idempotency_key_missing`.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "idempotency_key_missing": {
        "summary": "The Idempotency-Key is missing",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_key_missing",
         "title": "Chybí hlavička Idempotency-Key",
         "status": 400,
         "code": "idempotency_key_missing",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Chybí Idempotency-Key"
       }
      }
     }
    }
   },
   "Unauthorized": {
    "description": "`invalid_token`: the access token is missing, invalid, expired or revoked.",
    "x-description-cs": "`invalid_token`: access token chybí, je neplatný, vypršel nebo byl zneplatněn.",
    "headers": {
     "WWW-Authenticate": {
      "schema": {
       "type": "string",
       "examples": [
        "Bearer error=\"invalid_token\""
       ]
      }
     }
    },
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "invalid_token": {
        "summary": "The token is missing, invalid or expired",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#invalid_token",
         "title": "Access token chybí, je neplatný nebo vypršel",
         "status": 401,
         "code": "invalid_token",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Token chybí, je neplatný nebo vypršel"
       }
      }
     }
    }
   },
   "Forbidden": {
    "description": "`insufficient_scope` or `customer_not_verified`; on Profirest's own devices also `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` and – on the\nregister – `manager_approval_required`.\n",
    "x-description-cs": "`insufficient_scope` nebo `customer_not_verified`; na vlastních zařízeních Profirestu také `device_required`,\n`staff_session_required`, `staff_session_expired`, `staff_role_missing`, `module_not_licensed` a – na pokladně –\n`manager_approval_required`.\n",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "insufficient_scope": {
        "summary": "The token lacks the scope",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#insufficient_scope",
         "title": "Token nemá potřebné oprávnění",
         "status": 403,
         "code": "insufficient_scope",
         "detail": "Missing scope: orders:write",
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Token nemá potřebné oprávnění"
       }
      }
     }
    }
   },
   "NotFound": {
    "description": "`not_found`: the object does not exist or your connection may not see it.",
    "x-description-cs": "`not_found`: objekt neexistuje nebo ho vaše připojení nesmí vidět.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "not_found": {
        "summary": "No such object, or the connection cannot see it",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#not_found",
         "title": "Nenalezeno",
         "status": 404,
         "code": "not_found",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Objekt není, nebo ho připojení nevidí"
       }
      }
     }
    }
   },
   "Conflict": {
    "description": "A conflict with the current state; `code` says which – the description of the operation lists its codes, the error catalog says what to do.",
    "x-description-cs": "Konflikt s aktuálním stavem; jaký, říká `code` – kódy operace uvádí její popis, co dělat, říká katalog chyb.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "idempotency_in_progress": {
        "summary": "The same Idempotency-Key is still being processed",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#idempotency_in_progress",
         "title": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
         "status": 409,
         "code": "idempotency_in_progress",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Stejný Idempotency-Key se ještě zpracovává"
       }
      }
     }
    }
   },
   "Gone": {
    "description": "`cursor_expired`: the cursor was issued more than 30 days ago – events since then may be gone.",
    "x-description-cs": "`cursor_expired`: kurzor byl vydán před víc než 30 dny – události od té doby už mohou být pryč.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "cursor_expired": {
        "summary": "A cursor older than 30 days",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#cursor_expired",
         "title": "Kurzor vypršel",
         "status": 410,
         "code": "cursor_expired",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Kurzor starší než 30 dní"
       }
      }
     }
    }
   },
   "PreconditionFailed": {
    "description": "`precondition_failed`: the object changed since you read it. Read it again and retry.",
    "x-description-cs": "`precondition_failed`: záznam se od načtení změnil. Načtěte ho znovu a zkuste to znovu.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "precondition_failed": {
        "summary": "The object changed since you read it",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#precondition_failed",
         "title": "Záznam se mezitím změnil",
         "status": 412,
         "code": "precondition_failed",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Záznam se od načtení změnil"
       }
      }
     }
    }
   },
   "PreconditionRequired": {
    "description": "`precondition_required`: send the `ETag` you read in `If-Match`.",
    "x-description-cs": "`precondition_required`: pošlete načtený `ETag` v `If-Match`.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "precondition_required": {
        "summary": "If-Match is missing",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#precondition_required",
         "title": "Chybí hlavička If-Match",
         "status": 428,
         "code": "precondition_required",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Chybí If-Match"
       }
      }
     }
    }
   },
   "Unprocessable": {
    "description": "`validation_failed` (see `errors`) or a business rule, see `code`.",
    "x-description-cs": "`validation_failed` (viz `errors`) nebo obchodní pravidlo, viz `code`.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "validation_failed": {
        "summary": "Field errors",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#validation_failed",
         "title": "Neplatná data",
         "status": 422,
         "code": "validation_failed",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [
          {
           "pointer": "/items/0/quantity",
           "code": "too_small",
           "message": "Množství musí být aspoň 1."
          }
         ],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Chyby u polí"
       }
      }
     }
    }
   },
   "TooManyRequests": {
    "description": "`rate_limited` (requests of the connection or device), or a limit of the operation – `staff_locked`, `voucher_attempts_exceeded`, `verification_resend_too_early`, `sms_quota_exceeded`; see `code`. Wait `Retry-After` seconds.",
    "x-description-cs": "`rate_limited` (požadavky připojení nebo zařízení), nebo limit operace – `staff_locked`, `voucher_attempts_exceeded`, `verification_resend_too_early`, `sms_quota_exceeded`; viz `code`. Počkejte `Retry-After` sekund.",
    "headers": {
     "Retry-After": {
      "$ref": "#/components/headers/RetryAfter"
     }
    },
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "rate_limited": {
        "summary": "The request limit of the connection",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#rate_limited",
         "title": "Příliš mnoho požadavků",
         "status": 429,
         "code": "rate_limited",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Limit požadavků připojení"
       }
      }
     }
    }
   },
   "NotAcceptable": {
    "description": "`not_acceptable`: `Accept` asks for a type this operation does not give.",
    "x-description-cs": "`not_acceptable`: `Accept` žádá typ, který tato operace nevrací.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "not_acceptable": {
        "summary": "Accept asks for another type",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#not_acceptable",
         "title": "Požadovaný typ odpovědi není k dispozici",
         "status": 406,
         "code": "not_acceptable",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Accept chce jiný typ"
       }
      }
     }
    }
   },
   "PayloadTooLarge": {
    "description": "`payload_too_large`: the body is larger than the operation allows.",
    "x-description-cs": "`payload_too_large`: tělo je větší, než operace dovolí.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "payload_too_large": {
        "summary": "The body is over the limit",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#payload_too_large",
         "title": "Požadavek je příliš velký",
         "status": 413,
         "code": "payload_too_large",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Tělo je větší než limit"
       }
      }
     }
    }
   },
   "UnsupportedMediaType": {
    "description": "`unsupported_media_type`: send the body as the type this operation takes.",
    "x-description-cs": "`unsupported_media_type`: pošlete tělo v typu, který operace přijímá.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "unsupported_media_type": {
        "summary": "A Content-Type the operation does not take",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#unsupported_media_type",
         "title": "Nepodporovaný typ těla požadavku",
         "status": 415,
         "code": "unsupported_media_type",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Content-Type, který operace nebere"
       }
      }
     }
    }
   },
   "ServiceUnavailable": {
    "description": "`service_unavailable`: a service Profirest needs for this (SMS gateway, map service, the backup storage) does not answer. Try again after `Retry-After` seconds.",
    "x-description-cs": "`service_unavailable`: služba, kterou Profirest k tomu potřebuje (SMS brána, mapy, úložiště záloh), neodpovídá. Zkuste to znovu za `Retry-After` sekund.",
    "headers": {
     "Retry-After": {
      "$ref": "#/components/headers/RetryAfter"
     }
    },
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "service_unavailable": {
        "summary": "The SMS gateway does not answer",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#service_unavailable",
         "title": "Služba je dočasně nedostupná",
         "status": 503,
         "code": "service_unavailable",
         "detail": null,
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "SMS brána neodpovídá"
       }
      }
     }
    }
   },
   "StreamUnavailable": {
    "description": "`service_unavailable`: the live stream is not running right now. Read the state as without it (`listEvents`, or GET at the table) and try the stream again after `Retry-After` seconds.",
    "x-description-cs": "`service_unavailable`: živý proud teď neběží. Čtěte stav jako bez něj (`listEvents`, u stolu GET) a o proud se pokuste znovu za `Retry-After` sekund.",
    "headers": {
     "Retry-After": {
      "$ref": "#/components/headers/RetryAfter"
     }
    },
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      },
      "examples": {
       "service_unavailable": {
        "summary": "The stream is not running",
        "value": {
         "type": "https://api.mujprofirest.cz/v2/docs/errors#service_unavailable",
         "title": "Služba je dočasně nedostupná",
         "status": 503,
         "code": "service_unavailable",
         "detail": "Proud událostí teď neběží. Čtěte GET /v2/events se stejným kurzorem a o proud se pokuste znovu později.",
         "instance": null,
         "request_id": "7c9e6679a1f04d3b8e2b5f0a4c1d2e3f",
         "errors": [],
         "existing_id": null,
         "candidates": [],
         "paid_by": null
        },
        "x-summary-cs": "Proud teď neběží"
       }
      }
     }
    }
   },
   "VisitEnded": {
    "description": "`visit_ended`: the visit of the table ended (paid, or the staff ended it) and the token of the phone with it. Do not start a new session by yourself – only after a new scan of the QR code.",
    "x-description-cs": "`visit_ended`: návštěva stolu skončila (zaplaceno, nebo ji ukončila obsluha) a s ní token telefonu. Novou relaci nezakládejte sami – až po novém naskenování QR kódu.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      }
     }
    }
   },
   "Locked": {
    "description": "`join_locked`: this phone entered a wrong code from a friend too many times. The staff unlocks it.",
    "x-description-cs": "`join_locked`: tento telefon zadal špatný kód od kamaráda příliš mnohokrát. Odemkne ho obsluha.",
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      }
     }
    }
   },
   "RestaurantOffline": {
    "description": "`restaurant_offline`: the main register of the restaurant is not connected, so nobody would take the request over. Try again after `Retry-After` seconds, or ask the staff.",
    "x-description-cs": "`restaurant_offline`: hlavní kasa podniku není připojená, takže by žádost nikdo nepřevzal. Zkuste to znovu za `Retry-After` sekund, nebo požádejte obsluhu.",
    "headers": {
     "Retry-After": {
      "$ref": "#/components/headers/RetryAfter"
     }
    },
    "content": {
     "application/problem+json": {
      "schema": {
       "$ref": "#/components/schemas/Problem"
      }
     }
    }
   }
  },
  "schemas": {
   "Id": {
    "type": "string",
    "description": "Opaque identifier. Do not parse it.",
    "x-description-cs": "Neprůhledný identifikátor. Nerozkládejte ho.",
    "minLength": 1,
    "maxLength": 64,
    "examples": [
     "184223"
    ]
   },
   "ExternalId": {
    "type": "string",
    "description": "Your own ID from your system. Unique per object type within your connection.",
    "x-description-cs": "Vaše vlastní ID z vašeho systému. Unikátní pro typ objektu v rámci vašeho připojení.",
    "minLength": 1,
    "maxLength": 128,
    "pattern": "^[\\x21-\\x7E]+$",
    "examples": [
     "A-2026-000123"
    ]
   },
   "Metadata": {
    "type": "object",
    "description": "Your own key–value pairs (at most 20).",
    "x-description-cs": "Vaše vlastní dvojice klíč–hodnota (nejvýš 20).",
    "additionalProperties": {
     "type": "string"
    },
    "examples": [
     {
      "branch": "praha-2",
      "campaign": "autumn"
     }
    ]
   },
   "MetadataInput": {
    "type": "object",
    "description": "Up to 20 of your own key–value pairs. Keys have 1–40 characters `a-z`, `0-9`, `_`. Values are strings of\n1–500 characters. Replaces all your metadata. Do not store secrets or card data here.\n",
    "x-description-cs": "Až 20 vašich vlastních dvojic klíč–hodnota. Klíče mají 1–40 znaků `a-z`, `0-9`, `_`. Hodnoty jsou řetězce\no 1–500 znacích. Nahradí všechna vaše metadata. Neukládejte sem tajné údaje ani údaje o kartách.\n",
    "maxProperties": 20,
    "propertyNames": {
     "pattern": "^[a-z0-9_]{1,40}$"
    },
    "additionalProperties": {
     "type": "string",
     "minLength": 1,
     "maxLength": 500
    }
   },
   "MetadataPatch": {
    "type": "object",
    "description": "Keys you send are set; a key set to `null` is removed; other keys stay. At most 20 keys in total.",
    "x-description-cs": "Poslané klíče se nastaví; klíč s `null` se odebere; ostatní klíče zůstanou. Celkem nejvýš 20 klíčů.",
    "maxProperties": 20,
    "propertyNames": {
     "pattern": "^[a-z0-9_]{1,40}$"
    },
    "additionalProperties": {
     "type": [
      "string",
      "null"
     ],
     "maxLength": 500
    }
   },
   "Money": {
    "type": "object",
    "description": "Amount in minor units (haléře for CZK, cents for EUR) and ISO 4217 currency.",
    "x-description-cs": "Částka v nejmenších jednotkách (haléře u CZK, centy u EUR) a měna podle ISO 4217.",
    "required": [
     "amount",
     "currency"
    ],
    "properties": {
     "amount": {
      "type": "integer",
      "description": "Minor units. Negative for discounts.",
      "x-description-cs": "Nejmenší jednotky. U slev záporná.",
      "examples": [
       1229460
      ]
     },
     "currency": {
      "type": "string",
      "pattern": "^[A-Z]{3}$",
      "examples": [
       "CZK"
      ]
     }
    }
   },
   "MoneyInput": {
    "type": "object",
    "description": "Amount in minor units and ISO 4217 currency.",
    "x-description-cs": "Částka v nejmenších jednotkách a měna podle ISO 4217.",
    "additionalProperties": false,
    "required": [
     "amount",
     "currency"
    ],
    "properties": {
     "amount": {
      "type": "integer",
      "minimum": 0,
      "maximum": 9999999999,
      "description": "Minor units, at most 9 999 999 999 (99 999 999.99 – the limit of EET 2.0 amounts).",
      "x-description-cs": "Nejmenší jednotky, nejvýš 9 999 999 999 (99 999 999,99 – strop částek EET 2.0).",
      "examples": [
       48900
      ]
     },
     "currency": {
      "type": "string",
      "pattern": "^[A-Z]{3}$",
      "examples": [
       "CZK"
      ]
     }
    }
   },
   "VatRate": {
    "type": "string",
    "description": "VAT rate in percent as a decimal string.",
    "x-description-cs": "Sazba DPH v procentech jako desetinný řetězec.",
    "pattern": "^[0-9]{1,2}(\\.[0-9]{1,2})?$",
    "examples": [
     "12",
     "21",
     "0"
    ]
   },
   "Timestamp": {
    "type": "string",
    "format": "date-time",
    "description": "RFC 3339 instant with an offset.",
    "x-description-cs": "Okamžik podle RFC 3339 s posunem.",
    "examples": [
     "2026-10-05T18:30:00+02:00"
    ]
   },
   "LocalDate": {
    "type": "string",
    "format": "date",
    "description": "Calendar date in the time zone of the restaurant.",
    "x-description-cs": "Kalendářní datum v časové zóně provozovny.",
    "examples": [
     "2026-10-05"
    ]
   },
   "LocalTime": {
    "type": "string",
    "description": "Wall-clock time `HH:MM` in the time zone of the restaurant. `24:00` means midnight at the end of the day.",
    "x-description-cs": "Místní čas `HH:MM` v časové zóně provozovny. `24:00` znamená půlnoc na konci dne.",
    "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$|^24:00$",
    "examples": [
     "11:00",
     "22:30"
    ]
   },
   "Phone": {
    "type": "string",
    "description": "Phone number in E.164 format. Any country is accepted.",
    "x-description-cs": "Telefonní číslo ve formátu E.164. Přijímáme jakoukoli zemi.",
    "pattern": "^\\+[1-9][0-9]{6,14}$",
    "examples": [
     "+420777123456"
    ]
   },
   "Email": {
    "type": "string",
    "format": "email",
    "maxLength": 254
   },
   "GeoPoint": {
    "type": "object",
    "required": [
     "lat",
     "lon"
    ],
    "properties": {
     "lat": {
      "type": "number",
      "examples": [
       50.0833
      ]
     },
     "lon": {
      "type": "number",
      "examples": [
       14.4667
      ]
     }
    }
   },
   "GeoPointInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "lat",
     "lon"
    ],
    "properties": {
     "lat": {
      "type": "number",
      "minimum": -90,
      "maximum": 90,
      "examples": [
       50.0833
      ]
     },
     "lon": {
      "type": "number",
      "minimum": -180,
      "maximum": 180,
      "examples": [
       14.4667
      ]
     }
    }
   },
   "VatBreakdown": {
    "type": "object",
    "required": [
     "rate",
     "base",
     "vat",
     "total"
    ],
    "properties": {
     "rate": {
      "$ref": "#/components/schemas/VatRate"
     },
     "base": {
      "$ref": "#/components/schemas/Money",
      "description": "Amount without VAT.",
      "x-description-cs": "Částka bez DPH."
     },
     "vat": {
      "$ref": "#/components/schemas/Money"
     },
     "total": {
      "$ref": "#/components/schemas/Money",
      "description": "Amount with VAT.",
      "x-description-cs": "Částka s DPH."
     }
    }
   },
   "ApiRoot": {
    "type": "object",
    "required": [
     "name",
     "version",
     "docs_url",
     "oauth_metadata_url",
     "stream_url",
     "server_time"
    ],
    "properties": {
     "name": {
      "type": "string",
      "examples": [
       "Profirest API"
      ]
     },
     "version": {
      "type": "string",
      "description": "Version of this contract (`info.version` of `openapi.json`) – YY.M.N, the year, the month and the release within the month; compare part by part as numbers.",
      "x-description-cs": "Verze této smlouvy (`info.version` v `openapi.json`) – RR.M.N, rok, měsíc a pořadí vydání v měsíci; porovnávejte číselně po částech.",
      "examples": [
       "26.10.7"
      ]
     },
     "docs_url": {
      "type": "string",
      "format": "uri"
     },
     "oauth_metadata_url": {
      "type": "string",
      "format": "uri"
     },
     "stream_url": {
      "type": [
       "string",
       "null"
      ],
      "format": "uri",
      "description": "Address of the live change feed (`streamEvents`, Server-Sent Events), or `null` while the stream service is\nnot running – then poll `GET /events` and ask again in a few minutes. The stream and `GET /events` give the\nsame events with the same cursor.\n",
      "x-description-cs": "Adresa živého proudu změn (`streamEvents`, Server-Sent Events), nebo `null`, když služba proudu neběží – pak\nse ptejte přes `GET /events` a zeptejte se znovu za pár minut. Proud i `GET /events` dávají tytéž události\nse stejným kurzorem.\n"
     },
     "server_time": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "AppVersionList": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/AppVersion"
      }
     },
     "next_cursor": {
      "description": "Always `null` – the whole list in one response.",
      "x-description-cs": "Vždy `null` – celý seznam v jedné odpovědi.",
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "AppVersion": {
    "type": "object",
    "required": [
     "app",
     "channel",
     "version",
     "critical",
     "released_at",
     "download_url",
     "changelog",
     "sha256",
     "size"
    ],
    "properties": {
     "app": {
      "type": "string",
      "description": "The app as the administration names it (Super → Software): `bar` – the cash register for Windows; `kitchen` –\nthe kitchen application for Windows (kitchen tickets, phone and e-shop orders; not the Android kitchen\ndisplay); `server` – the local server of Windows registers (their sync, EET and communication with\nProfirest); `mobile` – the Android waiter app for older Windows registers; `mobile_android` – the Android\nregister and waiter app; `mobile_alpha` – test builds of the Android app for development; `kitchen_windows` –\nthe kitchen display for Windows. An app without an old key has `app_platform`.\n",
      "x-description-cs": "Aplikace, jak ji pojmenovává administrace (Super → Software): `bar` – pokladna pro Windows; `kitchen` –\nkuchyňská aplikace pro Windows (bony, telefonické objednávky a objednávky z e-shopu; ne kuchyňský displej\npro Android); `server` – místní server pokladen pro Windows (jejich synchronizace, EET a spojení\ns Profirestem); `mobile` – mobilní číšník pro Android ke starším pokladnám pro Windows; `mobile_android` –\npokladna a mobilní číšník pro Android; `mobile_alpha` – zkušební sestavení aplikace pro Android pro vývoj;\n`kitchen_windows` – kuchyňský displej pro Windows. Aplikace bez starého klíče má `aplikace_platforma`.\n",
      "x-extensible-enum": [
       "bar",
       "kitchen",
       "server",
       "mobile",
       "mobile_android",
       "mobile_alpha",
       "kitchen_windows"
      ]
     },
     "channel": {
      "type": "string",
      "description": "`stable` – the released version; `beta` – a test version. Each channel has its own newest version, so the\nbeta can be older than the stable one.\n",
      "x-description-cs": "`stable` – vydaná verze; `beta` – testovací verze. Každý kanál má svou nejnovější verzi, beta tedy může být\nstarší než ostrá.\n",
      "x-extensible-enum": [
       "stable",
       "beta"
      ]
     },
     "version": {
      "type": "string",
      "examples": [
       "1.2.168"
      ]
     },
     "critical": {
      "type": "boolean",
      "description": "Profirest marked the update as critical – the older version should not be used any more. The server only passes the mark on.",
      "x-description-cs": "Profirest označil aktualizaci jako kritickou – starší verzi už nepoužívejte. Server označení jen předává."
     },
     "released_at": {
      "description": "When the version was uploaded to Profirest.",
      "x-description-cs": "Kdy byla verze nahraná do Profirestu.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "download_url": {
      "type": [
       "string",
       "null"
      ],
      "format": "uri",
      "description": "Where to download the version; `null` when no file is stored.",
      "x-description-cs": "Odkud verzi stáhnout; `null`, když soubor uložený není."
     },
     "changelog": {
      "type": [
       "string",
       "null"
      ],
      "description": "What changed, as Profirest wrote it; `null` when empty.",
      "x-description-cs": "Co se změnilo, jak to Profirest napsal; `null`, když nic."
     },
     "sha256": {
      "type": [
       "string",
       "null"
      ],
      "pattern": "^[0-9a-f]{64}$",
      "description": "SHA-256 of the file at `download_url` in lowercase hex – check the downloaded file before installing it;\n`null` when Profirest has no fingerprint of the file (or no file).\n",
      "x-description-cs": "SHA-256 souboru z `download_url` malými hex znaky – stažený soubor před instalací ověřte; `null`, když\nProfirest otisk souboru nemá (nebo soubor není).\n"
     },
     "size": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 1,
      "description": "The size of the file at `download_url` in bytes; `null` when unknown (or no file).",
      "x-description-cs": "Velikost souboru z `download_url` v bajtech; `null`, když není známá (nebo soubor není)."
     }
    }
   },
   "Connection": {
    "type": "object",
    "required": [
     "id",
     "client",
     "account_id",
     "scopes",
     "restaurant_ids",
     "settings",
     "created_at",
     "device"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "client": {
      "type": "object",
      "required": [
       "id",
       "name",
       "order_channel"
      ],
      "properties": {
       "id": {
        "type": "string"
       },
       "name": {
        "type": "string"
       },
       "order_channel": {
        "type": "string",
        "description": "Who places the orders of your application. `web` – customers themselves (an e-shop): order hours\n(`getOrderHours`), delivery schedules, lead time and the scheduled-order settings apply. `staff` – the restaurant's own\nstaff (point of sale, kitchen display, phone orders): orders are accepted at any time, so the time\nrules do not apply and `ordering`, time slots and quotes say so. `kiosk` – the self-service kiosk of\nProfirest: guests order at the restaurant. The restaurant chooses how it orders: on its own – only\n\"as soon as possible\" while open, pickup only, without the web licence and the pause of `web`\napplications – or as its staff, then every request for that restaurant follows the `staff` rules.\nOnly the restaurant's switch for kiosks pauses it. Kiosk orders are guest orders in both cases: they\nare on the order-number screen and the kitchen does not add items to them; portions are tracked as\nat the registers. Set by Profirest when your application is registered.\n",
        "x-description-cs": "Kdo zadává objednávky vaší aplikace. `web` – zákazníci sami (e-shop): platí příjem objednávek\n(`getOrderHours`), časy rozvozu, předstih a nastavení objednávek na čas. `staff` – personál podniku (pokladna, kuchyňský\ndisplej, telefonické objednávky): objednávky se přijímají kdykoli, časová pravidla se nepoužijí\na `ordering`, časy i kalkulace to tak vracejí. `kiosk` – samoobslužný kiosek Profirestu: hosté\nobjednávají v provozovně. Jak objednává, volí provozovna: samostatně – jen „co nejdřív“ v otevírací\ndobě, jen osobní odběr, bez licence webu a bez pozastavení aplikací `web` – nebo jako obsluha, pak se\nkaždý požadavek na tu provozovnu řídí pravidly `staff`. Pozastaví ho jen přepínač provozovny pro\nkiosky. Objednávky z kiosku jsou v obou případech objednávky hostů: jsou na pořadníku a kuchyň k nim\nnepřidává položky; porce se hlídají jako na pokladnách. Nastavuje Profirest při registraci aplikace.\n",
        "x-extensible-enum": [
         "web",
         "staff",
         "kiosk"
        ]
       }
      }
     },
     "account_id": {
      "$ref": "#/components/schemas/Id"
     },
     "scopes": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "restaurant_ids": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "settings": {
      "type": "object",
      "description": "Settings the owner chose for this connection in Profirest.",
      "x-description-cs": "Nastavení, která pro toto připojení zvolil majitel v Profirestu.",
      "required": [
       "customer_messages"
      ],
      "properties": {
       "customer_messages": {
        "type": "string",
        "description": "Who sends order messages (confirmation, ready, on the way) to your customers.\n`integrator` – you do; `profirest` – Profirest sends SMS from the owner's credit.\n",
        "x-description-cs": "Kdo posílá vašim zákazníkům zprávy o objednávce (potvrzení, hotovo, na cestě).\n`integrator` – vy; `profirest` – Profirest pošle SMS z kreditu majitele.\n",
        "x-extensible-enum": [
         "integrator",
         "profirest"
        ]
       }
      }
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "device": {
      "description": "The paired device this token belongs to; `null` for an application connected by its owner.",
      "x-description-cs": "Spárované zařízení, kterému token patří; `null` u aplikace připojené majitelem.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Device"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "Device": {
    "type": "object",
    "required": [
     "id",
     "name",
     "restaurant_id",
     "platform",
     "app_version",
     "paired_at",
     "api_target"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "platform": {
      "type": [
       "string",
       "null"
      ]
     },
     "app_version": {
      "type": [
       "string",
       "null"
      ]
     },
     "paired_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "api_target": {
      "description": "Where the device should be – only for Profirest's own register, kitchen display and courier; `null` for others.",
      "x-description-cs": "Kde má zařízení být – jen u vlastní pokladny, kuchyňského displeje a kurýra Profirestu; jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ApiTarget"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ApiTarget": {
    "type": "object",
    "description": "Which API the restaurant's devices should use – Profirest moves restaurants to API v2 one by one and can move them\nback. Every answer to the register, kitchen display or courier app of Profirest carries the same in the header\n`Profirest-Api-Target: v1 | v2` (and API v1 too). On `v1` finish what you are doing, send the queue, wait a random\n0–90 seconds and sign in to API v1 with the stored identity (`createLegacyIdentity`); the API v2 tokens stop\nworking.\n",
    "x-description-cs": "Které API mají zařízení provozovny používat – Profirest pouští provozovny na API v2 jednu po druhé a umí je vrátit.\nKaždá odpověď aplikaci pokladny, kuchyňského displeje nebo kurýra Profirestu nese totéž v hlavičce\n`Profirest-Api-Target: v1 | v2` (i API v1). Při `v1` dokončete rozdělanou práci, odešlete frontu, počkejte náhodně\n0–90 sekund a přihlaste se v API v1 uloženou identitou (`createLegacyIdentity`); tokeny API v2 přestanou platit.\n",
    "required": [
     "target",
     "base_url"
    ],
    "properties": {
     "target": {
      "type": "string",
      "enum": [
       "v1",
       "v2"
      ]
     },
     "base_url": {
      "type": "string",
      "format": "uri",
      "description": "Address of API v2.",
      "x-description-cs": "Adresa API v2.",
      "examples": [
       "https://api.mujprofirest.cz/v2"
      ]
     }
    }
   },
   "LegacyIdentityRequest": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "v1_device_id"
    ],
    "properties": {
     "v1_device_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 512,
      "description": "The `DEVICE_ID` the app would send in API v1 (the courier app the ID of the phone).",
      "x-description-cs": "`DEVICE_ID`, který by aplikace poslala v API v1 (aplikace kurýra ID telefonu)."
     }
    }
   },
   "LegacyIdentity": {
    "type": "object",
    "description": "The API v1 identity: the register signs in with `app_key`, `login` and `device_id` (`get_token`), the kitchen\ndisplay uses `token` as `Authorization: Bearer`, the courier signs in with `login` and `password`.\n",
    "x-description-cs": "Identita API v1: pokladna se přihlásí `app_key`, `login` a `device_id` (`get_token`), kuchyňský displej posílá\n`token` jako `Authorization: Bearer`, kurýr se přihlásí `login` a `password`.\n",
    "required": [
     "kind",
     "login",
     "device_id",
     "app_key",
     "token",
     "password"
    ],
    "properties": {
     "kind": {
      "type": "string",
      "enum": [
       "pos",
       "kds",
       "courier"
      ]
     },
     "login": {
      "type": "string"
     },
     "device_id": {
      "type": "string"
     },
     "app_key": {
      "type": [
       "string",
       "null"
      ],
      "description": "Register only, otherwise `null`.",
      "x-description-cs": "Jen pokladna, jinak `null`."
     },
     "token": {
      "type": [
       "string",
       "null"
      ],
      "description": "Kitchen display only, otherwise `null`.",
      "x-description-cs": "Jen kuchyňský displej, jinak `null`."
     },
     "password": {
      "type": [
       "string",
       "null"
      ],
      "description": "Courier only, otherwise `null`.",
      "x-description-cs": "Jen kurýr, jinak `null`."
     }
    }
   },
   "EmployeeRef": {
    "type": "object",
    "required": [
     "id",
     "name"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     }
    }
   },
   "StaffMember": {
    "type": "object",
    "required": [
     "id",
     "name",
     "roles",
     "attendance",
     "sign_in",
     "offline_approval",
     "offline_sign_in"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "roles": {
      "type": "array",
      "description": "What the employee may do on devices of this restaurant: `pos` (cash register and waiter app),\n`pos_manager` (manager actions on the register), `kitchen` (kitchen display), `kitchen_manager` (manager\nactions in the kitchen), `reception` (the reception of the hotel, since 26.11.21), `reception_manager`\n(manager actions at the reception – cancelling the receipt for a stay and removing payments, since 26.11.23),\n`housekeeping` (a maid – cleaning of rooms, since 26.11.21). Since 26.11.23 the reception and maid roles come\nfrom their own permissions of the employee for devices (Reception, Reception – manager, Maid), like the\nregister and the kitchen. New roles may come.\n",
      "x-description-cs": "Co smí zaměstnanec na zařízeních této provozovny: `pos` (pokladna a mobilní číšník), `pos_manager`\n(manažerské akce na pokladně), `kitchen` (kuchyňský displej), `kitchen_manager` (manažerské akce\nv kuchyni), `reception` (recepce hotelu, od 26.11.21), `reception_manager` (manažerské akce na recepci – storno\ndokladu za pobyt a mazání plateb, od 26.11.23), `housekeeping` (pokojská – úklid pokojů, od 26.11.21). Od 26.11.23\nplynou role recepce a pokojské z vlastních práv zaměstnance pro zařízení (Recepce, Recepce – správce,\nPokojská) jako u pokladny a kuchyně. Mohou přibýt další role.\n",
      "items": {
       "type": "string",
       "x-extensible-enum": [
        "pos",
        "pos_manager",
        "kitchen",
        "kitchen_manager",
        "reception",
        "reception_manager",
        "housekeeping"
       ]
      }
     },
     "attendance": {
      "type": "object",
      "required": [
       "enabled"
      ],
      "properties": {
       "enabled": {
        "type": "boolean",
        "description": "The employee is kept in attendance at this restaurant and may punch here.",
        "x-description-cs": "Zaměstnanec se na této provozovně vede v docházce a smí tu píchat."
       }
      }
     },
     "sign_in": {
      "type": "object",
      "description": "How the employee can sign in. The PIN and the card number themselves are never returned.",
      "x-description-cs": "Jak se zaměstnanec může přihlásit. Samotný PIN ani číslo čipu se nikdy nevracejí.",
      "required": [
       "pin",
       "card"
      ],
      "properties": {
       "pin": {
        "type": "boolean"
       },
       "card": {
        "type": "boolean"
       }
      }
     },
     "offline_approval": {
      "description": "Only in `GET …/staff` for a paired register (`receipts:write`) and only for register managers with a PIN;\notherwise `null`. What the register needs to approve manual discounts and prices on an offline receipt.\n",
      "x-description-cs": "Jen v `GET …/staff` pro spárovanou pokladnu (`receipts:write`) a jen u vedoucích pokladny s PINem, jinak\n`null`. Co pokladna potřebuje ke schválení ruční slevy a ceny na offline účtence.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/OfflineApproval"
       },
       {
        "type": "null"
       }
      ]
     },
     "offline_sign_in": {
      "description": "Only in `GET …/staff` for a paired register (`receipts:write`) and only for employees with the `pos` or\n`pos_manager` role and a PIN; otherwise `null`. Signing in on a register without connection (it restarted\noffline): the register checks the PIN with `check` exactly as for `offline_approval` – the values are the\nsame, so a register manager gets the same object in both fields. Only 8 bits, so about one PIN in 256 passes:\nlet the employee pick their name first and then type the PIN, never find the employee by the PIN alone, and\nlimit the attempts on the device. Receipts made so go as offline receipts with `issued_by_id` once the\nconnection is back. Keep the list fresh – a new PIN in the administration changes `check`. Since 26.11.26.\n",
      "x-description-cs": "Jen v `GET …/staff` pro spárovanou pokladnu (`receipts:write`) a jen u zaměstnanců s rolí `pos` nebo\n`pos_manager` a PINem, jinak `null`. Přihlášení na pokladně bez spojení (spustila se offline): pokladna PIN\nzkontroluje pomocí `check` přesně jako u `offline_approval` – hodnoty jsou stejné, vedoucí pokladny tedy\ndostane v obou polích tentýž objekt. Jen 8 bitů, projde tedy asi každý 256. PIN: ať si zaměstnanec nejdřív\nvybere své jméno a pak napíše PIN, zaměstnance nikdy nehledejte jen podle PINu a pokusy na zařízení omezte.\nÚčtenky pořízené takto se pošlou jako offline účtenky s `issued_by_id`, až bude spojení zpět. Seznam držte\nčerstvý – nový PIN v administraci `check` změní. Od 26.11.26.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/OfflineApproval"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "OfflineApproval": {
    "type": "object",
    "description": "Approving manual discounts and prices on an offline receipt by a register manager. The register checks the\nPIN for typos with `check` and signs the receipt; the server verifies the signature when the receipt arrives\n(`approval_signature`). The official libraries compute it for you.\n\n- `check` = the first byte of HMAC-SHA256 with the salt as the key and `profirest-offline-check|` + PIN as the\n  message. Only 8 bits – about 40 four-digit PINs share it, so the PIN cannot be found from it; a different\n  value means a typo.\n- Signing key K = PBKDF2-HMAC-SHA256(PIN as UTF-8, salt, `iterations`, 32 bytes).\n- `approval_signature` = base64url without padding of HMAC-SHA256(K, message); the message is these lines\n  joined by a line feed: `profirest-offline-approval`, `id`, `number`, `issued_at` exactly as sent,\n  `approved_by_id`, the sum of `payments[].amount.amount`.\n\nWhoever gets a signed receipt waiting on the device can try PINs against it – send offline receipts as soon\nas the connection is back and do not keep them after sending.\n",
    "x-description-cs": "Schválení ruční slevy a ceny na offline účtence vedoucím pokladny. Pokladna PIN zkontroluje na překlep\npomocí `check` a účtenku podepíše; server podpis ověří, až účtenka dorazí (`approval_signature`). Oficiální\nknihovny to spočítají za vás.\n\n- `check` = první bajt HMAC-SHA256 se solí jako klíčem a zprávou `profirest-offline-check|` + PIN. Jen 8 bitů –\n  stejnou hodnotu má asi 40 čtyřmístných PINů, PIN z ní tedy zjistit nejde; jiná hodnota znamená překlep.\n- Klíč podpisu K = PBKDF2-HMAC-SHA256(PIN jako UTF-8, sůl, `iterations`, 32 bajtů).\n- `approval_signature` = base64url bez zarovnání z HMAC-SHA256(K, zpráva); zpráva jsou tyto řádky spojené\n  znakem nového řádku: `profirest-offline-approval`, `id`, `number`, `issued_at` přesně jak se posílá,\n  `approved_by_id`, součet `payments[].amount.amount`.\n\nKdo získá podepsanou účtenku čekající na zařízení, může proti ní zkoušet PINy – offline účtenky posílejte,\nhned jak je spojení zpět, a po odeslání je neuchovávejte.\n",
    "required": [
     "salt",
     "iterations",
     "check"
    ],
    "properties": {
     "salt": {
      "type": "string",
      "pattern": "^[A-Za-z0-9_-]{22}$",
      "description": "16 bytes in base64url without padding.",
      "x-description-cs": "16 bajtů v base64url bez zarovnání.",
      "examples": [
       "pHk3r9QnW1xY0aBcDeFgHw"
      ]
     },
     "iterations": {
      "type": "integer",
      "minimum": 1,
      "examples": [
       100000
      ]
     },
     "check": {
      "type": "integer",
      "minimum": 0,
      "maximum": 255,
      "examples": [
       141
      ]
     }
    }
   },
   "StaffMemberPage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/StaffMember"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "StaffCredential": {
    "type": "object",
    "description": "A PIN or a card entered at the device.",
    "x-description-cs": "PIN nebo čip zadaný na zařízení.",
    "additionalProperties": false,
    "required": [
     "method",
     "secret"
    ],
    "properties": {
     "method": {
      "type": "string",
      "enum": [
       "pin",
       "card"
      ],
      "description": "`pin` – the employee's PIN; `card` – the number read from the employee's card (chip).",
      "x-description-cs": "`pin` – PIN zaměstnance; `card` – číslo načtené z čipu zaměstnance."
     },
     "secret": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128,
      "description": "The PIN (digits only) or the number read from the card.",
      "x-description-cs": "PIN (jen číslice) nebo číslo načtené z čipu."
     },
     "employee_id": {
      "description": "The employee chosen after `409 staff_ambiguous`.",
      "x-description-cs": "Zaměstnanec vybraný po `409 staff_ambiguous`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "StaffPinChange": {
    "type": "object",
    "description": "The current and the new PIN of the signed-in employee.",
    "x-description-cs": "Současný a nový PIN přihlášeného zaměstnance.",
    "additionalProperties": false,
    "required": [
     "current_pin",
     "new_pin"
    ],
    "properties": {
     "current_pin": {
      "type": "string",
      "pattern": "^[0-9]{1,9}$"
     },
     "new_pin": {
      "type": "string",
      "pattern": "^[1-9][0-9]{3,8}$",
      "description": "4 to 9 digits, not starting with 0.",
      "x-description-cs": "4 až 9 číslic, nezačíná nulou."
     }
    }
   },
   "StaffSession": {
    "type": "object",
    "required": [
     "token",
     "expires_at",
     "max_expires_at",
     "idle_timeout_seconds",
     "employee"
    ],
    "properties": {
     "token": {
      "type": "string",
      "description": "Send it in the `Profirest-Staff-Token` header. Keep it in memory only.",
      "x-description-cs": "Posílejte ho v hlavičce `Profirest-Staff-Token`. Držte ho jen v paměti."
     },
     "expires_at": {
      "description": "When the session ends unless it is used. Every use moves it by `idle_timeout_seconds`.",
      "x-description-cs": "Kdy relace skončí, když se nepoužije. Každé použití ji posune o `idle_timeout_seconds`.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "max_expires_at": {
      "description": "The session ends at this time at the latest.",
      "x-description-cs": "Nejpozději v tuto chvíli relace skončí.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "idle_timeout_seconds": {
      "type": "integer",
      "description": "Seconds without use before the session ends. 300 on shared devices (kitchen display, reception); the register\nand the waiter app (`profirest-pos`, since 26.11.27), the courier and the maid keep the session for the\nwhole shift – until `max_expires_at`, signing out (`deleteStaffSession`) or a change of the PIN.\n",
      "x-description-cs": "Kolik sekund bez použití relace vydrží. 300 na sdílených zařízeních (kuchyňský displej, recepce); pokladna\na mobilní číšník (`profirest-pos`, od 26.11.27), kurýr a pokojská mají relaci na celou směnu – do\n`max_expires_at`, odhlášení (`deleteStaffSession`) nebo změny PINu.\n",
      "examples": [
       300
      ]
     },
     "employee": {
      "$ref": "#/components/schemas/StaffMember"
     }
    }
   },
   "AttendanceTerminal": {
    "type": "object",
    "description": "How an attendance terminal of the restaurant looks and what it may do.",
    "x-description-cs": "Jak docházkový terminál provozovny vypadá a co smí.",
    "required": [
     "restaurant_name",
     "branding",
     "offline",
     "absence_requests"
    ],
    "properties": {
     "restaurant_name": {
      "type": "string",
      "examples": [
       "Bistro U Lípy"
      ]
     },
     "branding": {
      "type": "object",
      "description": "The restaurant's look from the administration; `null` values mean Profirest's own look.",
      "x-description-cs": "Vzhled provozovny z administrace; hodnoty `null` znamenají vzhled Profirestu.",
      "required": [
       "logo_url",
       "accent_color",
       "theme",
       "welcome_text"
      ],
      "properties": {
       "logo_url": {
        "type": [
         "string",
         "null"
        ],
        "format": "uri",
        "description": "The restaurant's logo (PNG, JPEG, SVG or WebP); `null` – show Profirest's logo.",
        "x-description-cs": "Logo provozovny (PNG, JPEG, SVG nebo WebP); `null` – ukažte logo Profirestu."
       },
       "accent_color": {
        "type": [
         "string",
         "null"
        ],
        "pattern": "^#[0-9a-f]{6}$",
        "description": "The brand colour of buttons and highlights; `null` – Profirest's orange `#ff8c00`.",
        "x-description-cs": "Barva značky na tlačítkách a zvýrazněních; `null` – oranžová Profirestu `#ff8c00`.",
        "examples": [
         "#0e7c66"
        ]
       },
       "theme": {
        "type": "string",
        "description": "`dark` (default) or `light` screen.",
        "x-description-cs": "Tmavá (`dark`, výchozí) nebo světlá (`light`) obrazovka.",
        "x-extensible-enum": [
         "dark",
         "light"
        ]
       },
       "welcome_text": {
        "type": [
         "string",
         "null"
        ],
        "maxLength": 120,
        "description": "A short line under the clock, for example a greeting of the team.",
        "x-description-cs": "Krátký text pod hodinami, třeba pozdrav týmu."
       }
      }
     },
     "offline": {
      "type": "object",
      "required": [
       "allowed",
       "max_age_hours"
      ],
      "properties": {
       "allowed": {
        "type": "boolean",
        "description": "Punches without a network may be kept and sent later (`POST …/attendance/punches/batch`).",
        "x-description-cs": "Píchnutí bez sítě smí terminál uložit a poslat později (`POST …/attendance/punches/batch`)."
       },
       "max_age_hours": {
        "type": "integer",
        "description": "How old a punch made without a network may be when it arrives.",
        "x-description-cs": "Jak staré smí být píchnutí bez sítě, když dorazí.",
        "examples": [
         24
        ]
       }
      }
     },
     "absence_requests": {
      "$ref": "#/components/schemas/AbsenceRequestRules"
     }
    }
   },
   "AttendanceState": {
    "type": "string",
    "description": "`off` – not at work, `working` – during a shift, `on_break` – on a break during a shift.",
    "x-description-cs": "`off` – není v práci, `working` – ve směně, `on_break` – na přestávce během směny.",
    "x-extensible-enum": [
     "off",
     "working",
     "on_break"
    ]
   },
   "AttendancePresence": {
    "type": "object",
    "required": [
     "employee",
     "state",
     "since",
     "shift_started_at"
    ],
    "properties": {
     "employee": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "state": {
      "$ref": "#/components/schemas/AttendanceState"
     },
     "since": {
      "description": "When the current state began (the arrival or the start of the break); `null` for `off`.",
      "x-description-cs": "Kdy začal aktuální stav (příchod nebo začátek přestávky); u `off` je `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "shift_started_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "AttendancePresencePage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/AttendancePresence"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "AttendancePunchCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "type"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the punch, made on the device (UUIDv7 recommended).",
      "x-description-cs": "Vaše UUID píchnutí vytvořené na zařízení (doporučujeme UUIDv7)."
     },
     "type": {
      "type": "string",
      "enum": [
       "clock_in",
       "clock_out",
       "break_start",
       "break_end"
      ],
      "description": "`clock_in` – arrival, starts a shift (not while a shift runs); `clock_out` – departure, ends the shift and a\nbreak still running; `break_start` – a break during the shift; `break_end` – back from the break.\n",
      "x-description-cs": "`clock_in` – příchod, začne směnu (ne během běžící směny); `clock_out` – odchod, ukončí směnu i běžící\npřestávku; `break_start` – přestávka během směny; `break_end` – návrat z přestávky.\n"
     },
     "occurred_at": {
      "description": "When the person punched. Leave it out for a live punch.",
      "x-description-cs": "Kdy člověk píchl. U živého píchnutí ho vynechte.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "credential": {
      "description": "The PIN or card entered with the punch; leave it out when you send `Profirest-Staff-Token`.",
      "x-description-cs": "PIN nebo čip zadaný při píchnutí; vynechte ho, když posíláte `Profirest-Staff-Token`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/StaffCredential"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "AttendancePunchOffline": {
    "type": "object",
    "description": "A punch recorded without a network; it always carries the PIN or card entered with it.",
    "x-description-cs": "Píchnutí pořízené bez sítě; vždy nese PIN nebo čip, který byl při něm zadaný.",
    "additionalProperties": false,
    "required": [
     "id",
     "type",
     "occurred_at",
     "credential"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "type": {
      "type": "string",
      "enum": [
       "clock_in",
       "clock_out",
       "break_start",
       "break_end"
      ],
      "description": "As in `AttendancePunchCreate.type`.",
      "x-description-cs": "Jako `AttendancePunchCreate.type`."
     },
     "occurred_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "credential": {
      "$ref": "#/components/schemas/StaffCredential"
     }
    }
   },
   "AttendancePunchBatch": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "items"
    ],
    "properties": {
     "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 100,
      "items": {
       "$ref": "#/components/schemas/AttendancePunchOffline"
      }
     }
    }
   },
   "AttendanceShift": {
    "type": "object",
    "description": "The shift the punch belongs to. Durations are known after the departure.",
    "x-description-cs": "Směna, ke které píchnutí patří. Délky jsou známé po odchodu.",
    "required": [
     "started_at",
     "ended_at",
     "break_minutes",
     "worked_minutes"
    ],
    "properties": {
     "started_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "ended_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "break_minutes": {
      "description": "Breaks of the shift in minutes.",
      "x-description-cs": "Přestávky směny v minutách.",
      "type": [
       "integer",
       "null"
      ]
     },
     "worked_minutes": {
      "description": "Worked time by the restaurant's attendance rules (tolerances, breaks, overtime).",
      "x-description-cs": "Odpracovaná doba podle pravidel docházky provozovny (tolerance, přestávky, přesčasy).",
      "type": [
       "integer",
       "null"
      ]
     }
    }
   },
   "AttendancePunch": {
    "type": "object",
    "required": [
     "id",
     "employee",
     "type",
     "occurred_at",
     "received_at",
     "offline",
     "state",
     "shift"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "employee": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "type": {
      "type": "string",
      "description": "`clock_in` – arrival, `clock_out` – departure, `break_start` – start of a break, `break_end` – end of the break.",
      "x-description-cs": "`clock_in` – příchod, `clock_out` – odchod, `break_start` – začátek přestávky, `break_end` – konec přestávky.",
      "x-extensible-enum": [
       "clock_in",
       "clock_out",
       "break_start",
       "break_end"
      ]
     },
     "occurred_at": {
      "description": "The time written to attendance.",
      "x-description-cs": "Čas zapsaný do docházky.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "received_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "offline": {
      "type": "boolean",
      "description": "Recorded offline, with the time from the device.",
      "x-description-cs": "Pořízeno offline, s časem ze zařízení."
     },
     "state": {
      "description": "The employee's state after the punch.",
      "x-description-cs": "Stav zaměstnance po píchnutí.",
      "$ref": "#/components/schemas/AttendanceState"
     },
     "shift": {
      "$ref": "#/components/schemas/AttendanceShift"
     }
    }
   },
   "AttendancePunchBatchItem": {
    "type": "object",
    "required": [
     "id",
     "status",
     "retryable",
     "punch",
     "problem",
     "employee"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "status": {
      "type": "string",
      "description": "`created` – recorded now; `duplicate` – this `id` was recorded before (`punch` is that first result; what you\nsent again is not compared); `rejected` – not recorded, see `problem` and `retryable`.\n",
      "x-description-cs": "`created` – zapsáno teď; `duplicate` – toto `id` už bylo zapsáno dřív (`punch` je ten první výsledek; znovu\nposlaný obsah se neporovnává); `rejected` – nezapsáno, viz `problem` a `retryable`.\n",
      "x-extensible-enum": [
       "created",
       "duplicate",
       "rejected"
      ]
     },
     "retryable": {
      "type": "boolean",
      "description": "The item was not decided yet (for example a locked PIN); send it again later with the same `id`.",
      "x-description-cs": "Položka ještě rozhodnutá není (třeba zamčený PIN); pošlete ji později znovu se stejným `id`."
     },
     "punch": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/AttendancePunch"
       },
       {
        "type": "null"
       }
      ]
     },
     "problem": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Problem"
       },
       {
        "type": "null"
       }
      ]
     },
     "employee": {
      "description": "For a rejected item, the employee the credential belonged to when the server recognized them (a rule refused the punch, not the PIN) – so the manager knows whose record to add by hand. `null` otherwise.",
      "x-description-cs": "U odmítnuté položky zaměstnanec, kterému přihlašovací údaj patřil, když ho server poznal (odmítlo pravidlo, ne PIN) – vedoucí pak ví, komu záznam ručně doplnit. Jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/EmployeeRef"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "AttendancePunchBatchResult": {
    "type": "object",
    "required": [
     "results"
    ],
    "properties": {
     "results": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/AttendancePunchBatchItem"
      }
     }
    }
   },
   "AbsenceType": {
    "type": "string",
    "description": "`holiday` – holiday, `unpaid` – unpaid leave, `sick` – sickness.",
    "x-description-cs": "`holiday` – dovolená, `unpaid` – neplacené volno, `sick` – nemoc.",
    "x-extensible-enum": [
     "holiday",
     "unpaid",
     "sick"
    ]
   },
   "AbsenceRequestRules": {
    "type": "object",
    "description": "The restaurant's rules for requests for time off at the terminal (set in the administration).",
    "x-description-cs": "Pravidla provozovny pro žádosti o volno na terminálu (nastavují se v administraci).",
    "required": [
     "enabled",
     "types",
     "notice_days",
     "max_days",
     "horizon_days"
    ],
    "properties": {
     "enabled": {
      "type": "boolean",
      "description": "Employees may request time off at the terminal.",
      "x-description-cs": "Zaměstnanci smí na terminálu žádat o volno."
     },
     "types": {
      "type": "array",
      "description": "Which kinds may be requested.",
      "x-description-cs": "O jaké volno se smí žádat.",
      "items": {
       "$ref": "#/components/schemas/AbsenceType"
      }
     },
     "notice_days": {
      "type": "integer",
      "description": "A holiday or unpaid leave at least this many days ahead; a sickness from today.",
      "x-description-cs": "Dovolená a neplacené volno nejméně tolik dní předem; nemoc od dneška.",
      "examples": [
       14
      ]
     },
     "max_days": {
      "type": "integer",
      "description": "At most this many days in one request.",
      "x-description-cs": "Nejvýš tolik dní v jedné žádosti.",
      "examples": [
       14
      ]
     },
     "horizon_days": {
      "type": "integer",
      "description": "The last day at most this many days from today.",
      "x-description-cs": "Poslední den nejvýš tolik dní od dneška.",
      "examples": [
       180
      ]
     }
    }
   },
   "AttendanceScheduleItem": {
    "type": "object",
    "required": [
     "type",
     "starts_at",
     "ends_at",
     "section"
    ],
    "properties": {
     "type": {
      "type": "string",
      "description": "`work` – a work shift; `holiday`, `unpaid`, `sick` – time off as in `AbsenceType`.",
      "x-description-cs": "`work` – pracovní směna; `holiday`, `unpaid`, `sick` – volno jako u `AbsenceType`.",
      "x-extensible-enum": [
       "work",
       "holiday",
       "unpaid",
       "sick"
      ]
     },
     "starts_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "ends_at": {
      "description": "The end; time off spanning whole days ends at midnight after its last day.",
      "x-description-cs": "Konec; volno přes celé dny končí o půlnoci po svém posledním dni.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "section": {
      "description": "The section of a work shift; `null` without a section and for time off.",
      "x-description-cs": "Sekce pracovní směny; `null` bez sekce a u volna.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/AttendanceSectionRef"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "AttendanceSectionRef": {
    "type": "object",
    "required": [
     "id",
     "name"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "Kuchyň"
      ]
     }
    }
   },
   "AttendanceSchedule": {
    "type": "object",
    "required": [
     "employee",
     "from",
     "to",
     "items"
    ],
    "properties": {
     "employee": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "from": {
      "description": "The first day (today).",
      "x-description-cs": "První den (dnešek).",
      "$ref": "#/components/schemas/LocalDate"
     },
     "to": {
      "description": "The last day included.",
      "x-description-cs": "Poslední zahrnutý den.",
      "$ref": "#/components/schemas/LocalDate"
     },
     "items": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/AttendanceScheduleItem"
      }
     }
    }
   },
   "AbsenceRequestCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "type",
     "date_from",
     "date_to"
    ],
    "properties": {
     "type": {
      "$ref": "#/components/schemas/AbsenceType"
     },
     "date_from": {
      "description": "The first day off.",
      "x-description-cs": "První den volna.",
      "$ref": "#/components/schemas/LocalDate"
     },
     "date_to": {
      "description": "The last day off (included); the same as `date_from` for one day.",
      "x-description-cs": "Poslední den volna (včetně); u jednoho dne stejný jako `date_from`.",
      "$ref": "#/components/schemas/LocalDate"
     },
     "note": {
      "description": "A note for the manager, at most 300 characters.",
      "x-description-cs": "Poznámka pro vedoucího, nejvýš 300 znaků.",
      "type": [
       "string",
       "null"
      ],
      "maxLength": 300
     }
    }
   },
   "AbsenceRequest": {
    "type": "object",
    "required": [
     "id",
     "type",
     "date_from",
     "date_to",
     "days",
     "note",
     "status",
     "decided_automatically",
     "created_at",
     "decided_at",
     "decision_note"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "type": {
      "$ref": "#/components/schemas/AbsenceType"
     },
     "date_from": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "date_to": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "days": {
      "type": "integer",
      "description": "Calendar days of the request, both ends included.",
      "x-description-cs": "Kalendářní dny žádosti včetně obou krajních.",
      "examples": [
       5
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "status": {
      "type": "string",
      "description": "`pending` – waits for a manager, `approved` – in the shift planner, `rejected` – refused (`decision_note` says why), `cancelled` – withdrawn by the employee.",
      "x-description-cs": "`pending` – čeká na vedoucího, `approved` – je v rozpisu, `rejected` – zamítnutá (proč, říká `decision_note`), `cancelled` – zaměstnanec ji vzal zpět.",
      "x-extensible-enum": [
       "pending",
       "approved",
       "rejected",
       "cancelled"
      ]
     },
     "decided_automatically": {
      "type": "boolean",
      "description": "Approved by the restaurant's rules without a manager.",
      "x-description-cs": "Schválená podle pravidel provozovny bez vedoucího."
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "decided_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "decision_note": {
      "description": "The manager's note to the decision, for example why the request was refused.",
      "x-description-cs": "Poznámka vedoucího k rozhodnutí, třeba proč žádost zamítl.",
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "AbsenceRequestList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/AbsenceRequest"
      }
     }
    }
   },
   "KitchenTicket": {
    "type": "object",
    "description": "One order as the kitchen sees it, from any source – the registers, the e-shop, delivery platforms, the kitchen\ndisplay and applications – with its items. The money of the order is in `total`, `delivery_price` and\n`payment_method`; the prices of the items are at the items and the receipt to print for a delivery is\n`receipt`. The order-number screen (`queue:read`) never gets tickets – only `KitchenQueue`.\n",
    "x-description-cs": "Jedna objednávka tak, jak ji vidí kuchyně, z jakéhokoli zdroje – z pokladen, e-shopu, rozvozových platforem,\nkuchyňského displeje i aplikací – s jejími položkami. Peníze objednávky jsou v `total`, `delivery_price`\na `payment_method`; ceny položek jsou u položek a účtenka k vytištění pro rozvoz je `receipt`. Pořadník\n(`queue:read`) bony nedostává nikdy – jen `KitchenQueue`.\n",
    "required": [
     "id",
     "order_id",
     "number",
     "status",
     "area",
     "source",
     "platform",
     "name",
     "fulfillment",
     "express",
     "customer",
     "delivery_address",
     "delivery_zone",
     "note",
     "payment_method",
     "total",
     "delivery_price",
     "amount_due",
     "paid_by",
     "created_at",
     "scheduled_for",
     "printed",
     "courier",
     "not_delivered",
     "items",
     "receipt"
    ],
    "properties": {
     "id": {
      "description": "ID of the kitchen ticket – `ticket_id` in the paths.",
      "x-description-cs": "ID kuchyňského bonu – `ticket_id` v adresách.",
      "$ref": "#/components/schemas/Id"
     },
     "order_id": {
      "description": "ID of the order in Profirest (the receipt in the administration), not `Order.id` of applications.",
      "x-description-cs": "ID objednávky v Profirestu (doklad v administraci), ne `Order.id` aplikací.",
      "$ref": "#/components/schemas/Id"
     },
     "number": {
      "description": "Short number for the kitchen and the customer, at least three digits (`042`, `1027`); it starts again from 1 after every close of the whole kitchen shift (a courier's close does not restart it). `null` when it has none.",
      "x-description-cs": "Krátké číslo pro kuchyň a zákazníka, nejméně tři číslice (`042`, `1027`); po každé uzávěrce celé směny kuchyně začíná znovu od 1 (uzávěrka kurýra ho nenuluje). `null`, když žádné nemá.",
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "042"
      ]
     },
     "status": {
      "type": "string",
      "description": "`received` – waiting in the queue, `preparing` – the kitchen started, `ready` – done, `out_for_delivery` –\ndone and on a courier's route, `delivered` – handed out or delivered, `not_delivered` – the courier could\nnot hand it over (`not_delivered` says why; the restaurant writes it off, sends it out again or marks it\ndelivered), `cancelled`. `preparing` is set by the kitchen (`setKitchenTicketStatus`); work of production\nstations alone leaves the ticket `received`, while the order of an application already counts as\n`preparing` (`Order.status`).\n",
      "x-description-cs": "`received` – čeká ve frontě, `preparing` – kuchyně začala, `ready` – hotovo, `out_for_delivery` – hotovo\na na trase kurýra, `delivered` – vydáno nebo doručeno, `not_delivered` – kurýr ji nemohl předat (proč, říká\n`not_delivered`; provozovna ji odepíše, pošle znovu, nebo označí jako doručenou), `cancelled` – zrušeno.\n`preparing` nastavuje kuchyně (`setKitchenTicketStatus`); samotná práce výrobních stanovišť nechá bon\n`received`, kdežto objednávka aplikace se už počítá jako `preparing` (`Order.status`).\n",
      "x-extensible-enum": [
       "received",
       "preparing",
       "ready",
       "out_for_delivery",
       "delivered",
       "not_delivered",
       "cancelled"
      ]
     },
     "area": {
      "type": "string",
      "description": "`bar` for every order from a register (`source` `pos`) – open-table tickets as well as receipts sent to the\nkitchen; `kitchen` for all others. The bar handout (`listKitchenTickets?area=bar`) lists only the open-table\ntickets.\n",
      "x-description-cs": "`bar` u každé objednávky z pokladny (`source` `pos`) – bonů otevřených stolů i účtenek poslaných do kuchyně;\n`kitchen` u všech ostatních. Výdej baru (`listKitchenTickets?area=bar`) ukazuje jen bony otevřených stolů.\n",
      "x-extensible-enum": [
       "kitchen",
       "bar"
      ]
     },
     "source": {
      "type": "string",
      "description": "Where the order came from – `pos` (register), `kitchen` (kitchen display or staff application), `web` (e-shop, partner applications, delivery platforms).",
      "x-description-cs": "Odkud objednávka přišla – `pos` (pokladna), `kitchen` (kuchyňský displej nebo aplikace personálu), `web` (e-shop, partnerské aplikace, rozvozové platformy).",
      "x-extensible-enum": [
       "pos",
       "kitchen",
       "web"
      ]
     },
     "platform": {
      "type": [
       "string",
       "null"
      ],
      "description": "The delivery platform the order came from, recognised by the order name as on the kitchen display and the\norder-number screen (`Wolt #…`); `null` for other orders. Platform orders have `source` `web`.\n",
      "x-description-cs": "Rozvozová platforma, ze které objednávka přišla, poznaná podle názvu objednávky jako na kuchyňském displeji\na pořadníku (`Wolt #…`); u ostatních objednávek `null`. Objednávky platforem mají `source` `web`.\n",
      "x-extensible-enum": [
       "wolt",
       "bolt",
       "foodora",
       "choice"
      ]
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "description": "Name on the order – a table, a customer or a delivery platform with its order number.",
      "x-description-cs": "Jméno u objednávky – stůl, zákazník nebo rozvozová platforma s číslem objednávky."
     },
     "fulfillment": {
      "type": "string",
      "description": "`delivery` – delivered to `delivery_address`; `takeaway` – a takeaway order or a pick-up (orders placed\nthrough this API are always `delivery` or `takeaway`); `dine_in` – everything else: eaten at the restaurant,\nbut also pick-ups taken on the phone at the kitchen display, which are stored without the takeaway mark.\n",
      "x-description-cs": "`delivery` – rozvoz na `delivery_address`; `takeaway` – s sebou nebo osobní odběr (objednávky vytvořené přes\ntoto API jsou vždy `delivery` nebo `takeaway`); `dine_in` – vše ostatní: jídlo v provozovně, ale také osobní\nodběry přijaté po telefonu na kuchyňském displeji, které se ukládají bez označení „s sebou“.\n",
      "x-extensible-enum": [
       "dine_in",
       "takeaway",
       "delivery"
      ]
     },
     "express": {
      "type": "boolean",
      "description": "Express delivery – show a clear EXPRES mark on the display, the printed ticket and at the courier. It is\npriority without a promised time: the order of the tickets does not change, the kitchen decides when to\ntake it. The surcharge itself is the item with `charge` `express_delivery` (part of `total`); hide it in the\nlist of dishes.\n",
      "x-description-cs": "Expresní doručení – na displeji, tištěném bonu i u kurýra ukažte výrazný štítek EXPRES. Je to přednost bez\nslíbeného času: pořadí bonů se nemění, kdy ho vzít, rozhodne kuchyně. Samotný příplatek je položka\ns `charge` `express_delivery` (je v `total`); tu v seznamu jídel skryjte.\n"
     },
     "customer": {
      "description": "The customer from the restaurant's customer database the order is linked to, as stored there (the name may\ndiffer in letter case from `name`); `null` when the order has none or both values are empty.\n`not_delivered_count` – how many times the customer did not take over an order from a courier in any\nrestaurant of the account (reports later marked delivered do not count), with the last time in\n`last_not_delivered_at` – show it to the kitchen and the courier, the restaurant may want payment in advance.\n",
      "x-description-cs": "Zákazník z databáze klientů provozovny, ke kterému objednávka patří, jak je tam uložený (jméno se od `name`\nmůže lišit velikostí písmen); `null`, když objednávka žádného nemá nebo jsou obě hodnoty prázdné.\n`not_delivered_count` – kolikrát zákazník nepřevzal objednávku od kurýra v kterékoli provozovně účtu\n(hlášení později označená jako doručená se nepočítají), poslední v `last_not_delivered_at` – ukažte to\nkuchyni i kurýrovi, provozovna může chtít platbu předem.\n",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "name",
         "phone",
         "not_delivered_count",
         "last_not_delivered_at"
        ],
        "properties": {
         "name": {
          "type": [
           "string",
           "null"
          ]
         },
         "phone": {
          "type": [
           "string",
           "null"
          ]
         },
         "not_delivered_count": {
          "type": "integer",
          "minimum": 0,
          "examples": [
           2
          ]
         },
         "last_not_delivered_at": {
          "anyOf": [
           {
            "$ref": "#/components/schemas/Timestamp"
           },
           {
            "type": "null"
           }
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "delivery_address": {
      "description": "Only for `delivery`, otherwise `null`. `street` is the street with the house number as stored, `city` may be\nempty, `location` is `null` when the address has no coordinates.\n",
      "x-description-cs": "Jen u `delivery`, jinak `null`. `street` je ulice s číslem, jak je uložená, `city` může být prázdné,\n`location` je `null`, když adresa nemá souřadnice.\n",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "street",
         "city",
         "location"
        ],
        "properties": {
         "street": {
          "type": "string"
         },
         "city": {
          "type": "string"
         },
         "location": {
          "anyOf": [
           {
            "$ref": "#/components/schemas/GeoPoint"
           },
           {
            "type": "null"
           }
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "delivery_zone": {
      "description": "The delivery zone the address of a `delivery` order lies in (`id` and `name` as in `listDeliveryZones`).\nProfirest computes it from the location of the address by the rules of the e-shop: the zone that delivered\nat the time the order is for (`scheduled_for`, otherwise `created_at`), otherwise any zone the address lies\nin. It is not stored with the order – a change of the zones in the administration shows at once. For a\nsummary by zones on the kitchen display group the tickets by `id`. `null` for other orders, an address\nwithout coordinates, an address outside all zones and in a restaurant without delivery zones – offer\ngrouping by zones only when `listDeliveryZones` returns some.\n",
      "x-description-cs": "Rozvozová zóna, do které padne adresa objednávky s `delivery` (`id` a `name` jako v `listDeliveryZones`).\nSpočítá ji Profirest z polohy adresy pravidly e-shopu: zóna, která rozvážela v čase, na který objednávka\nje (`scheduled_for`, jinak `created_at`), jinak kterákoli zóna, do které adresa padne. S objednávkou se\nneukládá – změna zón v administraci se projeví hned. Pro souhrn podle zón na kuchyňském displeji seskupte\nbony podle `id`. `null` u ostatních objednávek, u adresy bez souřadnic, mimo všechny zóny a v provozovně\nbez rozvozových zón – seskupení podle zón nabízejte, jen když `listDeliveryZones` nějaké vrací.\n",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "id",
         "name"
        ],
        "properties": {
         "id": {
          "$ref": "#/components/schemas/Id"
         },
         "name": {
          "type": "string",
          "examples": [
           "Vinohrady do 3 km"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "description": "The note of the order for the kitchen and the courier; `null` when empty. For orders placed through this API it\nis put together from the payments (for example a gift voucher with its code masked, `ABC-***`, or what to\ncollect), the address note, the customer's note and the name of the application, joined by ` | `; items\nadded later end it with `[UPRAVENO: +…]`.\n",
      "x-description-cs": "Poznámka objednávky pro kuchyň a kurýra; `null`, když je prázdná. U objednávek vytvořených přes toto API je\nsložená z plateb (třeba dárkový voucher se zamaskovaným kódem `ABC-***` nebo co vybrat), poznámky k adrese,\npoznámky zákazníka a názvu aplikace, spojených ` | `; později přidané položky ji zakončí `[UPRAVENO: +…]`.\n"
     },
     "payment_method": {
      "type": "string",
      "description": "How the order is paid – `cash` (the customer pays in cash on receiving it, or paid in cash at the counter), `card_at_handover` (pays by card on receiving it, to the courier or at pick-up; nothing in cash), `card` (paid by card or online in advance; nothing to collect), `meal_voucher`, `company_account`, `invoice`.",
      "x-description-cs": "Jak se objednávka platí – `cash` (zákazník platí hotově při převzetí, nebo zaplatil hotově u pokladny), `card_at_handover` (platí kartou při převzetí, kurýrovi nebo při výdeji; nic hotově), `card` (zaplaceno kartou nebo online předem; nic se nevybírá), `meal_voucher` (stravenky), `company_account` (účet podniku), `invoice` (fakturou).",
      "x-extensible-enum": [
       "cash",
       "card_at_handover",
       "card",
       "meal_voucher",
       "company_account",
       "invoice"
      ]
     },
     "total": {
      "description": "The amount of the order including delivery, after gift vouchers (they are negative lines of the order) but not\nafter an online payment. It is read from the kitchen's order record, which keeps only 6 significant digits:\nfrom 10 000 CZK the minor units may be rounded (to tens of haléře, from 100 000 CZK to whole crowns). For\nexact amounts of an application's order use `Order.totals`.\n",
      "x-description-cs": "Částka objednávky včetně dopravy, po odečtení dárkových voucherů (jsou to záporné řádky objednávky), ale ne\nonline platby. Čte se ze záznamu objednávky kuchyně, který drží jen 6 platných číslic: od 10 000 Kč mohou být\nhaléře zaokrouhlené (na desetníky, od 100 000 Kč na celé koruny). Přesné částky objednávky aplikace jsou\nv `Order.totals`.\n",
      "$ref": "#/components/schemas/Money"
     },
     "delivery_price": {
      "description": "The delivery fee included in `total`, in whole crowns.",
      "x-description-cs": "Cena dopravy obsažená v `total`, v celých korunách.",
      "$ref": "#/components/schemas/Money"
     },
     "amount_due": {
      "description": "What is still to collect at the handover, in cash or by card: for `cash` and `card_at_handover` the `total`\nless a part paid online through this API, `0` once the payment was recorded (`handoverTicketPayment`). `0`\nfor orders paid in advance (by card or online, at the register), meal vouchers, the company account, an\ninvoice and cancelled orders. Offer a card only while it is not `0` – the order would be paid twice.\n",
      "x-description-cs": "Co zbývá vybrat při převzetí, hotově nebo kartou: u `cash` a `card_at_handover` `total` bez části zaplacené\nonline přes toto API, `0` po zapsání platby (`handoverTicketPayment`). `0` u objednávek zaplacených předem\n(kartou nebo online, u pokladny), stravenek, účtu podniku, faktury a u zrušených objednávek. Kartu nabízejte,\njen dokud není `0` – objednávka by se zaplatila dvakrát.\n",
      "$ref": "#/components/schemas/Money"
     },
     "paid_by": {
      "description": "How and when the courier took the payment at the door (`handoverTicketPayment`); `null` before.",
      "x-description-cs": "Čím a kdy kurýr u dveří vybral platbu (`handoverTicketPayment`); předtím `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/PaidBy"
       },
       {
        "type": "null"
       }
      ]
     },
     "created_at": {
      "description": "When the order came to the kitchen.",
      "x-description-cs": "Kdy objednávka přišla do kuchyně.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "scheduled_for": {
      "description": "The time the customer ordered it for; `null` when as soon as possible.",
      "x-description-cs": "Čas, na který zákazník objednal; `null`, když co nejdřív.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "printed": {
      "type": "boolean",
      "description": "A display confirmed printing the ticket (`markKitchenTicketPrinted`); `false` again after items were added.",
      "x-description-cs": "Některý displej potvrdil vytištění bonu (`markKitchenTicketPrinted`); po přidání položek znovu `false`."
     },
     "courier": {
      "description": "The courier the order was sent out with (`createDeliveryRoute`); `null` before, and again when the order goes back to `received` or `preparing`.",
      "x-description-cs": "Kurýr, se kterým objednávka odjela (`createDeliveryRoute`); předtím `null` a znovu, když se objednávka vrátí do `received` nebo `preparing`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/EmployeeRef"
       },
       {
        "type": "null"
       }
      ]
     },
     "not_delivered": {
      "description": "The courier's report while the ticket is `not_delivered` (`markTicketNotDelivered`); `null` otherwise.",
      "x-description-cs": "Hlášení kurýra, dokud je bon `not_delivered` (`markTicketNotDelivered`); jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/NotDeliveredInfo"
       },
       {
        "type": "null"
       }
      ]
     },
     "items": {
      "type": "array",
      "description": "The items in the order they were added; add-ons and other parts of an item are its `modifiers`.",
      "x-description-cs": "Položky v pořadí přidání; přísady a další části položky jsou její `modifiers`.",
      "items": {
       "$ref": "#/components/schemas/KitchenItem"
      }
     },
     "receipt": {
      "description": "The receipt of the order as the copy of the receipt in the administration – to print for the courier or the\ncustomer; `null` when it cannot be put together.\n",
      "x-description-cs": "Účtenka objednávky jako kopie účtenky v administraci – k vytištění pro kurýra nebo zákazníka; `null`, když ji\nnejde sestavit.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/KitchenTicketReceipt"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "KitchenTicketReceipt": {
    "type": "object",
    "description": "The amounts of the receipt of a kitchen ticket, computed by the server the same way as the copy of the receipt\nin the administration and the web kitchen display. `total` = `items` + the sum of `discounts` + `delivery` +\n`rounding` + `adjustment`; `to_pay` is `total` after gift vouchers (what the customer pays otherwise) and equals\n`KitchenTicket.total`. On a cancellation document the amounts have the opposite sign.\n",
    "x-description-cs": "Částky účtenky kuchyňského bonu, které spočítá server stejně jako kopii účtenky v administraci a webový\nkuchyňský displej. `total` = `items` + součet `discounts` + `delivery` + `rounding` + `adjustment`; `to_pay` je\n`total` po dárkových voucherech (co zákazník platí jinak) a rovná se `KitchenTicket.total`. Na storno dokladu\nmají částky opačné znaménko.\n",
    "required": [
     "items",
     "discounts",
     "delivery",
     "rounding",
     "adjustment",
     "total",
     "to_pay",
     "vat",
     "document"
    ],
    "properties": {
     "items": {
      "description": "The items including packaging, after the discounts of items (the prices of the lines), without gift voucher payments.",
      "x-description-cs": "Položky včetně obalů, po slevách na položky (ceny řádků), bez úhrad dárkovými vouchery.",
      "$ref": "#/components/schemas/Money"
     },
     "discounts": {
      "type": "array",
      "description": "Discounts of the whole receipt in the order of the receipt.",
      "x-description-cs": "Slevy na celý účet v pořadí účtenky.",
      "items": {
       "type": "object",
       "required": [
        "name",
        "amount"
       ],
       "properties": {
        "name": {
         "type": "string",
         "description": "The name of the promotion, or „Sleva na účet“ / „Sleva na účet 10 %“ for a discount without a promotion.",
         "x-description-cs": "Název akce, nebo „Sleva na účet“ / „Sleva na účet 10 %“ u slevy bez akce."
        },
        "amount": {
         "$ref": "#/components/schemas/Money",
         "description": "Negative amount.",
         "x-description-cs": "Záporná částka."
        }
       }
      }
     },
     "delivery": {
      "description": "The delivery fee.",
      "x-description-cs": "Cena dopravy.",
      "$ref": "#/components/schemas/Money"
     },
     "rounding": {
      "description": "Rounding of the total, less than one crown either way.",
      "x-description-cs": "Zaokrouhlení celkové částky, méně než jedna koruna oběma směry.",
      "$ref": "#/components/schemas/Money"
     },
     "adjustment": {
      "description": "A change of the price made after the order (the stored total differs from the lines by more than the rounding); usually zero.",
      "x-description-cs": "Úprava ceny po objednání (uložený součet se od řádků liší víc než o zaokrouhlení); obvykle nula.",
      "$ref": "#/components/schemas/Money"
     },
     "total": {
      "description": "The amount of the whole receipt.",
      "x-description-cs": "Úplata za celý účet.",
      "$ref": "#/components/schemas/Money"
     },
     "to_pay": {
      "description": "What the customer pays other than by gift voucher – the same as `KitchenTicket.total`.",
      "x-description-cs": "Co zákazník platí jinak než dárkovým voucherem – totéž co `KitchenTicket.total`.",
      "$ref": "#/components/schemas/Money"
     },
     "vat": {
      "type": "array",
      "description": "The VAT by rates as on the receipt – discounts of the whole receipt, delivery and adjustments split into the\nrates of the items; rates with a zero total are left out. Print it only for a VAT payer\n(`DeviceSettings.company.vat_payer`).\n",
      "x-description-cs": "DPH po sazbách jako na účtence – slevy na účet, doprava a úpravy rozdělené do sazeb položek; sazby s nulovým\nsoučtem chybí. Tiskněte ho jen u plátce DPH (`DeviceSettings.company.vat_payer`).\n",
      "items": {
       "$ref": "#/components/schemas/VatBreakdown"
      }
     },
     "document": {
      "type": "object",
      "required": [
       "title",
       "number",
       "tax_document"
      ],
      "properties": {
       "title": {
        "type": "string",
        "description": "„Účtenka“, or „Storno účtenky“ for a cancellation document.",
        "x-description-cs": "„Účtenka“, u storno dokladu „Storno účtenky“."
       },
       "number": {
        "type": "string",
        "description": "The number of the document as on the copy of the receipt in the administration.",
        "x-description-cs": "Číslo dokladu jako na kopii účtenky v administraci."
       },
       "tax_document": {
        "type": "string",
        "description": "„Zjednodušený daňový doklad“ for a VAT payer with a VAT number up to the limit of a simplified tax document;\nan empty string otherwise (not a VAT payer, a cancellation, over the limit).\n",
        "x-description-cs": "„Zjednodušený daňový doklad“ u plátce DPH s DIČ do limitu zjednodušeného daňového dokladu; jinak prázdný\nřetězec (neplátce, storno, nad limit).\n"
       }
      }
     }
    }
   },
   "KitchenItem": {
    "type": "object",
    "required": [
     "id",
     "product_id",
     "name",
     "kitchen_name",
     "note",
     "quantity",
     "kind",
     "charge",
     "course",
     "category",
     "from_daily_menu",
     "station_id",
     "status",
     "handed_out",
     "part",
     "size",
     "unit_price",
     "packaging_price",
     "discount",
     "gift",
     "vat_rate",
     "removed_ingredients",
     "modifiers"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "product_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "name": {
      "type": "string"
     },
     "kitchen_name": {
      "description": "The kitchen's own name of the product, when it has one.",
      "x-description-cs": "Kuchyňský název produktu, když ho má.",
      "type": [
       "string",
       "null"
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "quantity": {
      "type": "number",
      "examples": [
       2
      ]
     },
     "kind": {
      "type": "string",
      "description": "`full` – a whole portion; `half` – a half portion (from a register, the kitchen display or\n`QuoteItemInput.variant` `half`); `split_half` / `split_quarter` – a half or a quarter of a\nsplit pizza (the first part is the item, the other parts are its `modifiers`); `virtual` – a line the kitchen\ndoes not make, for example a gift voucher payment (negative, with the masked code in `note`), a voucher sale,\nan open item or the cash rounding. The surcharge to the minimum order and express delivery are `full` with\n`product_id: null` – see `charge`.\n",
      "x-description-cs": "`full` – celá porce; `half` – poloviční porce (z pokladny, kuchyňského displeje nebo `QuoteItemInput.variant`\n`half`); `split_half` / `split_quarter` – polovina nebo čtvrtina dělené\npizzy (první část je položka, ostatní části jsou její `modifiers`); `virtual` – řádek, který kuchyně nedělá,\ntřeba platba dárkovým voucherem (záporná, se zamaskovaným kódem v `note`), prodej voucheru, položka s vlastní\ncenou nebo zaokrouhlení hotovosti. Doplatek do minimální objednávky a expresní doručení jsou `full`\ns `product_id: null` – viz `charge`.\n",
      "x-extensible-enum": [
       "full",
       "half",
       "split_half",
       "split_quarter",
       "virtual"
      ]
     },
     "charge": {
      "type": [
       "string",
       "null"
      ],
      "description": "A charge written as a line of the order, not food: `minimum_order_surcharge` – the surcharge to the minimum\norder of the zone; `express_delivery` – express delivery (the ticket has `express`). Hide such lines in the\nlist of dishes and on the kitchen ticket; they are part of the order total. `null` for everything else.\nWhen the dishes have several VAT rates the charge has a line per rate – the next one is in `modifiers`.\n",
      "x-description-cs": "Poplatek zapsaný jako řádek objednávky, ne jídlo: `minimum_order_surcharge` – doplatek do minimální objednávky\nzóny; `express_delivery` – expresní doručení (bon má `express`). V seznamu jídel a na kuchyňském bonu takové\nřádky skryjte; jsou součástí ceny objednávky. U všeho ostatního `null`. Když mají jídla víc sazeb DPH, má\npoplatek řádek za každou sazbu – další je v `modifiers`.\n",
      "x-extensible-enum": [
       "minimum_order_surcharge",
       "express_delivery"
      ]
     },
     "course": {
      "type": "integer",
      "description": "Course number, from 0 for the first course; serve courses in order.",
      "x-description-cs": "Číslo chodu, od 0 pro první chod; chody se vydávají postupně."
     },
     "category": {
      "type": "object",
      "description": "The catalog category of the product, as the production stations and the pass group items. Add-ons belong to\nthe category of their item; a line without a category has `id` `0` and the name `Ostatní`. Use `id` as\n`category_id` in `completeStationSegment` and `handOverTicketSegment`.\n",
      "x-description-cs": "Kategorie produktu v sortimentu, podle které položky seskupují výrobní stanoviště i výdej. Přísady patří do\nkategorie své položky; řádek bez kategorie má `id` `0` a název `Ostatní`. `id` použijte jako `category_id`\nv `completeStationSegment` a `handOverTicketSegment`.\n",
      "required": [
       "id",
       "name"
      ],
      "properties": {
       "id": {
        "$ref": "#/components/schemas/Id"
       },
       "name": {
        "type": "string"
       }
      }
     },
     "from_daily_menu": {
      "type": "boolean",
      "description": "Sold through the daily menu; the kitchen display marks it so the cook knows.",
      "x-description-cs": "Prodáno přes denní menu; kuchyňský displej to označí, ať to kuchař pozná."
     },
     "station_id": {
      "description": "The production station that makes it, when the restaurant splits the kitchen. It can point to a station that\nis no longer active, which `listStationTickets` answers with `404`.\n",
      "x-description-cs": "Výrobní stanoviště, které položku dělá, když má provozovna rozdělenou kuchyni. Může ukazovat na stanoviště,\nkteré už není aktivní, a to `listStationTickets` odpoví `404`.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "status": {
      "type": "string",
      "description": "`pending` – not done yet; `done` – a production station marked it done (`completeStationSegment`; taking the action back makes it `pending` again).",
      "x-description-cs": "`pending` – ještě není hotová; `done` – výrobní stanoviště ji odbavilo (`completeStationSegment`; vzetím akce zpět je znovu `pending`).",
      "x-extensible-enum": [
       "pending",
       "done"
      ]
     },
     "handed_out": {
      "type": "boolean",
      "description": "The pass already took it to the customer (`POST …/handover`).",
      "x-description-cs": "Výdej už ji odnesl zákazníkovi (`POST …/handover`)."
     },
     "part": {
      "type": [
       "integer",
       "null"
      ],
      "description": "For a split pizza (`kind` `split_half` / `split_quarter`) `1` – the item is the first part; the other parts\nand the add-ons of each part are in `modifiers` with their `part`. `null` for other items.\n",
      "x-description-cs": "U dělené pizzy (`kind` `split_half` / `split_quarter`) `1` – položka je první díl; další díly i přísady\nkaždého dílu jsou v `modifiers` se svým `part`. U ostatních položek `null`.\n"
     },
     "size": {
      "description": "The size of the product as a label in front of the name, the same as on the web kitchen display: `name` –\nthe size only („Ø32cm“), `dish_name` – the shown name (`kitchen_name`, otherwise `name`) without the size.\n`null` for a product without sizes.\n",
      "x-description-cs": "Velikost produktu jako štítek před názvem, stejně jako na webovém kuchyňském displeji: `name` – jen\nvelikost („Ø32cm“), `dish_name` – zobrazený název (`kitchen_name`, jinak `name`) bez velikosti. `null`\nu produktu bez velikostí.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/KitchenItemSize"
       },
       {
        "type": "null"
       }
      ]
     },
     "unit_price": {
      "description": "The price per piece after `discount`, without packaging – the line of the receipt is `quantity` ×\n(`unit_price` + `packaging_price`). `0` for a gift.\n",
      "x-description-cs": "Cena za kus po slevě `discount`, bez obalu – řádek účtenky je `quantity` × (`unit_price` +\n`packaging_price`). U dárku `0`.\n",
      "$ref": "#/components/schemas/Money"
     },
     "packaging_price": {
      "description": "Packaging per piece.",
      "x-description-cs": "Obal za kus.",
      "$ref": "#/components/schemas/Money"
     },
     "discount": {
      "description": "The discount per piece from a promotion or the register, already deducted from `unit_price`; negative,\n`0` without a discount. The price before the discount is `unit_price` − `discount`.\n",
      "x-description-cs": "Sleva na kus z akce nebo z pokladny, už odečtená v `unit_price`; záporně, bez slevy `0`. Cena před slevou je\n`unit_price` − `discount`.\n",
      "$ref": "#/components/schemas/Money"
     },
     "gift": {
      "type": "boolean",
      "description": "A gift of a promotion (price `0` and the full price in `discount`). A free piece of „2+1“ or a manual 100%\ndiscount is not a gift – it only has a discount.\n",
      "x-description-cs": "Dárek z akce (cena `0` a plná cena v `discount`). Kus zdarma z „2+1“ ani ruční 100% sleva dárek nejsou – mají\njen slevu.\n"
     },
     "vat_rate": {
      "description": "The VAT rate of the line.",
      "x-description-cs": "Sazba DPH řádku.",
      "$ref": "#/components/schemas/VatRate"
     },
     "removed_ingredients": {
      "type": "array",
      "description": "The names of the ingredients the guest removed from the dish (for a split pizza from the first part – the other\nparts have theirs in `modifiers`), in the order of the composition; empty when nothing was removed. Show them\nprominently at the dish, the same as the web kitchen display („WITHOUT: MUSHROOMS, ONION“). They are not part\nof `note`.\n",
      "x-description-cs": "Názvy surovin, které host z jídla odebral (u dělené pizzy z prvního dílu – ostatní díly je mají\nv `modifiers`), v pořadí složení; prázdné, když nic neodebral. Ukažte je výrazně u jídla stejně jako webový\nkuchyňský displej („BEZ: ŽAMPIONY, CIBULE“). V `note` nejsou.\n",
      "items": {
       "type": "string",
       "examples": [
        "žampiony"
       ]
      }
     },
     "modifiers": {
      "type": "array",
      "description": "Add-ons, options and other parts that belong to this item.",
      "x-description-cs": "Přísady, volby a další části, které k položce patří.",
      "items": {
       "$ref": "#/components/schemas/KitchenModifier"
      }
     }
    }
   },
   "KitchenItemSize": {
    "type": "object",
    "required": [
     "name",
     "dish_name"
    ],
    "properties": {
     "name": {
      "type": "string",
      "description": "The size only, as the size set names it („Ø42cm“, „300 g“) – as `ProductSize.name`.",
      "x-description-cs": "Jen velikost, jak ji pojmenuje sada („Ø42cm“, „300 g“) – jako `ProductSize.name`."
     },
     "dish_name": {
      "type": "string",
      "description": "The shown name without the size („Margherita“).",
      "x-description-cs": "Zobrazený název bez velikosti („Margherita“)."
     }
    }
   },
   "KitchenModifier": {
    "type": "object",
    "description": "A part of a kitchen item – an add-on, or another part of a split pizza: the lines of the order that belong to the\nsame item. The fields mean the same as in `KitchenItem`.\n",
    "x-description-cs": "Část kuchyňské položky – přísada nebo další část dělené pizzy: řádky objednávky, které patří ke stejné položce.\nPole znamenají totéž co v `KitchenItem`.\n",
    "required": [
     "id",
     "product_id",
     "name",
     "kitchen_name",
     "note",
     "quantity",
     "kind",
     "charge",
     "status",
     "handed_out",
     "part",
     "size",
     "unit_price",
     "packaging_price",
     "discount",
     "gift",
     "vat_rate",
     "removed_ingredients"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "charge": {
      "type": [
       "string",
       "null"
      ],
      "description": "As `KitchenItem.charge` – the next VAT rate of a charge; `null` for add-ons and parts of dishes.",
      "x-description-cs": "Jako `KitchenItem.charge` – další sazba DPH poplatku; u přísad a částí jídel `null`.",
      "x-extensible-enum": [
       "minimum_order_surcharge",
       "express_delivery"
      ]
     },
     "product_id": {
      "description": "The product; `null` for a line without a product.",
      "x-description-cs": "Produkt; `null` u řádku bez produktu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "name": {
      "type": "string",
      "description": "The current name of the product (the name on the order for a line without a product).",
      "x-description-cs": "Aktuální název produktu (u řádku bez produktu název z objednávky)."
     },
     "kitchen_name": {
      "type": [
       "string",
       "null"
      ],
      "description": "The kitchen's own name of the product, when it has one.",
      "x-description-cs": "Kuchyňský název produktu, když ho má."
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "description": "The note of the line.",
      "x-description-cs": "Poznámka řádku."
     },
     "quantity": {
      "type": "number",
      "description": "Pieces; decimals for items sold by weight.",
      "x-description-cs": "Kusy; desetinná čísla u položek na váhu."
     },
     "kind": {
      "type": "string",
      "description": "As `KitchenItem.kind`; for a part of a split pizza `split_half` or `split_quarter`.",
      "x-description-cs": "Jako `KitchenItem.kind`; u části dělené pizzy `split_half` nebo `split_quarter`.",
      "x-extensible-enum": [
       "full",
       "half",
       "split_half",
       "split_quarter",
       "virtual"
      ]
     },
     "status": {
      "type": "string",
      "description": "As `KitchenItem.status`.",
      "x-description-cs": "Jako `KitchenItem.status`.",
      "x-extensible-enum": [
       "pending",
       "done"
      ]
     },
     "handed_out": {
      "type": "boolean",
      "description": "As `KitchenItem.handed_out`.",
      "x-description-cs": "Jako `KitchenItem.handed_out`."
     },
     "part": {
      "type": [
       "integer",
       "null"
      ],
      "description": "The part of a split pizza the line belongs to, from 1 (the item itself is part 1): a part starts with\na line `split_half` / `split_quarter` and its add-ons follow it. `null` when the item is not a split pizza.\n",
      "x-description-cs": "Díl dělené pizzy, ke kterému řádek patří, od 1 (samotná položka je díl 1): díl začíná řádkem `split_half` /\n`split_quarter` a jeho přísady jdou za ním. `null`, když položka není dělená pizza.\n"
     },
     "size": {
      "description": "As `KitchenItem.size`.",
      "x-description-cs": "Jako `KitchenItem.size`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/KitchenItemSize"
       },
       {
        "type": "null"
       }
      ]
     },
     "unit_price": {
      "description": "As `KitchenItem.unit_price` – the price of the add-on or the part per piece after `discount`.",
      "x-description-cs": "Jako `KitchenItem.unit_price` – cena přílohy nebo dílu za kus po slevě `discount`.",
      "$ref": "#/components/schemas/Money"
     },
     "packaging_price": {
      "description": "As `KitchenItem.packaging_price`.",
      "x-description-cs": "Jako `KitchenItem.packaging_price`.",
      "$ref": "#/components/schemas/Money"
     },
     "discount": {
      "description": "As `KitchenItem.discount`.",
      "x-description-cs": "Jako `KitchenItem.discount`.",
      "$ref": "#/components/schemas/Money"
     },
     "gift": {
      "type": "boolean",
      "description": "As `KitchenItem.gift`.",
      "x-description-cs": "Jako `KitchenItem.gift`."
     },
     "vat_rate": {
      "description": "As `KitchenItem.vat_rate`.",
      "x-description-cs": "Jako `KitchenItem.vat_rate`.",
      "$ref": "#/components/schemas/VatRate"
     },
     "removed_ingredients": {
      "type": "array",
      "description": "As `KitchenItem.removed_ingredients` – for another part of a split pizza (`kind` `split_half` /\n`split_quarter`) the ingredients removed from that part; empty for add-ons.\n",
      "x-description-cs": "Jako `KitchenItem.removed_ingredients` – u další části dělené pizzy (`kind` `split_half` / `split_quarter`)\nsuroviny odebrané z toho dílu; u přísad prázdné.\n",
      "items": {
       "type": "string",
       "examples": [
        "cibule"
       ]
      }
     }
    }
   },
   "StationTicketList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/StationTicket"
      }
     }
    }
   },
   "StationTicket": {
    "type": "object",
    "required": [
     "ticket",
     "working",
     "other_stations",
     "courses"
    ],
    "properties": {
     "ticket": {
      "$ref": "#/components/schemas/KitchenTicket"
     },
     "working": {
      "type": "boolean",
      "description": "This station is working on the order.",
      "x-description-cs": "Toto stanoviště na objednávce pracuje."
     },
     "other_stations": {
      "type": "array",
      "description": "Other stations working on the same order.",
      "x-description-cs": "Další stanoviště, která na stejné objednávce pracují.",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string"
        }
       }
      }
     },
     "courses": {
      "type": "array",
      "description": "The items of this station by course and category, as the station screen shows them.",
      "x-description-cs": "Položky tohoto stanoviště podle chodů a kategorií, jak je ukazuje obrazovka stanoviště.",
      "items": {
       "type": "object",
       "required": [
        "course",
        "done",
        "categories"
       ],
       "properties": {
        "course": {
         "type": "integer"
        },
        "done": {
         "type": "boolean"
        },
        "categories": {
         "type": "array",
         "items": {
          "type": "object",
          "required": [
           "id",
           "name",
           "done",
           "item_ids"
          ],
          "properties": {
           "id": {
            "$ref": "#/components/schemas/Id"
           },
           "name": {
            "type": "string"
           },
           "done": {
            "type": "boolean"
           },
           "item_ids": {
            "type": "array",
            "items": {
             "$ref": "#/components/schemas/Id"
            }
           }
          }
         }
        }
       }
      }
     }
    }
   },
   "ShiftTotals": {
    "type": "object",
    "required": [
     "orders",
     "completed",
     "by_payment",
     "not_completed",
     "not_delivered",
     "cancelled"
    ],
    "properties": {
     "orders": {
      "type": "integer",
      "description": "Orders in the shift, whatever their state.",
      "x-description-cs": "Objednávky ve směně v jakémkoli stavu."
     },
     "completed": {
      "description": "Takings – done and handed-out or delivered orders, delivery included.",
      "x-description-cs": "Tržba – hotové a vydané nebo doručené objednávky včetně dopravy.",
      "$ref": "#/components/schemas/Money"
     },
     "by_payment": {
      "description": "The takings by payment.",
      "x-description-cs": "Tržba podle platby.",
      "type": "object",
      "required": [
       "cash",
       "card",
       "meal_voucher",
       "company_account",
       "invoice"
      ],
      "properties": {
       "cash": {
        "$ref": "#/components/schemas/Money"
       },
       "card": {
        "$ref": "#/components/schemas/Money"
       },
       "meal_voucher": {
        "$ref": "#/components/schemas/Money"
       },
       "company_account": {
        "$ref": "#/components/schemas/Money"
       },
       "invoice": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "not_completed": {
      "description": "Orders still waiting or being prepared – not paid yet; they stay for the next shift.",
      "x-description-cs": "Objednávky, které ještě čekají nebo se připravují – zatím nezaplacené; zůstanou do další směny.",
      "$ref": "#/components/schemas/Money"
     },
     "not_delivered": {
      "description": "Orders the customer did not take over from the courier (`not_delivered`) and the restaurant has not settled\nyet – how many and their value. They are not in the takings, no cash is expected for them and a close\nleaves them for the next shift until they are written off, sent out again or marked delivered.\n",
      "x-description-cs": "Objednávky, které zákazník od kurýra nepřevzal (`not_delivered`) a provozovna je ještě nevyřešila – počet\na hodnota. Nejsou v tržbě, hotovost se za ně nečeká a uzávěrka je nechá do další směny, dokud se neodepíšou,\nnepošlou znovu nebo neoznačí jako doručené.\n",
      "type": "object",
      "required": [
       "orders",
       "total"
      ],
      "properties": {
       "orders": {
        "type": "integer",
        "minimum": 0
       },
       "total": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "cancelled": {
      "$ref": "#/components/schemas/Money"
     }
    }
   },
   "KitchenShiftSummary": {
    "allOf": [
     {
      "$ref": "#/components/schemas/ShiftTotals"
     },
     {
      "type": "object",
      "required": [
       "courier_id",
       "couriers"
      ],
      "properties": {
       "courier_id": {
        "description": "The courier the totals are limited to; `null` for the whole shift.",
        "x-description-cs": "Kurýr, na kterého jsou součty omezené; `null` za celou směnu.",
        "anyOf": [
         {
          "$ref": "#/components/schemas/Id"
         },
         {
          "type": "null"
         }
        ]
       },
       "couriers": {
        "type": "array",
        "description": "The same totals per courier; `courier: null` for orders without a courier.",
        "x-description-cs": "Tytéž součty po kurýrech; `courier: null` u objednávek bez kurýra.",
        "items": {
         "allOf": [
          {
           "$ref": "#/components/schemas/ShiftTotals"
          },
          {
           "type": "object",
           "required": [
            "courier"
           ],
           "properties": {
            "courier": {
             "anyOf": [
              {
               "$ref": "#/components/schemas/EmployeeRef"
              },
              {
               "type": "null"
              }
             ]
            }
           }
          }
         ]
        }
       }
      }
     }
    ]
   },
   "KitchenShiftCloseRequest": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
     "courier_id": {
      "description": "Close only this courier's orders; missing or `null` closes the whole shift.",
      "x-description-cs": "Uzavřít jen objednávky tohoto kurýra; chybějící nebo `null` uzavře celou směnu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "KitchenShiftClose": {
    "type": "object",
    "required": [
     "id",
     "closed_at",
     "closed_by",
     "closed_orders",
     "numbering_reset",
     "summary"
    ],
    "properties": {
     "id": {
      "description": "The shift close in the administration.",
      "x-description-cs": "Uzávěrka v administraci.",
      "$ref": "#/components/schemas/Id"
     },
     "closed_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "closed_by": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "closed_orders": {
      "type": "integer",
      "description": "Orders that went into the close. Deleted orders are closed too but not counted, and alone they do not allow a close.",
      "x-description-cs": "Objednávky, které do uzávěrky přešly. Smazané se uzavřou taky, ale nepočítají se a samy uzávěrku nepovolí."
     },
     "numbering_reset": {
      "type": "boolean",
      "description": "The kitchen numbering starts again from 1 (whole shift only).",
      "x-description-cs": "Číslování kuchyně začíná znovu od 1 (jen u celé směny)."
     },
     "summary": {
      "description": "The totals as they were at the close.",
      "x-description-cs": "Součty tak, jak byly při uzávěrce.",
      "$ref": "#/components/schemas/KitchenShiftSummary"
     }
    }
   },
   "EventKitchenShiftData": {
    "type": "object",
    "required": [
     "shift_id",
     "courier_id",
     "closed_orders"
    ],
    "properties": {
     "shift_id": {
      "$ref": "#/components/schemas/Id"
     },
     "courier_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "closed_orders": {
      "type": "integer",
      "description": "As `KitchenShiftClose.closed_orders` (deleted orders not counted).",
      "x-description-cs": "Jako `KitchenShiftClose.closed_orders` (smazané objednávky se nepočítají)."
     }
    }
   },
   "KitchenTicketItemsAdd": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "items"
    ],
    "properties": {
     "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 50,
      "items": {
       "$ref": "#/components/schemas/QuoteItemInput"
      }
     },
     "channel": {
      "type": "string",
      "enum": [
       "kitchen",
       "pos",
       "web"
      ],
      "default": "kitchen",
      "description": "The catalog the items come from, as `channel` of `GET /catalog`: `kitchen` – the order menu of the kitchen\ndisplay (\"K\"), `pos` – the register (\"B\"), `web` – the e-shop (\"W\"). Prices are the same in every channel; the\nchannel decides what is offered and the VAT rate (`kitchen` uses the takeaway rate). Applications that are not\nof the restaurant staff must send `web`; anything else, the default included, answers `422` with `not_allowed`.\n",
      "x-description-cs": "Sortiment, ze kterého položky jsou, jako `channel` u `GET /catalog`: `kitchen` – nabídka objednávky\nkuchyňského displeje („K“), `pos` – pokladna („B“), `web` – e-shop („W“). Ceny jsou ve všech kanálech stejné;\nkanál určuje, co se nabízí, a sazbu DPH (`kitchen` počítá se sazbou „s sebou“). Aplikace, které nejsou aplikacemi\npersonálu provozovny, musí poslat `web`; cokoli jiného včetně výchozí hodnoty odpoví `422` s `not_allowed`.\n"
     }
    }
   },
   "StationSegmentComplete": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "scope"
    ],
    "properties": {
     "scope": {
      "type": "string",
      "enum": [
       "order",
       "course",
       "category"
      ],
      "description": "`order` – all open items of the order (across all courses); `course` – the open items of one course\n(`course`); `category` – the open items of one catalog category within a course (`course` and `category_id`;\nadd-ons go with the category of their item). At a station only the items the station makes count; at the pass\nall items of the order.\n",
      "x-description-cs": "`order` – všechny otevřené položky objednávky (přes všechny chody); `course` – otevřené položky jednoho chodu\n(`course`); `category` – otevřené položky jedné kategorie sortimentu v chodu (`course` a `category_id`;\npřísady patří do kategorie své položky). Na stanovišti se počítají jen položky, které stanoviště dělá, na\nvýdeji všechny položky objednávky.\n"
     },
     "course": {
      "description": "The course for `course` and `category`.",
      "x-description-cs": "Chod u `course` a `category`.",
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "category_id": {
      "description": "The category for `category`.",
      "x-description-cs": "Kategorie u `category`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ProductionAction": {
    "type": "object",
    "required": [
     "id",
     "ticket_id",
     "kind",
     "scope",
     "name",
     "item_count",
     "undone",
     "created_at",
     "employee"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "ticket_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "kind": {
      "type": "string",
      "description": "`production` (done at the station), `handover` or `order_complete` (at the pass).",
      "x-description-cs": "`production` (odbaveno na stanovišti), `handover` nebo `order_complete` (na výdeji).",
      "x-extensible-enum": [
       "production",
       "handover",
       "order_complete"
      ]
     },
     "scope": {
      "type": "string",
      "description": "The segment the action covered, as `StationSegmentComplete.scope` – `order`, `course` or `category`.",
      "x-description-cs": "Segment, kterého se akce týkala, jako `StationSegmentComplete.scope` – `order`, `course` nebo `category`.",
      "x-extensible-enum": [
       "order",
       "course",
       "category"
      ]
     },
     "name": {
      "type": "string",
      "description": "What was done, for a person, e.g. \"Pizza · 2. chod\".",
      "x-description-cs": "Co se udělalo, pro člověka, např. „Pizza · 2. chod“."
     },
     "item_count": {
      "type": "integer"
     },
     "undone": {
      "type": "boolean"
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "employee": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/EmployeeRef"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ProductionActionList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ProductionAction"
      }
     }
    }
   },
   "KitchenQueue": {
    "type": "object",
    "required": [
     "preparing",
     "ready"
    ],
    "properties": {
     "preparing": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/KitchenQueueNumber"
      }
     },
     "ready": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/KitchenQueueNumber"
      }
     }
    }
   },
   "KitchenQueueNumber": {
    "type": "object",
    "required": [
     "ticket_id",
     "number",
     "since"
    ],
    "properties": {
     "ticket_id": {
      "$ref": "#/components/schemas/Id"
     },
     "number": {
      "type": "string",
      "examples": [
       "042"
      ]
     },
     "since": {
      "description": "When the order came, or the time it was ordered for.",
      "x-description-cs": "Kdy objednávka přišla, nebo čas, na který byla objednaná.",
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "KitchenTicketPage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor",
     "preorders_later"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/KitchenTicket"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     },
     "preorders_later": {
      "type": "integer",
      "description": "How many preorders wait more than 2 hours ahead (for a badge on the display).",
      "x-description-cs": "Kolik předobjednávek čeká víc než 2 hodiny dopředu (pro odznak na displeji)."
     }
    }
   },
   "KitchenTicketStatusChange": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "status"
    ],
    "properties": {
     "status": {
      "type": "string",
      "enum": [
       "received",
       "preparing",
       "ready",
       "delivered"
      ],
      "description": "`received` – back to the queue (takes the order off a courier's route); `preparing` – the kitchen started\n(also off a route); `ready` – done, waiting for the handout or a courier; `delivered` – handed out.\n",
      "x-description-cs": "`received` – zpět do fronty (sundá objednávku z trasy kurýra); `preparing` – kuchyně začala (také ji sundá\nz trasy); `ready` – hotovo, čeká na výdej nebo kurýra; `delivered` – vydáno.\n"
     }
    }
   },
   "KitchenTicketCancel": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "reason"
    ],
    "properties": {
     "reason": {
      "description": "Why, for the history of the order. With `write_off` and no reason, the reason of the courier's report (`not_delivered`) is used.",
      "x-description-cs": "Proč, pro historii objednávky. S `write_off` a bez důvodu se použije důvod z hlášení kurýra (`not_delivered`).",
      "type": [
       "string",
       "null"
      ],
      "maxLength": 200
     },
     "write_off": {
      "type": "boolean",
      "default": false,
      "description": "Write the order off – the takings go back, no stock goes back (the food was made and is lost).",
      "x-description-cs": "Odepsat objednávku – tržba se vrátí, sklad ne (jídlo je uvařené a ztracené)."
     }
    }
   },
   "Courier": {
    "type": "object",
    "required": [
     "employee",
     "on_shift",
     "on_shift_since",
     "open_routes"
    ],
    "properties": {
     "employee": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "on_shift": {
      "type": "boolean"
     },
     "on_shift_since": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "open_routes": {
      "type": "integer",
      "description": "How many routes of the current shift the courier is still delivering – counted as `listDeliveryRoutes` with\n`status=open`, so a route whose orders a kitchen shift close already took in does not count.\n",
      "x-description-cs": "Kolik tras aktuální směny kurýr ještě rozváží – počítá se jako `listDeliveryRoutes` se `status=open`, takže\ntrasa, jejíž objednávky už zahrnula uzávěrka kuchyně, se nepočítá.\n"
     }
    }
   },
   "CourierPage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Courier"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "CourierTelemetryBatch": {
    "type": "object",
    "additionalProperties": false,
    "description": "What the courier's phone measured since the last batch. Every part may be missing.",
    "x-description-cs": "Co telefon kurýra naměřil od minulé dávky. Kterákoli část může chybět.",
    "properties": {
     "samples": {
      "type": "array",
      "maxItems": 300,
      "description": "Points of the route in any order – the server sorts them by `recorded_at`.",
      "x-description-cs": "Body trasy v libovolném pořadí – server je seřadí podle `recorded_at`.",
      "items": {
       "$ref": "#/components/schemas/CourierTelemetrySample"
      }
     },
     "driving_events": {
      "type": "array",
      "maxItems": 50,
      "description": "Harsh manoeuvres the phone recognised with `thresholds` of the last answer.",
      "x-description-cs": "Prudké manévry, které telefon poznal podle `thresholds` z minulé odpovědi.",
      "items": {
       "$ref": "#/components/schemas/DrivingEventInput"
      }
     },
     "device": {
      "description": "The state of the phone now; missing or `null` keeps the last one.",
      "x-description-cs": "Stav telefonu teď; když chybí nebo je `null`, zůstane poslední.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/CourierDeviceStateInput"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "CourierTelemetrySample": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "recorded_at",
     "location"
    ],
    "properties": {
     "recorded_at": {
      "description": "When the phone measured the point – not when it sent it. Milliseconds are kept.",
      "x-description-cs": "Kdy telefon bod změřil – ne kdy ho odeslal. Milisekundy se zachovají.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "location": {
      "$ref": "#/components/schemas/CourierLocationInput"
     },
     "speed_mps": {
      "type": [
       "number",
       "null"
      ],
      "minimum": 0,
      "maximum": 100,
      "description": "Speed from the GPS in metres a second (not computed from the distance of points).",
      "x-description-cs": "Rychlost z GPS v metrech za sekundu (ne spočítaná ze vzdálenosti bodů).",
      "examples": [
       9.4
      ]
     },
     "heading_deg": {
      "type": [
       "number",
       "null"
      ],
      "minimum": 0,
      "maximum": 360,
      "description": "Direction of travel in degrees clockwise from the north.",
      "x-description-cs": "Směr jízdy ve stupních po směru hodinových ručiček od severu.",
      "examples": [
       212
      ]
     },
     "altitude_m": {
      "type": [
       "number",
       "null"
      ],
      "minimum": -500,
      "maximum": 9000,
      "description": "Altitude above the sea level in metres.",
      "x-description-cs": "Nadmořská výška v metrech.",
      "examples": [
       368
      ]
     },
     "accel_peak_g": {
      "type": [
       "number",
       "null"
      ],
      "minimum": 0,
      "maximum": 16,
      "description": "The highest acceleration without the gravity since the previous point, in g.",
      "x-description-cs": "Nejvyšší zrychlení bez gravitace od předchozího bodu, v g.",
      "examples": [
       0.31
      ]
     },
     "route_id": {
      "description": "The route the courier is driving, the ride back to the restaurant included; `null` without a route.",
      "x-description-cs": "Trasa, kterou kurýr jede, včetně cesty zpět do provozovny; `null` bez trasy.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "CourierLocationInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "lat",
     "lon"
    ],
    "properties": {
     "lat": {
      "type": "number",
      "minimum": -90,
      "maximum": 90,
      "examples": [
       49.755612
      ]
     },
     "lon": {
      "type": "number",
      "minimum": -180,
      "maximum": 180,
      "examples": [
       16.468301
      ]
     },
     "accuracy_m": {
      "type": [
       "number",
       "null"
      ],
      "minimum": 0,
      "maximum": 100000,
      "description": "Accuracy of the location in metres.",
      "x-description-cs": "Přesnost polohy v metrech.",
      "examples": [
       6
      ]
     }
    }
   },
   "DrivingEventInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "type",
     "recorded_at",
     "value_g"
    ],
    "properties": {
     "type": {
      "type": "string",
      "enum": [
       "harsh_braking",
       "harsh_acceleration",
       "sharp_turn"
      ],
      "description": "What the manoeuvre was – see `DrivingEventType`.",
      "x-description-cs": "Jaký to byl manévr – viz `DrivingEventType`."
     },
     "recorded_at": {
      "description": "When the manoeuvre began.",
      "x-description-cs": "Kdy manévr začal.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "value_g": {
      "type": "number",
      "minimum": 0,
      "maximum": 16,
      "description": "The peak acceleration during the manoeuvre in g – along the direction of travel for braking and accelerating, sideways for a turn.",
      "x-description-cs": "Špička přetížení během manévru v g – podélně u brzdění a zrychlení, bočně u zatáčky.",
      "examples": [
       0.52
      ]
     },
     "duration_ms": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "maximum": 60000,
      "description": "How long the acceleration stayed over the threshold.",
      "x-description-cs": "Jak dlouho přetížení drželo nad prahem.",
      "examples": [
       900
      ]
     },
     "speed_mps": {
      "type": [
       "number",
       "null"
      ],
      "minimum": 0,
      "maximum": 100,
      "description": "Speed when the manoeuvre began, in metres a second.",
      "x-description-cs": "Rychlost na začátku manévru v metrech za sekundu.",
      "examples": [
       11.2
      ]
     },
     "location": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/CourierLocationInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "route_id": {
      "description": "The route the courier was driving; `null` without a route.",
      "x-description-cs": "Trasa, kterou kurýr jel; `null` bez trasy.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "CourierDeviceStateInput": {
    "type": "object",
    "additionalProperties": false,
    "description": "The state of the phone. `null` in a field means the phone does not know.",
    "x-description-cs": "Stav telefonu. `null` v poli znamená, že to telefon neví.",
    "properties": {
     "battery_pct": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "maximum": 100,
      "examples": [
       64
      ]
     },
     "charging": {
      "type": [
       "boolean",
       "null"
      ]
     },
     "network": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "wifi",
       "cellular",
       "none",
       "unknown",
       null
      ],
      "description": "The connection of the phone – see `CourierNetwork`.",
      "x-description-cs": "Připojení telefonu – viz `CourierNetwork`."
     },
     "activity": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "still",
       "walking",
       "running",
       "cycling",
       "vehicle",
       "unknown",
       null
      ],
      "description": "How the courier moves by the motion sensors of the phone – see `CourierActivity`.",
      "x-description-cs": "Jak se kurýr pohybuje podle pohybových senzorů telefonu – viz `CourierActivity`."
     },
     "mock_location": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "The phone reports a simulated location (a fake GPS application).",
      "x-description-cs": "Telefon hlásí podvrženou polohu (aplikace na falešné GPS)."
     },
     "location_permission": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "always",
       "while_in_use",
       "denied",
       "unknown",
       null
      ],
      "description": "What the courier allowed the application – see `LocationPermission`.",
      "x-description-cs": "Co kurýr aplikaci povolil – viz `LocationPermission`."
     },
     "power_save": {
      "type": [
       "boolean",
       "null"
      ],
      "description": "The phone saves power – it may stop measuring in the background.",
      "x-description-cs": "Telefon šetří energii – měření na pozadí může zastavit."
     },
     "app_version": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "examples": [
       "26.11.3"
      ]
     }
    }
   },
   "CourierTelemetryResult": {
    "type": "object",
    "required": [
     "accepted",
     "duplicates",
     "discarded",
     "mode",
     "off_reason",
     "send_every_s",
     "sample_every_s",
     "thresholds",
     "server_time"
    ],
    "properties": {
     "accepted": {
      "type": "integer",
      "description": "Points and manoeuvres recorded now.",
      "x-description-cs": "Body a manévry zapsané teď.",
      "examples": [
       3
      ]
     },
     "duplicates": {
      "type": "integer",
      "description": "Points and manoeuvres recorded before – the batch came again.",
      "x-description-cs": "Body a manévry zapsané už dřív – dávka přišla znovu.",
      "examples": [
       0
      ]
     },
     "discarded": {
      "type": "integer",
      "description": "Dropped – outside the shift, older than 24 hours, ahead of the server, or tracking is off.",
      "x-description-cs": "Zahozené – mimo směnu, starší než 24 hodin, napřed proti serveru, nebo je sledování vypnuté.",
      "examples": [
       0
      ]
     },
     "mode": {
      "$ref": "#/components/schemas/CourierTrackingMode"
     },
     "off_reason": {
      "description": "Why `mode` is `off`; `null` otherwise.",
      "x-description-cs": "Proč je `mode` `off`; jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/CourierTrackingOffReason"
       },
       {
        "type": "null"
       }
      ]
     },
     "send_every_s": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Send the next batch after this many seconds; `null` with `off`.",
      "x-description-cs": "Další dávku pošlete za tolik sekund; `null` u `off`.",
      "examples": [
       15
      ]
     },
     "sample_every_s": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Take a point this often while moving (and after 25 m); `null` with `off`.",
      "x-description-cs": "Bod berte takhle často za jízdy (a po 25 m); `null` u `off`.",
      "examples": [
       5
      ]
     },
     "thresholds": {
      "$ref": "#/components/schemas/DrivingThresholds"
     },
     "server_time": {
      "description": "The time of the server – correct the clock of the phone by it.",
      "x-description-cs": "Čas serveru – podle něj opravte hodiny telefonu.",
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "CourierTrackingMode": {
    "type": "string",
    "description": "`route` – the courier has an open route, send a batch every 15 s; `shift` – on shift without a route, every\n60 s; `off` – stop measuring.\n",
    "x-description-cs": "`route` – kurýr má otevřenou trasu, dávku každých 15 s; `shift` – na směně bez trasy, každých 60 s; `off` –\npřestaňte měřit.\n",
    "x-extensible-enum": [
     "route",
     "shift",
     "off"
    ]
   },
   "CourierTrackingOffReason": {
    "type": "string",
    "description": "`tracking_disabled` – the restaurant did not turn courier tracking on; `off_shift` – the courier is not on shift;\n`idle` – on shift without a route for over 3 hours (a forgotten check-out), start again with a new route.\n",
    "x-description-cs": "`tracking_disabled` – provozovna sledování kurýrů nezapnula; `off_shift` – kurýr není na směně; `idle` – na\nsměně bez trasy přes 3 hodiny (zapomenuté odhlášení), znovu začněte s novou trasou.\n",
    "x-extensible-enum": [
     "tracking_disabled",
     "off_shift",
     "idle"
    ]
   },
   "DrivingThresholds": {
    "type": "object",
    "description": "Limits of harsh manoeuvres in g set by the restaurant (or the defaults).",
    "x-description-cs": "Prahy prudkých manévrů v g podle provozovny (nebo výchozí).",
    "required": [
     "harsh_braking_g",
     "harsh_acceleration_g",
     "sharp_turn_g"
    ],
    "properties": {
     "harsh_braking_g": {
      "type": "number",
      "description": "Slowing down at least this strongly is harsh braking.",
      "x-description-cs": "Zpomalení aspoň takhle silné je prudké brzdění.",
      "examples": [
       0.4
      ]
     },
     "harsh_acceleration_g": {
      "type": "number",
      "description": "Speeding up at least this strongly is harsh acceleration.",
      "x-description-cs": "Zrychlení aspoň takhle silné je prudké zrychlení.",
      "examples": [
       0.35
      ]
     },
     "sharp_turn_g": {
      "type": "number",
      "description": "A sideways acceleration at least this strong is a sharp turn.",
      "x-description-cs": "Boční přetížení aspoň takhle silné je ostrá zatáčka.",
      "examples": [
       0.45
      ]
     }
    }
   },
   "DrivingEventType": {
    "type": "string",
    "description": "`harsh_braking` – harsh braking; `harsh_acceleration` – harsh acceleration; `sharp_turn` – a sharp turn\n(sideways acceleration).\n",
    "x-description-cs": "`harsh_braking` – prudké brzdění; `harsh_acceleration` – prudké zrychlení; `sharp_turn` – ostrá zatáčka\n(boční přetížení).\n",
    "x-extensible-enum": [
     "harsh_braking",
     "harsh_acceleration",
     "sharp_turn"
    ]
   },
   "CourierNetwork": {
    "type": "string",
    "description": "`wifi`, `cellular` (mobile data), `none` (no connection, the batch waited on the phone), `unknown`.",
    "x-description-cs": "`wifi`, `cellular` (mobilní data), `none` (bez připojení, dávka čekala v telefonu), `unknown`.",
    "x-extensible-enum": [
     "wifi",
     "cellular",
     "none",
     "unknown"
    ]
   },
   "CourierActivity": {
    "type": "string",
    "description": "`still`, `walking`, `running`, `cycling`, `vehicle` (a car or a scooter), `unknown`.",
    "x-description-cs": "`still` (stojí), `walking`, `running`, `cycling`, `vehicle` (auto nebo skútr), `unknown`.",
    "x-extensible-enum": [
     "still",
     "walking",
     "running",
     "cycling",
     "vehicle",
     "unknown"
    ]
   },
   "LocationPermission": {
    "type": "string",
    "description": "`always` – also in the background; `while_in_use` – while the application runs (with the notification of the\nshift that is enough); `denied` – the location is off, the restaurant does not see the courier; `unknown`.\n",
    "x-description-cs": "`always` – i na pozadí; `while_in_use` – když aplikace běží (s oznámením o směně to stačí); `denied` – poloha\nje vypnutá, provozovna kurýra nevidí; `unknown`.\n",
    "x-extensible-enum": [
     "always",
     "while_in_use",
     "denied",
     "unknown"
    ]
   },
   "CourierLocation": {
    "type": "object",
    "required": [
     "lat",
     "lon",
     "accuracy_m"
    ],
    "properties": {
     "lat": {
      "type": "number",
      "examples": [
       49.755612
      ]
     },
     "lon": {
      "type": "number",
      "examples": [
       16.468301
      ]
     },
     "accuracy_m": {
      "type": [
       "number",
       "null"
      ],
      "description": "Accuracy of the location in metres; `null` when unknown.",
      "x-description-cs": "Přesnost polohy v metrech; `null`, když není známá.",
      "examples": [
       6
      ]
     }
    }
   },
   "CourierDeviceState": {
    "type": "object",
    "description": "The last state of the phone it sent; `null` in a field means it does not know or never said.",
    "x-description-cs": "Poslední stav, který telefon poslal; `null` v poli znamená, že neví nebo nikdy neřekl.",
    "required": [
     "battery_pct",
     "charging",
     "network",
     "activity",
     "mock_location",
     "location_permission",
     "power_save",
     "app_version"
    ],
    "properties": {
     "battery_pct": {
      "type": [
       "integer",
       "null"
      ],
      "examples": [
       64
      ]
     },
     "charging": {
      "type": [
       "boolean",
       "null"
      ]
     },
     "network": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/CourierNetwork"
       },
       {
        "type": "null"
       }
      ]
     },
     "activity": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/CourierActivity"
       },
       {
        "type": "null"
       }
      ]
     },
     "mock_location": {
      "type": [
       "boolean",
       "null"
      ]
     },
     "location_permission": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/LocationPermission"
       },
       {
        "type": "null"
       }
      ]
     },
     "power_save": {
      "type": [
       "boolean",
       "null"
      ]
     },
     "app_version": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "26.11.3"
      ]
     }
    }
   },
   "CourierPositionState": {
    "type": "string",
    "description": "`moving` – drives (at least 7 km/h); `stopped` – stands (at a customer, in traffic); `at_restaurant` – within\n100 m of the restaurant; `stale` – nothing from the phone for over 3 minutes, the location is old.\n",
    "x-description-cs": "`moving` – jede (aspoň 7 km/h); `stopped` – stojí (u zákazníka, v koloně); `at_restaurant` – do 100 m od\nprovozovny; `stale` – od telefonu přes 3 minuty nic, poloha je stará.\n",
    "x-extensible-enum": [
     "moving",
     "stopped",
     "at_restaurant",
     "stale"
    ]
   },
   "CourierPosition": {
    "type": "object",
    "required": [
     "employee",
     "state",
     "location",
     "speed_mps",
     "heading_deg",
     "altitude_m",
     "recorded_at",
     "received_at",
     "route_id",
     "remaining_tickets",
     "device"
    ],
    "properties": {
     "employee": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "state": {
      "$ref": "#/components/schemas/CourierPositionState"
     },
     "location": {
      "$ref": "#/components/schemas/CourierLocation"
     },
     "speed_mps": {
      "type": [
       "number",
       "null"
      ],
      "description": "Speed from the GPS in metres a second (× 3.6 = km/h).",
      "x-description-cs": "Rychlost z GPS v metrech za sekundu (× 3,6 = km/h).",
      "examples": [
       9.4
      ]
     },
     "heading_deg": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Direction of travel, 0–359 degrees clockwise from the north.",
      "x-description-cs": "Směr jízdy, 0–359 stupňů po směru hodinových ručiček od severu.",
      "examples": [
       212
      ]
     },
     "altitude_m": {
      "type": [
       "integer",
       "null"
      ],
      "examples": [
       368
      ]
     },
     "recorded_at": {
      "description": "When the phone measured the location.",
      "x-description-cs": "Kdy telefon polohu změřil.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "received_at": {
      "description": "When the server last heard from the phone.",
      "x-description-cs": "Kdy se telefon serveru naposledy ozval.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "route_id": {
      "description": "The open route of the courier; `null` without one.",
      "x-description-cs": "Otevřená trasa kurýra; `null`, když žádnou nemá.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "remaining_tickets": {
      "type": "integer",
      "description": "Orders of the open route the courier still has to hand over (not delivered, not cancelled and not reported as not taken over); 0 without a route.",
      "x-description-cs": "Objednávky otevřené trasy, které kurýr ještě musí předat (nedoručené, nezrušené a nenahlášené jako nepřevzaté); bez trasy 0.",
      "examples": [
       2
      ]
     },
     "device": {
      "$ref": "#/components/schemas/CourierDeviceState"
     }
    }
   },
   "CourierPositionList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/CourierPosition"
      }
     }
    }
   },
   "DeliveryRouteTrack": {
    "type": "object",
    "required": [
     "route_id",
     "courier",
     "summary",
     "points_expired",
     "points",
     "driving_events"
    ],
    "properties": {
     "route_id": {
      "$ref": "#/components/schemas/Id"
     },
     "courier": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "summary": {
      "description": "The summary of the ride; `null` when the phone sent nothing for the route.",
      "x-description-cs": "Souhrn jízdy; `null`, když telefon k trase nic neposlal.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/DeliveryRouteTrackSummary"
       },
       {
        "type": "null"
       }
      ]
     },
     "points_expired": {
      "type": "boolean",
      "description": "The points and manoeuvres were deleted after 14 days; only the summary stays.",
      "x-description-cs": "Body a manévry se po 14 dnech smazaly; zůstal jen souhrn."
     },
     "points": {
      "type": "array",
      "description": "The driven track from the oldest point, at least 10 m between points, at most 5 000.",
      "x-description-cs": "Projetá stopa od nejstaršího bodu, aspoň 10 m mezi body, nejvýš 5 000.",
      "items": {
       "$ref": "#/components/schemas/TrackPoint"
      }
     },
     "driving_events": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/DrivingEvent"
      }
     }
    }
   },
   "DeliveryRouteTrackSummary": {
    "type": "object",
    "required": [
     "started_at",
     "ended_at",
     "distance_m",
     "moving_s",
     "duration_s",
     "max_speed_mps",
     "avg_moving_speed_mps",
     "points",
     "harsh_braking",
     "harsh_acceleration",
     "sharp_turn"
    ],
    "properties": {
     "started_at": {
      "description": "The first point of the route.",
      "x-description-cs": "První bod trasy.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "ended_at": {
      "description": "The last point of the route.",
      "x-description-cs": "Poslední bod trasy.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "distance_m": {
      "type": "integer",
      "description": "Distance driven in metres – from points with an accuracy of 50 m or better, without GPS jumps.",
      "x-description-cs": "Ujetá vzdálenost v metrech – z bodů s přesností do 50 m, bez skoků GPS.",
      "examples": [
       7420
      ]
     },
     "moving_s": {
      "type": "integer",
      "description": "Time moving in seconds.",
      "x-description-cs": "Čas v jízdě v sekundách.",
      "examples": [
       1260
      ]
     },
     "duration_s": {
      "type": "integer",
      "description": "From the first to the last point in seconds.",
      "x-description-cs": "Od prvního do posledního bodu v sekundách.",
      "examples": [
       2310
      ]
     },
     "max_speed_mps": {
      "type": [
       "number",
       "null"
      ],
      "examples": [
       16.4
      ]
     },
     "avg_moving_speed_mps": {
      "type": [
       "number",
       "null"
      ],
      "description": "Average speed while moving; `null` before the courier moved.",
      "x-description-cs": "Průměrná rychlost za jízdy; `null`, dokud se kurýr nerozjel.",
      "examples": [
       5.89
      ]
     },
     "points": {
      "type": "integer",
      "description": "Points received for the route.",
      "x-description-cs": "Přijaté body trasy.",
      "examples": [
       412
      ]
     },
     "harsh_braking": {
      "type": "integer",
      "examples": [
       1
      ]
     },
     "harsh_acceleration": {
      "type": "integer",
      "examples": [
       0
      ]
     },
     "sharp_turn": {
      "type": "integer",
      "examples": [
       2
      ]
     }
    }
   },
   "TrackPoint": {
    "type": "object",
    "required": [
     "recorded_at",
     "lat",
     "lon",
     "accuracy_m",
     "speed_mps",
     "heading_deg"
    ],
    "properties": {
     "recorded_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "lat": {
      "type": "number",
      "examples": [
       49.755612
      ]
     },
     "lon": {
      "type": "number",
      "examples": [
       16.468301
      ]
     },
     "accuracy_m": {
      "type": [
       "number",
       "null"
      ],
      "examples": [
       6
      ]
     },
     "speed_mps": {
      "type": [
       "number",
       "null"
      ],
      "examples": [
       9.4
      ]
     },
     "heading_deg": {
      "type": [
       "integer",
       "null"
      ],
      "examples": [
       212
      ]
     }
    }
   },
   "DrivingEvent": {
    "type": "object",
    "required": [
     "type",
     "recorded_at",
     "value_g",
     "duration_ms",
     "speed_mps",
     "location"
    ],
    "properties": {
     "type": {
      "$ref": "#/components/schemas/DrivingEventType"
     },
     "recorded_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "value_g": {
      "type": "number",
      "examples": [
       0.52
      ]
     },
     "duration_ms": {
      "type": [
       "integer",
       "null"
      ],
      "examples": [
       900
      ]
     },
     "speed_mps": {
      "type": [
       "number",
       "null"
      ],
      "examples": [
       11.2
      ]
     },
     "location": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/CourierLocation"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "DeliveryRoute": {
    "type": "object",
    "required": [
     "id",
     "courier",
     "status",
     "created_at",
     "completed_at",
     "tickets"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "courier": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "status": {
      "type": "string",
      "description": "`open` – still being delivered; `completed` – every order of the route was delivered, cancelled or not\ndelivered (`completed_at`).\n",
      "x-description-cs": "`open` – ještě se rozváží; `completed` – všechny objednávky trasy jsou doručené, zrušené nebo nepřevzaté\n(`completed_at`).\n",
      "x-extensible-enum": [
       "open",
       "completed"
      ]
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "completed_at": {
      "description": "When the route was completed; `null` while it is open.",
      "x-description-cs": "Kdy se trasa dokončila; `null`, dokud je otevřená.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "tickets": {
      "type": "array",
      "description": "The orders of the route in the planned order, with addresses, phone numbers, `payment_method` and `total`.\nAn order moved back to the kitchen queue leaves the route.\n",
      "x-description-cs": "Objednávky trasy v naplánovaném pořadí, s adresami, telefony, `payment_method` a `total`. Objednávka vrácená\ndo fronty kuchyně z trasy zmizí.\n",
      "items": {
       "$ref": "#/components/schemas/KitchenTicket"
      }
     }
    }
   },
   "DeliveryRoutePage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/DeliveryRoute"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "DeliveryRouteCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "courier_id",
     "ticket_ids"
    ],
    "properties": {
     "courier_id": {
      "$ref": "#/components/schemas/Id"
     },
     "ticket_ids": {
      "type": "array",
      "minItems": 1,
      "maxItems": 20,
      "description": "Kitchen tickets in the order the courier delivers them.",
      "x-description-cs": "Kuchyňské bony v pořadí, v jakém je kurýr rozveze.",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     }
    }
   },
   "HandoverPayment": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "method",
     "amount",
     "paid_at"
    ],
    "properties": {
     "method": {
      "type": "string",
      "enum": [
       "card",
       "cash"
      ],
      "description": "How the customer actually paid at the door.",
      "x-description-cs": "Čím zákazník u dveří skutečně zaplatil."
     },
     "amount": {
      "description": "The amount paid, tip included – it must equal `amount_due` + `tip` of the ticket.",
      "x-description-cs": "Zaplacená částka včetně spropitného – musí se rovnat `amount_due` + `tip` bonu.",
      "$ref": "#/components/schemas/MoneyInput"
     },
     "tip": {
      "description": "The tip the customer added on the terminal; `null` or missing = none.",
      "x-description-cs": "Spropitné, které zákazník přidal na terminálu; `null` nebo chybí = žádné.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/MoneyInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "gateway_payment_id": {
      "type": [
       "string",
       "null"
      ],
      "minLength": 1,
      "maxLength": 128,
      "description": "The transaction ID of the payment terminal (Teya) – for finding and refunding the payment. Required for `card`.",
      "x-description-cs": "ID transakce platebního terminálu (Teya) – k dohledání a vrácení platby. U `card` povinné.",
      "examples": [
       "teya-7f3a9c41"
      ]
     },
     "card_brand": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "description": "The card scheme for the receipt and the administration, as the terminal reports it.",
      "x-description-cs": "Karetní asociace pro účtenku a administraci, jak ji hlásí terminál.",
      "examples": [
       "visa"
      ]
     },
     "card_last4": {
      "type": [
       "string",
       "null"
      ],
      "pattern": "^[0-9]{4}$",
      "description": "The last four digits of the card.",
      "x-description-cs": "Poslední čtyři číslice karty.",
      "examples": [
       "4242"
      ]
     },
     "paid_at": {
      "description": "When the customer paid at the door – not when the phone sent it.",
      "x-description-cs": "Kdy zákazník u dveří zaplatil – ne kdy to telefon odeslal.",
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "PaidBy": {
    "type": "object",
    "required": [
     "method",
     "amount",
     "tip",
     "card_brand",
     "card_last4",
     "gateway_payment_id",
     "paid_at"
    ],
    "properties": {
     "method": {
      "type": "string",
      "description": "How the customer paid at the door.",
      "x-description-cs": "Čím zákazník u dveří zaplatil.",
      "x-extensible-enum": [
       "card",
       "cash"
      ]
     },
     "amount": {
      "description": "The amount paid, tip included.",
      "x-description-cs": "Zaplacená částka včetně spropitného.",
      "$ref": "#/components/schemas/Money"
     },
     "tip": {
      "description": "The tip included in `amount`; zero when none.",
      "x-description-cs": "Spropitné obsažené v `amount`; nula, když žádné.",
      "$ref": "#/components/schemas/Money"
     },
     "card_brand": {
      "type": [
       "string",
       "null"
      ]
     },
     "card_last4": {
      "type": [
       "string",
       "null"
      ]
     },
     "gateway_payment_id": {
      "type": [
       "string",
       "null"
      ]
     },
     "paid_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "NotDeliveredReason": {
    "type": "string",
    "description": "`customer_absent` – the customer could not be reached (did not open, did not answer the phone); `refused` –\nrefused to take it over; `refused_payment` – did not pay (no cash, the card did not go through, refused);\n`cancelled_by_customer` – cancelled the order (on the phone, on the way); `wrong_address` – the address does\nnot exist, cannot be found or there is no way in; `damaged` – the food was damaged on the way; `other` – another\nreason, `note` required.\n",
    "x-description-cs": "`customer_absent` – zákazník nebyl k zastižení (neotvírá, nebere telefon); `refused` – odmítl převzít;\n`refused_payment` – nezaplatil (nemá hotovost, karta neprošla, odmítl); `cancelled_by_customer` – objednávku\nzrušil (po telefonu, cestou); `wrong_address` – adresa neexistuje, nedá se najít nebo se nedá dostat dovnitř;\n`damaged` – jídlo se cestou poškodilo; `other` – jiný důvod, `note` povinná.\n",
    "x-extensible-enum": [
     "customer_absent",
     "refused",
     "refused_payment",
     "cancelled_by_customer",
     "wrong_address",
     "damaged",
     "other"
    ]
   },
   "NotDeliveredReport": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "reason",
     "attempted_at"
    ],
    "properties": {
     "reason": {
      "type": "string",
      "enum": [
       "customer_absent",
       "refused",
       "refused_payment",
       "cancelled_by_customer",
       "wrong_address",
       "damaged",
       "other"
      ],
      "description": "Why the customer did not take the order over – see `NotDeliveredReason`.",
      "x-description-cs": "Proč zákazník objednávku nepřevzal – viz `NotDeliveredReason`."
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 500,
      "description": "The courier's note; required for `other`.",
      "x-description-cs": "Poznámka kurýra; u `other` povinná.",
      "examples": [
       "Zvonil jsem 2×, čekal 10 min, telefon nebere."
      ]
     },
     "attempted_at": {
      "description": "When the courier was at the door – not when the phone sent it.",
      "x-description-cs": "Kdy byl kurýr u dveří – ne kdy to telefon odeslal.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "location": {
      "description": "Where the phone was, as evidence of the attempt; `null` or missing when it does not know.",
      "x-description-cs": "Kde telefon byl, jako doklad o pokusu; `null` nebo chybí, když ji nezná.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/DeliveryAttemptLocationInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "call_attempts": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "maximum": 99,
      "description": "How many times the courier called the customer from the application.",
      "x-description-cs": "Kolikrát kurýr zákazníkovi volal z aplikace."
     }
    }
   },
   "DeliveryAttemptLocationInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "lat",
     "lon"
    ],
    "properties": {
     "lat": {
      "type": "number",
      "minimum": -90,
      "maximum": 90,
      "examples": [
       50.0874
      ]
     },
     "lon": {
      "type": "number",
      "minimum": -180,
      "maximum": 180,
      "examples": [
       14.4213
      ]
     },
     "accuracy_m": {
      "type": [
       "number",
       "null"
      ],
      "minimum": 0,
      "maximum": 100000,
      "description": "Accuracy of the location in metres.",
      "x-description-cs": "Přesnost polohy v metrech.",
      "examples": [
       12
      ]
     }
    }
   },
   "DeliveryAttemptLocation": {
    "type": "object",
    "required": [
     "lat",
     "lon",
     "accuracy_m"
    ],
    "properties": {
     "lat": {
      "type": "number",
      "examples": [
       50.0874
      ]
     },
     "lon": {
      "type": "number",
      "examples": [
       14.4213
      ]
     },
     "accuracy_m": {
      "type": [
       "number",
       "null"
      ],
      "description": "Accuracy of the location in metres; `null` when unknown.",
      "x-description-cs": "Přesnost polohy v metrech; `null`, když není známá."
     }
    }
   },
   "NotDeliveredInfo": {
    "type": "object",
    "required": [
     "reason",
     "note",
     "attempted_at",
     "employee",
     "location",
     "call_attempts"
    ],
    "properties": {
     "reason": {
      "$ref": "#/components/schemas/NotDeliveredReason"
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "attempted_at": {
      "description": "When the courier was at the door.",
      "x-description-cs": "Kdy byl kurýr u dveří.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "employee": {
      "description": "The courier who reported it; `null` when no employee was signed in (the kitchen display).",
      "x-description-cs": "Kurýr, který to nahlásil; `null`, když nebyl přihlášený žádný zaměstnanec (kuchyňský displej).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/EmployeeRef"
       },
       {
        "type": "null"
       }
      ]
     },
     "location": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/DeliveryAttemptLocation"
       },
       {
        "type": "null"
       }
      ]
     },
     "call_attempts": {
      "type": [
       "integer",
       "null"
      ]
     }
    }
   },
   "PostalAddress": {
    "type": "object",
    "description": "A postal address as entered in the administration (the restaurant or the company). A part that is not filled in is an empty string.",
    "x-description-cs": "Poštovní adresa tak, jak je zadaná v administraci (provozovna nebo firma). Nevyplněná část je prázdný řetězec.",
    "required": [
     "street",
     "city",
     "postal_code"
    ],
    "properties": {
     "street": {
      "type": "string",
      "description": "Street with the house number, as one text.",
      "x-description-cs": "Ulice s číslem domu jako jeden text."
     },
     "city": {
      "type": "string",
      "description": "City or village.",
      "x-description-cs": "Obec."
     },
     "postal_code": {
      "type": "string",
      "description": "Postal code as entered.",
      "x-description-cs": "PSČ, jak je zadané.",
      "examples": [
       "53002"
      ]
     }
    }
   },
   "DeviceSettings": {
    "type": "object",
    "description": "What a device of the restaurant needs from the administration (see `getDeviceSettings`). No event announces a\nchange; read it again with `If-None-Match`.\n",
    "x-description-cs": "Co zařízení provozovny potřebuje z administrace (viz `getDeviceSettings`). Změnu neohlásí žádná událost; čtěte\nznovu s `If-None-Match`.\n",
    "required": [
     "restaurant",
     "company",
     "receipt_layouts",
     "predefined_notes",
     "printers",
     "kitchen_stations",
     "rooms",
     "kitchen",
     "eet",
     "features",
     "paid_until",
     "table_ordering",
     "pos"
    ],
    "properties": {
     "restaurant": {
      "type": "object",
      "description": "The restaurant as printed on receipts: name, phone and website as entered (`null` when empty), the address,\nthe location (`null` without coordinates), the currency of the account and the time zone (`Europe/Prague`).\n",
      "x-description-cs": "Provozovna, jak se tiskne na účtenky: název, telefon a web, jak jsou zadané (`null`, když chybí), adresa,\npoloha (`null` bez souřadnic), měna účtu a časová zóna (`Europe/Prague`).\n",
      "required": [
       "name",
       "phone",
       "website",
       "address",
       "location",
       "currency",
       "timezone"
      ],
      "properties": {
       "name": {
        "type": "string"
       },
       "phone": {
        "type": [
         "string",
         "null"
        ]
       },
       "website": {
        "type": [
         "string",
         "null"
        ]
       },
       "address": {
        "$ref": "#/components/schemas/PostalAddress"
       },
       "location": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/GeoPoint"
         },
         {
          "type": "null"
         }
        ]
       },
       "currency": {
        "type": "string",
        "examples": [
         "CZK"
        ]
       },
       "timezone": {
        "type": "string",
        "examples": [
         "Europe/Prague"
        ]
       }
      }
     },
     "company": {
      "type": "object",
      "description": "The company on receipts and invoices (set in the user settings of the account).",
      "x-description-cs": "Firma na účtenkách a fakturách (nastavuje se v nastavení uživatele účtu).",
      "required": [
       "name",
       "registration_number",
       "vat_number",
       "vat_payer",
       "address",
       "email"
      ],
      "properties": {
       "name": {
        "type": "string"
       },
       "registration_number": {
        "description": "IČO.",
        "x-description-cs": "IČO.",
        "type": [
         "string",
         "null"
        ]
       },
       "vat_number": {
        "description": "DIČ.",
        "x-description-cs": "DIČ.",
        "type": [
         "string",
         "null"
        ]
       },
       "vat_payer": {
        "type": "boolean"
       },
       "address": {
        "$ref": "#/components/schemas/PostalAddress"
       },
       "email": {
        "type": [
         "string",
         "null"
        ]
       }
      }
     },
     "receipt_layouts": {
      "type": "object",
      "description": "Receipt layouts from Print layouts in the administration, as the cash register and the kitchen display read\nthem; `null` when the restaurant has not set its own.\n",
      "x-description-cs": "Tiskové šablony z Tiskových sestav v administraci tak, jak je čte pokladna a kuchyňský displej; `null`, když\nprovozovna vlastní nenastavila.\n",
      "required": [
       "receipt",
       "takeaway"
      ],
      "properties": {
       "receipt": {
        "anyOf": [
         {
          "type": "array",
          "items": {
           "type": "object"
          }
         },
         {
          "type": "object"
         },
         {
          "type": "null"
         }
        ]
       },
       "takeaway": {
        "anyOf": [
         {
          "type": "array",
          "items": {
           "type": "object"
          }
         },
         {
          "type": "object"
         },
         {
          "type": "null"
         }
        ]
       }
      }
     },
     "predefined_notes": {
      "type": "array",
      "description": "Notes prepared in the administration for the staff to pick, ordered by `id`. The administration only adds and\ndeletes them, so an `id` always keeps its text.\n",
      "x-description-cs": "Poznámky připravené v administraci, ze kterých personál vybírá, seřazené podle `id`. Administrace je jen\npřidává a maže, takže `id` si svůj text drží vždy.\n",
      "items": {
       "type": "object",
       "required": [
        "id",
        "text"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "text": {
         "type": "string"
        }
       }
      }
     },
     "printers": {
      "type": "array",
      "description": "Extra printers of the split kitchen; products are routed to them by `KitchenItem.station_id`.",
      "x-description-cs": "Další tiskárny rozdělené kuchyně; produkty k nim vede `KitchenItem.station_id`.",
      "items": {
       "$ref": "#/components/schemas/ProductionDevice"
      }
     },
     "kitchen_stations": {
      "type": "array",
      "description": "Production monitors of the split kitchen.",
      "x-description-cs": "Výrobní monitory rozdělené kuchyně.",
      "items": {
       "$ref": "#/components/schemas/ProductionDevice"
      }
     },
     "rooms": {
      "description": "Rooms with tables in percent of the room; `null` when the licence does not include the table map.",
      "x-description-cs": "Místnosti se stoly v procentech místnosti; `null`, když licence mapu provozovny neobsahuje.",
      "anyOf": [
       {
        "type": "array",
        "items": {
         "$ref": "#/components/schemas/Room"
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "kitchen": {
      "type": "object",
      "description": "Settings of the kitchen and of orders in it.",
      "x-description-cs": "Nastavení kuchyně a objednávek v ní.",
      "required": [
       "portion_mode",
       "extra_ticket",
       "redirect_restaurant_id",
       "ready_sms"
      ],
      "properties": {
       "portion_mode": {
        "type": "string",
        "description": "How the restaurant limits portions: `none` – not at all; `local` – at the registers and in the\napplications of the restaurant staff (the server takes the portions off for their receipts and orders);\n`full` – also for the e-shop and guest applications (`Restaurant.portion_tracking`).\n",
        "x-description-cs": "Jak provozovna hlídá porce: `none` – vůbec; `local` – na pokladnách a v aplikacích personálu provozovny\n(server porce odečte u jejich účtenek a objednávek); `full` – i pro e-shop a aplikace pro hosty\n(`Restaurant.portion_tracking`).\n",
        "x-extensible-enum": [
         "none",
         "local",
         "full"
        ]
       },
       "extra_ticket": {
        "type": "boolean",
        "description": "Print one more, shortened copy of each kitchen ticket (in the administration the extra ticket for delivery).",
        "x-description-cs": "Tisknout ke každému kuchyňskému bonu ještě zkrácenou kopii (v administraci extra bon pro rozvoz)."
       },
       "redirect_restaurant_id": {
        "description": "Kitchen tickets of open tables go to the kitchen of this restaurant – applied only when it is an existing\nrestaurant of the same account.\n",
        "x-description-cs": "Kuchyňské bony otevřených stolů jdou do kuchyně této provozovny – platí jen tehdy, když je to existující\nprovozovna stejného účtu.\n",
        "anyOf": [
         {
          "$ref": "#/components/schemas/Id"
         },
         {
          "type": "null"
         }
        ]
       },
       "ready_sms": {
        "type": "boolean",
        "description": "The restaurant sends customers its \"order is ready\" SMS when an order becomes ready or goes onto a route –\nnot when the text of the SMS is empty, and not for orders of an application that writes to its customers\nitself.\n",
        "x-description-cs": "Provozovna posílá zákazníkům svou SMS „objednávka je hotová“, když se objednávka stane hotovou nebo\nodjede na trase – ne když je text SMS prázdný a ne u objednávek aplikace, která zákazníkům píše sama.\n"
       }
      }
     },
     "eet": {
      "type": "object",
      "description": "The legacy EET 1.0 settings (the EET 1.0 certificate in the administration), kept for older registers.\n`enabled` – EET 1.0 is on and a certificate is stored; `premises_id` – the EET 1.0 premises number;\n`certificate_valid_to` – when that certificate expires. The certificate itself is never part of this answer.\nEET 2.0 is not set here: the server records the sales itself (`ReceiptEet`, `ReceiptPreview.eet_recorded`).\n",
      "x-description-cs": "Původní nastavení EET 1.0 (certifikát EET 1.0 v administraci), ponechané pro starší pokladny. `enabled` –\nEET 1.0 je zapnuté a certifikát je uložený; `premises_id` – číslo provozovny EET 1.0;\n`certificate_valid_to` – kdy certifikát vyprší. Samotný certifikát v této odpovědi nikdy není. EET 2.0 se\ntu nenastavuje: tržby eviduje server sám (`ReceiptEet`, `ReceiptPreview.eet_recorded`).\n",
      "required": [
       "enabled",
       "premises_id",
       "certificate_valid_to"
      ],
      "properties": {
       "enabled": {
        "type": "boolean"
       },
       "premises_id": {
        "type": [
         "string",
         "null"
        ]
       },
       "certificate_valid_to": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/Timestamp"
         },
         {
          "type": "null"
         }
        ]
       }
      }
     },
     "features": {
      "type": "object",
      "description": "What the licence of the restaurant includes.",
      "x-description-cs": "Co licence provozovny obsahuje.",
      "required": [
       "kitchen",
       "multiple_cash_registers",
       "multiple_kitchen_devices",
       "other_devices",
       "attendance",
       "reservations",
       "lodging",
       "daily_menu",
       "table_map",
       "customer_database"
      ],
      "properties": {
       "kitchen": {
        "type": "boolean",
        "description": "A kitchen display may be used.",
        "x-description-cs": "Smí se používat kuchyňský displej."
       },
       "multiple_cash_registers": {
        "type": "boolean",
        "description": "More than one register may be used.",
        "x-description-cs": "Smí se používat víc než jedna pokladna."
       },
       "multiple_kitchen_devices": {
        "type": "boolean",
        "description": "More than one kitchen display may be used.",
        "x-description-cs": "Smí se používat víc než jeden kuchyňský displej."
       },
       "other_devices": {
        "type": "boolean",
        "description": "More than one register, or a kitchen display, may be used.",
        "x-description-cs": "Smí se používat víc než jedna pokladna, nebo kuchyňský displej."
       },
       "attendance": {
        "type": "boolean",
        "description": "The Attendance module.",
        "x-description-cs": "Modul Docházka."
       },
       "reservations": {
        "type": "boolean",
        "description": "The Reservation system module (the tag *Reservations*).",
        "x-description-cs": "Modul Rezervační systém (skupina *Reservations*)."
       },
       "lodging": {
        "type": "boolean",
        "description": "The Accommodation module – the register may offer charging a bill to a room (`chargeToStay`).",
        "x-description-cs": "Modul Ubytování – pokladna může nabídnout zapsání útraty na pokoj (`chargeToStay`)."
       },
       "daily_menu": {
        "type": "boolean",
        "description": "The daily menu (the API returns the daily menu also without it, see `getDailyMenu`).",
        "x-description-cs": "Denní menu (API denní menu vrací i bez něj, viz `getDailyMenu`)."
       },
       "table_map": {
        "type": "boolean",
        "description": "The map of the restaurant with tables (`rooms`).",
        "x-description-cs": "Mapa provozovny se stoly (`rooms`)."
       },
       "customer_database": {
        "type": "boolean",
        "description": "The customer database.",
        "x-description-cs": "Databáze klientů."
       }
      }
     },
     "paid_until": {
      "description": "The licence is paid until this moment. After it the server first tries to renew the licence from the credit\nof the account; when that fails, operations of the devices of the restaurant answer `403 license_expired`\n(since 26.11.27) – except the device settings, backups, diagnostics and offline receipts issued before this\nmoment. Lock the device on `license_expired` as on the end of `paid_until`.\n",
      "x-description-cs": "Licence je zaplacená do tohoto okamžiku. Po něm server nejdřív zkusí licenci obnovit z kreditu účtu; když to\nnejde, operace zařízení provozovny odpoví `403 license_expired` (od 26.11.27) – kromě nastavení zařízení,\nzáloh, diagnostiky a offline účtenek vystavených před tímto okamžikem. Na `license_expired` zařízení zamkněte\nstejně jako po konci `paid_until`.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "table_ordering": {
      "description": "The rules of ordering from the table (the tag *Table ordering*); `enabled` `false` when it is off.",
      "x-description-cs": "Pravidla objednávání od stolu (skupina *Table ordering*); `enabled` `false`, když je vypnuté.",
      "$ref": "#/components/schemas/TableOrderingSettings"
     },
     "pos": {
      "type": "object",
      "description": "Rules of the register set by the restaurant (Restaurant settings, part Register).",
      "x-description-cs": "Pravidla pokladny, která nastavuje provozovna (Nastavení provozovny, část Pokladna).",
      "required": [
       "receipt_cancel_by",
       "takeaway_only",
       "calculator"
      ],
      "properties": {
       "receipt_cancel_by": {
        "type": "string",
        "enum": [
         "staff",
         "manager"
        ],
        "description": "Who may cancel a receipt (`cancelReceipt`) and change its payment (`changeReceiptPayment`).\n`staff` – any employee with the `pos` role, without the manager's PIN (default, as in API v1);\n`manager` – only a register manager, ask for the manager's PIN (`manager_credential`) first.\n",
        "x-description-cs": "Kdo smí stornovat účtenku (`cancelReceipt`) a změnit její platbu (`changeReceiptPayment`).\n`staff` – kdokoli s rolí `pos`, bez PINu vedoucího (výchozí, jako v API v1);\n`manager` – jen vedoucí pokladny, nejdřív chtějte PIN vedoucího (`manager_credential`).\n"
       },
       "takeaway_only": {
        "type": "boolean",
        "description": "A takeaway-only restaurant (a pizza counter without tables): every receipt and ticket of the register is\n`takeaway` with the packaging fee of the products, also when you send `order_type` `dine_in`. Do not\noffer eating in; preselect takeaway so the price on the display matches the receipt. A kiosk order\n(`createQuote`) with `fulfillment.type` `dine_in` becomes `pickup`, also with packaging.\n",
        "x-description-cs": "Výdejna bez stolů (třeba výdejna pizzy): každá účtenka a bon pokladny je `takeaway` s obalem produktů,\ni když pošlete `order_type` `dine_in`. Jídlo na místě nenabízejte; předvolte s sebou, ať cena na displeji\nsedí s účtenkou. Objednávka kiosku (`createQuote`) s `fulfillment.type` `dine_in` se změní na `pickup`,\ntaké s obalem.\n"
       },
       "calculator": {
        "description": "The Calculator mode of the register – selling without products. `enabled` `false` when it is off.",
        "x-description-cs": "Režim Kalkulačka pokladny – prodej bez produktů. `enabled` `false`, když je vypnutý.",
        "$ref": "#/components/schemas/PosCalculator"
       }
      }
     }
    }
   },
   "PosCalculator": {
    "type": "object",
    "description": "The Calculator mode for shops without a catalog (a bakery, a kiosk): the cashier types a quantity and a price and\ntaps a key of a group („Bakery 12 %“). The register sends an `open_item` line with the key's name and VAT rate and\n`calculator_key_id` (`createReceipt`); any employee with the `pos` role may sell it, no manager's PIN. The line has\nno product – no stock write-off, no kitchen. The owner turns the mode on for the whole restaurant in the\nadministration; there is no switch on the register. When `enabled` is `true`, show the calculator instead of the\ncatalog (the retail PLU mode and the table map are off meanwhile); when it turns `false`, return to what the register\nhad before. Waiter phones stay on the catalog.\n",
    "x-description-cs": "Režim Kalkulačka pro provozovny bez sortimentu (pekárna, stánek): obsluha napíše počet a cenu a klepne na tlačítko\nskupiny („Pečivo 12 %“). Pokladna pošle řádek `open_item` s názvem a sazbou tlačítka a `calculator_key_id`\n(`createReceipt`); prodat ho smí každý s rolí `pos`, bez PINu vedoucího. Řádek nemá produkt – nic se neodepisuje\nze skladu, nic nejde do kuchyně. Režim zapíná majitel pro celou provozovnu v administraci, na pokladně žádný\npřepínač není. Když je `enabled` `true`, ukažte místo sortimentu kalkulačku (režim maloobchod s PLU a mapa stolů\njsou mezitím mimo provoz); když se změní na `false`, vraťte pokladnu k tomu, co měla předtím. Telefony číšníků\nzůstávají na sortimentu.\n",
    "required": [
     "enabled",
     "keys"
    ],
    "properties": {
     "enabled": {
      "type": "boolean",
      "description": "The restaurant turned the mode on and has at least one key – switch the register to the calculator.",
      "x-description-cs": "Provozovna režim zapnula a má aspoň jedno tlačítko – přepněte pokladnu na kalkulačku."
     },
     "keys": {
      "type": "array",
      "maxItems": 6,
      "description": "The keys in the order of the administration (`position`); empty when the mode is off.",
      "x-description-cs": "Tlačítka v pořadí z administrace (`position`); prázdné, když je režim vypnutý.",
      "items": {
       "$ref": "#/components/schemas/PosCalculatorKey"
      }
     }
    }
   },
   "PosCalculatorKey": {
    "type": "object",
    "required": [
     "id",
     "name",
     "vat_rate",
     "color",
     "position"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "maxLength": 32,
      "description": "The group, also the name of the line on the receipt.",
      "x-description-cs": "Skupina, zároveň název řádku na účtence."
     },
     "vat_rate": {
      "$ref": "#/components/schemas/VatRate"
     },
     "color": {
      "type": "string",
      "pattern": "^#[0-9a-f]{6}$",
      "description": "The colour of the key, `#rrggbb`.",
      "x-description-cs": "Barva tlačítka, `#rrggbb`."
     },
     "position": {
      "type": "integer",
      "minimum": 1,
      "description": "The order of the key, from 1.",
      "x-description-cs": "Pořadí tlačítka, od 1."
     }
    }
   },
   "ProductionDevice": {
    "type": "object",
    "required": [
     "id",
     "name",
     "sections",
     "auto_print"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "sections": {
      "type": "string",
      "description": "`all`, `kitchen` (delivery and takeaway) or `bar` (orders on the premises).",
      "x-description-cs": "`all`, `kitchen` (rozvoz a s sebou) nebo `bar` (objednávky na místě).",
      "x-extensible-enum": [
       "all",
       "kitchen",
       "bar"
      ]
     },
     "auto_print": {
      "type": "boolean"
     }
    }
   },
   "Room": {
    "type": "object",
    "required": [
     "id",
     "name",
     "width",
     "height",
     "tables"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "width": {
      "type": "integer",
      "description": "Size of the room on the map; 100 today (positions of tables are in percent).",
      "x-description-cs": "Velikost místnosti na mapě; dnes 100 (poloha stolů je v procentech)."
     },
     "height": {
      "type": "integer",
      "description": "As `width`.",
      "x-description-cs": "Jako `width`."
     },
     "tables": {
      "type": "array",
      "description": "Tables and other items; position and size in whole percent of the room (0–100).",
      "x-description-cs": "Stoly a další předměty; poloha a velikost v celých procentech místnosti (0–100).",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name",
        "kind",
        "code",
        "left",
        "top",
        "width",
        "height"
       ],
       "properties": {
        "id": {
         "description": "Stays the same when the administration saves the map (a table is matched by its ID, otherwise by its\nname); a removed table disappears and a new one gets a new ID. Tabs and kitchen tickets carry only a\ntable name (`table_name`, free text); names of tables on the map are unique in the restaurant.\n",
         "x-description-cs": "Při uložení mapy v administraci zůstává stejné (stůl se páruje podle ID, jinak podle názvu); odebraný\nstůl zmizí a nový dostane nové ID. Účty stolů a kuchyňské bony nesou jen název stolu (`table_name`,\nvolný text); názvy stolů na mapě jsou v provozovně jedinečné.\n",
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string"
        },
        "kind": {
         "type": "string",
         "description": "`table` – a table; `item` – another object on the map.",
         "x-description-cs": "`table` – stůl; `item` – jiný předmět na mapě.",
         "x-extensible-enum": [
          "table",
          "item"
         ]
        },
        "code": {
         "type": [
          "string",
          "null"
         ],
         "description": "The table's code for ordering at the table (its QR code): 8 characters of Crockford base32 (no I, L, O,\nU), unique across Profirest, kept when the table is renamed or moved. `null` for other items and until\nthe restaurant has table codes.\n",
         "x-description-cs": "Kód stolu pro objednávání od stolu (jeho QR kód): 8 znaků Crockford base32 (bez I, L, O, U), jedinečný\nv celém Profirestu, stůl si ho drží i po přejmenování a přesunu. U jiných předmětů a dokud provozovna\nkódy stolů nemá, `null`.\n",
         "pattern": "^[0-9A-HJKMNP-TV-Z]{8}$",
         "examples": [
          "K7M2Q9XB"
         ]
        },
        "left": {
         "type": "integer"
        },
        "top": {
         "type": "integer"
        },
        "width": {
         "type": "integer"
        },
        "height": {
         "type": "integer"
        }
       }
      }
     }
    }
   },
   "EventKitchenTicketData": {
    "type": "object",
    "required": [
     "ticket_id",
     "order_id",
     "status"
    ],
    "properties": {
     "ticket_id": {
      "$ref": "#/components/schemas/Id"
     },
     "order_id": {
      "$ref": "#/components/schemas/Id"
     },
     "status": {
      "type": "string",
      "description": "The status after the change, with the meanings of `KitchenTicket.status`. A status change made through\n`setKitchenTicketStatus` reports the status as an application's order counts it (`Order.status`), which can\ndiffer from the ticket's own – for example `preparing` while stations work on a ticket that is still\n`received`. Read the ticket for its current status.\n",
      "x-description-cs": "Stav po změně s významy jako `KitchenTicket.status`. Změna stavu přes `setKitchenTicketStatus` hlásí stav tak,\njak ho počítá objednávka aplikace (`Order.status`), a ten se může od stavu bonu lišit – třeba `preparing`,\nzatímco stanoviště pracují na bonu, který je ještě `received`. Aktuální stav zjistíte načtením bonu.\n",
      "x-extensible-enum": [
       "received",
       "preparing",
       "ready",
       "out_for_delivery",
       "delivered",
       "not_delivered",
       "cancelled"
      ]
     }
    }
   },
   "EventAttendanceData": {
    "type": "object",
    "required": [
     "employee",
     "state",
     "since"
    ],
    "properties": {
     "employee": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "state": {
      "$ref": "#/components/schemas/AttendanceState"
     },
     "since": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "DirectoryCustomer": {
    "type": "object",
    "description": "A customer of the account as the administration keeps them.",
    "x-description-cs": "Zákazník účtu tak, jak ho vede administrace.",
    "required": [
     "id",
     "name",
     "phone",
     "registered",
     "points",
     "orders"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": [
       "string",
       "null"
      ]
     },
     "phone": {
      "type": [
       "string",
       "null"
      ],
      "description": "As Profirest stores it; Czech numbers usually without `+420`.",
      "x-description-cs": "Jak ho Profirest ukládá; česká čísla obvykle bez `+420`.",
      "examples": [
       "777123456"
      ]
     },
     "registered": {
      "type": "boolean",
      "description": "The customer has an account in the restaurant's e-shop.",
      "x-description-cs": "Zákazník má účet v e-shopu provozovny."
     },
     "points": {
      "type": "integer",
      "description": "Loyalty points.",
      "x-description-cs": "Věrnostní body."
     },
     "orders": {
      "type": "integer",
      "description": "Number of orders the customer made.",
      "x-description-cs": "Počet objednávek zákazníka."
     }
    }
   },
   "DirectoryAddress": {
    "type": "object",
    "required": [
     "id",
     "street",
     "city",
     "location"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "street": {
      "type": "string",
      "description": "Street and number on one line, as stored.",
      "x-description-cs": "Ulice a číslo na jednom řádku, jak je uložená.",
      "examples": [
       "Dlouhá 12"
      ]
     },
     "city": {
      "type": [
       "string",
       "null"
      ]
     },
     "location": {
      "description": "`null` when the address has no coordinates (it cannot be used for delivery as it is).",
      "x-description-cs": "`null`, když adresa nemá souřadnice (pro rozvoz se tak, jak je, použít nedá).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/GeoPoint"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "DirectoryEntry": {
    "type": "object",
    "required": [
     "customer",
     "address"
    ],
    "properties": {
     "customer": {
      "$ref": "#/components/schemas/DirectoryCustomer"
     },
     "address": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/DirectoryAddress"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "CustomerDirectoryList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "maxItems": 10,
      "items": {
       "$ref": "#/components/schemas/DirectoryEntry"
      }
     }
    }
   },
   "CallReport": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "phone"
    ],
    "properties": {
     "phone": {
      "description": "The calling number. Add the country prefix to a national number.",
      "x-description-cs": "Volající číslo. K národnímu číslu doplňte předvolbu země.",
      "$ref": "#/components/schemas/Phone"
     },
     "kind": {
      "type": "string",
      "enum": [
       "incoming",
       "missed"
      ],
      "default": "incoming",
      "description": "`incoming` – the phone is ringing or was answered, `missed` – a missed call.",
      "x-description-cs": "`incoming` – telefon zvoní nebo byl přijat, `missed` – zmeškaný hovor."
     }
    }
   },
   "IncomingCall": {
    "type": "object",
    "description": "A call to the restaurant and who is calling. Also `data` of the event `call.received`.",
    "x-description-cs": "Hovor do provozovny a kdo volá. Také `data` události `call.received`.",
    "required": [
     "phone",
     "kind",
     "received_at",
     "customer",
     "last_address"
    ],
    "properties": {
     "phone": {
      "type": "string",
      "description": "The calling number as Profirest stores it.",
      "x-description-cs": "Volající číslo, jak ho Profirest ukládá."
     },
     "kind": {
      "type": "string",
      "description": "`incoming` – the phone is ringing or was answered; `missed` – a missed call (as reported in `CallReport.kind`).",
      "x-description-cs": "`incoming` – telefon zvoní nebo byl přijat; `missed` – zmeškaný hovor (jak ho hlásí `CallReport.kind`).",
      "x-extensible-enum": [
       "incoming",
       "missed"
      ]
     },
     "received_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "customer": {
      "description": "The customer with this number; `null` when the account does not know it. `reportCall` first adds an unknown\nnumber to the account's customers, so its answer always has a customer.\n",
      "x-description-cs": "Zákazník s tímto číslem; `null`, když ho účet nezná. `reportCall` neznámé číslo nejdřív přidá mezi zákazníky\núčtu, takže jeho odpověď zákazníka má vždy.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/DirectoryCustomer"
       },
       {
        "type": "null"
       }
      ]
     },
     "last_address": {
      "description": "Address of the customer's last delivery from this restaurant; `null` when there was none.",
      "x-description-cs": "Adresa posledního rozvozu zákazníkovi z této provozovny; `null`, když žádný nebyl.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/DirectoryAddress"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "LatestCall": {
    "type": "object",
    "required": [
     "call"
    ],
    "properties": {
     "call": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/IncomingCall"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "SuggestedAddress": {
    "type": "object",
    "description": "Address parts as `AddressInput` takes them.",
    "x-description-cs": "Části adresy tak, jak je bere `AddressInput`.",
    "required": [
     "street",
     "house_number",
     "city",
     "postal_code",
     "country"
    ],
    "properties": {
     "street": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "Jeseniova"
      ]
     },
     "house_number": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "1196/52"
      ]
     },
     "city": {
      "type": "string",
      "examples": [
       "Praha 3"
      ]
     },
     "postal_code": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "130 00"
      ]
     },
     "country": {
      "type": "string",
      "examples": [
       "CZ"
      ]
     }
    }
   },
   "AddressSuggestion": {
    "type": "object",
    "required": [
     "label",
     "address",
     "location",
     "zone"
    ],
    "properties": {
     "label": {
      "type": "string",
      "description": "The address on one line as the map service writes it.",
      "x-description-cs": "Adresa na jednom řádku, jak ji píše mapová služba.",
      "examples": [
       "Jeseniova 1196/52, Praha 3"
      ]
     },
     "address": {
      "$ref": "#/components/schemas/SuggestedAddress"
     },
     "location": {
      "$ref": "#/components/schemas/GeoPoint"
     },
     "zone": {
      "type": "object",
      "required": [
       "id",
       "name",
       "fee",
       "minimum_order",
       "express_fee"
      ],
      "properties": {
       "id": {
        "$ref": "#/components/schemas/Id"
       },
       "name": {
        "type": "string"
       },
       "fee": {
        "$ref": "#/components/schemas/Money"
       },
       "minimum_order": {
        "$ref": "#/components/schemas/Money"
       },
       "express_fee": {
        "description": "The surcharge for express delivery; `null` when the zone does not offer it.",
        "x-description-cs": "Příplatek za expresní doručení; `null`, když ho zóna nenabízí.",
        "anyOf": [
         {
          "$ref": "#/components/schemas/Money"
         },
         {
          "type": "null"
         }
        ]
       }
      }
     }
    }
   },
   "AddressSuggestionList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "maxItems": 8,
      "items": {
       "$ref": "#/components/schemas/AddressSuggestion"
      }
     }
    }
   },
   "ReceiptPreviewRequest": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "items"
    ],
    "properties": {
     "issued_at": {
      "description": "Price at this moment; now when left out.",
      "x-description-cs": "Spočítat v tomto okamžiku; bez něj teď.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "offline": {
      "type": "boolean",
      "default": false,
      "description": "Price it as a receipt recorded offline (`ReceiptCreate.offline`).",
      "x-description-cs": "Spočítat jako účtenku pořízenou offline (`ReceiptCreate.offline`)."
     },
     "order_type": {
      "type": "string",
      "enum": [
       "dine_in",
       "takeaway"
      ],
      "default": "dine_in",
      "description": "As `ReceiptCreate.order_type`.",
      "x-description-cs": "Jako `ReceiptCreate.order_type`."
     },
     "manager_credential": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/StaffCredential"
       },
       {
        "type": "null"
       }
      ]
     },
     "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 300,
      "items": {
       "$ref": "#/components/schemas/ReceiptItemInput"
      }
     },
     "discounts": {
      "type": "array",
      "maxItems": 5,
      "items": {
       "$ref": "#/components/schemas/ReceiptDiscountInput"
      }
     }
    }
   },
   "ReceiptCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "number",
     "issued_at",
     "items",
     "payments"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the receipt, made on the device.",
      "x-description-cs": "Vaše UUID účtenky vytvořené na zařízení."
     },
     "number": {
      "type": "integer",
      "minimum": 1,
      "maximum": 2147483647,
      "description": "The receipt number from the register's own counter. It is printed on the receipt, shown in the administration\nand sent to EET 2.0 as the sequence number. Numbers of different devices may repeat; a number the device already\nused answers `409 receipt_number_conflict` with `existing_id` (in EET 2.0 two such receipts would be one sale).\n",
      "x-description-cs": "Číslo účtenky z vlastního počítadla pokladny. Tiskne se na účtenku, ukazuje v administraci a do EET 2.0 jde\njako pořadové číslo. Čísla různých zařízení se mohou opakovat; číslo, které zařízení už použilo, vrátí\n`409 receipt_number_conflict` s `existing_id` (v EET 2.0 by z obou účtenek byla jedna tržba).\n"
     },
     "issued_at": {
      "description": "When the receipt was paid (device clock). At most 7 days ago (recorded offline 62 days) and 5 minutes ahead.",
      "x-description-cs": "Kdy byla účtenka zaplacena (hodiny zařízení). Nejvýš 7 dní zpět (pořízená offline 62 dní) a 5 minut napřed.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "offline": {
      "type": "boolean",
      "default": false,
      "description": "Recorded while offline – the prices the register charged are kept (see `price_differences`).",
      "x-description-cs": "Pořízeno offline – ponechají se ceny, které pokladna účtovala (viz `price_differences`)."
     },
     "issued_by_id": {
      "description": "Only without a staff session (an offline receipt) – the employee who issued it. The receipt answers it as\n`issued_by` (the employee object). Since 26.11.27 also an employee of the account deleted or removed from the\nrestaurant meanwhile (they took the money while still working here); the action timeline of the\nadministration notes it.\n",
      "x-description-cs": "Jen bez relace zaměstnance (offline účtenka) – kdo ji vystavil. Účtenka ho vrací jako `issued_by` (objekt\nzaměstnance). Od 26.11.27 i zaměstnanec účtu, kterého mezitím smazali nebo odebrali z provozovny (peníze\nvybral, když tu ještě pracoval); Časová osa akcí v administraci to zaznamená.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "approved_by_id": {
      "description": "Only on an offline receipt – the register manager who approved manual discounts or prices on the device (the receipt answers it as `approved_by`). Without `approval_signature` it is only what the device says – the receipt goes to the action timeline of the administration and it is not enough for a voucher sold below its value. Send it only when a manager really approved on the device. Since 26.11.27 an offline receipt with manual discounts or open items and no manager is accepted too (the money was taken already) – the timeline marks it „without a manager's approval“; never send the first manager of the list instead.",
      "x-description-cs": "Jen u offline účtenky – vedoucí pokladny, který na zařízení schválil ruční slevu nebo cenu (účtenka ho vrací jako `approved_by`). Bez `approval_signature` je to jen údaj zařízení – účtenka jde do Časové osy akcí v administraci a na voucher pod hodnotou nestačí. Posílejte ho, jen když vedoucí na zařízení opravdu schválil. Od 26.11.27 se přijme i offline účtenka s ruční slevou nebo vlastní položkou bez vedoucího (peníze jsou vybrané) – Časová osa ji označí „bez schválení vedoucího“; nikdy místo toho neposílejte prvního vedoucího ze seznamu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "approval_signature": {
      "description": "Only with `offline` and `approved_by_id` – the approval signed with a key from the manager's PIN (see\n`OfflineApproval`). When it matches, the approval counts as verified; when it does not, the receipt is still\naccepted (it was already paid) and the timeline shows the approval as unverified. Otherwise `422`.\n",
      "x-description-cs": "Jen s `offline` a `approved_by_id` – schválení podepsané klíčem z PINu vedoucího (viz `OfflineApproval`).\nKdyž sedí, schválení platí jako ověřené; když nesedí, účtenka se přesto přijme (už je zaplacená) a Časová\nosa ukáže schválení jako neověřené. Jinak `422`.\n",
      "anyOf": [
       {
        "type": "string",
        "pattern": "^[A-Za-z0-9_-]{43}$"
       },
       {
        "type": "null"
       }
      ]
     },
     "manager_credential": {
      "description": "PIN or card of a register manager approving manual discounts or prices now.",
      "x-description-cs": "PIN nebo čip vedoucího pokladny, který teď schvaluje ruční slevu nebo cenu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/StaffCredential"
       },
       {
        "type": "null"
       }
      ]
     },
     "opened_at": {
      "description": "When the table or the bill was opened; `issued_at` when left out.",
      "x-description-cs": "Kdy se stůl nebo účet otevřel; bez něj `issued_at`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "opened_by_id": {
      "description": "Who opened the table; the issuer when left out.",
      "x-description-cs": "Kdo stůl otevřel; bez něj ten, kdo účtenku vystavil.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "table_name": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64
     },
     "order_type": {
      "type": "string",
      "enum": [
       "dine_in",
       "takeaway"
      ],
      "default": "dine_in",
      "description": "`dine_in` (default) – eaten at the restaurant; `takeaway` – taken away: every product line adds the packaging\nfee of the product (`packaging_unit_price`). The VAT rate is the same for both. A receipt sent to the kitchen\nshows there as `dine_in` or `takeaway`. A takeaway-only restaurant (`getDeviceSettings`,\n`pos.takeaway_only`) is always `takeaway`, also when you send `dine_in`.\n",
      "x-description-cs": "`dine_in` (výchozí) – na místě; `takeaway` – s sebou: každý řádek produktu připočte obal produktu\n(`packaging_unit_price`). Sazba DPH je v obou případech stejná. Účtenka poslaná do kuchyně se tam ukáže jako\n`dine_in` nebo `takeaway`. Výdejna bez stolů (`getDeviceSettings`, `pos.takeaway_only`) je vždy `takeaway`,\ni když pošlete `dine_in`.\n"
     },
     "customer_id": {
      "description": "A customer from `searchCustomerDirectory`; earns loyalty points (1 point per whole crown, vouchers sold excluded).",
      "x-description-cs": "Zákazník ze `searchCustomerDirectory`; získá věrnostní body (1 bod za celou korunu, bez prodaných voucherů).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 500
     },
     "tab_id": {
      "type": [
       "string",
       "null"
      ],
      "format": "uuid",
      "description": "The open tab this receipt pays; it is closed together with the receipt (`409 tab_closed` when already closed,\n`422` with `not_found` when there is no such tab). Send `tab_version` with it. The receipt charges everything\non the tab – every product, variant and add-on at least in the tab's quantity. A receipt charging less closes\nthe tab only with a register manager verified now (signed in or `manager_credential`, otherwise\n`403 manager_approval_required`) and the table log says what was missing; remove the lines you do not charge\nfrom the tab first. A late receipt – recorded offline, or issued more than 10 minutes before it arrives – was\nalready paid, so the tab never stops it: an unknown tab is ignored, and a late receipt charging less leaves\nthe tab open with a note in the table log.\n",
      "x-description-cs": "Otevřený účet stolu, který účtenka platí; uzavře se spolu s ní (`409 tab_closed`, když už je uzavřený, `422`\ns `not_found`, když takový účet není). Pošlete k němu `tab_version`. Účtenka účtuje všechno z účtu – každý\nprodukt, variantu i přílohu aspoň v množství z účtu. Účtenka na méně účet zavře jen s vedoucím pokladny\nověřeným teď (přihlášený nebo `manager_credential`, jinak `403 manager_approval_required`) a do logu stolu se\nzapíše, co chybělo; položky, které neúčtujete, z účtu nejdřív odeberte. Opožděná účtenka – pořízená offline,\nnebo vystavená víc než 10 minut před tím, než dorazí – je už zaplacená, a tak ji účet nikdy nezastaví:\nneznámý účet se přejde a opožděná účtenka na méně nechá účet otevřený s upozorněním v logu stolu.\n"
     },
     "tab_version": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 1,
      "description": "The `version` of the tab you charged, required with `tab_id`. When another device changed the tab meanwhile\n(for example added items), the answer is `412 precondition_failed` and nothing is issued – read the tab again\nand charge it all. A late receipt (see `tab_id`) was already paid, so it is always issued: a tab changed\nmeanwhile stays open, a closed one stays closed, and the table log in the administration gets a note to check\nit.\n",
      "x-description-cs": "`version` účtu, který jste účtovali; s `tab_id` povinné. Když účet mezitím změnilo jiné zařízení (například\npřidalo položky), odpověď je `412 precondition_failed` a nic se nevystaví – načtěte účet znovu a účtujte celý.\nOpožděná účtenka (viz `tab_id`) je už zaplacená, proto se vystaví vždy: účet změněný mezitím zůstane\notevřený, uzavřený zůstane uzavřený a do logu stolu v administraci se zapíše upozornění ke kontrole.\n"
     },
     "send_to_kitchen": {
      "type": "boolean",
      "default": false,
      "description": "Also send the paid receipt to the kitchen queue (counter service). Ignored when the restaurant has no kitchen display.",
      "x-description-cs": "Zaplacenou účtenku poslat i do fronty kuchyně (výdej u pultu). Bez kuchyňského displeje se ignoruje."
     },
     "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 300,
      "items": {
       "$ref": "#/components/schemas/ReceiptItemInput"
      }
     },
     "discounts": {
      "type": "array",
      "maxItems": 5,
      "description": "Discounts on the whole receipt, applied after the item discounts. Vouchers sold are never discounted.",
      "x-description-cs": "Slevy na celou účtenku, po slevách položek. Prodané vouchery se nikdy nezlevňují.",
      "items": {
       "$ref": "#/components/schemas/ReceiptDiscountInput"
      }
     },
     "payments": {
      "type": "array",
      "maxItems": 10,
      "description": "How the receipt was paid; they add up to `totals.total`. Empty only for a receipt of zero.",
      "x-description-cs": "Jak se účtenka zaplatila; dávají dohromady `totals.total`. Prázdné jen u účtenky na nulu.",
      "items": {
       "$ref": "#/components/schemas/ReceiptPaymentInput"
      }
     }
    }
   },
   "ReceiptItemInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "quantity"
    ],
    "properties": {
     "type": {
      "type": "string",
      "enum": [
       "product",
       "open_item",
       "voucher_sale"
      ],
      "default": "product",
      "description": "`product` – from the register catalog; `open_item` – a name, price and VAT rate typed on the register (manager\nonly, or anybody with `calculator_key_id`); `voucher_sale` – selling a gift voucher by its code (outside VAT).\n",
      "x-description-cs": "`product` – ze sortimentu pokladny; `open_item` – název, cena a sazba DPH zadané na pokladně (jen vedoucí,\nnebo kdokoli s `calculator_key_id`); `voucher_sale` – prodej dárkového voucheru podle kódu (mimo DPH).\n"
     },
     "product_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "variant": {
      "type": "string",
      "enum": [
       "full",
       "half"
      ],
      "default": "full",
      "description": "`full` (default) – a whole portion; `half` – a half portion at `Product.pos.half_price` (the half price applies\nalso with `at_employee_price`); a product not sold in halves answers `422` with `not_allowed`.\n",
      "x-description-cs": "`full` (výchozí) – celá porce; `half` – polovina za `Product.pos.half_price` (cena půlky platí\ni s `at_employee_price`); produkt, který se po půlkách neprodává, odpoví `422` s `not_allowed`.\n"
     },
     "quantity": {
      "type": "number",
      "exclusiveMinimum": 0,
      "maximum": 9999,
      "multipleOf": 0.001,
      "description": "Pieces; decimals for items sold by weight.",
      "x-description-cs": "Kusy; desetinná čísla u položek na váhu."
     },
     "unit_price": {
      "description": "The price per unit the register charged, without add-ons and packaging. Leave out for the catalog price; for\n`voucher_sale` for the value of the voucher (since 26.11.26 – before it was required).\n",
      "x-description-cs": "Cena za kus, kterou pokladna účtovala, bez příloh a obalu. Vynechte pro cenu ze sortimentu; u `voucher_sale`\npro hodnotu voucheru (od 26.11.26 – dřív byla povinná).\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/MoneyInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "at_employee_price": {
      "type": "boolean",
      "default": false,
      "description": "Sold at the employee price (`PosProductInfo.employee_price`).",
      "x-description-cs": "Prodáno za cenu pro zaměstnance (`PosProductInfo.employee_price`)."
     },
     "ordered_at": {
      "description": "When the guest ordered the item – for items of an open table (`ordered_at` of the tab line). The price, the\navailability and the portions of the item are taken at that time, so a daily menu ordered in its time can be\npaid after it. At most 24 hours before `issued_at`; leave out for items ordered at payment. With `tab_id` it must\nbe the `ordered_at` of a line of that tab with the same product (otherwise `invalid_value`); an online receipt\nwithout a tab on the server ignores it (the payment time counts), an offline receipt may send it.\n",
      "x-description-cs": "Kdy host položku objednal – u položek otevřeného stolu (`ordered_at` řádku účtu). Cena, dostupnost a porce\npoložky se berou k tomuto okamžiku, takže denní menu objednané v jeho čase jde zaplatit i po něm. Nejvýš 24 hodin\npřed `issued_at`; u položek objednaných při placení vynechte. S `tab_id` to musí být `ordered_at` některého\nřádku toho účtu se stejným produktem (jinak `invalid_value`); online účtenka bez účtu na serveru ho nebere\n(platí čas zaplacení), offline účtenka ho poslat smí.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 128,
      "description": "Only for `open_item`.",
      "x-description-cs": "Jen u `open_item`."
     },
     "vat_rate": {
      "description": "Only for `open_item`.",
      "x-description-cs": "Jen u `open_item`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/VatRate"
       },
       {
        "type": "null"
       }
      ]
     },
     "calculator_key_id": {
      "description": "Only for `open_item` in the Calculator mode: the key of the group the line was sold with\n(`getDeviceSettings`, `pos.calculator.keys[].id`). Send `name` and `vat_rate` of the key as printed. Such a\nline needs no manager (`price_source` `calculator`) while the restaurant has the mode on; a late or offline\nreceipt is accepted also after the key was deleted or the mode turned off. The VAT rate of a key never changes\n(a new rate in the administration creates a new key), so a queued receipt keeps matching its key. `not_found` –\nnot a key of this restaurant; `calculator_key_mismatch` at `vat_rate` – the key has another VAT rate.\n",
      "x-description-cs": "Jen u `open_item` v režimu Kalkulačka: tlačítko skupiny, kterým se řádek prodal (`getDeviceSettings`,\n`pos.calculator.keys[].id`). `name` a `vat_rate` pošlete z tlačítka tak, jak se vytiskly. Takový řádek\nnepotřebuje vedoucího (`price_source` `calculator`), dokud má provozovna režim zapnutý; opožděná nebo offline\núčtenka se přijme i po smazání tlačítka nebo vypnutí režimu. Sazba tlačítka se nikdy nemění (jiná sazba\nv administraci založí nové tlačítko), takže účtenka z fronty ke svému tlačítku pořád sedí. `not_found` – tlačítko\nprovozovny není; `calculator_key_mismatch` u `vat_rate` – tlačítko má jinou sazbu.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "voucher_code": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "description": "Only for `voucher_sale`.",
      "x-description-cs": "Jen u `voucher_sale`."
     },
     "add_ons": {
      "type": "array",
      "maxItems": 20,
      "items": {
       "$ref": "#/components/schemas/ReceiptAddOnInput"
      }
     },
     "removed_ingredient_ids": {
      "type": "array",
      "maxItems": 30,
      "uniqueItems": true,
      "description": "Only for `product`: ingredients the guest removed – `Product.removable_ingredients[].id` of the product, each at\nmost once (`ingredient_not_removable` otherwise). The price does not change; the stock does not write them off\nand the kitchen ticket of the receipt shows them.\n",
      "x-description-cs": "Jen u `product`: suroviny, které host odebral – `Product.removable_ingredients[].id` produktu, každá nejvýš\njednou (jinak `ingredient_not_removable`). Cena se nemění; sklad je neodepíše a kuchyňský bon účtenky je\nukáže.\n",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32
     },
     "course": {
      "type": "integer",
      "minimum": 0,
      "maximum": 20,
      "default": 0,
      "description": "Course number for the kitchen.",
      "x-description-cs": "Číslo chodu pro kuchyň."
     },
     "discount": {
      "description": "Discount of this item, from the price of the product only (not add-ons or packaging).",
      "x-description-cs": "Sleva této položky, jen z ceny produktu (ne z příloh a obalu).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ReceiptDiscountInput"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReceiptAddOnInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "product_id"
    ],
    "properties": {
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "unit_price": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/MoneyInput"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReceiptDiscountInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "type"
    ],
    "description": "A discount: `percent` with `value`, or `amount` with `amount` in the currency of the restaurant. On an item the\ndiscount is for the whole line – a percent of the item's price × quantity, rounded half up to minor units, or\nthe amount itself (at most the item's price × quantity); the item's add-ons and packaging are not discounted. On\nthe whole receipt it is taken from the total after the item discounts, add-ons and packaging included (vouchers\nsold never). A percent above 100 or an amount above its base is `422` with `too_large` – nothing is cut down\nsilently; `value` with `amount`, or the other way round, is `422` too.\n",
    "x-description-cs": "Sleva: `percent` s `value`, nebo `amount` s `amount` v měně provozovny. U položky platí pro celý řádek – procento\nz ceny položky × množství zaokrouhlené matematicky na nejmenší jednotky, nebo přímo částka (nejvýš cena položky\n× množství); přílohy a obal položky se nezlevňují. Na celou účtenku se počítá z částky po slevách položek včetně\npříloh a obalů (prodané vouchery nikdy). Procenta nad 100 nebo částka nad základem jsou `422` s `too_large` – nic\nse tiše neořezává; `value` u částky nebo `amount` u procent je také `422`.\n",
    "properties": {
     "type": {
      "type": "string",
      "enum": [
       "percent",
       "amount"
      ],
      "description": "`percent` – `value` percent; `amount` – the fixed `amount`.",
      "x-description-cs": "`percent` – `value` procent; `amount` – pevná částka `amount`."
     },
     "value": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "description": "Percent (1–100), only with `type` `percent`.",
      "x-description-cs": "Procenta (1–100), jen u `type` `percent`."
     },
     "amount": {
      "$ref": "#/components/schemas/MoneyInput",
      "description": "The discount, only with `type` `amount`; at least one minor unit.",
      "x-description-cs": "Výše slevy, jen u `type` `amount`; aspoň jedna nejmenší jednotka."
     },
     "method": {
      "type": "string",
      "enum": [
       "manual",
       "automatic"
      ],
      "default": "manual",
      "description": "`manual` (default) – entered by an employee; needs a register manager. `automatic` – applied by a rule of the\nregister (for example a happy hour). The server does not check the rule: any employee may send `automatic`,\nand the administration shows it as an automatic discount.\n",
      "x-description-cs": "`manual` (výchozí) – zadal ji zaměstnanec; potřebuje vedoucího pokladny. `automatic` – použilo ji pravidlo\npokladny (například happy hour). Server pravidlo nekontroluje: `automatic` smí poslat kterýkoli zaměstnanec\na administrace ji ukáže jako automatickou slevu.\n"
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64
     }
    }
   },
   "ReceiptPaymentInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "method",
     "amount"
    ],
    "properties": {
     "method": {
      "type": "string",
      "enum": [
       "cash",
       "card",
       "meal_voucher",
       "company_account",
       "invoice",
       "voucher"
      ],
      "description": "`cash`; `card` (with `terminal` from the card terminal); `meal_voucher` – meal vouchers; `company_account` –\ncharged to the account of a company; `invoice` – paid by an invoice (`reference`); `voucher` – a gift voucher\nby its code (`voucher_code`). A tip only with `cash` or `card`, `tendered` only with `cash`. EET 2.0 records\nthe cash, card, meal voucher and gift voucher payments, not company account and invoice payments.\n",
      "x-description-cs": "`cash` – hotově; `card` – kartou (s `terminal` z platebního terminálu); `meal_voucher` – stravenky;\n`company_account` – na účet firmy; `invoice` – fakturou (`reference`); `voucher` – dárkový voucher podle kódu\n(`voucher_code`). Dýško jen u `cash` nebo `card`, `tendered` jen u `cash`. EET 2.0 eviduje platby hotově,\nkartou, stravenkami a dárkovými vouchery, ne platby na firemní účet a fakturou.\n"
     },
     "amount": {
      "description": "The part of the receipt this payment covers, without the tip. With cash, after rounding.",
      "x-description-cs": "Kolik z účtenky tato platba hradí, bez dýška. U hotovosti po zaokrouhlení.",
      "$ref": "#/components/schemas/MoneyInput"
     },
     "tip": {
      "description": "Tip paid with this payment (cash or card only).",
      "x-description-cs": "Dýško zaplacené s touto platbou (jen hotově nebo kartou).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/MoneyInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "tip_source": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "not_requested",
       "terminal_confirmed",
       "request_fallback",
       "recovered_from_context",
       "unresolved_manual_required",
       null
      ],
      "description": "How the register obtained the tip, in the register application's own terms (`not_requested`,\n`terminal_confirmed`, `request_fallback`, `recovered_from_context`, `unresolved_manual_required`). The server\ndoes not interpret it: it keeps the first value of the receipt with the order in the administration\n(`not_requested` when no payment sends one) and never returns it.\n",
      "x-description-cs": "Jak pokladna k dýšku přišla, slovy samotné aplikace pokladny (`not_requested`, `terminal_confirmed`,\n`request_fallback`, `recovered_from_context`, `unresolved_manual_required`). Server hodnotu nevykládá: první\nhodnotu účtenky uloží k objednávce v administraci (`not_requested`, když ji žádná platba nepošle) a nikdy ji\nnevrací.\n"
     },
     "tendered": {
      "description": "Cash received from the customer, to compute the change.",
      "x-description-cs": "Hotovost přijatá od zákazníka, pro výpočet vrácení.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/MoneyInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "voucher_code": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "description": "Only for `voucher`.",
      "x-description-cs": "Jen u `voucher`."
     },
     "reference": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 128,
      "description": "For example the invoice number or the company.",
      "x-description-cs": "Například číslo faktury nebo firma."
     },
     "terminal": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/TerminalPaymentInput"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "TerminalPaymentInput": {
    "type": "object",
    "description": "The card terminal's record of the payment, as the terminal returned it – only with `card`. The server keeps it\nwith the receipt for the administration and does not check it (send only approved payments); `provider`,\n`transaction_id`, `card_number_masked` and `auth_code` come back in `ReceiptPayment.terminal`. A\n`transaction_id` that is already stored is not stored again; the receipt is issued anyway.\n",
    "x-description-cs": "Záznam platby z platebního terminálu, jak ho terminál vrátil – jen u `card`. Server ho uloží k účtence pro\nadministraci a nekontroluje ho (posílejte jen schválené platby); `provider`, `transaction_id`,\n`card_number_masked` a `auth_code` se vracejí v `ReceiptPayment.terminal`. `transaction_id`, který už uložený je,\nse znovu neuloží; účtenka se vystaví i tak.\n",
    "additionalProperties": false,
    "required": [
     "provider",
     "transaction_id"
    ],
    "properties": {
     "provider": {
      "type": "string",
      "minLength": 1,
      "maxLength": 50,
      "description": "The provider of the card terminal, as the register names it.",
      "x-description-cs": "Poskytovatel platebního terminálu, jak ho pojmenovává pokladna."
     },
     "transaction_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255,
      "description": "The terminal's ID of the transaction.",
      "x-description-cs": "ID transakce z terminálu."
     },
     "terminal_id": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 100,
      "description": "The ID of the terminal.",
      "x-description-cs": "ID terminálu."
     },
     "response_code": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 10,
      "description": "The response code of the terminal.",
      "x-description-cs": "Kód odpovědi terminálu."
     },
     "response_message": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 2000,
      "description": "The response text of the terminal.",
      "x-description-cs": "Text odpovědi terminálu."
     },
     "card_number_masked": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 20,
      "description": "The masked card number, as the terminal gave it.",
      "x-description-cs": "Maskované číslo karty, jak ho dal terminál."
     },
     "auth_code": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 50,
      "description": "The authorization code of the payment.",
      "x-description-cs": "Autorizační kód platby."
     },
     "aid": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 100,
      "description": "The application identifier of the card (EMV AID).",
      "x-description-cs": "Identifikátor aplikace karty (EMV AID)."
     },
     "app_label": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 100,
      "description": "The label of the card application, for example `VISA`.",
      "x-description-cs": "Označení aplikace karty, například `VISA`."
     },
     "acquirer_terminal_id": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 100,
      "description": "The ID of the terminal at the acquiring bank.",
      "x-description-cs": "ID terminálu u banky příjemce."
     },
     "merchant_id": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 100,
      "description": "The merchant ID at the acquiring bank.",
      "x-description-cs": "ID obchodníka u banky příjemce."
     },
     "sequence_number": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 50,
      "description": "The sequence number of the transaction at the terminal.",
      "x-description-cs": "Pořadové číslo transakce v terminálu."
     },
     "terminal_time": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 50,
      "description": "The time of the transaction as the terminal wrote it (free text, not parsed).",
      "x-description-cs": "Čas transakce, jak ho zapsal terminál (volný text, nezpracovává se)."
     },
     "card_input_type": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 50,
      "description": "How the card was read (for example contactless or chip), as the terminal wrote it.",
      "x-description-cs": "Jak se karta načetla (například bezkontaktně nebo čipem), jak to zapsal terminál."
     }
    }
   },
   "KitchenTicketCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "items"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the ticket, made on the device.",
      "x-description-cs": "Vaše UUID bonu vytvořené na zařízení."
     },
     "table_name": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32
     },
     "order_type": {
      "type": "string",
      "enum": [
       "dine_in",
       "takeaway"
      ],
      "default": "dine_in",
      "description": "`dine_in` (default) or `takeaway` – only marks the ticket (`KitchenTicket.fulfillment`); a ticket has no prices or packaging. A takeaway-only restaurant (`pos.takeaway_only`) is always `takeaway`.",
      "x-description-cs": "`dine_in` (výchozí) nebo `takeaway` – jen označí bon (`KitchenTicket.fulfillment`); bon nemá ceny ani obaly. Výdejna bez stolů (`pos.takeaway_only`) je vždy `takeaway`."
     },
     "preorder_at": {
      "description": "When the ticket is due – a table ordered ahead. `null` or missing means now, a time in the past too; at most 7 days\nahead. Due more than 2 hours ahead, the ticket waits in `view=preorders` of the kitchen display.\n",
      "x-description-cs": "Kdy má být bon hotový – stůl objednaný dopředu. `null`, chybějící i čas v minulosti znamená teď; nejvýš 7 dní\ndopředu. S termínem víc než 2 hodiny dopředu čeká bon ve `view=preorders` kuchyňského displeje.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 500
     },
     "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 100,
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "product_id",
        "quantity"
       ],
       "properties": {
        "product_id": {
         "$ref": "#/components/schemas/Id"
        },
        "variant": {
         "type": "string",
         "enum": [
          "full",
          "half"
         ],
         "default": "full"
        },
        "quantity": {
         "type": "number",
         "exclusiveMinimum": 0,
         "maximum": 9999,
         "multipleOf": 0.001
        },
        "add_ons": {
         "type": "array",
         "maxItems": 20,
         "items": {
          "type": "object",
          "additionalProperties": false,
          "required": [
           "product_id"
          ],
          "properties": {
           "product_id": {
            "$ref": "#/components/schemas/Id"
           }
          }
         }
        },
        "removed_ingredient_ids": {
         "type": "array",
         "maxItems": 30,
         "uniqueItems": true,
         "description": "Ingredients the guest removed – `Product.removable_ingredients[].id` of the product in the `pos` catalog,\neach at most once (`ingredient_not_removable` otherwise); the kitchen shows them at the dish.\n",
         "x-description-cs": "Suroviny, které host odebral – `Product.removable_ingredients[].id` produktu v sortimentu `pos`, každá\nnejvýš jednou (jinak `ingredient_not_removable`); kuchyň je ukáže u jídla.\n",
         "items": {
          "$ref": "#/components/schemas/Id"
         }
        },
        "note": {
         "type": [
          "string",
          "null"
         ],
         "maxLength": 32
        },
        "course": {
         "type": "integer",
         "minimum": 0,
         "maximum": 20,
         "default": 0
        }
       }
      }
     }
    }
   },
   "TabInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "table_name",
     "items"
    ],
    "properties": {
     "table_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 32
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 500
     },
     "items": {
      "type": "array",
      "maxItems": 300,
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "id",
        "product_id",
        "quantity"
       ],
       "properties": {
        "id": {
         "type": "string",
         "minLength": 1,
         "maxLength": 36,
         "description": "Your stable ID of the line, so that devices can merge changes.",
         "x-description-cs": "Vaše stálé ID řádku, aby zařízení mohla slučovat změny."
        },
        "product_id": {
         "$ref": "#/components/schemas/Id"
        },
        "variant": {
         "type": "string",
         "enum": [
          "full",
          "half"
         ],
         "default": "full"
        },
        "quantity": {
         "type": "number",
         "exclusiveMinimum": 0,
         "maximum": 9999,
         "multipleOf": 0.001
        },
        "add_ons": {
         "type": "array",
         "maxItems": 20,
         "items": {
          "type": "object",
          "additionalProperties": false,
          "required": [
           "product_id"
          ],
          "properties": {
           "product_id": {
            "$ref": "#/components/schemas/Id"
           }
          }
         }
        },
        "removed_ingredient_ids": {
         "type": "array",
         "maxItems": 30,
         "uniqueItems": true,
         "description": "Ingredients the guest removed – `Product.removable_ingredients[].id` of the product in the `pos` catalog,\neach at most once (`ingredient_not_removable` otherwise). Send them again with every `putTab`; a line\nwith another set is a changed line (`TabLine`).\n",
         "x-description-cs": "Suroviny, které host odebral – `Product.removable_ingredients[].id` produktu v sortimentu `pos`, každá\nnejvýš jednou (jinak `ingredient_not_removable`). Posílejte je znovu s každým `putTab`; řádek s jinými\nje změněný řádek (`TabLine`).\n",
         "items": {
          "$ref": "#/components/schemas/Id"
         }
        },
        "note": {
         "type": [
          "string",
          "null"
         ],
         "maxLength": 32
        },
        "course": {
         "type": "integer",
         "minimum": 0,
         "maximum": 20,
         "default": 0
        },
        "sent_to_kitchen": {
         "type": "boolean",
         "default": false,
         "description": "The line was already sent to the kitchen (`createKitchenTicket`).",
         "x-description-cs": "Řádek už šel do kuchyně (`createKitchenTicket`)."
        }
       }
      }
     },
     "moved_line_ids": {
      "type": "array",
      "maxItems": 300,
      "description": "IDs of lines you took off this tab, or lowered, because they moved to another tab: the whole quantity removed\nfrom such a line is not recorded as cancelled. Otherwise pieces removed from a line already sent to the\nkitchen are recorded as cancelled items (storno) in the shift close of the administration, like today's\nregister does. The server does not check that the lines appear on another tab – `moveTabLines` moves lines in\none step and keeps their price and `ordered_at`.\n",
      "x-description-cs": "ID řádků, které jste z účtu sundali nebo snížili, protože se přesunuly na jiný účet: celé množství odebrané\nz takového řádku se nezapíše jako storno. Jinak se kusy odebrané z řádku, který už šel do kuchyně, zapíšou jako\nstorno položek do uzávěrky v administraci, stejně jako u dnešní pokladny. Server nekontroluje, že řádky jsou\nna jiném účtu – `moveTabLines` přesune řádky v jednom kroku i s cenou a `ordered_at`.\n",
      "items": {
       "type": "string",
       "minLength": 1,
       "maxLength": 36
      }
     }
    }
   },
   "TabMoveInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "target_tab_id",
     "lines"
    ],
    "properties": {
     "target_tab_id": {
      "type": "string",
      "format": "uuid",
      "description": "The tab the lines move to – an open tab of the restaurant, or a new UUID that opens a new tab.",
      "x-description-cs": "Účet, na který se řádky přesouvají – otevřený účet provozovny, nebo nové UUID, které otevře nový účet."
     },
     "target_version": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 1,
      "description": "The `version` of the target tab as you read it; required for an existing tab, `null` or missing for a new one.",
      "x-description-cs": "`version` cílového účtu, jak jste ji načetli; u existujícího účtu povinná, u nového `null` nebo chybí."
     },
     "target_table_name": {
      "type": [
       "string",
       "null"
      ],
      "minLength": 1,
      "maxLength": 32,
      "description": "The table of a new target tab; only for a new one.",
      "x-description-cs": "Stůl nového cílového účtu; jen u nového."
     },
     "lines": {
      "type": "array",
      "minItems": 1,
      "maxItems": 300,
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "line_id",
        "quantity"
       ],
       "properties": {
        "line_id": {
         "type": "string",
         "minLength": 1,
         "maxLength": 36,
         "description": "The ID of the line on this tab.",
         "x-description-cs": "ID řádku na tomto účtu."
        },
        "quantity": {
         "type": "number",
         "exclusiveMinimum": 0,
         "maximum": 9999,
         "multipleOf": 0.001,
         "description": "How much of the line moves, at most its quantity.",
         "x-description-cs": "Kolik z řádku se přesouvá, nejvýš jeho množství."
        },
        "target_line_id": {
         "type": [
          "string",
          "null"
         ],
         "minLength": 1,
         "maxLength": 36,
         "description": "The ID of the line on the target tab; `line_id` when missing.",
         "x-description-cs": "ID řádku na cílovém účtu; když chybí, `line_id`."
        }
       }
      }
     }
    }
   },
   "TabMove": {
    "type": "object",
    "required": [
     "source",
     "target"
    ],
    "properties": {
     "source": {
      "description": "This tab after the move; `status` `closed` when nothing was left on it.",
      "x-description-cs": "Tento účet po přesunu; `status` `closed`, když na něm nic nezůstalo.",
      "$ref": "#/components/schemas/Tab"
     },
     "target": {
      "description": "The target tab after the move.",
      "x-description-cs": "Cílový účet po přesunu.",
      "$ref": "#/components/schemas/Tab"
     }
    }
   },
   "TabLine": {
    "type": "object",
    "description": "A line keeps the price from the time it was added: a line you send unchanged (same `id`, product, variant,\nadd-ons and removed ingredients, the same or a lower quantity) is not checked against the catalog again, so a daily\nmenu stays on the tab after its time. A new line or a higher quantity is priced now – add pieces ordered later as\na new line.\n",
    "x-description-cs": "Řádek si drží cenu z doby, kdy byl přidán: řádek, který pošlete beze změny (stejné `id`, produkt, varianta,\npřílohy i odebrané suroviny, stejné nebo nižší množství), se proti sortimentu znovu nekontroluje, takže denní\nmenu zůstane na účtu i po svém čase. Nový řádek nebo vyšší množství se ocení teď – později objednané kusy přidejte\njako nový řádek.\n",
    "required": [
     "id",
     "product_id",
     "name",
     "variant",
     "quantity",
     "unit_price",
     "add_ons",
     "removed_ingredients",
     "note",
     "course",
     "sent_to_kitchen",
     "total",
     "ordered_at"
    ],
    "properties": {
     "id": {
      "type": "string"
     },
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "variant": {
      "type": "string",
      "description": "`full` – a whole portion; `half` – a half portion (`Product.pos.half_price`).",
      "x-description-cs": "`full` – celá porce; `half` – polovina (`Product.pos.half_price`).",
      "x-extensible-enum": [
       "full",
       "half"
      ]
     },
     "quantity": {
      "type": "number"
     },
     "ordered_at": {
      "description": "When the line was added (or its quantity raised). Send it as `ordered_at` of the receipt item.",
      "x-description-cs": "Kdy byl řádek přidán (nebo zvýšeno množství). Pošlete ho jako `ordered_at` položky účtenky.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "unit_price": {
      "$ref": "#/components/schemas/Money"
     },
     "add_ons": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "product_id",
        "name",
        "unit_price"
       ],
       "properties": {
        "product_id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string"
        },
        "unit_price": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "removed_ingredients": {
      "type": "array",
      "description": "Ingredients the guest removed (`TabInput.items[].removed_ingredient_ids`) with their names from the time the\nline was added; empty when nothing was removed (also for tabs from before this field).\n",
      "x-description-cs": "Suroviny, které host odebral (`TabInput.items[].removed_ingredient_ids`), s názvy z doby, kdy byl řádek\npřidán; prázdné, když nic neodebral (i u účtů z doby před tímto polem).\n",
      "items": {
       "$ref": "#/components/schemas/RemovableIngredient"
      }
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "course": {
      "type": "integer"
     },
     "sent_to_kitchen": {
      "type": "boolean"
     },
     "total": {
      "$ref": "#/components/schemas/Money"
     }
    }
   },
   "Tab": {
    "type": "object",
    "description": "The tab of a table on the registers and waiter apps, shared by all devices of the restaurant. `putTab` writes its\nwhole state; `createReceipt` with `tab_id`, or `closeTab`, closes it.\n",
    "x-description-cs": "Účet stolu na pokladnách a u mobilních číšníků, společný všem zařízením provozovny. `putTab` zapíše celý jeho\nstav; `createReceipt` s `tab_id` nebo `closeTab` ho uzavře.\n",
    "required": [
     "id",
     "restaurant_id",
     "table_name",
     "note",
     "opened_at",
     "opened_by",
     "updated_by",
     "lines",
     "totals",
     "version",
     "status",
     "updated_at",
     "device_id",
     "closed_at",
     "receipt_id"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the tab, made on the device that opened it (`tab_id` in the path).",
      "x-description-cs": "Vaše UUID účtu vytvořené na zařízení, které ho otevřelo (`tab_id` v adrese)."
     },
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "table_name": {
      "type": "string",
      "description": "The table, as the device sent it. It is not checked against the map, and several open tabs may have the same name.",
      "x-description-cs": "Stůl, jak ho poslalo zařízení. Proti mapě se nekontroluje a stejný název může mít víc otevřených účtů."
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "description": "The note of the tab; `null` when empty.",
      "x-description-cs": "Poznámka účtu; `null`, když je prázdná."
     },
     "opened_at": {
      "description": "When the tab was opened (the first `putTab`).",
      "x-description-cs": "Kdy se účet otevřel (první `putTab`).",
      "$ref": "#/components/schemas/Timestamp"
     },
     "opened_by": {
      "description": "The employee who opened the tab; `id` `0` with the name of the phone when an order from the table opened it\nwithout an employee (`applyTableOrder`).\n",
      "x-description-cs": "Zaměstnanec, který účet otevřel; `id` `0` se jménem telefonu, když ho otevřela objednávka od stolu bez\nzaměstnance (`applyTableOrder`).\n",
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "updated_by": {
      "description": "The employee of the last `putTab` or `applyTableOrder` (`id` `0` with the name of the phone when the rules\nof the restaurant accepted the order); closing the tab does not change it.\n",
      "x-description-cs": "Zaměstnanec posledního `putTab` nebo `applyTableOrder` (`id` `0` se jménem telefonu, když objednávku přijala\npravidla podniku); uzavření účtu ho nemění.\n",
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "lines": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TabLine"
      }
     },
     "totals": {
      "type": "object",
      "description": "The sum of the lines – `items` and `total` are the same, a tab has no discounts. Every line keeps the price from\nthe time it was added (see `TabLine`); the receipt prices the items again.\n",
      "x-description-cs": "Součet řádků – `items` a `total` jsou stejné, účet stolu slevy nemá. Každý řádek si drží cenu z doby, kdy byl\npřidán (viz `TabLine`); účtenka položky spočítá znovu.\n",
      "required": [
       "items",
       "total"
      ],
      "properties": {
       "items": {
        "$ref": "#/components/schemas/Money"
       },
       "total": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "version": {
      "type": "integer",
      "description": "Grows with every change; the `ETag` is built from it.",
      "x-description-cs": "Roste s každou změnou; z ní je `ETag`."
     },
     "status": {
      "type": "string",
      "description": "`open` – the tab can be changed; `closed` – closed by a receipt (`receipt_id`) or by `closeTab`, and it can\nnever be opened again (`409 tab_closed`); `transferred` – its register moved to API v1 and took the tab over,\nor the register was unpaired (changes end with `409 tab_closed` too). Only `getTab` returns closed and\ntransferred tabs; `listTabs` lists open ones.\n",
      "x-description-cs": "`open` – účet jde měnit; `closed` – uzavřel ho účtenka (`receipt_id`) nebo `closeTab` a znovu otevřít už nejde\n(`409 tab_closed`); `transferred` – jeho pokladna přešla na API v1 a účet převzala, nebo ji někdo odpojil\n(změna skončí také `409 tab_closed`). Uzavřené a převedené účty vrací jen `getTab`; `listTabs` vypisuje otevřené.\n",
      "x-extensible-enum": [
       "open",
       "closed",
       "transferred"
      ]
     },
     "updated_at": {
      "description": "When the tab was changed last – the last `putTab` or the close.",
      "x-description-cs": "Kdy se účet naposledy změnil – poslední `putTab` nebo uzavření.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "device_id": {
      "description": "The device of the last `putTab`; closing the tab does not change it.",
      "x-description-cs": "Zařízení posledního `putTab`; uzavření účtu ho nemění.",
      "$ref": "#/components/schemas/Id"
     },
     "closed_at": {
      "description": "When the tab was closed; `null` while it is open.",
      "x-description-cs": "Kdy se účet uzavřel; `null`, dokud je otevřený.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "receipt_id": {
      "type": [
       "string",
       "null"
      ],
      "format": "uuid",
      "description": "The receipt that paid the tab; `null` while open and after `closeTab`.",
      "x-description-cs": "Účtenka, která účet zaplatila; `null`, dokud je otevřený, a po `closeTab`."
     }
    }
   },
   "TabList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Tab"
      }
     }
    }
   },
   "EventTabClosedData": {
    "type": "object",
    "required": [
     "tab_id",
     "table_name",
     "receipt_id"
    ],
    "properties": {
     "tab_id": {
      "type": "string",
      "format": "uuid"
     },
     "table_name": {
      "type": "string"
     },
     "receipt_id": {
      "type": [
       "string",
       "null"
      ],
      "format": "uuid"
     }
    }
   },
   "PosActivityBatch": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "items"
    ],
    "properties": {
     "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 200,
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "id",
        "employee_id",
        "occurred_at",
        "action"
       ],
       "properties": {
        "id": {
         "type": "string",
         "format": "uuid"
        },
        "employee_id": {
         "$ref": "#/components/schemas/Id"
        },
        "occurred_at": {
         "$ref": "#/components/schemas/Timestamp"
        },
        "action": {
         "type": "string",
         "minLength": 1,
         "maxLength": 255,
         "examples": [
          "Otevřena zásuvka bez prodeje"
         ]
        }
       }
      }
     }
    }
   },
   "PosActivityResult": {
    "type": "object",
    "required": [
     "created",
     "duplicates"
    ],
    "properties": {
     "created": {
      "type": "integer"
     },
     "duplicates": {
      "type": "integer"
     }
    }
   },
   "StockUnit": {
    "type": "string",
    "description": "`kg`, `l`, `pcs` (pieces), `pack` (packages), `m` (metres).",
    "x-description-cs": "`kg`, `l`, `pcs` (kusy), `pack` (balení), `m` (metry).",
    "x-extensible-enum": [
     "kg",
     "l",
     "pcs",
     "pack",
     "m"
    ]
   },
   "StockTakingItem": {
    "type": "object",
    "description": "A warehouse item to count.",
    "x-description-cs": "Skladová položka k přepočítání.",
    "required": [
     "warehouse_item_id",
     "name",
     "category",
     "unit",
     "ean",
     "expected_quantity",
     "tolerance_percent",
     "weighing"
    ],
    "properties": {
     "warehouse_item_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "category": {
      "type": "object",
      "required": [
       "id",
       "name"
      ],
      "properties": {
       "id": {
        "description": "`null` for items without a category.",
        "x-description-cs": "`null` u položek bez kategorie.",
        "anyOf": [
         {
          "$ref": "#/components/schemas/Id"
         },
         {
          "type": "null"
         }
        ]
       },
       "name": {
        "type": "string"
       }
      }
     },
     "unit": {
      "$ref": "#/components/schemas/StockUnit"
     },
     "ean": {
      "type": [
       "string",
       "null"
      ],
      "description": "The barcode for scanning, when it is filled in.",
      "x-description-cs": "Čárový kód ke skenování, když je vyplněný."
     },
     "expected_quantity": {
      "type": "number",
      "description": "What the stock expects now, in `unit`. It can be negative when more was used than received.",
      "x-description-cs": "Kolik teď očekává sklad, v jednotce `unit`. Může být záporné, když se spotřebovalo víc, než se naskladnilo."
     },
     "tolerance_percent": {
      "type": "integer",
      "minimum": 0,
      "maximum": 100,
      "description": "The difference the restaurant still accepts, in percent of the expected quantity. `0` = not set.",
      "x-description-cs": "Rozdíl, který provozovna ještě snese, v procentech očekávaného množství. `0` = nenastaveno."
     },
     "weighing": {
      "description": "For counting an opened package by its weight; `null` when the item is not weighed.",
      "x-description-cs": "Pro přepočet otevřeného balení podle váhy; `null`, když se položka neváží.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "pack_content",
         "full_weight_g",
         "empty_weight_g"
        ],
        "properties": {
         "pack_content": {
          "type": "number",
          "description": "Content of one package in `unit` (a 0.7 l bottle is 0.7).",
          "x-description-cs": "Obsah jednoho balení v jednotce `unit` (lahev 0,7 l je 0.7)."
         },
         "full_weight_g": {
          "type": "integer",
          "description": "Weight of a full package including the packaging, in grams.",
          "x-description-cs": "Váha plného balení i s obalem v gramech."
         },
         "empty_weight_g": {
          "type": "integer",
          "description": "Weight of the empty packaging, in grams.",
          "x-description-cs": "Váha prázdného obalu v gramech."
         }
        }
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "StockTakingItemPage": {
    "type": "object",
    "description": "One page of items to count.",
    "x-description-cs": "Jedna stránka položek k přepočítání.",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/StockTakingItem"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "StockTakingCreate": {
    "type": "object",
    "description": "A finished stock taking from the device.",
    "x-description-cs": "Dokončená inventura ze zařízení.",
    "additionalProperties": false,
    "required": [
     "id",
     "items"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the stock taking, made on the device.",
      "x-description-cs": "Vaše UUID inventury vytvořené na zařízení."
     },
     "area": {
      "type": "string",
      "enum": [
       "bar",
       "kitchen"
      ],
      "default": "bar",
      "description": "Where it was counted – it decides the role the employee needs: `bar` (default) – at the registers, `pos` or\n`pos_manager`; `kitchen` – in the kitchen, `kitchen` or `kitchen_manager`. It does not choose a warehouse (the\nrestaurant has one stock), and the items sent are not checked against the list of the area.\n",
      "x-description-cs": "Kde se počítalo – určuje roli, kterou zaměstnanec potřebuje: `bar` (výchozí) – na pokladnách, `pos` nebo\n`pos_manager`; `kitchen` – v kuchyni, `kitchen` nebo `kitchen_manager`. Nevybírá sklad (provozovna má jeden\nstav skladu) a poslané položky se proti seznamu oblasti nekontrolují.\n"
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 1000,
      "description": "A note shown at the stock taking in the administration.",
      "x-description-cs": "Poznámka, kterou administrace ukáže u inventury."
     },
     "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 2000,
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "warehouse_item_id",
        "quantity"
       ],
       "properties": {
        "warehouse_item_id": {
         "$ref": "#/components/schemas/Id"
        },
        "quantity": {
         "type": "number",
         "minimum": 0,
         "maximum": 99999999,
         "multipleOf": 0.001,
         "description": "The counted quantity in the unit of the item.",
         "x-description-cs": "Napočítané množství v jednotce položky."
        }
       }
      }
     }
    }
   },
   "StockTaking": {
    "type": "object",
    "description": "A stock taking recorded through the API.",
    "x-description-cs": "Inventura zapsaná přes API.",
    "required": [
     "id",
     "number",
     "area",
     "created_at",
     "employee",
     "note",
     "stock_updated",
     "items",
     "difference_value"
    ],
    "properties": {
     "id": {
      "description": "Your UUID of the stock taking.",
      "x-description-cs": "Vaše UUID inventury.",
      "$ref": "#/components/schemas/Id"
     },
     "number": {
      "description": "The number of the stock taking in the administration.",
      "x-description-cs": "Číslo inventury v administraci.",
      "$ref": "#/components/schemas/Id"
     },
     "area": {
      "type": "string",
      "description": "Where it was counted, as sent in `StockTakingCreate.area` – `bar` or `kitchen`.",
      "x-description-cs": "Kde se počítalo, jak přišlo v `StockTakingCreate.area` – `bar` nebo `kitchen`.",
      "x-extensible-enum": [
       "bar",
       "kitchen"
      ]
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "employee": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "stock_updated": {
      "type": "boolean",
      "description": "`false` when the restaurant does not set the stock from stock takings on devices; the stock taking was only recorded.",
      "x-description-cs": "`false`, když provozovna nenastavuje sklad podle inventur ze zařízení; inventura se jen zapsala."
     },
     "items": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/StockTakingLine"
      }
     },
     "difference_value": {
      "description": "The value of all differences at the purchase prices without VAT (negative = a shortage).",
      "x-description-cs": "Hodnota všech rozdílů v nákupních cenách bez DPH (záporná = manko).",
      "$ref": "#/components/schemas/Money"
     }
    }
   },
   "StockTakingLine": {
    "type": "object",
    "required": [
     "warehouse_item_id",
     "name",
     "unit",
     "expected_quantity",
     "counted_quantity",
     "difference",
     "difference_value"
    ],
    "properties": {
     "warehouse_item_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "unit": {
      "$ref": "#/components/schemas/StockUnit"
     },
     "expected_quantity": {
      "type": "number",
      "description": "The stock before the stock taking.",
      "x-description-cs": "Stav skladu před inventurou."
     },
     "counted_quantity": {
      "type": "number"
     },
     "difference": {
      "type": "number",
      "description": "`counted_quantity − expected_quantity`.",
      "x-description-cs": "`counted_quantity − expected_quantity`."
     },
     "difference_value": {
      "description": "The difference at the purchase price without VAT.",
      "x-description-cs": "Rozdíl v nákupní ceně bez DPH.",
      "$ref": "#/components/schemas/Money"
     }
    }
   },
   "BackupPage": {
    "type": "object",
    "description": "One page of backups, newest first.",
    "x-description-cs": "Jedna stránka záloh od nejnovější.",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Backup"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Backup": {
    "type": "object",
    "description": "A backup of a register's local database.",
    "x-description-cs": "Záloha místní databáze pokladny.",
    "required": [
     "id",
     "type",
     "created_at",
     "size_bytes",
     "app_version",
     "db_version",
     "device_name",
     "this_device",
     "legacy"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "type": {
      "type": "string",
      "description": "`automatic`, `manual`, `closure`; `other` – from an old version of the app.",
      "x-description-cs": "`automatic`, `manual`, `closure`; `other` – ze staré verze aplikace.",
      "x-extensible-enum": [
       "automatic",
       "manual",
       "closure",
       "other"
      ]
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "size_bytes": {
      "type": "integer",
      "minimum": 0
     },
     "app_version": {
      "type": "string",
      "description": "Version of the app that made it (empty when unknown).",
      "x-description-cs": "Verze aplikace, která ji vytvořila (prázdné, když není známá)."
     },
     "db_version": {
      "type": "string",
      "description": "Version of the local database (empty when unknown).",
      "x-description-cs": "Verze místní databáze (prázdné, když není známá)."
     },
     "device_name": {
      "type": [
       "string",
       "null"
      ],
      "description": "The device that uploaded it, when known.",
      "x-description-cs": "Zařízení, které ji nahrálo, když je známé."
     },
     "this_device": {
      "type": "boolean",
      "description": "Uploaded by the device that asks.",
      "x-description-cs": "Nahrálo ji zařízení, které se ptá."
     },
     "legacy": {
      "type": "boolean",
      "description": "Uploaded by a register on API v1.",
      "x-description-cs": "Nahrála ji pokladna na API v1."
     }
    }
   },
   "DeviceLogBatch": {
    "type": "object",
    "description": "Log records of the device.",
    "x-description-cs": "Záznamy logu zařízení.",
    "additionalProperties": false,
    "required": [
     "events"
    ],
    "properties": {
     "events": {
      "type": "array",
      "minItems": 1,
      "maxItems": 500,
      "items": {
       "$ref": "#/components/schemas/DeviceLogEvent"
      }
     }
    }
   },
   "DeviceLogEvent": {
    "type": "object",
    "description": "One log record.",
    "x-description-cs": "Jeden záznam logu.",
    "additionalProperties": false,
    "required": [
     "level",
     "logged_at",
     "message"
    ],
    "properties": {
     "level": {
      "type": "string",
      "enum": [
       "debug",
       "info",
       "warning",
       "error"
      ],
      "description": "The level, from the lowest: `debug`, `info`, `warning`, `error`. Records below `DeviceLogResult.min_level` are dropped.",
      "x-description-cs": "Úroveň od nejnižší: `debug`, `info`, `warning`, `error`. Záznamy pod `DeviceLogResult.min_level` se zahodí."
     },
     "logged_at": {
      "type": "string",
      "format": "date-time",
      "description": "When it happened on the device.",
      "x-description-cs": "Kdy se to na zařízení stalo."
     },
     "message": {
      "type": "string",
      "minLength": 1,
      "maxLength": 8000
     },
     "tag": {
      "type": [
       "string",
       "null"
      ],
      "description": "Part of the app, for example `printer`, `sync`, `payment`.",
      "x-description-cs": "Část aplikace, například `printer`, `sync`, `payment`.",
      "maxLength": 32,
      "pattern": "^[a-z0-9_.-]+$"
     },
     "employee_name": {
      "type": [
       "string",
       "null"
      ],
      "description": "Who was signed in on the device.",
      "x-description-cs": "Kdo byl na zařízení přihlášený.",
      "maxLength": 64
     }
    }
   },
   "DeviceLogResult": {
    "type": "object",
    "description": "What the server did with the batch.",
    "x-description-cs": "Co server s dávkou udělal.",
    "required": [
     "received",
     "stored",
     "min_level"
    ],
    "properties": {
     "received": {
      "type": "integer",
      "minimum": 0
     },
     "stored": {
      "type": "integer",
      "minimum": 0,
      "description": "Records kept (levels from `min_level` up).",
      "x-description-cs": "Uložené záznamy (úrovně od `min_level` výš)."
     },
     "min_level": {
      "type": "string",
      "description": "The lowest level the server keeps for this restaurant now: `warning`, or `debug` while Profirest support has\ndetailed logging on (`info` and `error` do not come today). Lower records are accepted and dropped; send nothing\nbelow it.\n",
      "x-description-cs": "Nejnižší úroveň, kterou server u této provozovny teď ukládá: `warning`, nebo `debug`, dokud má podpora\nProfirestu zapnuté podrobné logování (`info` a `error` dnes nepřicházejí). Nižší záznamy se přijmou a zahodí;\nnic nižšího neposílejte.\n",
      "x-extensible-enum": [
       "debug",
       "info",
       "warning",
       "error"
      ]
     }
    }
   },
   "BugReportCreate": {
    "type": "object",
    "description": "A bug report from the device's user.",
    "x-description-cs": "Hlášení chyby od uživatele zařízení.",
    "additionalProperties": false,
    "required": [
     "code",
     "description"
    ],
    "properties": {
     "code": {
      "type": "string",
      "description": "Code of the report made by the device and shown to the user (for example `A3F2-K8XQ1`).",
      "x-description-cs": "Kód hlášení, který vymyslí zařízení a ukáže uživateli (například `A3F2-K8XQ1`).",
      "pattern": "^[A-Z0-9][A-Z0-9-]{3,19}$"
     },
     "description": {
      "type": "string",
      "description": "What the user wrote (may be empty).",
      "x-description-cs": "Co uživatel napsal (smí být prázdné).",
      "maxLength": 4000
     },
     "employee_name": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64
     },
     "app_version": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 50
     },
     "db_version": {
      "type": [
       "string",
       "null"
      ],
      "minLength": 1,
      "maxLength": 16,
      "pattern": "^[0-9A-Za-z._+-]+$",
      "description": "Version of the local database (text, like `Backup.db_version`).",
      "x-description-cs": "Verze místní databáze (text, stejně jako `Backup.db_version`)."
     },
     "os_version": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 50
     },
     "device_model": {
      "type": [
       "string",
       "null"
      ],
      "description": "Manufacturer and model of the device.",
      "x-description-cs": "Výrobce a model zařízení.",
      "maxLength": 128
     },
     "device_ip": {
      "type": [
       "string",
       "null"
      ],
      "description": "Address of the device in the local network.",
      "x-description-cs": "Adresa zařízení v místní síti.",
      "maxLength": 45
     },
     "mode": {
      "type": [
       "string",
       "null"
      ],
      "description": "Mode of the app (for example how registers share data in the restaurant).",
      "x-description-cs": "Režim aplikace (například jak pokladny v provozovně sdílejí data).",
      "maxLength": 50
     },
     "server_id": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 255
     },
     "logs": {
      "type": "array",
      "description": "Recent log records from the device, oldest first.",
      "x-description-cs": "Nedávné záznamy logu ze zařízení od nejstaršího.",
      "maxItems": 2000,
      "items": {
       "$ref": "#/components/schemas/DeviceLogEvent"
      }
     }
    }
   },
   "BugReport": {
    "type": "object",
    "description": "A recorded bug report.",
    "x-description-cs": "Zapsané hlášení chyby.",
    "required": [
     "code",
     "received_at",
     "logs_attached"
    ],
    "properties": {
     "code": {
      "type": "string"
     },
     "received_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "logs_attached": {
      "type": "integer",
      "minimum": 0,
      "description": "Log records stored with the report.",
      "x-description-cs": "Záznamy logu uložené k hlášení."
     }
    }
   },
   "DeviceCheckIn": {
    "type": "object",
    "description": "The state of the device now (`checkInDevice`).",
    "x-description-cs": "Stav zařízení teď (`checkInDevice`).",
    "additionalProperties": false,
    "required": [
     "role",
     "app_version"
    ],
    "properties": {
     "role": {
      "type": "string",
      "enum": [
       "register",
       "waiter",
       "kds",
       "terminal",
       "courier",
       "kiosk",
       "other"
      ],
      "description": "What the device is – `register` (the cash register), `waiter` (a waiter's phone), `kds`, `terminal` (attendance), `courier`, `kiosk`.",
      "x-description-cs": "Co zařízení je – `register` (pokladna), `waiter` (telefon číšníka), `kds`, `terminal` (docházka), `courier`, `kiosk`."
     },
     "app_version": {
      "type": "string",
      "minLength": 1,
      "maxLength": 32,
      "examples": [
       "26.10.3"
      ]
     },
     "os_version": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 50,
      "examples": [
       "Android 13"
      ]
     },
     "device_model": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 128,
      "examples": [
       "Sunmi T2s"
      ]
     },
     "sent_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ],
      "description": "The device's clock when it sent this – with `server_time` of the answer the device computes its offset.",
      "x-description-cs": "Hodiny zařízení ve chvíli odeslání – se `server_time` odpovědi zařízení spočítá svůj posun."
     },
     "uptime_seconds": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "maximum": 2147483647
     },
     "battery": {
      "anyOf": [
       {
        "type": "object",
        "additionalProperties": false,
        "properties": {
         "percent": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "maximum": 100
         },
         "charging": {
          "type": [
           "boolean",
           "null"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "network": {
      "anyOf": [
       {
        "type": "object",
        "additionalProperties": false,
        "properties": {
         "type": {
          "type": "string",
          "enum": [
           "wifi",
           "mobile",
           "ethernet",
           "none",
           "unknown"
          ]
         },
         "ip": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 45,
          "description": "Address in the local network.",
          "x-description-cs": "Adresa v místní síti."
         },
         "signal_dbm": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": -200,
          "maximum": 0,
          "description": "Signal strength of Wi-Fi or mobile data.",
          "x-description-cs": "Síla signálu Wi-Fi nebo mobilních dat."
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "queues": {
      "description": "What waits on the device to be sent or done – the server derives alerts from the oldest item.",
      "x-description-cs": "Co na zařízení čeká na odeslání nebo vyřízení – z nejstarší položky server odvozuje upozornění.",
      "anyOf": [
       {
        "type": "object",
        "additionalProperties": false,
        "properties": {
         "receipts": {
          "$ref": "#/components/schemas/DeviceQueue"
         },
         "payments": {
          "$ref": "#/components/schemas/DeviceQueue"
         },
         "print_jobs": {
          "$ref": "#/components/schemas/DeviceQueue"
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "last_backup_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "last_sync_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ],
      "description": "The last successful exchange with the server (orders, tables).",
      "x-description-cs": "Poslední úspěšná výměna se serverem (objednávky, stoly)."
     },
     "log_store": {
      "description": "The device's own log store (the black box).",
      "x-description-cs": "Vlastní úložiště logů zařízení (černá skříňka).",
      "anyOf": [
       {
        "type": "object",
        "additionalProperties": false,
        "properties": {
         "segments": {
          "type": "integer",
          "minimum": 0,
          "maximum": 1000000
         },
         "bytes": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
         },
         "oldest_at": {
          "anyOf": [
           {
            "$ref": "#/components/schemas/Timestamp"
           },
           {
            "type": "null"
           }
          ]
         },
         "errors_today": {
          "type": "integer",
          "minimum": 0,
          "maximum": 2147483647
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "counters": {
      "type": "object",
      "description": "Free counters of the app since start (`polls`, `broadcasts`, `errors`, `socket_reconnects` …): a name of up to 40 characters and a whole number.",
      "x-description-cs": "Volná počítadla aplikace od startu (`polls`, `broadcasts`, `errors`, `socket_reconnects` …): název do 40 znaků a celé číslo.",
      "maxProperties": 40,
      "propertyNames": {
       "pattern": "^[a-z][a-z0-9_.]{0,39}$"
      },
      "additionalProperties": {
       "type": "integer",
       "minimum": 0,
       "maximum": 9007199254740991
      }
     },
     "peers": {
      "type": "array",
      "description": "Devices connected to this one over the local network without a token of their own (waiters' phones of the register).",
      "x-description-cs": "Zařízení připojená k tomuto po místní síti bez vlastního tokenu (telefony číšníků kasy).",
      "maxItems": 30,
      "items": {
       "$ref": "#/components/schemas/DevicePeer"
      }
     },
     "command_results": {
      "type": "array",
      "description": "What happened with the commands from the last answer.",
      "x-description-cs": "Co se stalo s příkazy z minulé odpovědi.",
      "maxItems": 20,
      "items": {
       "$ref": "#/components/schemas/DeviceCommandResult"
      }
     }
    }
   },
   "DeviceQueue": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "count"
    ],
    "properties": {
     "count": {
      "type": "integer",
      "minimum": 0,
      "maximum": 2147483647,
      "description": "How many wait.",
      "x-description-cs": "Kolik jich čeká."
     },
     "oldest_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ],
      "description": "When the oldest one started waiting.",
      "x-description-cs": "Od kdy čeká nejstarší."
     }
    }
   },
   "DevicePeer": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "key",
     "name",
     "connected"
    ],
    "properties": {
     "key": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "pattern": "^[A-Za-z0-9_.-]+$",
      "description": "Stable ID of the peer on the register (the same in its log header and in `reportDeviceError.peer_key`).",
      "x-description-cs": "Stálé ID zařízení u kasy (stejné v hlavičce jeho logu a v `reportDeviceError.peer_key`).",
      "examples": [
       "9bb5f040"
      ]
     },
     "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "examples": [
       "Jana"
      ]
     },
     "role": {
      "type": "string",
      "enum": [
       "waiter",
       "kds",
       "terminal",
       "courier",
       "kiosk",
       "other"
      ],
      "default": "waiter"
     },
     "app_version": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32
     },
     "connected": {
      "type": "boolean",
      "description": "Connected to the register now.",
      "x-description-cs": "Teď připojené ke kase."
     },
     "last_seen_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "log_store": {
      "type": "boolean",
      "default": true,
      "description": "The peer keeps its own log store – logs can be asked of it.",
      "x-description-cs": "Zařízení má vlastní úložiště logů – jdou si od něj vyžádat."
     }
    }
   },
   "DeviceCommandResult": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "command_id",
     "status"
    ],
    "properties": {
     "command_id": {
      "type": "string",
      "minLength": 1,
      "maxLength": 32
     },
     "status": {
      "type": "string",
      "enum": [
       "done",
       "failed",
       "unsupported"
      ],
      "description": "`done` – carried out, `failed` – could not (say why in `message`), `unsupported` – the app does not know the command.",
      "x-description-cs": "`done` – vyřízeno, `failed` – nešlo (proč, řekne `message`), `unsupported` – aplikace příkaz nezná."
     },
     "message": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 500
     }
    }
   },
   "DeviceCheckInResult": {
    "type": "object",
    "required": [
     "server_time",
     "next_in_seconds",
     "commands",
     "api_target"
    ],
    "properties": {
     "server_time": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "api_target": {
      "description": "Where the device should be – only for Profirest's own register, kitchen display and courier; `null` for others.",
      "x-description-cs": "Kde má zařízení být – jen u vlastní pokladny, kuchyňského displeje a kurýra Profirestu; jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ApiTarget"
       },
       {
        "type": "null"
       }
      ]
     },
     "next_in_seconds": {
      "type": "integer",
      "description": "When to check in next (60 for a register, 300 for a waiter's phone; the server may raise it).",
      "x-description-cs": "Kdy přihlásit stav příště (60 u kasy, 300 u telefonu číšníka; server může zvednout).",
      "examples": [
       60
      ]
     },
     "commands": {
      "type": "array",
      "description": "Commands to carry out, oldest first.",
      "x-description-cs": "Příkazy k vyřízení, od nejstaršího.",
      "items": {
       "$ref": "#/components/schemas/DeviceCommand"
      }
     }
    }
   },
   "DeviceCommand": {
    "type": "object",
    "description": "A command for the device from Profirest support or the restaurant. After `expires_at` it is void – do not carry it out any more.",
    "x-description-cs": "Příkaz pro zařízení od podpory Profirestu nebo provozovny. Po `expires_at` neplatí – už ho nevyřizujte.",
    "required": [
     "id",
     "type",
     "created_at",
     "expires_at",
     "upload_logs",
     "live_logs"
    ],
    "properties": {
     "id": {
      "type": "string",
      "examples": [
       "c-8f2c1a"
      ]
     },
     "type": {
      "type": "string",
      "description": "`upload_logs` (details in `upload_logs`), `live_logs` (details in `live_logs`), `ping`. An unknown type: report `unsupported`.",
      "x-description-cs": "`upload_logs` (podrobnosti v `upload_logs`), `live_logs` (podrobnosti v `live_logs`), `ping`. Neznámý typ: hlaste `unsupported`.",
      "x-extensible-enum": [
       "upload_logs",
       "live_logs",
       "ping"
      ]
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "expires_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "upload_logs": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/LogUploadCommand"
       },
       {
        "type": "null"
       }
      ]
     },
     "live_logs": {
      "anyOf": [
       {
        "type": "object",
        "required": [
         "until",
         "level"
        ],
        "properties": {
         "until": {
          "$ref": "#/components/schemas/Timestamp"
         },
         "level": {
          "type": "string",
          "enum": [
           "warning",
           "info"
          ],
          "description": "Report records from this level up with `reportDeviceError` until `until`.",
          "x-description-cs": "Do `until` hlaste přes `reportDeviceError` záznamy od této úrovně výš."
         }
        }
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "LogUploadCommand": {
    "type": "object",
    "required": [
     "request_id",
     "reason",
     "from",
     "to",
     "detail",
     "uploads"
    ],
    "properties": {
     "request_id": {
      "type": "string",
      "examples": [
       "3105"
      ]
     },
     "reason": {
      "type": [
       "string",
       "null"
      ],
      "description": "Why the logs are wanted (shown to the staff when the app asks for consent).",
      "x-description-cs": "Proč jsou logy potřeba (ukažte obsluze, když se aplikace ptá na souhlas).",
      "examples": [
       "karta stržena, stůl 11"
      ]
     },
     "from": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "to": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "detail": {
      "type": "string",
      "enum": [
       "trace",
       "full"
      ],
      "description": "`trace` – levels E, W and I only; `full` – also D records with whole messages.",
      "x-description-cs": "`trace` – jen úrovně E, W a I; `full` – i záznamy D s celými zprávami."
     },
     "uploads": {
      "type": "array",
      "description": "One target per device – this device (`peer_key` null) and its peers.",
      "x-description-cs": "Jeden cíl na zařízení – toto zařízení (`peer_key` null) a jeho připojená zařízení.",
      "items": {
       "$ref": "#/components/schemas/LogUploadTarget"
      }
     }
    }
   },
   "LogUploadTarget": {
    "type": "object",
    "required": [
     "upload_id",
     "peer_key",
     "token",
     "upload_url",
     "max_part_bytes",
     "expires_at"
    ],
    "properties": {
     "upload_id": {
      "type": "string",
      "examples": [
       "7742"
      ]
     },
     "peer_key": {
      "type": [
       "string",
       "null"
      ],
      "description": "The peer whose log this is; `null` – the device that checks in.",
      "x-description-cs": "Připojené zařízení, jehož log to je; `null` – zařízení, které přihlašuje stav."
     },
     "token": {
      "type": "string",
      "description": "Bearer token for `putLogUploadPart`, `completeLogUpload` and `abortLogUpload` of this target (`pfl_…`). Hand it to the peer; it is good for this upload only.",
      "x-description-cs": "Bearer token pro `putLogUploadPart`, `completeLogUpload` a `abortLogUpload` tohoto cíle (`pfl_…`). Předejte ho připojenému zařízení; platí jen pro toto nahrávání."
     },
     "upload_url": {
      "type": "string",
      "format": "uri",
      "description": "Address of the upload (`…/v2/log-uploads/{upload_id}`); add `/parts/{part}`, `/complete` or `/abort`.",
      "x-description-cs": "Adresa nahrávání (`…/v2/log-uploads/{upload_id}`); přidejte `/parts/{part}`, `/complete` nebo `/abort`."
     },
     "max_part_bytes": {
      "type": "integer",
      "examples": [
       4194304
      ]
     },
     "expires_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "LogUploadStatus": {
    "type": "object",
    "required": [
     "id",
     "request_id",
     "status",
     "parts_received",
     "parts_expected",
     "bytes",
     "from",
     "to",
     "detail",
     "max_part_bytes",
     "expires_at"
    ],
    "properties": {
     "id": {
      "type": "string",
      "examples": [
       "7742"
      ]
     },
     "request_id": {
      "type": "string",
      "examples": [
       "3105"
      ]
     },
     "status": {
      "type": "string",
      "enum": [
       "waiting",
       "uploading",
       "done",
       "failed",
       "unsupported",
       "no_data",
       "declined",
       "expired",
       "cancelled"
      ],
      "description": "`waiting` – no part yet, `uploading` – parts arrive, `done` – complete; `failed`, `unsupported`, `no_data`, `declined` – given up by the device; `expired` – the request ran out; `cancelled` – withdrawn in the administration.",
      "x-description-cs": "`waiting` – zatím žádná část, `uploading` – části přicházejí, `done` – hotovo; `failed`, `unsupported`, `no_data`, `declined` – vzdané zařízením; `expired` – žádost vypršela; `cancelled` – stažené v administraci."
     },
     "parts_received": {
      "type": "array",
      "description": "Numbers of the parts the server has.",
      "x-description-cs": "Čísla částí, které server má.",
      "items": {
       "type": "integer"
      }
     },
     "parts_expected": {
      "type": [
       "integer",
       "null"
      ],
      "description": "From `completeLogUpload`.",
      "x-description-cs": "Z `completeLogUpload`."
     },
     "bytes": {
      "type": "integer",
      "description": "Bytes received so far.",
      "x-description-cs": "Zatím přijaté bajty."
     },
     "from": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "to": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "detail": {
      "type": "string",
      "enum": [
       "trace",
       "full"
      ]
     },
     "max_part_bytes": {
      "type": "integer"
     },
     "expires_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "LogUploadComplete": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "parts"
    ],
    "properties": {
     "parts": {
      "type": "integer",
      "minimum": 1,
      "maximum": 500,
      "description": "How many parts were sent.",
      "x-description-cs": "Kolik částí bylo odesláno."
     },
     "lines": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "maximum": 2147483647,
      "description": "Lines of NDJSON in the file.",
      "x-description-cs": "Řádků NDJSON v souboru."
     },
     "from": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ],
      "description": "The first record in the file (may be later than asked when the log store is shorter).",
      "x-description-cs": "První záznam v souboru (může být později, než se chtělo, když je úložiště kratší)."
     },
     "to": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "sha256": {
      "type": [
       "string",
       "null"
      ],
      "pattern": "^[0-9a-f]{64}$",
      "description": "SHA-256 of the whole joined file (optional check).",
      "x-description-cs": "SHA-256 celého spojeného souboru (nepovinná kontrola)."
     }
    }
   },
   "LogUploadAbort": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "reason"
    ],
    "properties": {
     "reason": {
      "type": "string",
      "enum": [
       "failed",
       "unsupported",
       "no_data",
       "declined"
      ]
     },
     "message": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 500
     }
    }
   },
   "DeviceErrorCreate": {
    "type": "object",
    "description": "One error from the device's log with the lines before it.",
    "x-description-cs": "Jedna chyba z logu zařízení s řádky před ní.",
    "additionalProperties": false,
    "required": [
     "id",
     "occurred_at",
     "code",
     "message"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "UUID made on the device – the same one again is recorded once.",
      "x-description-cs": "UUID vytvořené na zařízení – stejné podruhé se zapíše jednou."
     },
     "occurred_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "level": {
      "type": "string",
      "enum": [
       "error",
       "warning"
      ],
      "default": "error"
     },
     "code": {
      "type": "string",
      "minLength": 2,
      "maxLength": 64,
      "pattern": "^[A-Za-z][A-Za-z0-9_.-]{1,63}$",
      "description": "Code from the app's catalog (`SOCK.timeout`, `PAY.pending`, `UI.crash`).",
      "x-description-cs": "Kód z číselníku aplikace (`SOCK.timeout`, `PAY.pending`, `UI.crash`).",
      "examples": [
       "SOCK.timeout"
      ]
     },
     "area": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 16,
      "pattern": "^[A-Za-z0-9_]+$",
      "description": "Part of the app (`SOCK`, `PAY`, `UI`, `ENV`, `PRINT` …).",
      "x-description-cs": "Část aplikace (`SOCK`, `PAY`, `UI`, `ENV`, `PRINT` …).",
      "examples": [
       "SOCK"
      ]
     },
     "event": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64,
      "description": "Name of the event from the app's catalog.",
      "x-description-cs": "Jméno události z číselníku aplikace.",
      "examples": [
       "req.timeout"
      ]
     },
     "message": {
      "type": "string",
      "minLength": 1,
      "maxLength": 1000
     },
     "peer_key": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64,
      "pattern": "^[A-Za-z0-9_.-]+$",
      "description": "The error happened on a peer of the register (its `DevicePeer.key`); `null` – on this device.",
      "x-description-cs": "Chyba se stala na zařízení připojeném ke kase (jeho `DevicePeer.key`); `null` – na tomto zařízení."
     },
     "employee_name": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64
     },
     "app_version": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32
     },
     "refs": {
      "description": "IDs valid at the time – the same on the register and on the waiter's phone.",
      "x-description-cs": "ID platná v tu chvíli – stejná na kase i u číšníka.",
      "anyOf": [
       {
        "type": "object",
        "additionalProperties": false,
        "properties": {
         "session": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 64,
          "description": "Shift of the employee.",
          "x-description-cs": "Směna zaměstnance."
         },
         "tab": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 64,
          "description": "Tab (table) – the stable ID of the order.",
          "x-description-cs": "Účet (stůl) – stálé ID objednávky."
         },
         "payment": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 64,
          "description": "Payment attempt.",
          "x-description-cs": "Pokus o platbu."
         },
         "request": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 64,
          "description": "Request between devices or to the server (`X-Request-Id`).",
          "x-description-cs": "Požadavek mezi zařízeními nebo na server (`X-Request-Id`)."
         },
         "broadcast": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 64
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "context": {
      "type": "array",
      "description": "Log lines before the error (NDJSON, one record per item), oldest first – about 30.",
      "x-description-cs": "Řádky logu před chybou (NDJSON, jeden záznam na položku), od nejstaršího – asi 30.",
      "maxItems": 60,
      "items": {
       "type": "string",
       "maxLength": 4000
      }
     },
     "stack": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 16000,
      "description": "Stack trace of a crash.",
      "x-description-cs": "Zásobník volání při pádu."
     }
    }
   },
   "DeviceErrorResult": {
    "type": "object",
    "required": [
     "id",
     "received_at"
    ],
    "properties": {
     "id": {
      "type": "string",
      "description": "ID of the record on the server.",
      "x-description-cs": "ID záznamu na serveru.",
      "examples": [
       "90115"
      ]
     },
     "received_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "ReceiptCancel": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "number",
     "reason"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the cancellation document.",
      "x-description-cs": "Vaše UUID storno dokladu."
     },
     "number": {
      "type": "integer",
      "minimum": 1,
      "maximum": 2147483647,
      "description": "Number of the cancellation document from the register's counter. A number the device already used for a cancellation answers `409 receipt_number_conflict`.",
      "x-description-cs": "Číslo storno dokladu z počítadla pokladny. Číslo, které zařízení už u storna použilo, vrátí `409 receipt_number_conflict`."
     },
     "reason": {
      "type": "string",
      "minLength": 1,
      "maxLength": 255
     },
     "restock": {
      "type": "boolean",
      "default": true,
      "description": "Return the stock and portions.",
      "x-description-cs": "Vrátit sklad a porce."
     },
     "manager_credential": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/StaffCredential"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReceiptPaymentChange": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "payments"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the change; the same `id` again returns the receipt and changes nothing.",
      "x-description-cs": "Vaše UUID změny; stejné `id` znovu vrátí účtenku a nic nezmění."
     },
     "payments": {
      "type": "array",
      "minItems": 1,
      "maxItems": 20,
      "description": "What paid the part of the receipt that was paid in cash, by meal vouchers, to a company account or by\ninvoice – instead of those payments. Card and gift voucher payments of the receipt stay and are not sent;\n`voucher` is not allowed here. Same amount and same tip as the payments being changed.\n",
      "x-description-cs": "Čím se zaplatila část účtenky placená hotově, stravenkami, na firemní účet nebo fakturou – místo těchto\nplateb. Platby kartou a dárkovým voucherem zůstávají a neposílají se; `voucher` tu nejde. Stejná částka\na stejné dýško jako měněné platby.\n",
      "items": {
       "$ref": "#/components/schemas/ReceiptPaymentInput"
      }
     },
     "reason": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 255,
      "description": "Why the payment changes; shown in the Timeline of the administration.",
      "x-description-cs": "Proč se platba mění; ukáže se v Časové ose administrace."
     },
     "manager_credential": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/StaffCredential"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReceiptLine": {
    "type": "object",
    "required": [
     "id",
     "type",
     "product_id",
     "name",
     "variant",
     "quantity",
     "unit_price",
     "catalog_unit_price",
     "price_source",
     "at_employee_price",
     "packaging_unit_price",
     "vat_rate",
     "add_ons",
     "note",
     "course",
     "total",
     "voucher_code"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "type": {
      "type": "string",
      "description": "`product` – from the register catalog; `open_item` – a name, price and VAT rate entered on the register;\n`voucher_sale` – a gift voucher sold (`voucher_code`, outside VAT).\n",
      "x-description-cs": "`product` – ze sortimentu pokladny; `open_item` – název, cena a sazba DPH zadané na pokladně; `voucher_sale`\n– prodaný dárkový voucher (`voucher_code`, mimo DPH).\n",
      "x-extensible-enum": [
       "product",
       "open_item",
       "voucher_sale"
      ]
     },
     "product_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "name": {
      "type": "string"
     },
     "variant": {
      "type": [
       "string",
       "null"
      ],
      "description": "`full` or `half` for a `product`; `null` for `open_item` and `voucher_sale`.",
      "x-description-cs": "`full` nebo `half` u `product`; `null` u `open_item` a `voucher_sale`.",
      "x-extensible-enum": [
       "full",
       "half",
       null
      ]
     },
     "quantity": {
      "type": "number",
      "description": "Negative on a cancellation document.",
      "x-description-cs": "Na storno dokladu záporný."
     },
     "unit_price": {
      "$ref": "#/components/schemas/Money",
      "description": "Price per unit charged, before the item discount.",
      "x-description-cs": "Účtovaná cena za kus, před slevou položky."
     },
     "catalog_unit_price": {
      "description": "The catalog price per unit of the variant at the time the item was priced – `issued_at`, or `ordered_at` when\nthat was used; `null` for open items and vouchers.\n",
      "x-description-cs": "Cena za kus varianty ze sortimentu v okamžiku, ke kterému se položka počítala – v `issued_at`, nebo\nv `ordered_at`, když se použil; `null` u položek s vlastní cenou a voucherů.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "price_source": {
      "type": "string",
      "description": "`catalog`, `manager` (a manager's price or an open item), `device` (the register's price on a late receipt) or `calculator` (an open item sold with a key of the Calculator mode, `calculator_key_id`).",
      "x-description-cs": "`catalog`, `manager` (cena vedoucího nebo položka s vlastní cenou), `device` (cena pokladny u opožděné účtenky) nebo `calculator` (položka s vlastní cenou prodaná tlačítkem režimu Kalkulačka, `calculator_key_id`).",
      "x-extensible-enum": [
       "catalog",
       "manager",
       "device",
       "calculator"
      ]
     },
     "at_employee_price": {
      "type": "boolean"
     },
     "packaging_unit_price": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "vat_rate": {
      "$ref": "#/components/schemas/VatRate",
      "description": "`0` for a voucher sale, which is outside VAT and not in `totals.vat`.",
      "x-description-cs": "`0` u prodeje voucheru, který je mimo DPH a není v `totals.vat`."
     },
     "add_ons": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "product_id",
        "name",
        "unit_price",
        "vat_rate"
       ],
       "properties": {
        "product_id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string"
        },
        "unit_price": {
         "$ref": "#/components/schemas/Money"
        },
        "vat_rate": {
         "$ref": "#/components/schemas/VatRate"
        }
       }
      }
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "course": {
      "type": "integer"
     },
     "total": {
      "$ref": "#/components/schemas/Money",
      "description": "quantity × (unit price + packaging + add-ons), before discounts.",
      "x-description-cs": "počet × (cena za kus + obal + přílohy), před slevami."
     },
     "voucher_code": {
      "type": [
       "string",
       "null"
      ],
      "description": "The sold voucher, masked.",
      "x-description-cs": "Prodaný voucher, maskovaně."
     }
    }
   },
   "ReceiptDiscount": {
    "type": "object",
    "required": [
     "line_id",
     "method",
     "type",
     "value",
     "name",
     "amount",
     "vat"
    ],
    "properties": {
     "line_id": {
      "description": "The discounted line; `null` for a discount on the whole receipt.",
      "x-description-cs": "Zlevněný řádek; `null` u slevy na celou účtenku.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "method": {
      "type": "string",
      "description": "As `ReceiptDiscountInput.method` – `manual` or `automatic`.",
      "x-description-cs": "Jako `ReceiptDiscountInput.method` – `manual` nebo `automatic`.",
      "x-extensible-enum": [
       "manual",
       "automatic"
      ]
     },
     "type": {
      "type": "string",
      "description": "As `ReceiptDiscountInput.type` – `percent` or `amount`.",
      "x-description-cs": "Jako `ReceiptDiscountInput.type` – `percent` nebo `amount`.",
      "x-extensible-enum": [
       "percent",
       "amount"
      ]
     },
     "value": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Percent for `percent`; `null` for `amount` on a receipt – the discount is in `amount`. In a preview\n(`previewReceipt`) an `amount` discount has its minor units here instead; read `amount`.\n",
      "x-description-cs": "Procenta u `percent`; u `amount` na účtence `null` – sleva je v `amount`. V náhledu (`previewReceipt`) je tu\nu slevy `amount` místo toho částka v nejmenších jednotkách; čtěte `amount`.\n"
     },
     "name": {
      "type": [
       "string",
       "null"
      ]
     },
     "amount": {
      "$ref": "#/components/schemas/Money",
      "description": "Negative amount (positive on a cancellation document).",
      "x-description-cs": "Záporná částka (na storno dokladu kladná)."
     },
     "vat": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/VatBreakdown"
      }
     }
    }
   },
   "ReceiptPayment": {
    "type": "object",
    "required": [
     "id",
     "method",
     "amount",
     "tip",
     "tendered",
     "change",
     "voucher_code",
     "reference",
     "terminal"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "method": {
      "type": "string",
      "description": "As `ReceiptPaymentInput.method`.",
      "x-description-cs": "Jako `ReceiptPaymentInput.method`.",
      "x-extensible-enum": [
       "cash",
       "card",
       "meal_voucher",
       "company_account",
       "invoice",
       "voucher"
      ]
     },
     "amount": {
      "description": "The part of the receipt this payment covers, without the tip; negative on a cancellation document.",
      "x-description-cs": "Kolik z účtenky platba hradí, bez dýška; na storno dokladu záporné.",
      "$ref": "#/components/schemas/Money"
     },
     "tip": {
      "description": "The tip of this payment; negative on a cancellation document.",
      "x-description-cs": "Dýško této platby; na storno dokladu záporné.",
      "$ref": "#/components/schemas/Money"
     },
     "tendered": {
      "description": "Cash received from the customer; `null` when not sent and on a cancellation document.",
      "x-description-cs": "Hotovost přijatá od zákazníka; `null`, když nepřišla, a na storno dokladu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "change": {
      "description": "Change given back – `tendered` minus `amount` and `tip`; `null` without `tendered`.",
      "x-description-cs": "Vráceno zákazníkovi – `tendered` minus `amount` a `tip`; `null` bez `tendered`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "voucher_code": {
      "type": [
       "string",
       "null"
      ],
      "description": "Masked.",
      "x-description-cs": "Maskovaně."
     },
     "reference": {
      "type": [
       "string",
       "null"
      ]
     },
     "terminal": {
      "description": "Part of the card terminal's record (`TerminalPaymentInput`); on a cancellation document the record of the original payment.",
      "x-description-cs": "Část záznamu z platebního terminálu (`TerminalPaymentInput`); na storno dokladu záznam původní platby.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "provider",
         "transaction_id",
         "card_number_masked",
         "auth_code"
        ],
        "properties": {
         "provider": {
          "type": "string"
         },
         "transaction_id": {
          "type": "string"
         },
         "card_number_masked": {
          "type": [
           "string",
           "null"
          ]
         },
         "auth_code": {
          "type": [
           "string",
           "null"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReceiptPriceDifference": {
    "type": "object",
    "description": "A price the register charged that differs from the catalog – for the audit. Accepted from a register manager, or\non a late receipt (recorded offline, or sent more than 10 minutes after it was issued).\n",
    "x-description-cs": "Cena, kterou pokladna účtovala jinak než sortiment – pro audit. Přijme se od vedoucího pokladny, nebo\nu opožděné účtenky (pořízené offline, nebo poslané víc než 10 minut po vystavení).\n",
    "required": [
     "line_id",
     "product_id",
     "add_on_product_id",
     "catalog_unit_price",
     "charged_unit_price",
     "reason"
    ],
    "properties": {
     "line_id": {
      "description": "The line of the receipt.",
      "x-description-cs": "Řádek účtenky.",
      "$ref": "#/components/schemas/Id"
     },
     "product_id": {
      "description": "The product of the line – also when the price of one of its add-ons differs.",
      "x-description-cs": "Produkt řádku – i když se liší cena některé jeho přílohy.",
      "$ref": "#/components/schemas/Id"
     },
     "add_on_product_id": {
      "description": "The add-on whose price differs; `null` when the price of the product itself differs.",
      "x-description-cs": "Příloha, jejíž cena se liší; `null`, když se liší cena samotného produktu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "catalog_unit_price": {
      "description": "The catalog price per unit – of the variant used (a half, the employee price) or of the add-on.",
      "x-description-cs": "Cena za kus ze sortimentu – použité varianty (půlka, cena pro zaměstnance) nebo přílohy.",
      "$ref": "#/components/schemas/Money"
     },
     "charged_unit_price": {
      "description": "The price per unit the register sent (`unit_price`).",
      "x-description-cs": "Cena za kus, kterou poslala pokladna (`unit_price`).",
      "$ref": "#/components/schemas/Money"
     },
     "reason": {
      "type": "string",
      "description": "`manager` – a register manager approved it (signed in, `manager_credential`, or `approved_by_id` of an\noffline receipt, signed or not); `offline` – without a manager, on a late receipt.\n",
      "x-description-cs": "`manager` – schválil ji vedoucí pokladny (přihlášený, `manager_credential`, nebo `approved_by_id` offline\núčtenky, podepsané i nepodepsané); `offline` – bez vedoucího, u opožděné účtenky.\n",
      "x-extensible-enum": [
       "offline",
       "manager"
      ]
     }
    }
   },
   "ReceiptEet": {
    "type": "object",
    "description": "The sale recorded in EET 2.0 (Czech electronic registration of sales), sent by the server. `pending` is sent\nagain automatically; `rejected` needs a person (certificate, settings) in the administration; `test` – the\nrestaurant has a test certificate, the sale went only to the test environment and is not recorded (do not show\nit as recorded).\n",
    "x-description-cs": "Tržba evidovaná v EET 2.0, kterou odesílá server. `pending` se odešle znovu sama; `rejected` potřebuje člověka\n(certifikát, nastavení) v administraci; `test` – provozovna má testovací certifikát, tržba šla jen do testovacího\nprostředí a evidovaná není (neukazujte ji jako zaevidovanou).\n",
    "required": [
     "status",
     "total",
     "prepaid_issued",
     "prepaid_used",
     "register_id",
     "sequence",
     "unit_id",
     "sold_at",
     "pok",
     "environment",
     "error",
     "warnings",
     "deadline_at"
    ],
    "properties": {
     "status": {
      "type": "string",
      "description": "`pending` – waiting to be sent, or sent again after an error (also while the restaurant has no certificate);\n`accepted` – the tax administration accepted it (`pok`); `rejected` – refused (an error of the tax\nadministration or of the data); a person sends it again from the administration; `skipped` – the\nrestaurant chose not to send it (\"Nevyřizovat\" in the administration, `error.code` `skipped`); `test` –\naccepted by the test environment only (a test certificate), not recorded.\n",
      "x-description-cs": "`pending` – čeká na odeslání nebo se po chybě odesílá znovu (i když provozovna ještě nemá certifikát);\n`accepted` – finanční správa ji přijala (`pok`); `rejected` – odmítnuto (chyba finanční správy nebo dat); znovu\nji odešle člověk z administrace; `skipped` – provozovna ji rozhodla neodeslat („Nevyřizovat“ v administraci,\n`error.code` `skipped`); `test` – přijalo ji jen testovací prostředí (testovací certifikát), evidovaná není.\n",
      "x-extensible-enum": [
       "pending",
       "accepted",
       "rejected",
       "skipped",
       "test"
      ]
     },
     "total": {
      "$ref": "#/components/schemas/Money",
      "description": "The recorded amount (celk_trzba).",
      "x-description-cs": "Evidovaná částka (celk_trzba)."
     },
     "prepaid_issued": {
      "description": "Vouchers sold (urceno_cerp_zuct).",
      "x-description-cs": "Prodané vouchery (urceno_cerp_zuct).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "prepaid_used": {
      "description": "Paid with vouchers (cerp_zuct).",
      "x-description-cs": "Zaplaceno vouchery (cerp_zuct).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "register_id": {
      "type": "string",
      "description": "The register's identifier sent to EET (id_pokl).",
      "x-description-cs": "Označení pokladny poslané do EET (id_pokl)."
     },
     "sequence": {
      "type": "string",
      "description": "The sequence number sent to EET (porad_cis).",
      "x-description-cs": "Pořadové číslo poslané do EET (porad_cis)."
     },
     "unit_id": {
      "type": "string",
      "description": "The registration unit from DIS+ (id_jednotky).",
      "x-description-cs": "Evidenční jednotka z DIS+ (id_jednotky)."
     },
     "sold_at": {
      "type": "string",
      "description": "The time of the sale exactly as sent (dat_trzby).",
      "x-description-cs": "Čas tržby přesně jak se poslal (dat_trzby)."
     },
     "pok": {
      "type": [
       "string",
       "null"
      ],
      "description": "The confirmation code from the tax administration; ends with `-ff` in the test environment.",
      "x-description-cs": "Potvrzovací kód od finanční správy; v testovacím prostředí končí `-ff`."
     },
     "environment": {
      "type": [
       "string",
       "null"
      ],
      "description": "`production` – the real EET 2.0; `playground` – the test environment (a test certificate); `null` before the first attempt to send it.",
      "x-description-cs": "`production` – ostré EET 2.0; `playground` – testovací prostředí (testovací certifikát); `null` před prvním pokusem o odeslání.",
      "x-extensible-enum": [
       "production",
       "playground",
       null
      ]
     },
     "error": {
      "anyOf": [
       {
        "type": "object",
        "required": [
         "code",
         "message"
        ],
        "properties": {
         "code": {
          "type": "string"
         },
         "message": {
          "type": "string"
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "warnings": {
      "type": "array",
      "description": "Warnings of the tax administration (the sale was still accepted).",
      "x-description-cs": "Varování finanční správy (tržba se i tak přijala).",
      "items": {
       "type": "object",
       "required": [
        "code",
        "message"
       ],
       "properties": {
        "code": {
         "type": "integer"
        },
        "message": {
         "type": "string"
        }
       }
      }
     },
     "deadline_at": {
      "$ref": "#/components/schemas/Timestamp",
      "description": "48 hours after the sale – the legal deadline when the sale could not be sent at once.",
      "x-description-cs": "48 hodin po tržbě – zákonná lhůta, když tržba nešla odeslat hned."
     }
    }
   },
   "ReceiptCancellationRef": {
    "type": "object",
    "required": [
     "receipt_id",
     "issued_at",
     "reason"
    ],
    "properties": {
     "receipt_id": {
      "type": "string",
      "format": "uuid"
     },
     "issued_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "reason": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Receipt": {
    "type": "object",
    "description": "A receipt or a cancellation document (`kind`) issued through this API by a register of the restaurant, as the\nserver priced and saved it. Money is in minor units; on a cancellation document the amounts are negative.\n",
    "x-description-cs": "Účtenka nebo storno doklad (`kind`), které přes toto API vystavila pokladna provozovny, tak, jak je server\nspočítal a uložil. Peníze jsou v nejmenších jednotkách; na storno dokladu jsou částky záporné.\n",
    "required": [
     "id",
     "restaurant_id",
     "device_id",
     "number",
     "kind",
     "status",
     "issued_at",
     "received_at",
     "offline",
     "issued_by",
     "approved_by",
     "table_name",
     "order_type",
     "customer_id",
     "note",
     "lines",
     "discounts",
     "totals",
     "payments",
     "tips",
     "price_differences",
     "kitchen_number",
     "cancels",
     "cancelled_by",
     "eet",
     "shift_closed_at"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the receipt or of the cancellation document, in lower case.",
      "x-description-cs": "Vaše UUID účtenky nebo storno dokladu, malými písmeny."
     },
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "device_id": {
      "description": "The paired device that issued it (for a cancellation document, the device that cancelled).",
      "x-description-cs": "Spárované zařízení, které ji vystavilo (u storno dokladu zařízení, které stornovalo).",
      "$ref": "#/components/schemas/Id"
     },
     "number": {
      "type": "integer",
      "description": "The number from the register's counter; receipts and cancellation documents are numbered separately.",
      "x-description-cs": "Číslo z počítadla pokladny; účtenky a storno doklady se číslují zvlášť."
     },
     "kind": {
      "type": "string",
      "description": "`sale` – a receipt; `storno` – a cancellation document with negative amounts.",
      "x-description-cs": "`sale` – účtenka; `storno` – storno doklad se zápornými částkami.",
      "x-extensible-enum": [
       "sale",
       "storno"
      ]
     },
     "status": {
      "type": "string",
      "description": "`issued` – valid; `cancelled` – a sale cancelled through `cancelReceipt` (see `cancelled_by`). A cancellation\ndocument is always `issued`. A cancellation made in the kitchen or in the administration does not change it.\n",
      "x-description-cs": "`issued` – platná; `cancelled` – účtenka stornovaná přes `cancelReceipt` (viz `cancelled_by`). Storno doklad\nje vždy `issued`. Storno v kuchyni nebo v administraci stav nemění.\n",
      "x-extensible-enum": [
       "issued",
       "cancelled"
      ]
     },
     "issued_at": {
      "description": "When it was paid, by the clock of the device; for a cancellation document when the server issued it.",
      "x-description-cs": "Kdy byla zaplacena, podle hodin zařízení; u storno dokladu kdy ho vystavil server.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "received_at": {
      "description": "When the server received it the first time.",
      "x-description-cs": "Kdy ji server poprvé přijal.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "offline": {
      "type": "boolean",
      "description": "Recorded offline (`ReceiptCreate.offline`); always `false` on a cancellation document.",
      "x-description-cs": "Pořízena offline (`ReceiptCreate.offline`); na storno dokladu vždy `false`."
     },
     "issued_by": {
      "description": "The employee who issued it – the signed-in one, or `issued_by_id` of an offline receipt.",
      "x-description-cs": "Zaměstnanec, který ji vystavil – přihlášený, nebo `issued_by_id` offline účtenky.",
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "approved_by": {
      "description": "The register manager who approved manual discounts or prices of an employee (`manager_credential`, or\n`approved_by_id` of an offline receipt); `null` when nobody approved – also when the issuer is a manager.\n",
      "x-description-cs": "Vedoucí pokladny, který zaměstnanci schválil ruční slevu nebo cenu (`manager_credential`, nebo `approved_by_id`\noffline účtenky); `null`, když nikdo neschvaloval – i když účtenku vystavil vedoucí.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/EmployeeRef"
       },
       {
        "type": "null"
       }
      ]
     },
     "table_name": {
      "type": [
       "string",
       "null"
      ],
      "description": "The table, as sent; `null` when none.",
      "x-description-cs": "Stůl, jak přišel; `null`, když žádný."
     },
     "order_type": {
      "type": "string",
      "description": "As `ReceiptCreate.order_type` – `dine_in` or `takeaway`; a cancellation document copies it.",
      "x-description-cs": "Jako `ReceiptCreate.order_type` – `dine_in` nebo `takeaway`; storno doklad ho přebírá.",
      "x-extensible-enum": [
       "dine_in",
       "takeaway"
      ]
     },
     "customer_id": {
      "description": "The customer from `searchCustomerDirectory` who earned loyalty points; `null` when none.",
      "x-description-cs": "Zákazník ze `searchCustomerDirectory`, který získal věrnostní body; `null`, když žádný.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "description": "The note, as sent; `null` when none.",
      "x-description-cs": "Poznámka, jak přišla; `null`, když žádná."
     },
     "lines": {
      "type": "array",
      "description": "The lines as the server priced them.",
      "x-description-cs": "Řádky tak, jak je server spočítal.",
      "items": {
       "$ref": "#/components/schemas/ReceiptLine"
      }
     },
     "discounts": {
      "type": "array",
      "description": "Discounts of items (`line_id`) and of the whole receipt.",
      "x-description-cs": "Slevy položek (`line_id`) a celé účtenky.",
      "items": {
       "$ref": "#/components/schemas/ReceiptDiscount"
      }
     },
     "totals": {
      "description": "`items` – all lines, vouchers sold included; `charges` – always zero on a receipt; `discounts` – negative;\n`rounding` – the rounding of the cash part; `total` – what was paid, without tips. `vat` leaves out vouchers\nsold and the rounding.\n",
      "x-description-cs": "`items` – všechny řádky včetně prodaných voucherů; `charges` – na účtence vždy nula; `discounts` – záporné;\n`rounding` – zaokrouhlení části placené hotově; `total` – kolik se zaplatilo, bez dýška. `vat` neobsahuje\nprodané vouchery ani zaokrouhlení.\n",
      "$ref": "#/components/schemas/Totals"
     },
     "payments": {
      "type": "array",
      "description": "The payments as sent, voucher codes masked.",
      "x-description-cs": "Platby, jak přišly, kódy voucherů maskovaně.",
      "items": {
       "$ref": "#/components/schemas/ReceiptPayment"
      }
     },
     "tips": {
      "$ref": "#/components/schemas/Money",
      "description": "All tips; not part of `totals.total`.",
      "x-description-cs": "Všechna dýška; nejsou součástí `totals.total`."
     },
     "price_differences": {
      "type": "array",
      "description": "Prices that differ from the catalog; always empty on a cancellation document.",
      "x-description-cs": "Ceny, které se liší od sortimentu; na storno dokladu vždy prázdné.",
      "items": {
       "$ref": "#/components/schemas/ReceiptPriceDifference"
      }
     },
     "kitchen_number": {
      "type": [
       "string",
       "null"
      ],
      "description": "The number in the kitchen queue when sent to the kitchen, three digits as on the kitchen display (`027`), like `Order.kitchen_number`.",
      "x-description-cs": "Číslo ve frontě kuchyně, když šla do kuchyně, na tři číslice jako na kuchyňském displeji (`027`), stejně jako `Order.kitchen_number`."
     },
     "cancels": {
      "type": [
       "string",
       "null"
      ],
      "format": "uuid",
      "description": "On a cancellation document, the receipt it cancels.",
      "x-description-cs": "U storno dokladu účtenka, kterou ruší."
     },
     "cancelled_by": {
      "description": "On a cancelled receipt, its cancellation document with the reason (the cancellation document itself does not carry the reason).",
      "x-description-cs": "U stornované účtenky její storno doklad s důvodem (samotný storno doklad důvod nenese).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ReceiptCancellationRef"
       },
       {
        "type": "null"
       }
      ]
     },
     "eet": {
      "description": "`null` when the restaurant does not record sales in EET 2.0, nothing was to be recorded (for example only company\naccount or invoice payments) or the account is the public demo account. In the `receipt.created` event it is the\nstate before sending (usually `pending`); read the receipt for the current state.\n",
      "x-description-cs": "`null`, když provozovna tržby v EET 2.0 neeviduje, nebylo co evidovat (třeba jen platby na firemní účet nebo\nfakturou) nebo jde o veřejný ukázkový účet. V události `receipt.created` je to stav před odesláním (obvykle\n`pending`); aktuální stav zjistíte načtením účtenky.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ReceiptEet"
       },
       {
        "type": "null"
       }
      ]
     },
     "shift_closed_at": {
      "description": "When the shift close of the device included the receipt; `null` while the shift is open.",
      "x-description-cs": "Kdy účtenku zahrnula uzávěrka zařízení; `null`, dokud je směna otevřená.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReceiptPage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Receipt"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "ReceiptPreview": {
    "type": "object",
    "required": [
     "lines",
     "discounts",
     "totals",
     "price_differences",
     "cash_amount_due",
     "eet_recorded"
    ],
    "properties": {
     "lines": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ReceiptLine"
      }
     },
     "discounts": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ReceiptDiscount"
      }
     },
     "totals": {
      "$ref": "#/components/schemas/Totals"
     },
     "price_differences": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ReceiptPriceDifference"
      }
     },
     "cash_amount_due": {
      "$ref": "#/components/schemas/Money",
      "description": "What to take in cash – `totals.total` rounded to whole crowns.",
      "x-description-cs": "Kolik vybrat v hotovosti – `totals.total` zaokrouhlená na celé koruny."
     },
     "eet_recorded": {
      "type": "boolean",
      "description": "The restaurant records sales in EET 2.0.",
      "x-description-cs": "Provozovna eviduje tržby v EET 2.0."
     }
    }
   },
   "PosShiftSummary": {
    "type": "object",
    "required": [
     "device_id",
     "opened_at",
     "receipts",
     "totals",
     "payments",
     "tips",
     "vat",
     "vouchers",
     "eet",
     "open_tabs",
     "cash_movements",
     "device_ids",
     "by_device",
     "by_employee"
    ],
    "properties": {
     "device_id": {
      "$ref": "#/components/schemas/Id"
     },
     "opened_at": {
      "description": "The first receipt of the shift; `null` without receipts.",
      "x-description-cs": "První účtenka směny; `null` bez účtenek.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "receipts": {
      "type": "object",
      "required": [
       "sales",
       "storno"
      ],
      "properties": {
       "sales": {
        "type": "integer"
       },
       "storno": {
        "type": "integer"
       }
      }
     },
     "totals": {
      "type": "object",
      "required": [
       "sales",
       "storno",
       "net"
      ],
      "properties": {
       "sales": {
        "$ref": "#/components/schemas/Money"
       },
       "storno": {
        "$ref": "#/components/schemas/Money"
       },
       "net": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "payments": {
      "type": "array",
      "description": "Net amounts by payment method (cancellations included).",
      "x-description-cs": "Čisté částky podle způsobu platby (včetně storen).",
      "items": {
       "type": "object",
       "required": [
        "method",
        "amount",
        "tips",
        "count"
       ],
       "properties": {
        "method": {
         "type": "string",
         "x-extensible-enum": [
          "cash",
          "card",
          "meal_voucher",
          "company_account",
          "invoice",
          "voucher"
         ]
        },
        "amount": {
         "$ref": "#/components/schemas/Money"
        },
        "tips": {
         "$ref": "#/components/schemas/Money"
        },
        "count": {
         "type": "integer"
        }
       }
      }
     },
     "tips": {
      "$ref": "#/components/schemas/Money"
     },
     "vat": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/VatBreakdown"
      }
     },
     "vouchers": {
      "type": "object",
      "required": [
       "sold",
       "redeemed"
      ],
      "properties": {
       "sold": {
        "$ref": "#/components/schemas/Money"
       },
       "redeemed": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "eet": {
      "type": "object",
      "description": "Sales of the shift not yet accepted by EET 2.0.",
      "x-description-cs": "Tržby směny, které EET 2.0 ještě nepřijalo.",
      "required": [
       "pending",
       "rejected"
      ],
      "properties": {
       "pending": {
        "type": "integer"
       },
       "rejected": {
        "type": "integer"
       }
      }
     },
     "open_tabs": {
      "type": "object",
      "description": "Tabs still open in the restaurant (of all devices) and their total. The close does not close them – show\nthem before closing, so no table stays unpaid overnight.\n",
      "x-description-cs": "Účty stolů, které jsou v provozovně ještě otevřené (všech zařízení), a jejich součet. Uzávěrka je nezavírá –\nukažte je před uzavřením, ať přes noc nezůstane nezaplacený stůl.\n",
      "required": [
       "count",
       "total"
      ],
      "properties": {
       "count": {
        "type": "integer"
       },
       "total": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "cash_movements": {
      "$ref": "#/components/schemas/PosShiftCashMovements"
     },
     "device_ids": {
      "type": "array",
      "description": "Devices the summary covers – this one and those from `devices` (or `device_ids` of the close).",
      "x-description-cs": "Zařízení, která souhrn pokrývá – toto a ta z `devices` (nebo `device_ids` uzávěrky).",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "by_device": {
      "type": "array",
      "description": "Per device, in the order of `device_ids`.",
      "x-description-cs": "Po zařízeních, v pořadí `device_ids`.",
      "items": {
       "$ref": "#/components/schemas/PosShiftDevicePart"
      }
     },
     "by_employee": {
      "type": "array",
      "description": "Per employee who issued the receipts, from the highest net amount – the cash payments and cash tips are what the\nemployee hands over.\n",
      "x-description-cs": "Po zaměstnancích, kteří účtenky vystavili, od nejvyšší čisté částky – platby hotově a dýško v hotovosti jsou to,\nco zaměstnanec odvádí.\n",
      "items": {
       "$ref": "#/components/schemas/PosShiftEmployeePart"
      }
     }
    }
   },
   "PosShiftDevicePart": {
    "type": "object",
    "description": "The part of a shift issued on one device.",
    "x-description-cs": "Část směny vystavená na jednom zařízení.",
    "required": [
     "device_id",
     "name",
     "receipts",
     "net",
     "payments"
    ],
    "properties": {
     "device_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "description": "Name of the device as it was paired.",
      "x-description-cs": "Název zařízení ze spárování.",
      "examples": [
       "Pokladna u baru"
      ]
     },
     "receipts": {
      "type": "object",
      "required": [
       "sales",
       "storno"
      ],
      "properties": {
       "sales": {
        "type": "integer"
       },
       "storno": {
        "type": "integer"
       }
      }
     },
     "net": {
      "$ref": "#/components/schemas/Money"
     },
     "payments": {
      "type": "array",
      "description": "Net amounts by payment method (cancellations included), with tips.",
      "x-description-cs": "Čisté částky podle způsobu platby (včetně storen), s dýškem.",
      "items": {
       "type": "object",
       "required": [
        "method",
        "amount",
        "tips",
        "count"
       ],
       "properties": {
        "method": {
         "type": "string",
         "x-extensible-enum": [
          "cash",
          "card",
          "meal_voucher",
          "company_account",
          "invoice",
          "voucher"
         ]
        },
        "amount": {
         "$ref": "#/components/schemas/Money"
        },
        "tips": {
         "$ref": "#/components/schemas/Money"
        },
        "count": {
         "type": "integer"
        }
       }
      }
     }
    }
   },
   "PosShiftEmployeePart": {
    "type": "object",
    "description": "The part of a shift issued by one employee – their cash payments and cash tips are what they hand over.",
    "x-description-cs": "Část směny, kterou vystavil jeden zaměstnanec – jeho platby hotově a dýško v hotovosti odvádí.",
    "required": [
     "employee",
     "receipts",
     "net",
     "payments"
    ],
    "properties": {
     "employee": {
      "description": "Who issued the receipts; `null` for receipts without an employee.",
      "x-description-cs": "Kdo účtenky vystavil; `null` u účtenek bez zaměstnance.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/EmployeeRef"
       },
       {
        "type": "null"
       }
      ]
     },
     "receipts": {
      "type": "object",
      "required": [
       "sales",
       "storno"
      ],
      "properties": {
       "sales": {
        "type": "integer"
       },
       "storno": {
        "type": "integer"
       }
      }
     },
     "net": {
      "$ref": "#/components/schemas/Money"
     },
     "payments": {
      "type": "array",
      "description": "Net amounts by payment method (cancellations included), with tips.",
      "x-description-cs": "Čisté částky podle způsobu platby (včetně storen), s dýškem.",
      "items": {
       "type": "object",
       "required": [
        "method",
        "amount",
        "tips",
        "count"
       ],
       "properties": {
        "method": {
         "type": "string",
         "x-extensible-enum": [
          "cash",
          "card",
          "meal_voucher",
          "company_account",
          "invoice",
          "voucher"
         ]
        },
        "amount": {
         "$ref": "#/components/schemas/Money"
        },
        "tips": {
         "$ref": "#/components/schemas/Money"
        },
        "count": {
         "type": "integer"
        }
       }
      }
     }
    }
   },
   "PosShiftCashMovements": {
    "type": "object",
    "description": "Cash movements this device recorded since its last close (`createCashMovement`), without the opening balance\nand without movements deleted in the administration.\n",
    "x-description-cs": "Pohyby hotovosti, které toto zařízení zapsalo od své poslední uzávěrky (`createCashMovement`), bez počátečního\nstavu a bez pohybů smazaných v administraci.\n",
    "required": [
     "count",
     "deposits",
     "incomes",
     "withdrawals",
     "expenses",
     "net"
    ],
    "properties": {
     "count": {
      "type": "integer",
      "minimum": 0
     },
     "deposits": {
      "$ref": "#/components/schemas/Money"
     },
     "incomes": {
      "$ref": "#/components/schemas/Money"
     },
     "withdrawals": {
      "$ref": "#/components/schemas/Money",
      "description": "Positive amount taken out.",
      "x-description-cs": "Kladná vybraná částka."
     },
     "expenses": {
      "$ref": "#/components/schemas/Money",
      "description": "Positive amount paid out.",
      "x-description-cs": "Kladná vydaná částka."
     },
     "net": {
      "$ref": "#/components/schemas/Money",
      "description": "Deposits and incomes minus withdrawals and expenses; part of the expected cash of the close.",
      "x-description-cs": "Vklady a příjmy minus výběry a výdaje; část očekávané hotovosti uzávěrky."
     }
    }
   },
   "CashMovementInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "kind",
     "amount"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the movement, made on the device.",
      "x-description-cs": "Vaše UUID pohybu, vytvořené na zařízení."
     },
     "kind": {
      "type": "string",
      "enum": [
       "opening",
       "deposit",
       "income",
       "withdrawal",
       "expense"
      ],
      "description": "`deposit` and `income` add to the drawer, `withdrawal` and `expense` take from it, `opening` starts the book\nwith the cash in the drawer (once). `withdrawal`, `expense` and `opening` need a register manager.\n",
      "x-description-cs": "`deposit` a `income` do kasy přidávají, `withdrawal` a `expense` z ní berou, `opening` začíná knihu stavem\nkasy (jednou). `withdrawal`, `expense` a `opening` potřebují vedoucího pokladny.\n"
     },
     "amount": {
      "$ref": "#/components/schemas/MoneyInput",
      "description": "Always positive (zero only for `opening`); the kind gives the direction.",
      "x-description-cs": "Vždy kladná (nula jen u `opening`); směr dává druh."
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 255,
      "description": "What it was for; required except for `opening`.",
      "x-description-cs": "O co šlo; povinné kromě `opening`."
     },
     "document": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "description": "Number of the paper document (a till slip, a supplier invoice); goes to Pohoda as the document number.",
      "x-description-cs": "Číslo papírového dokladu (paragon, faktura dodavatele); jde do Pohody jako číslo dokladu."
     },
     "occurred_at": {
      "description": "When the money moved; now when left out. At most 7 days back.",
      "x-description-cs": "Kdy se peníze pohnuly; bez něj teď. Nejvýš 7 dní zpátky.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "manager_credential": {
      "description": "PIN or card of a register manager approving a withdrawal, an expense or the opening balance now.",
      "x-description-cs": "PIN nebo čip vedoucího pokladny, který teď schvaluje výběr, výdaj nebo počáteční stav.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/StaffCredential"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "CashMovement": {
    "type": "object",
    "required": [
     "id",
     "number",
     "kind",
     "amount",
     "note",
     "document",
     "occurred_at",
     "recorded_at",
     "recorded_by",
     "approved_by",
     "device_id"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the movement.",
      "x-description-cs": "Vaše UUID pohybu."
     },
     "number": {
      "$ref": "#/components/schemas/Id",
      "description": "Number of the movement in the cash book (`CashBookEntry.number`).",
      "x-description-cs": "Číslo pohybu v pokladní knize (`CashBookEntry.number`)."
     },
     "kind": {
      "type": "string",
      "x-extensible-enum": [
       "opening",
       "deposit",
       "income",
       "withdrawal",
       "expense"
      ]
     },
     "amount": {
      "$ref": "#/components/schemas/Money",
      "description": "As recorded – always positive; the kind gives the direction.",
      "x-description-cs": "Jak se zapsala – vždy kladná; směr dává druh."
     },
     "note": {
      "type": "string"
     },
     "document": {
      "type": [
       "string",
       "null"
      ]
     },
     "occurred_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "recorded_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "recorded_by": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "approved_by": {
      "description": "The register manager who approved it (also the signed-in manager); `null` without approval.",
      "x-description-cs": "Vedoucí pokladny, který ho schválil (i přihlášený vedoucí); `null` bez schválení.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/EmployeeRef"
       },
       {
        "type": "null"
       }
      ]
     },
     "device_id": {
      "$ref": "#/components/schemas/Id"
     }
    }
   },
   "CashBook": {
    "type": "object",
    "required": [
     "date_from",
     "date_to",
     "opening",
     "balance_start",
     "balance_end",
     "balance_now",
     "days",
     "movements"
    ],
    "properties": {
     "date_from": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "date_to": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "opening": {
      "description": "The opening balance that started the book; `null` while the book has not started.",
      "x-description-cs": "Počáteční stav, kterým kniha začala; `null`, dokud nezačala.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "amount",
         "occurred_at"
        ],
        "properties": {
         "amount": {
          "$ref": "#/components/schemas/Money"
         },
         "occurred_at": {
          "$ref": "#/components/schemas/Timestamp"
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "balance_start": {
      "description": "Cash at the start of `date_from`; `null` before the opening balance.",
      "x-description-cs": "Hotovost na začátku `date_from`; `null` před počátečním stavem.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "balance_end": {
      "description": "Cash at the end of `date_to` (now for today).",
      "x-description-cs": "Hotovost na konci `date_to` (u dneška teď).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "balance_now": {
      "description": "Cash the book expects in the drawer now.",
      "x-description-cs": "Hotovost, kterou kniha teď očekává v kase.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "days": {
      "type": "array",
      "description": "Every day of the period, oldest first.",
      "x-description-cs": "Každý den období, od nejstaršího.",
      "items": {
       "$ref": "#/components/schemas/CashBookDay"
      }
     },
     "movements": {
      "type": "array",
      "description": "Movements recorded by hand in the period, oldest first, deleted ones included.",
      "x-description-cs": "Ručně zapsané pohyby v období, od nejstaršího, i smazané.",
      "items": {
       "$ref": "#/components/schemas/CashBookEntry"
      }
     }
    }
   },
   "CashBookDay": {
    "type": "object",
    "required": [
     "date",
     "start",
     "cash_receipts",
     "receipts_count",
     "cash_tips",
     "income",
     "outgoings",
     "differences",
     "end"
    ],
    "properties": {
     "date": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "start": {
      "description": "Cash at the start of the day; `null` before the opening balance.",
      "x-description-cs": "Hotovost na začátku dne; `null` před počátečním stavem.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "cash_receipts": {
      "$ref": "#/components/schemas/Money",
      "description": "Receipts paid in cash (cancellations subtract), from the opening balance on.",
      "x-description-cs": "Účtenky placené hotově (storna odečítají), od počátečního stavu."
     },
     "receipts_count": {
      "type": "integer"
     },
     "cash_tips": {
      "$ref": "#/components/schemas/Money"
     },
     "income": {
      "$ref": "#/components/schemas/Money",
      "description": "Deposits and other income.",
      "x-description-cs": "Vklady a jiné příjmy."
     },
     "outgoings": {
      "$ref": "#/components/schemas/Money",
      "description": "Withdrawals and expenses, as a positive amount.",
      "x-description-cs": "Výběry a výdaje, kladnou částkou."
     },
     "differences": {
      "$ref": "#/components/schemas/Money",
      "description": "Differences found by cash checks (negative = missing cash).",
      "x-description-cs": "Rozdíly zjištěné kontrolou pokladny (záporné = chyběla hotovost)."
     },
     "end": {
      "description": "Cash at the end of the day; `null` before the opening balance.",
      "x-description-cs": "Hotovost na konci dne; `null` před počátečním stavem.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "CashBookEntry": {
    "type": "object",
    "required": [
     "number",
     "kind",
     "amount",
     "note",
     "document",
     "occurred_at",
     "recorded_by",
     "device_id",
     "pos_movement_id",
     "deleted_at",
     "deleted_by"
    ],
    "properties": {
     "number": {
      "$ref": "#/components/schemas/Id"
     },
     "kind": {
      "type": "string",
      "x-extensible-enum": [
       "opening",
       "deposit",
       "income",
       "withdrawal",
       "expense",
       "difference"
      ]
     },
     "amount": {
      "$ref": "#/components/schemas/Money",
      "description": "Effect on the drawer – deposits and income positive, withdrawals and expenses negative, a difference with its\nsign; for `opening` the cash in the drawer at the start.\n",
      "x-description-cs": "Vliv na kasu – vklady a příjmy kladně, výběry a výdaje záporně, rozdíl se znaménkem; u `opening` hotovost\nv kase na začátku.\n"
     },
     "note": {
      "type": "string"
     },
     "document": {
      "type": [
       "string",
       "null"
      ]
     },
     "occurred_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "recorded_by": {
      "type": "string",
      "description": "Who recorded it – the name in the administration, or the employee and the device of a register.",
      "x-description-cs": "Kdo ho zapsal – jméno v administraci, nebo zaměstnanec a zařízení pokladny."
     },
     "device_id": {
      "description": "The register that recorded it through this API; `null` for the administration.",
      "x-description-cs": "Pokladna, která ho zapsala přes toto API; `null` u administrace.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "pos_movement_id": {
      "description": "`CashMovement.id` of the register; `null` for the administration.",
      "x-description-cs": "`CashMovement.id` z pokladny; `null` u administrace.",
      "type": [
       "string",
       "null"
      ],
      "format": "uuid"
     },
     "deleted_at": {
      "description": "When it was deleted in the administration; a deleted movement does not count.",
      "x-description-cs": "Kdy byl v administraci smazán; smazaný pohyb se nepočítá.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "deleted_by": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "PosShiftCloseRequest": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "Your UUID of the close.",
      "x-description-cs": "Vaše UUID uzávěrky."
     },
     "counted_cash": {
      "description": "Cash counted in the drawer.",
      "x-description-cs": "Napočítaná hotovost v pokladně.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/MoneyInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 255
     },
     "device_ids": {
      "type": "array",
      "maxItems": 50,
      "uniqueItems": true,
      "description": "Other devices of the restaurant whose open shifts this close takes too (`GET …/pos-shift?devices=all` shows\nthem first). Needs a register manager.\n",
      "x-description-cs": "Další zařízení provozovny, jejichž otevřené směny tato uzávěrka vezme také (nejdřív je ukáže\n`GET …/pos-shift?devices=all`). Potřebuje vedoucího pokladny.\n",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "legacy_receipt_ids": {
      "type": "array",
      "maxItems": 2000,
      "uniqueItems": true,
      "description": "Profirest's own register after moving between API v1 and v2 in the middle of the shift: UUIDs of the receipts of\nthis shift it issued in API v1. The close takes them in as well (each only once, even across both APIs).\n",
      "x-description-cs": "Vlastní pokladna Profirestu po přechodu mezi API v1 a v2 uprostřed směny: UUID účtenek této směny, které\nvystavila v API v1. Uzávěrka je vezme také (každou jen jednou, i přes obě API).\n",
      "items": {
       "type": "string",
       "format": "uuid"
      }
     },
     "manager_credential": {
      "description": "PIN or card of a register manager approving `device_ids` now (not needed when the manager is signed in).",
      "x-description-cs": "PIN nebo čip vedoucího pokladny, který teď schvaluje `device_ids` (není potřeba, když je vedoucí přihlášený).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/StaffCredential"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "PosShiftClose": {
    "type": "object",
    "required": [
     "id",
     "device_id",
     "closed_at",
     "closed_by",
     "summary",
     "cash_expected",
     "counted_cash",
     "cash_difference",
     "note"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "device_id": {
      "$ref": "#/components/schemas/Id"
     },
     "closed_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "closed_by": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "summary": {
      "$ref": "#/components/schemas/PosShiftSummary"
     },
     "cash_expected": {
      "$ref": "#/components/schemas/Money",
      "description": "Cash payments and cash tips of the shift plus `summary.cash_movements.net` – deposits and incomes minus\nwithdrawals and expenses this device recorded (`createCashMovement`). It is the cash the drawer should hold\nwhen the shift started with an empty drawer or with the change recorded as a deposit; it can be negative\nwhen more was taken out than came in during the shift.\n",
      "x-description-cs": "Platby hotově a dýško v hotovosti za směnu plus `summary.cash_movements.net` – vklady a příjmy minus výběry\na výdaje, které zařízení zapsalo (`createCashMovement`). Tolik má být v kase, když směna začala s prázdnou\nkasou nebo s drobnými zapsanými jako vklad; může být záporná, když se za směnu víc vybralo, než přišlo.\n"
     },
     "counted_cash": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "cash_difference": {
      "description": "counted − expected; negative means missing cash.",
      "x-description-cs": "napočítáno − očekáváno; záporné znamená chybějící hotovost.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "PosShiftClosePage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/PosShiftClose"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Problem": {
    "type": "object",
    "description": "RFC 9457 problem details.",
    "x-description-cs": "Popis chyby podle RFC 9457.",
    "required": [
     "type",
     "title",
     "status",
     "code",
     "detail",
     "instance",
     "request_id",
     "errors",
     "existing_id",
     "candidates",
     "paid_by"
    ],
    "properties": {
     "type": {
      "type": "string",
      "format": "uri",
      "description": "Stable URL that documents the error code.",
      "x-description-cs": "Stálá adresa s popisem kódu chyby.",
      "examples": [
       "https://api.mujprofirest.cz/v2/docs/errors#quote_expired"
      ]
     },
     "title": {
      "type": "string",
      "description": "Short summary for a person, in the language of `Content-Language`.",
      "x-description-cs": "Krátký popis pro člověka v jazyce podle `Content-Language`."
     },
     "status": {
      "type": "integer",
      "examples": [
       409
      ]
     },
     "code": {
      "type": "string",
      "description": "Machine-readable error code from the catalog. Never changes. What every code means and what to do is in the\nerror catalog (`x-error-catalog` of `openapi.json`, the *Error catalog* section of the documentation). Codes\nmay be added; treat an unknown one by its HTTP `status`.\n",
      "x-description-cs": "Strojový kód chyby z katalogu. Nikdy se nemění. Co který kód znamená a co dělat, je v katalogu chyb\n(`x-error-catalog` v `openapi.json`, kapitola *Katalog chyb* dokumentace). Kódy mohou přibýt; neznámý\nposuzujte podle HTTP `status`.\n",
      "x-extensible-enum": [
       "malformed_request",
       "idempotency_key_missing",
       "invalid_token",
       "insufficient_scope",
       "not_found",
       "method_not_allowed",
       "not_acceptable",
       "conflict",
       "idempotency_in_progress",
       "external_id_conflict",
       "cursor_expired",
       "precondition_failed",
       "payload_too_large",
       "unsupported_media_type",
       "validation_failed",
       "idempotency_key_mismatch",
       "precondition_required",
       "rate_limited",
       "internal_error",
       "not_implemented",
       "service_unavailable",
       "restaurant_closed",
       "ordering_disabled",
       "delivery_unavailable",
       "pickup_unavailable",
       "outside_delivery_zone",
       "time_unavailable",
       "express_unavailable",
       "product_unavailable",
       "quote_expired",
       "quote_already_used",
       "payment_amount_mismatch",
       "order_not_cancellable",
       "order_not_awaiting_payment",
       "customer_not_verified",
       "verification_failed",
       "verification_resend_too_early",
       "sms_quota_exceeded",
       "sms_country_not_supported",
       "voucher_invalid",
       "voucher_expired",
       "voucher_used_up",
       "voucher_blocked",
       "voucher_not_accepted_here",
       "voucher_attempts_exceeded",
       "promo_code_invalid",
       "promo_code_expired",
       "promo_code_not_applicable",
       "promo_code_used_up",
       "promo_code_attempts_exceeded",
       "promotion_changed",
       "device_required",
       "legacy_identity_unsupported",
       "no_legacy_identity",
       "staff_session_required",
       "staff_session_expired",
       "staff_credentials_invalid",
       "staff_ambiguous",
       "staff_locked",
       "license_expired",
       "module_not_licensed",
       "reservation_unavailable",
       "reservation_not_allowed",
       "reservation_state_conflict",
       "lodging_state_conflict",
       "stay_state_conflict",
       "lodging_room_unavailable",
       "attendance_not_enabled",
       "attendance_state_conflict",
       "offline_records_disabled",
       "occurred_at_out_of_range",
       "punch_id_conflict",
       "absence_requests_disabled",
       "absence_request_not_allowed",
       "absence_request_conflict",
       "absence_request_decided",
       "staff_role_missing",
       "portion_tracking_disabled",
       "ticket_cancelled",
       "ticket_already_delivered",
       "already_paid",
       "payment_method_not_changeable",
       "amount_mismatch",
       "note_required",
       "nothing_to_complete",
       "action_already_undone",
       "ticket_not_amendable",
       "price_changed",
       "manager_approval_required",
       "receipt_id_conflict",
       "receipt_number_conflict",
       "receipt_already_cancelled",
       "receipt_not_cancellable",
       "receipt_payment_not_changeable",
       "pos_shift_closed",
       "issued_at_out_of_range",
       "pos_shift_empty",
       "cash_book_not_started",
       "cash_book_already_started",
       "voucher_not_for_sale",
       "tab_closed",
       "stock_taking_id_conflict",
       "table_not_found",
       "visit_ended",
       "ordering_paused",
       "table_not_open",
       "device_not_verified",
       "join_code_invalid",
       "join_locked",
       "join_not_available",
       "product_not_orderable",
       "too_many_pending_orders",
       "order_not_pending",
       "restaurant_offline",
       "inbox_item_conflict",
       "main_device_conflict",
       "upload_closed",
       "upload_incomplete"
      ],
      "examples": [
       "quote_expired"
      ]
     },
     "detail": {
      "type": [
       "string",
       "null"
      ],
      "description": "What happened in this particular case.",
      "x-description-cs": "Co se stalo v tomto konkrétním případě."
     },
     "instance": {
      "type": [
       "string",
       "null"
      ],
      "description": "Path of the request.",
      "x-description-cs": "Cesta požadavku."
     },
     "request_id": {
      "type": "string"
     },
     "errors": {
      "type": "array",
      "description": "Field-level problems for `validation_failed` and some business errors; empty otherwise.",
      "x-description-cs": "Problémy u jednotlivých polí u `validation_failed` a některých obchodních chyb; jinak prázdné.",
      "items": {
       "$ref": "#/components/schemas/FieldError"
      }
     },
     "existing_id": {
      "description": "For `external_id_conflict` and `quote_already_used`, the ID of the existing object, when your connection\ncan see it; for `receipt_number_conflict` the receipt that already has the number; for `conflict` of\n`POST /customers` and `PATCH /customers/{customer_id}` the customer your connection already linked with that\nphone. `null` otherwise.\n",
      "x-description-cs": "U `external_id_conflict` a `quote_already_used` ID existujícího objektu, pokud ho vaše připojení vidí;\nu `receipt_number_conflict` účtenka, která už číslo má; u `conflict` z `POST /customers`\na `PATCH /customers/{customer_id}` zákazník, kterého vaše připojení s tímto telefonem už propojilo. Jinak\n`null`.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "candidates": {
      "type": "array",
      "description": "For `staff_ambiguous`, the employees who share the PIN; empty otherwise.",
      "x-description-cs": "U `staff_ambiguous` zaměstnanci, kteří mají stejný PIN; jinak prázdné.",
      "items": {
       "$ref": "#/components/schemas/EmployeeRef"
      }
     },
     "paid_by": {
      "description": "For `already_paid`, how and when the order was paid at the door – show it as paid and take no payment again; `null` otherwise.",
      "x-description-cs": "U `already_paid` čím a kdy se objednávka u dveří zaplatila – ukažte ji jako zaplacenou a platbu znovu neberte; jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/PaidBy"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "FieldError": {
    "type": "object",
    "required": [
     "pointer",
     "code",
     "message"
    ],
    "properties": {
     "pointer": {
      "type": "string",
      "description": "JSON Pointer (RFC 6901) to the field in the request body, for example `/items/2/quantity`.",
      "x-description-cs": "JSON Pointer (RFC 6901) na pole v těle požadavku, například `/items/2/quantity`."
     },
     "code": {
      "type": "string",
      "description": "What is wrong with the field: `required` – it is missing; `unknown_field` – the API does not know this field\nor query parameter; `invalid_type` – a wrong JSON type; `invalid_format` – the text does not match the\npattern or the format (also a `metadata` key); `invalid_value` – a value that is not allowed (not one of the\nlisted values, not a multiple of the step, not exactly one of the variants, or not allowed together with\nanother field); `too_short`, `too_long` – a text shorter or longer than allowed; `too_small`, `too_large` – a\nnumber, a list or an object under or over its limits; `unsupported_characters` – characters outside the\nBasic Multilingual Plane (emoji); `not_found` – the ID points to nothing your connection can see (a quote,\ncustomer, employee, zone, warehouse item, tab…); `duplicate` – the same value twice in the request (a voucher,\nan add-on, a line ID), or a phone your connection already linked; `not_allowed` – a valid value that may not\nbe used here (a channel of staff applications, halves of a product not sold in halves, a field that does not\nbelong to this situation); `too_many` – too many entries in total (`metadata`); `currency_mismatch` – not the\ncurrency of the restaurant; `option_not_in_group` – the option is not one of the item's product\n(`ProductOption.id`); `option_group_min`, `option_group_max` – fewer or more portions in a group of options\nthan allowed; `split_category_mismatch`, `split_size_mismatch` – the parts of a pizza are not from the same\ncategory or of the same size; `ingredient_not_removable` – the product of the line (or of the part) has no such\nremovable ingredient (`Product.removable_ingredients[].id`), or it is in the list twice;\n`calculator_key_mismatch` – the VAT rate of the line is not the rate of its key of the Calculator mode\n(`calculator_key_id`); `product_unavailable`, `product_not_orderable`, `price_changed`, `voucher_*` – the business error of the\nsame name, pointing at the field.\n",
      "x-description-cs": "Co je s polem špatně: `required` – chybí; `unknown_field` – toto pole nebo parametr adresy API nezná;\n`invalid_type` – špatný typ JSON; `invalid_format` – text neodpovídá vzoru nebo formátu (i klíč `metadata`);\n`invalid_value` – nepovolená hodnota (není mezi vyjmenovanými, není násobkem kroku, není právě jedna\nz variant, nebo nejde spolu s jiným polem); `too_short`, `too_long` – text kratší nebo delší, než je dovoleno;\n`too_small`, `too_large` – číslo, seznam nebo objekt pod nebo nad svými mezemi; `unsupported_characters` –\nznaky mimo základní rovinu Unicode (emoji); `not_found` – ID neukazuje na nic, co vaše připojení vidí\n(kalkulace, zákazník, zaměstnanec, zóna, skladová položka, účet stolu…); `duplicate` – stejná hodnota\nv požadavku dvakrát (voucher, příloha, ID řádku), nebo telefon, který vaše připojení už propojilo;\n`not_allowed` – platná hodnota, která se tu použít nesmí (kanál aplikací personálu, půlky produktu, který se\npo půlkách neprodává, pole, které do této situace nepatří); `too_many` – celkem příliš mnoho položek\n(`metadata`); `currency_mismatch` – jiná měna než měna provozovny; `option_not_in_group` – volba nepatří\nproduktu položky (`ProductOption.id`); `option_group_min`, `option_group_max` – ve skupině voleb méně nebo\nvíc porcí, než je dovoleno; `split_category_mismatch`, `split_size_mismatch` – díly pizzy nejsou ze stejné\nkategorie nebo stejné velikosti; `ingredient_not_removable` – produkt řádku (nebo dílu) takovou surovinu\nk odebrání nemá (`Product.removable_ingredients[].id`), nebo je v seznamu dvakrát; `calculator_key_mismatch` –\nsazba DPH řádku není sazba jeho tlačítka režimu Kalkulačka (`calculator_key_id`); `product_unavailable`,\n`product_not_orderable`, `price_changed`, `voucher_*` – obchodní chyba stejného jména, která ukazuje na pole.\n",
      "x-extensible-enum": [
       "required",
       "unknown_field",
       "invalid_type",
       "invalid_format",
       "invalid_value",
       "too_small",
       "too_large",
       "too_short",
       "too_long",
       "not_found",
       "duplicate",
       "unsupported_characters",
       "product_unavailable",
       "not_allowed",
       "too_many",
       "currency_mismatch",
       "price_changed",
       "voucher_invalid",
       "voucher_expired",
       "voucher_used_up",
       "voucher_blocked",
       "voucher_not_accepted_here",
       "voucher_not_for_sale",
       "product_not_orderable",
       "option_not_in_group",
       "option_group_min",
       "option_group_max",
       "split_category_mismatch",
       "split_size_mismatch",
       "ingredient_not_removable",
       "calculator_key_mismatch"
      ]
     },
     "message": {
      "type": "string",
      "description": "Explanation for a person in the response language.",
      "x-description-cs": "Vysvětlení pro člověka v jazyce odpovědi."
     }
    }
   },
   "TokenRequestAuthorizationCode": {
    "type": "object",
    "description": "Unknown parameters are ignored (RFC 6749).",
    "x-description-cs": "Neznámé parametry se ignorují (RFC 6749).",
    "required": [
     "grant_type",
     "code",
     "redirect_uri",
     "code_verifier"
    ],
    "properties": {
     "grant_type": {
      "type": "string",
      "enum": [
       "authorization_code"
      ],
      "description": "`authorization_code` – exchange the `code` your redirect URI got from the consent page.",
      "x-description-cs": "`authorization_code` – výměna `code`, které dostala vaše adresa pro přesměrování ze souhlasové stránky."
     },
     "code": {
      "type": "string"
     },
     "redirect_uri": {
      "type": "string",
      "format": "uri"
     },
     "code_verifier": {
      "type": "string",
      "minLength": 43,
      "maxLength": 128
     },
     "client_id": {
      "type": "string"
     },
     "client_secret": {
      "type": "string"
     }
    }
   },
   "TokenRequestRefreshToken": {
    "type": "object",
    "description": "Unknown parameters are ignored (RFC 6749).",
    "x-description-cs": "Neznámé parametry se ignorují (RFC 6749).",
    "required": [
     "grant_type",
     "refresh_token"
    ],
    "properties": {
     "grant_type": {
      "type": "string",
      "enum": [
       "refresh_token"
      ],
      "description": "`refresh_token` – a new access token and a new refresh token for the refresh token you have.",
      "x-description-cs": "`refresh_token` – nový access token a nový refresh token za refresh token, který máte."
     },
     "refresh_token": {
      "type": "string"
     },
     "scope": {
      "type": "string",
      "description": "Optional narrower set of scopes.",
      "x-description-cs": "Nepovinně užší sada oprávnění."
     },
     "client_id": {
      "type": "string"
     },
     "client_secret": {
      "type": "string"
     }
    }
   },
   "TokenRequestDeviceCode": {
    "type": "object",
    "description": "Unknown parameters are ignored (RFC 6749).",
    "x-description-cs": "Neznámé parametry se ignorují (RFC 6749).",
    "required": [
     "grant_type",
     "device_code",
     "client_id"
    ],
    "properties": {
     "grant_type": {
      "type": "string",
      "enum": [
       "urn:ietf:params:oauth:grant-type:device_code"
      ],
      "description": "The device picks up its tokens after a manager confirmed its code (RFC 8628).",
      "x-description-cs": "Zařízení si vyzvedne tokeny poté, co vedoucí potvrdil jeho kód (RFC 8628)."
     },
     "device_code": {
      "type": "string"
     },
     "client_id": {
      "type": "string"
     }
    }
   },
   "TokenRequestV1Device": {
    "type": "object",
    "description": "Only Profirest's own register (`profirest-pos`), kitchen display (`profirest-kds`) and courier (`profirest-kuryr`)\napps. The API v1 identity the app keeps: the register its app key, login and device ID; the kitchen display its\nAPI v1 token and device ID; the courier the login and password of the web kitchen and the phone's ID. Unknown\nparameters are ignored (RFC 6749).\n",
    "x-description-cs": "Jen vlastní aplikace Profirestu pro pokladnu (`profirest-pos`), kuchyňský displej (`profirest-kds`) a kurýra\n(`profirest-kuryr`). Identita API v1, kterou si aplikace drží: pokladna aplikační klíč, login a ID zařízení;\nkuchyňský displej token API v1 a ID zařízení; kurýr login a heslo webové kuchyně a ID telefonu. Neznámé parametry\nse ignorují (RFC 6749).\n",
    "required": [
     "grant_type",
     "client_id",
     "v1_device_id"
    ],
    "properties": {
     "grant_type": {
      "type": "string",
      "enum": [
       "urn:profirest:params:oauth:grant-type:v1-device"
      ],
      "description": "An API v1 identity for device tokens – the device moves to API v2 without pairing again.",
      "x-description-cs": "Identita API v1 za tokeny zařízení – zařízení přejde na API v2 bez nového párování."
     },
     "client_id": {
      "type": "string",
      "enum": [
       "profirest-pos",
       "profirest-kds",
       "profirest-kuryr"
      ]
     },
     "v1_device_id": {
      "type": "string",
      "maxLength": 512,
      "description": "The `DEVICE_ID` the app sends in API v1 (the courier app the ID of the phone).",
      "x-description-cs": "`DEVICE_ID`, který aplikace posílá v API v1 (aplikace kurýra ID telefonu)."
     },
     "v1_app_key": {
      "type": "string",
      "description": "Register: `APP_KEY` of API v1.",
      "x-description-cs": "Pokladna: `APP_KEY` z API v1."
     },
     "v1_login": {
      "type": "string",
      "description": "Register and courier: `LOGIN` of API v1.",
      "x-description-cs": "Pokladna a kurýr: `LOGIN` z API v1."
     },
     "v1_token": {
      "type": "string",
      "description": "Kitchen display: its API v1 token.",
      "x-description-cs": "Kuchyňský displej: jeho token API v1."
     },
     "v1_password": {
      "type": "string",
      "description": "Courier: `PASS` of API v1.",
      "x-description-cs": "Kurýr: `PASS` z API v1."
     },
     "scope": {
      "type": "string",
      "description": "Permissions the device needs, separated by spaces; without it all the application may have.",
      "x-description-cs": "Oprávnění, která zařízení potřebuje, oddělená mezerou; bez něj všechna, která aplikace mít smí."
     },
     "device_platform": {
      "type": "string"
     },
     "app_version": {
      "type": "string"
     }
    }
   },
   "DeviceAuthorizationRequest": {
    "type": "object",
    "description": "Unknown parameters are ignored (RFC 6749).",
    "x-description-cs": "Neznámé parametry se ignorují (RFC 6749).",
    "required": [
     "client_id",
     "scope"
    ],
    "properties": {
     "client_id": {
      "type": "string"
     },
     "scope": {
      "type": "string",
      "description": "Permissions the device needs, separated by spaces. At most those Profirest allowed your application.",
      "x-description-cs": "Oprávnění, která zařízení potřebuje, oddělená mezerou. Nejvýš ta, která Profirest povolil vaší aplikaci."
     },
     "device_name": {
      "type": "string",
      "maxLength": 100,
      "description": "Suggested name shown to the manager, for example `Pokladna u baru`. The manager can change it. Emoji and other characters outside the Basic Multilingual Plane are refused with `invalid_request` (also in `device_platform` and `app_version`).",
      "x-description-cs": "Navržený název, který uvidí vedoucí, například `Pokladna u baru`. Vedoucí ho může změnit. Emoji a jiné znaky mimo základní rovinu Unicode odmítne `invalid_request` (stejně u `device_platform` a `app_version`)."
     },
     "device_platform": {
      "type": "string",
      "maxLength": 64,
      "description": "Operating system or browser, for example `Android 14`.",
      "x-description-cs": "Operační systém nebo prohlížeč, například `Android 14`."
     },
     "app_version": {
      "type": "string",
      "maxLength": 32,
      "examples": [
       "3.4.1"
      ]
     }
    }
   },
   "DeviceAuthorizationResponse": {
    "type": "object",
    "required": [
     "device_code",
     "user_code",
     "verification_uri",
     "verification_uri_complete",
     "expires_in",
     "interval"
    ],
    "properties": {
     "device_code": {
      "type": "string",
      "description": "Secret of the device for polling `POST /oauth/token`. Never show it.",
      "x-description-cs": "Tajný údaj zařízení pro dotazy na `POST /oauth/token`. Nikdy ho neukazujte."
     },
     "user_code": {
      "type": "string",
      "description": "Code the manager enters in Profirest; show it large, with the dash.",
      "x-description-cs": "Kód, který vedoucí zadá v Profirestu; ukažte ho velkým písmem, s pomlčkou.",
      "examples": [
       "WDJB-MJHT"
      ]
     },
     "verification_uri": {
      "type": "string",
      "format": "uri",
      "examples": [
       "https://www.mujprofirest.cz/zarizeni"
      ]
     },
     "verification_uri_complete": {
      "type": "string",
      "format": "uri",
      "description": "The same page with the code filled in – show it as a QR code.",
      "x-description-cs": "Stejná stránka s vyplněným kódem – ukažte ji jako QR kód.",
      "examples": [
       "https://www.mujprofirest.cz/zarizeni?code=WDJBMJHT"
      ]
     },
     "expires_in": {
      "type": "integer",
      "examples": [
       600
      ]
     },
     "interval": {
      "type": "integer",
      "description": "Seconds between polls of `POST /oauth/token`.",
      "x-description-cs": "Kolik sekund čekat mezi dotazy na `POST /oauth/token`.",
      "examples": [
       5
      ]
     }
    }
   },
   "TokenResponse": {
    "type": "object",
    "required": [
     "access_token",
     "token_type",
     "expires_in",
     "refresh_token",
     "refresh_token_expires_in",
     "scope"
    ],
    "properties": {
     "access_token": {
      "type": "string"
     },
     "token_type": {
      "type": "string",
      "description": "Always `Bearer`: send the access token as `Authorization: Bearer <token>`.",
      "x-description-cs": "Vždy `Bearer`: access token posílejte jako `Authorization: Bearer <token>`.",
      "x-extensible-enum": [
       "Bearer"
      ]
     },
     "expires_in": {
      "type": "integer",
      "examples": [
       1800
      ]
     },
     "refresh_token": {
      "type": "string"
     },
     "refresh_token_expires_in": {
      "type": "integer",
      "description": "Seconds the refresh token stays valid when unused.",
      "x-description-cs": "Kolik sekund refresh token platí, když se nepoužije.",
      "examples": [
       7776000
      ]
     },
     "scope": {
      "type": "string",
      "examples": [
       "restaurants:read catalog:read orders:write orders:read"
      ]
     }
    }
   },
   "OAuthError": {
    "type": "object",
    "required": [
     "error",
     "error_description",
     "api_target"
    ],
    "properties": {
     "error": {
      "type": "string",
      "description": "RFC 6749 and RFC 8628 codes: `invalid_request` – a parameter is missing or wrong (also a body that is not a\nform, or two ways of client authentication at once); `invalid_client` – the client authentication failed\n(`401`); `invalid_grant` – the code, refresh token or device code is unknown, used, expired or revoked, or\n`redirect_uri` or `code_verifier` do not match, or the device was unpaired; `unauthorized_client` – the client\nmay not pair devices; `unsupported_grant_type` – an unknown `grant_type`; `invalid_scope` – a scope the client\nmay not ask for, or a refresh asking for more scopes than granted; `authorization_pending` – the manager has\nnot confirmed the device code yet, keep polling; `slow_down` – polling faster than `interval`, wait 5 seconds\nlonger from now on; `access_denied` – the manager refused the device, or the device or the connection was\nrevoked; `expired_token` – the device code expired.\n",
      "x-description-cs": "Kódy podle RFC 6749 a RFC 8628: `invalid_request` – chybí nebo je špatně parametr (i tělo, které není\nformulář, nebo dva způsoby ověření klienta naráz); `invalid_client` – ověření klienta selhalo (`401`);\n`invalid_grant` – kód, refresh token nebo kód zařízení je neznámý, použitý, prošlý nebo zneplatněný, nebo\nnesedí `redirect_uri` či `code_verifier`, nebo bylo zařízení odpárováno; `unauthorized_client` – klient nesmí\npárovat zařízení; `unsupported_grant_type` – neznámý `grant_type`; `invalid_scope` – oprávnění, o které klient\nžádat nesmí, nebo obnova žádající víc oprávnění, než bylo povoleno; `authorization_pending` – vedoucí kód\nzařízení ještě nepotvrdil, ptejte se dál; `slow_down` – dotazy častěji než `interval`, od teď čekejte o 5 sekund\ndéle; `access_denied` – vedoucí zařízení odmítl, nebo bylo zařízení či připojení zrušeno; `expired_token` –\nkód zařízení vypršel.\n",
      "x-extensible-enum": [
       "invalid_request",
       "invalid_client",
       "invalid_grant",
       "unauthorized_client",
       "unsupported_grant_type",
       "invalid_scope",
       "authorization_pending",
       "slow_down",
       "access_denied",
       "expired_token"
      ]
     },
     "error_description": {
      "type": "string",
      "description": "A sentence for the developer, in English.",
      "x-description-cs": "Věta pro vývojáře, anglicky."
     },
     "api_target": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "v1",
       null
      ],
      "description": "`null`, except with `invalid_grant` on a refresh of Profirest's own register, kitchen display or courier: the device was\nmoved back to API v1 – sign in there with the API v1 identity, it is not unpaired.\n",
      "x-description-cs": "`null`, jen u `invalid_grant` při obnově tokenu vlastní pokladny, kuchyňského displeje nebo kurýra Profirestu:\nzařízení se vrátilo na API v1 – přihlaste se tam identitou API v1, odpárované není.\n"
     }
    }
   },
   "OAuthServerMetadata": {
    "type": "object",
    "required": [
     "issuer",
     "authorization_endpoint",
     "token_endpoint",
     "revocation_endpoint",
     "device_authorization_endpoint",
     "scopes_supported",
     "response_types_supported",
     "grant_types_supported",
     "code_challenge_methods_supported",
     "token_endpoint_auth_methods_supported",
     "authorization_response_iss_parameter_supported"
    ],
    "properties": {
     "issuer": {
      "type": "string",
      "examples": [
       "https://api.mujprofirest.cz"
      ]
     },
     "authorization_endpoint": {
      "type": "string",
      "format": "uri"
     },
     "token_endpoint": {
      "type": "string",
      "format": "uri"
     },
     "revocation_endpoint": {
      "type": "string",
      "format": "uri"
     },
     "scopes_supported": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "response_types_supported": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "grant_types_supported": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "code_challenge_methods_supported": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "token_endpoint_auth_methods_supported": {
      "type": "array",
      "items": {
       "type": "string"
      },
      "examples": [
       [
        "client_secret_basic",
        "client_secret_post",
        "none"
       ]
      ]
     },
     "authorization_response_iss_parameter_supported": {
      "type": "boolean"
     },
     "device_authorization_endpoint": {
      "type": "string",
      "format": "uri"
     }
    }
   },
   "Address": {
    "type": "object",
    "description": "Address as Profirest stores and shows it.",
    "x-description-cs": "Adresa tak, jak ji Profirest ukládá a zobrazuje.",
    "required": [
     "street",
     "house_number",
     "city",
     "postal_code",
     "country",
     "note",
     "formatted"
    ],
    "properties": {
     "street": {
      "type": [
       "string",
       "null"
      ]
     },
     "house_number": {
      "type": [
       "string",
       "null"
      ]
     },
     "city": {
      "type": [
       "string",
       "null"
      ]
     },
     "postal_code": {
      "type": [
       "string",
       "null"
      ]
     },
     "country": {
      "type": "string",
      "examples": [
       "CZ"
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "description": "Floor, door bell, access code.",
      "x-description-cs": "Patro, zvonek, kód od vchodu."
     },
     "formatted": {
      "type": "string",
      "description": "The whole address on one line, as the courier sees it.",
      "x-description-cs": "Celá adresa na jednom řádku, jak ji vidí kurýr."
     }
    }
   },
   "AddressInput": {
    "type": "object",
    "description": "Delivery address. Send `street`, `house_number` or both (villages often have only a house number).\n`location` is required: use your own address search and send the coordinates of the chosen address.\nProfirest decides the delivery zone from `location`.\n",
    "x-description-cs": "Doručovací adresa. Pošlete `street`, `house_number` nebo obojí (v obcích bývá jen číslo popisné).\n`location` je povinná: použijte vlastní vyhledávání adres a pošlete souřadnice zvolené adresy. Rozvozovou\nzónu Profirest určí podle `location`.\n",
    "additionalProperties": false,
    "required": [
     "city",
     "location"
    ],
    "anyOf": [
     {
      "required": [
       "street"
      ]
     },
     {
      "required": [
       "house_number"
      ]
     }
    ],
    "properties": {
     "street": {
      "type": [
       "string",
       "null"
      ],
      "minLength": 1,
      "maxLength": 100,
      "examples": [
       "Jeseniova"
      ]
     },
     "house_number": {
      "type": [
       "string",
       "null"
      ],
      "minLength": 1,
      "maxLength": 16,
      "examples": [
       "1196/52"
      ]
     },
     "city": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "examples": [
       "Praha 3"
      ]
     },
     "postal_code": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 12,
      "examples": [
       "130 00"
      ]
     },
     "country": {
      "type": "string",
      "pattern": "^[A-Z]{2}$",
      "default": "CZ"
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64,
      "description": "Floor, door bell, access code.",
      "x-description-cs": "Patro, zvonek, kód od vchodu."
     },
     "location": {
      "$ref": "#/components/schemas/GeoPointInput"
     }
    }
   },
   "Restaurant": {
    "type": "object",
    "description": "A restaurant your connection may see, with its contact data as entered in the administration and what it accepts\nfrom your application right now (`ordering`).\n",
    "x-description-cs": "Provozovna, kterou vaše připojení smí vidět, s kontaktními údaji, jak jsou zadané v administraci, a s tím, co\nod vaší aplikace právě přijímá (`ordering`).\n",
    "required": [
     "id",
     "name",
     "is_test",
     "address",
     "location",
     "phone",
     "website",
     "timezone",
     "currency",
     "ordering",
     "portion_tracking",
     "external_id",
     "metadata"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "description": "The name of the restaurant, as entered in the administration.",
      "x-description-cs": "Název provozovny, jak je zadaný v administraci.",
      "examples": [
       "Pizzerie U Kašny"
      ]
     },
     "is_test": {
      "type": "boolean",
      "description": "Test restaurant. Its orders are never prepared.",
      "x-description-cs": "Testovací provozovna. Její objednávky nikdo nepřipravuje."
     },
     "address": {
      "description": "The address of the restaurant. `street` holds the street together with the house number (`house_number` is\n`null`), `postal_code` is written `NNN NN`, `country` is `CZ` and `note` is `null`.\n",
      "x-description-cs": "Adresa provozovny. `street` obsahuje ulici i s číslem domu (`house_number` je `null`), `postal_code` je ve\ntvaru `NNN NN`, `country` je `CZ` a `note` je `null`.\n",
      "$ref": "#/components/schemas/Address"
     },
     "location": {
      "description": "Coordinates of the restaurant; `null` when the administration has none.",
      "x-description-cs": "Souřadnice provozovny; `null`, když je administrace nemá.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/GeoPoint"
       },
       {
        "type": "null"
       }
      ]
     },
     "phone": {
      "type": [
       "string",
       "null"
      ],
      "description": "As entered by the restaurant; not always in E.164.",
      "x-description-cs": "Jak ho zadala provozovna; ne vždy ve formátu E.164."
     },
     "website": {
      "type": [
       "string",
       "null"
      ],
      "description": "The website as entered by the restaurant (not checked); `null` when empty.",
      "x-description-cs": "Web, jak ho zadala provozovna (nekontroluje se); `null`, když chybí."
     },
     "timezone": {
      "type": "string",
      "description": "The time zone of the restaurant's times and dates; `Europe/Prague` for every restaurant today.",
      "x-description-cs": "Časová zóna časů a dat provozovny; dnes u všech provozoven `Europe/Prague`.",
      "examples": [
       "Europe/Prague"
      ]
     },
     "currency": {
      "type": "string",
      "pattern": "^[A-Z]{3}$",
      "description": "The currency of the account – the same for all its restaurants; all prices and amounts are in it.",
      "x-description-cs": "Měna účtu – stejná pro všechny jeho provozovny; jsou v ní všechny ceny a částky.",
      "examples": [
       "CZK"
      ]
     },
     "ordering": {
      "$ref": "#/components/schemas/RestaurantOrdering"
     },
     "portion_tracking": {
      "type": "boolean",
      "description": "The restaurant limits portions for your application; see `GET /restaurants/{restaurant_id}/availability`.\nFor applications of the restaurant staff and for a kiosk also when it tracks portions only at its registers.\n",
      "x-description-cs": "Provozovna pro vaši aplikaci hlídá počty porcí; viz `GET /restaurants/{restaurant_id}/availability`.\nPro aplikace personálu a kiosek i tehdy, když porce hlídá jen na pokladnách.\n"
     },
     "external_id": {
      "description": "Your own ID of the restaurant (`putExternalRef`); `null` when you set none.",
      "x-description-cs": "Vaše vlastní ID provozovny (`putExternalRef`); `null`, když žádné nenastavíte.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "description": "Your own key–value pairs on the restaurant (`putExternalRef`).",
      "x-description-cs": "Vaše vlastní dvojice klíč–hodnota u provozovny (`putExternalRef`).",
      "$ref": "#/components/schemas/Metadata"
     }
    }
   },
   "RestaurantOrdering": {
    "type": "object",
    "description": "What the restaurant accepts from your application, computed at the moment of the request. The time rules are\nthose of `web` applications: `open_now` follows the order hours (`getOrderHours`), `venue_open_now` the opening\nhours (`getOpeningHours`) – show guests „Open/Closed“ from `venue_open_now`, not from `open_now`. For a `staff`\napplication (`GET /connection`) orders are accepted at any time: delivery and pickup are always available,\nscheduled orders are enabled without `max_days_ahead` and with `lead_minutes` 0; `open_now`, `venue_open_now`\nand `next_change_at` still describe the opening hours for information. A `kiosk`\nfollows the restaurant's kiosk setting: as staff, or on its own with pickup only and no scheduled orders; in\nboth cases `accepting_orders` is `false` while the restaurant pauses kiosks.\n",
    "x-description-cs": "Co provozovna přijímá od vaší aplikace, spočítáno v okamžiku požadavku. Časová pravidla jsou pravidla\naplikací `web`: `open_now` se řídí příjmem objednávek (`getOrderHours`), `venue_open_now` otevírací dobou\n(`getOpeningHours`) – štítek „Otevřeno/Zavřeno“ pro hosty berte z `venue_open_now`, ne z `open_now`. U aplikace\n`staff` (`GET /connection`) se objednávky přijímají kdykoli: rozvoz i odběr jsou vždy k dispozici, objednávky na\nčas jsou zapnuté bez `max_days_ahead` a s `lead_minutes` 0; `open_now`, `venue_open_now` a `next_change_at` dál\npro informaci popisují otevírací dobu. `kiosk` se řídí nastavením kiosku u provozovny:\njako obsluha, nebo samostatně jen s osobním odběrem a bez objednávek na čas; v obou případech je\n`accepting_orders` `false`, když provozovna kiosky pozastaví.\n",
    "required": [
     "accepting_orders",
     "open_now",
     "venue_open_now",
     "next_change_at",
     "delivery",
     "pickup",
     "scheduled_orders"
    ],
    "properties": {
     "accepting_orders": {
      "type": "boolean",
      "description": "Orders through the API are possible at all (active subscription, not paused).",
      "x-description-cs": "Objednávky přes API jsou vůbec možné (aktivní předplatné, nepozastaveno)."
     },
     "open_now": {
      "type": "boolean",
      "description": "Orders are accepted right now by time – for `web` by the order hours (`getOrderHours`).",
      "x-description-cs": "Podle času se teď objednávky přijímají – u `web` podle příjmu objednávek (`getOrderHours`)."
     },
     "venue_open_now": {
      "type": "boolean",
      "description": "The restaurant is open right now by its opening hours (`getOpeningHours`). For display only.",
      "x-description-cs": "Provozovna má teď podle otevírací doby otevřeno (`getOpeningHours`). Jen pro zobrazení."
     },
     "next_change_at": {
      "description": "Next moment any value in `ordering` changes because of time; `null` when none is planned.",
      "x-description-cs": "Nejbližší okamžik, kdy se kvůli času změní některá hodnota v `ordering`; `null`, když žádný není.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "delivery": {
      "type": "object",
      "required": [
       "enabled",
       "available_now"
      ],
      "properties": {
       "enabled": {
        "type": "boolean"
       },
       "available_now": {
        "type": "boolean",
        "description": "At least one delivery zone is inside its delivery schedule right now.",
        "x-description-cs": "Aspoň jedna rozvozová zóna je právě teď v čase rozvozu."
       }
      }
     },
     "pickup": {
      "type": "object",
      "required": [
       "enabled",
       "available_now"
      ],
      "properties": {
       "enabled": {
        "type": "boolean"
       },
       "available_now": {
        "type": "boolean"
       }
      }
     },
     "scheduled_orders": {
      "type": "object",
      "description": "Orders for a later time. Set by the owner for the restaurant; accepted only while the restaurant accepts\norders (`open_now`).\n",
      "x-description-cs": "Objednávky na pozdější čas. Nastavuje je majitel u provozovny; přijímají se jen v době, kdy provozovna\npřijímá objednávky (`open_now`).\n",
      "required": [
       "enabled",
       "max_days_ahead",
       "slot_minutes",
       "lead_minutes"
      ],
      "properties": {
       "enabled": {
        "type": "boolean"
       },
       "max_days_ahead": {
        "type": [
         "integer",
         "null"
        ],
        "examples": [
         7
        ]
       },
       "slot_minutes": {
        "type": [
         "integer",
         "null"
        ],
        "examples": [
         15
        ]
       },
       "lead_minutes": {
        "type": [
         "integer",
         "null"
        ],
        "description": "Minimum time between placing the order and its time.",
        "x-description-cs": "Nejkratší doba mezi odesláním objednávky a jejím časem.",
        "examples": [
         90
        ]
       }
      }
     }
    }
   },
   "RestaurantPage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Restaurant"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "TimeInterval": {
    "type": "object",
    "description": "Both ends inclusive: an order for exactly `to` is still accepted. `to` may be `24:00`. An interval never crosses\nmidnight; a night opening is two intervals on two days.\n",
    "x-description-cs": "Oba konce včetně: objednávka přesně na `to` se ještě přijme. `to` může být `24:00`. Interval nikdy nepřekračuje\npůlnoc; noční provoz jsou dva intervaly ve dvou dnech.\n",
    "required": [
     "from",
     "to"
    ],
    "properties": {
     "from": {
      "$ref": "#/components/schemas/LocalTime"
     },
     "to": {
      "$ref": "#/components/schemas/LocalTime"
     }
    }
   },
   "OpeningHoursInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "weekly"
    ],
    "properties": {
     "weekly": {
      "type": "array",
      "minItems": 7,
      "maxItems": 7,
      "description": "All 7 days, each once. Day 1 = Monday, 7 = Sunday (ISO 8601).",
      "x-description-cs": "Všech 7 dní, každý jednou. Den 1 = pondělí, 7 = neděle (ISO 8601).",
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "day",
        "intervals"
       ],
       "properties": {
        "day": {
         "type": "integer",
         "minimum": 1,
         "maximum": 7
        },
        "intervals": {
         "type": "array",
         "maxItems": 6,
         "description": "In order of time, without overlapping; empty = closed that day.",
         "x-description-cs": "Popořadě, bez překryvu; prázdné = ten den zavřeno.",
         "items": {
          "$ref": "#/components/schemas/TimeIntervalInput"
         }
        }
       }
      }
     }
    }
   },
   "TimeIntervalInput": {
    "type": "object",
    "additionalProperties": false,
    "description": "Both ends inclusive; `to` may be `24:00`, `from` not.",
    "x-description-cs": "Oba konce včetně; `to` může být `24:00`, `from` ne.",
    "required": [
     "from",
     "to"
    ],
    "properties": {
     "from": {
      "$ref": "#/components/schemas/LocalTime"
     },
     "to": {
      "$ref": "#/components/schemas/LocalTime"
     }
    }
   },
   "OpeningHours": {
    "type": "object",
    "required": [
     "restaurant_id",
     "timezone",
     "weekly",
     "days"
    ],
    "properties": {
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "timezone": {
      "type": "string",
      "examples": [
       "Europe/Prague"
      ]
     },
     "weekly": {
      "type": "array",
      "description": "Regular week for display, always 7 items. Day 1 = Monday, 7 = Sunday (ISO 8601).",
      "x-description-cs": "Běžný týden pro zobrazení, vždy 7 položek. Den 1 = pondělí, 7 = neděle (ISO 8601).",
      "items": {
       "type": "object",
       "required": [
        "day",
        "intervals"
       ],
       "properties": {
        "day": {
         "type": "integer",
         "minimum": 1,
         "maximum": 7
        },
        "intervals": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/TimeInterval"
         }
        }
       }
      }
     },
     "days": {
      "type": "array",
      "description": "Effective hours per date. On a day without intervals the restaurant is closed.",
      "x-description-cs": "Skutečná doba po datech. V den bez intervalů je zavřeno.",
      "items": {
       "type": "object",
       "required": [
        "date",
        "intervals"
       ],
       "properties": {
        "date": {
         "$ref": "#/components/schemas/LocalDate"
        },
        "intervals": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/TimeInterval"
         }
        }
       }
      }
     }
    }
   },
   "OrderHours": {
    "type": "object",
    "description": "When orders from `web` applications are accepted (`getOrderHours`). Same shape as `OpeningHours`; a day without\nintervals accepts no orders.\n",
    "x-description-cs": "Kdy se přijímají objednávky aplikací `web` (`getOrderHours`). Stejný tvar jako `OpeningHours`; den bez\nintervalů objednávky nepřijímá.\n",
    "required": [
     "restaurant_id",
     "timezone",
     "same_as_opening_hours",
     "weekly",
     "days"
    ],
    "properties": {
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "timezone": {
      "type": "string",
      "examples": [
       "Europe/Prague"
      ]
     },
     "same_as_opening_hours": {
      "type": "boolean",
      "description": "`true` – the restaurant has no own order hours, orders are accepted during the whole opening hours and the\nintervals are the same as in `getOpeningHours`.\n",
      "x-description-cs": "`true` – provozovna nemá vlastní příjem objednávek, objednávky se přijímají celou otevírací dobu a intervaly\njsou stejné jako v `getOpeningHours`.\n"
     },
     "weekly": {
      "type": "array",
      "description": "Regular week for display, always 7 items. Day 1 = Monday, 7 = Sunday (ISO 8601).",
      "x-description-cs": "Běžný týden pro zobrazení, vždy 7 položek. Den 1 = pondělí, 7 = neděle (ISO 8601).",
      "items": {
       "type": "object",
       "required": [
        "day",
        "intervals"
       ],
       "properties": {
        "day": {
         "type": "integer",
         "minimum": 1,
         "maximum": 7
        },
        "intervals": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/TimeInterval"
         }
        }
       }
      }
     },
     "days": {
      "type": "array",
      "description": "Effective order hours per date. On a day without intervals no orders are accepted.",
      "x-description-cs": "Skutečný příjem objednávek po datech. V den bez intervalů se objednávky nepřijímají.",
      "items": {
       "type": "object",
       "required": [
        "date",
        "intervals"
       ],
       "properties": {
        "date": {
         "$ref": "#/components/schemas/LocalDate"
        },
        "intervals": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/TimeInterval"
         }
        }
       }
      }
     }
    }
   },
   "GeoJsonPolygon": {
    "type": "object",
    "description": "GeoJSON geometry (RFC 7946). Positions are `[longitude, latitude]`.",
    "x-description-cs": "Geometrie GeoJSON (RFC 7946). Souřadnice jsou `[zeměpisná délka, zeměpisná šířka]`.",
    "required": [
     "type",
     "coordinates"
    ],
    "properties": {
     "type": {
      "type": "string",
      "description": "`Polygon` – one area: `coordinates` is one closed ring, the outer ring counter-clockwise. Every zone is one\n`Polygon` today. `MultiPolygon` – several separate areas; reserved, accept it.\n",
      "x-description-cs": "`Polygon` – jedna oblast: `coordinates` je jeden uzavřený okruh, vnější okruh proti směru hodinových\nručiček. Každá zóna je dnes jeden `Polygon`. `MultiPolygon` – více oddělených oblastí; vyhrazené,\npočítejte s ním.\n",
      "x-extensible-enum": [
       "Polygon",
       "MultiPolygon"
      ]
     },
     "coordinates": {
      "type": "array",
      "items": {}
     }
    }
   },
   "DeliveryZone": {
    "type": "object",
    "required": [
     "id",
     "name",
     "fee",
     "minimum_order",
     "express_fee",
     "area",
     "schedule",
     "available_now"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "fee": {
      "$ref": "#/components/schemas/Money"
     },
     "minimum_order": {
      "$ref": "#/components/schemas/Money"
     },
     "express_fee": {
      "description": "The surcharge for express delivery (`FulfillmentInput.speed`); `null` when the zone does not offer it.",
      "x-description-cs": "Příplatek za expresní doručení (`FulfillmentInput.speed`); `null`, když ho zóna nenabízí.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "area": {
      "$ref": "#/components/schemas/GeoJsonPolygon"
     },
     "schedule": {
      "type": "array",
      "description": "When the zone delivers. Empty means always during the order hours (`getOrderHours`).",
      "x-description-cs": "Kdy zóna rozváží. Prázdné znamená vždy během příjmu objednávek (`getOrderHours`).",
      "items": {
       "type": "object",
       "required": [
        "days",
        "from",
        "to"
       ],
       "properties": {
        "days": {
         "type": "array",
         "items": {
          "type": "integer",
          "minimum": 1,
          "maximum": 7
         }
        },
        "from": {
         "$ref": "#/components/schemas/LocalTime"
        },
        "to": {
         "$ref": "#/components/schemas/LocalTime"
        }
       }
      }
     },
     "available_now": {
      "type": "boolean"
     }
    }
   },
   "DeliveryZonePage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/DeliveryZone"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "FulfillmentType": {
    "type": "string",
    "description": "`delivery` – delivered to an address; `pickup` – the customer picks the order up at the restaurant; `dine_in` –\neaten at the restaurant (the \"eat in\" choice of a kiosk): no packaging fee, the VAT rate for eating in, the kitchen\nsees it as eaten in. `dine_in` only for a kiosk and staff applications (`Connection.client.order_channel`), others\nget `422` with `not_allowed`; its times are those of `pickup`. A takeaway-only restaurant (`getDeviceSettings`,\n`pos.takeaway_only`) turns `dine_in` into `pickup` – with packaging, and the quote and the order say `pickup`.\n",
    "x-description-cs": "`delivery` – rozvoz na adresu; `pickup` – zákazník si objednávku vyzvedne v provozovně; `dine_in` – jídlo na místě\n(volba „Tady“ na kiosku): bez obalu, se sazbou DPH na místě, kuchyně ji vidí jako na místě. `dine_in` jen pro\nkiosek a aplikace personálu (`Connection.client.order_channel`), ostatní dostanou `422` s `not_allowed`; časy\nmá stejné jako `pickup`. Výdejna bez stolů (`getDeviceSettings`, `pos.takeaway_only`) z `dine_in` udělá\n`pickup` – s obalem, kalkulace i objednávka pak uvádějí `pickup`.\n",
    "enum": [
     "delivery",
     "pickup",
     "dine_in"
    ]
   },
   "TimeSlots": {
    "type": "object",
    "required": [
     "restaurant_id",
     "type",
     "date",
     "asap",
     "slots"
    ],
    "properties": {
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "type": {
      "type": "string",
      "description": "The `type` you asked for – `delivery` (when the customer receives the order), `pickup` or `dine_in` (when it is ready).",
      "x-description-cs": "`type`, na který jste se ptali – `delivery` (kdy zákazník objednávku dostane), `pickup` nebo `dine_in` (kdy je připravená).",
      "x-extensible-enum": [
       "delivery",
       "pickup",
       "dine_in"
      ]
     },
     "date": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "asap": {
      "type": "object",
      "required": [
       "available",
       "reason"
      ],
      "properties": {
       "available": {
        "type": "boolean"
       },
       "reason": {
        "type": [
         "string",
         "null"
        ],
        "description": "Error code that explains why not, for example `restaurant_closed`.",
        "x-description-cs": "Kód chyby, který vysvětluje proč ne, například `restaurant_closed`."
       }
      }
     },
     "slots": {
      "type": "array",
      "description": "Times that can be chosen for an order for later.",
      "x-description-cs": "Časy, které lze zvolit pro objednávku na později.",
      "items": {
       "type": "object",
       "required": [
        "time"
       ],
       "properties": {
        "time": {
         "$ref": "#/components/schemas/Timestamp"
        }
       }
      }
     }
    }
   },
   "Catalog": {
    "type": "object",
    "required": [
     "restaurant_id",
     "currency",
     "at",
     "generated_at",
     "next_change_at",
     "categories",
     "products",
     "daily_menu",
     "allergens"
    ],
    "properties": {
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "currency": {
      "type": "string",
      "pattern": "^[A-Z]{3}$",
      "examples": [
       "CZK"
      ]
     },
     "at": {
      "$ref": "#/components/schemas/Timestamp",
      "description": "The moment this catalog is for.",
      "x-description-cs": "Okamžik, pro který sortiment platí."
     },
     "generated_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "next_change_at": {
      "description": "Next moment after `at` when the catalog changes because of time rules; `null` when none is planned.",
      "x-description-cs": "Nejbližší okamžik po `at`, kdy se sortiment změní kvůli časovým pravidlům; `null`, když žádný není.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "categories": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Category"
      }
     },
     "products": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Product"
      }
     },
     "daily_menu": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/DailyMenu"
       },
       {
        "type": "null"
       }
      ]
     },
     "allergens": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Allergen"
      }
     }
    }
   },
   "Category": {
    "type": "object",
    "required": [
     "id",
     "name",
     "description",
     "image_url",
     "color",
     "icon",
     "position",
     "external_id",
     "metadata"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "description": {
      "type": [
       "string",
       "null"
      ]
     },
     "image_url": {
      "type": [
       "string",
       "null"
      ],
      "format": "uri"
     },
     "color": {
      "description": "Colour of the category's buttons on the registers and in phone orders, `#rrggbb`; `null` when not set.",
      "x-description-cs": "Barva tlačítek kategorie na pokladnách a v telefonické objednávce, `#rrggbb`; `null`, když není nastavená.",
      "type": [
       "string",
       "null"
      ],
      "pattern": "^#[0-9a-f]{6}$",
      "examples": [
       "#e53935"
      ]
     },
     "icon": {
      "description": "Font Awesome 6 icon of the category as the e-shop templates show it (class `fa-solid` plus this one, for\nexample `fa-pizza-slice`); `null` when not set. Registers and the kitchen do not use it.\n",
      "x-description-cs": "Ikonka kategorie z Font Awesome 6, jak ji ukazují šablony e-shopu (třída `fa-solid` a tahle, třeba\n`fa-pizza-slice`); `null`, když není nastavená. Pokladny ani kuchyň ji nepoužívají.\n",
      "type": [
       "string",
       "null"
      ],
      "pattern": "^fa-[a-z0-9-]{1,60}$",
      "examples": [
       "fa-pizza-slice"
      ]
     },
     "position": {
      "type": "integer",
      "description": "Order in the menu, ascending.",
      "x-description-cs": "Pořadí v menu, vzestupně."
     },
     "external_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "$ref": "#/components/schemas/Metadata"
     }
    }
   },
   "Product": {
    "type": "object",
    "description": "A product the restaurant offers in the channel of the catalog at the moment `at`, with the price valid then.\n",
    "x-description-cs": "Produkt, který provozovna v kanálu sortimentu nabízí v okamžiku `at`, s cenou, která tehdy platí.\n",
    "required": [
     "id",
     "category_id",
     "name",
     "description",
     "image_url",
     "price",
     "vat_rate",
     "packaging_fee",
     "weight",
     "allergens",
     "labels",
     "age_restricted",
     "add_ons",
     "option_groups",
     "removable_ingredients",
     "split",
     "half_price",
     "position",
     "ean",
     "kitchen_name",
     "size",
     "pos",
     "external_id",
     "metadata"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "category_id": {
      "description": "`null` when the product is offered only in the daily menu.",
      "x-description-cs": "`null`, když se produkt nabízí jen v denním menu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "name": {
      "type": "string",
      "description": "The name as entered in the administration.",
      "x-description-cs": "Název, jak je zadaný v administraci."
     },
     "description": {
      "type": [
       "string",
       "null"
      ],
      "description": "The description as entered; `null` when empty.",
      "x-description-cs": "Popis, jak je zadaný; `null`, když chybí."
     },
     "image_url": {
      "type": [
       "string",
       "null"
      ],
      "format": "uri",
      "description": "The picture of the product; `null` when it has none.",
      "x-description-cs": "Obrázek produktu; `null`, když žádný nemá."
     },
     "price": {
      "$ref": "#/components/schemas/Money",
      "description": "Price at the moment `at`, including VAT. In the daily menu window it is the menu price.",
      "x-description-cs": "Cena v okamžiku `at` včetně DPH. V okně denního menu je to cena z menu."
     },
     "vat_rate": {
      "description": "The VAT rate in this channel – the takeaway rate of the product in `kitchen`, the normal rate in `web` and `pos`.",
      "x-description-cs": "Sazba DPH v tomto kanálu – v `kitchen` sazba produktu „s sebou“, ve `web` a `pos` běžná sazba.",
      "$ref": "#/components/schemas/VatRate"
     },
     "packaging_fee": {
      "description": "Per unit, charged for delivery and pickup, with the VAT rate of the product.",
      "x-description-cs": "Za kus, účtuje se u rozvozu i odběru, se sazbou DPH produktu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "weight": {
      "type": [
       "integer",
       "null"
      ],
      "description": "As entered by the restaurant; by convention grams for food and millilitres for drinks.",
      "x-description-cs": "Jak ji zadala provozovna; zvykem gramy u jídla a mililitry u nápojů."
     },
     "allergens": {
      "type": "array",
      "description": "Codes from `Catalog.allergens`.",
      "x-description-cs": "Kódy z `Catalog.allergens`.",
      "items": {
       "type": "string"
      }
     },
     "labels": {
      "type": "array",
      "description": "Marks the restaurant set for the e-shop in the administration, for display only – they change no price and no\noffer: `new` – new; `limited_edition` – limited edition; `seasonal` – seasonal offer; `bestseller` –\nbestseller; `favourite` – most popular; `chefs_tip` – chef's tip; `recommended` – recommended; `summer_hit` –\nsummer hit; `winter_hit` – winter hit; `freshly_baked` – freshly baked; `best_price` – reduced price;\n`promotion` – promotion; `discount` – on sale; `special_offer` – special offer; `good_price` – good price;\n`happy_hour` – happy hour; `today_only` – today only; `limited_offer` – limited offer; `while_stocks_last` –\nwhile stocks last; `last_pieces` – last pieces; `gluten_free` – gluten free; `vegan` – vegan; `organic` –\norganic (BIO); `premium_quality` – premium quality; `home_made` – home made; `draft_original` – an original on\ndraught.\n",
      "x-description-cs": "Příznaky, které provozovna nastavila pro e-shop v administraci, jen pro zobrazení – nemění cenu ani nabídku:\n`new` – Novinka; `limited_edition` – Limitovaná edice; `seasonal` – Sezónní nabídka; `bestseller` –\nBestseller; `favourite` – Nejoblíbenější; `chefs_tip` – Tip šéfkuchaře; `recommended` – Doporučujeme;\n`summer_hit` – Letní HIT; `winter_hit` – Zimní HIT; `freshly_baked` – Právě upečeno; `best_price` – Cenově\nzvýhodněno; `promotion` – Akce; `discount` – Ve slevě; `special_offer` – Speciální nabídka; `good_price` –\nVýhodná cena; `happy_hour` – Happy hour; `today_only` – Pouze dnes; `limited_offer` – Omezená nabídka;\n`while_stocks_last` – Do vyprodání zásob; `last_pieces` – Poslední kusy; `gluten_free` – Bez lepku; `vegan` –\nVegan; `organic` – BIO; `premium_quality` – Prémiová kvalita; `home_made` – Domácí výroba; `draft_original` –\nČepovaný originál.\n",
      "items": {
       "type": "string",
       "x-extensible-enum": [
        "new",
        "limited_edition",
        "seasonal",
        "bestseller",
        "favourite",
        "chefs_tip",
        "recommended",
        "summer_hit",
        "winter_hit",
        "freshly_baked",
        "best_price",
        "promotion",
        "discount",
        "special_offer",
        "good_price",
        "happy_hour",
        "today_only",
        "limited_offer",
        "while_stocks_last",
        "last_pieces",
        "gluten_free",
        "vegan",
        "organic",
        "premium_quality",
        "home_made",
        "draft_original"
       ]
      }
     },
     "age_restricted": {
      "type": "boolean",
      "description": "Sold only to adults (18+). Checking the customer's age is up to you.",
      "x-description-cs": "Prodej jen dospělým (18+). Ověření věku zákazníka je na vás."
     },
     "add_ons": {
      "type": "array",
      "description": "Optional extras the customer may add, each at most once per item with any number of portions\n(`AddOnInput.quantity`). Empty for a product with `option_groups` – such a product is ordered with options.\n",
      "x-description-cs": "Nepovinné přílohy a doplňky, které si zákazník může přidat, každý nejvýš jednou na položku s libovolným\npočtem porcí (`AddOnInput.quantity`). U produktu s `option_groups` prázdné – takový produkt se objednává\ns volbami.\n",
      "items": {
       "$ref": "#/components/schemas/ProductAddOn"
      }
     },
     "option_groups": {
      "type": "array",
      "description": "Groups of options of a product the customer composes – a custom pizza, a required choice of dough or side\n(\"Dough: choose 1\", \"Toppings: 0 to 8, 4 included\"). Send the choice in `QuoteItemInput.options`; the quote\nchecks the limits and prices it. Empty for a product without groups and in the channels `kitchen` and `pos`\n(the staff applications order such a product with `add_ons` as before).\n",
      "x-description-cs": "Skupiny voleb produktu, který si zákazník skládá – vlastní pizza, povinný výběr těsta nebo přílohy\n(„Těsto: vyberte 1“, „Ingredience: 0 až 8, 4 v ceně“). Výběr pošlete v `QuoteItemInput.options`; kalkulace\nzkontroluje meze a spočítá cenu. Prázdné u produktu bez skupin a v kanálech `kitchen` a `pos` (aplikace\npersonálu takový produkt objednávají s `add_ons` jako dřív).\n",
      "items": {
       "$ref": "#/components/schemas/ProductOptionGroup"
      }
     },
     "removable_ingredients": {
      "type": "array",
      "description": "The composition of the dish – ingredients the guest may remove („without mushrooms“), in the order the\nrestaurant set them; empty when the product has none. In every channel. Show them ticked and send the unticked\nones in `QuoteItemInput.removed_ingredient_ids` (for a part of a split pizza in\n`SplitPartInput.removed_ingredient_ids`). Removing an ingredient never changes the price – a paid change\n(„without cheese −10 CZK“) is an add-on or an option. Every size of a dish is a product with its own IDs –\ntake them from the chosen size.\n",
      "x-description-cs": "Složení jídla – suroviny, které si host smí odebrat („bez žampionů“), v pořadí, jak je provozovna zadala;\nprázdné, když je produkt nemá. Ve všech kanálech. Ukažte je zaškrtnuté a odškrtnuté pošlete\nv `QuoteItemInput.removed_ingredient_ids` (u dílu pizzy z dílů v `SplitPartInput.removed_ingredient_ids`).\nOdebrání nikdy nemění cenu – placená změna („bez sýra −10 Kč“) je příloha nebo volba. Každá velikost jídla\nje samostatný produkt s vlastními ID – berte je ze zvolené velikosti.\n",
      "items": {
       "$ref": "#/components/schemas/RemovableIngredient"
      }
     },
     "split": {
      "description": "The product may be a part of a pizza from halves or quarters (`QuoteItemInput.type` `split`), with the price\nof one part; `null` when it may not. Parts of one pizza must be from the same `category_id` and of the same\nsize (`size.name`, or all without a size). A product with `option_groups` is never a part.\n",
      "x-description-cs": "Produkt může být dílem pizzy z půlek nebo čtvrtek (`QuoteItemInput.type` `split`), s cenou jednoho dílu;\n`null`, když nemůže. Díly jedné pizzy musí být ze stejné `category_id` a stejné velikosti (`size.name`,\nnebo všechny bez velikosti). Produkt s `option_groups` dílem nikdy není.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ProductSplit"
       },
       {
        "type": "null"
       }
      ]
     },
     "half_price": {
      "description": "The price of a half portion for applications of the restaurant staff (`QuoteItemInput.variant` `half`), from\nthe price at `at`, rounded up to whole crowns – the same as `pos.half_price`. Only in the catalogs `kitchen`\nand `pos`; `null` in `web` and when the product is not sold in halves. Packaging and add-ons of a half are\ncharged in full.\n",
      "x-description-cs": "Cena půl porce pro aplikace personálu provozovny (`QuoteItemInput.variant` `half`) z ceny v okamžiku `at`,\nzaokrouhlená nahoru na celé koruny – totéž co `pos.half_price`. Jen v sortimentu `kitchen` a `pos`; ve `web`\na když se produkt po půlkách neprodává, `null`. Obal a přílohy půlky se účtují celé.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "position": {
      "type": "integer",
      "description": "Order within its category, ascending from 1, as the channel orders the products; for a product offered only in\nthe daily menu, its place in the daily menu.\n",
      "x-description-cs": "Pořadí v kategorii, vzestupně od 1, jak produkty řadí daný kanál; u produktu jen v denním menu jeho místo\nv denním menu.\n"
     },
     "ean": {
      "type": [
       "string",
       "null"
      ],
      "description": "The barcode as entered (not checked); `null` when empty.",
      "x-description-cs": "Čárový kód, jak je zadaný (nekontroluje se); `null`, když chybí."
     },
     "kitchen_name": {
      "description": "Short name for the kitchen tickets and displays (`KitchenItem.kitchen_name`); `null` when the product has none.",
      "x-description-cs": "Krátký název pro kuchyňské bony a displeje (`KitchenItem.kitchen_name`); `null`, když ho produkt nemá.",
      "type": [
       "string",
       "null"
      ]
     },
     "size": {
      "description": "The size of a dish sold in several sizes (pizza Ø28cm / Ø32cm / Ø42cm, steak 100 g / 200 g / 300 g); `null` for\na product without sizes. Every size is a product of its own with its own `id`, price, portions and recipe, and\nits `name` already contains the size („Ø42cm Margherita“).\n",
      "x-description-cs": "Velikost jídla, které se prodává ve více velikostech (pizza Ø28cm / Ø32cm / Ø42cm, steak 100 g / 200 g / 300 g);\n`null` u produktu bez velikostí. Každá velikost je samostatný produkt s vlastním `id`, cenou, porcemi\na recepturou a její `name` už velikost obsahuje („Ø42cm Margherita“).\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ProductSize"
       },
       {
        "type": "null"
       }
      ]
     },
     "pos": {
      "description": "Register details, only in the `pos` channel; `null` in the others.",
      "x-description-cs": "Údaje pro pokladnu, jen v kanálu `pos`; v ostatních `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/PosProductInfo"
       },
       {
        "type": "null"
       }
      ]
     },
     "external_id": {
      "description": "Your own ID of the product (`putExternalRef`, only for products on the web); `null` when you set none.",
      "x-description-cs": "Vaše vlastní ID produktu (`putExternalRef`, jen u produktů na webu); `null`, když žádné nenastavíte.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "description": "Your own key–value pairs on the product (`putExternalRef`).",
      "x-description-cs": "Vaše vlastní dvojice klíč–hodnota u produktu (`putExternalRef`).",
      "$ref": "#/components/schemas/Metadata"
     }
    }
   },
   "ProductSize": {
    "type": "object",
    "description": "The place of a product among the sizes of one dish. Products with the same `group_id` are the sizes of one dish –\nshow them as one item with a size switcher (in `position` order, `base` preselected, at the place of the base size)\nand put the `id` of the chosen size into the quote and the order; the price, portions and add-ons are those of that\nproduct. The sizes come from the size sets in the administration (Sortiment › Size sets); the restaurant's e-shop\nshows them the same way. Halves of a split pizza must be of the same size there.\n",
    "x-description-cs": "Místo produktu mezi velikostmi jednoho jídla. Produkty se stejným `group_id` jsou velikosti jednoho jídla – ukažte\nje jako jednu položku s přepínačem velikostí (v pořadí `position`, předvolená `base`, na místě základní velikosti)\na do kalkulace i objednávky dejte `id` zvolené velikosti; cena, porce i přílohy jsou toho produktu. Velikosti\nvznikají ze sad velikostí v administraci (Sortiment › Sady velikostí); e-shop provozovny je ukazuje stejně\na půlky pizzy v něm skládá jen ze stejné velikosti.\n",
    "required": [
     "group_id",
     "name",
     "dish_name",
     "position",
     "base"
    ],
    "properties": {
     "group_id": {
      "description": "ID of the base size of the dish – the same for all its sizes, the base size included. The base size need not\nbe in this catalog (it may be offered only in another channel); group by `group_id` anyway.\n",
      "x-description-cs": "ID základní velikosti jídla – stejné u všech jeho velikostí včetně základní. Základní velikost v tomto\nsortimentu být nemusí (může se nabízet jen v jiném kanálu); seskupujte podle `group_id` i tak.\n",
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "description": "The size only, as the size set names it („Ø42cm“, „300 g“, „0,5 l“).",
      "x-description-cs": "Jen velikost, jak ji pojmenuje sada („Ø42cm“, „300 g“, „0,5 l“)."
     },
     "dish_name": {
      "type": "string",
      "description": "The name of the dish without the size („Margherita“) – for the item with the switcher.",
      "x-description-cs": "Název jídla bez velikosti („Margherita“) – pro položku s přepínačem."
     },
     "position": {
      "type": "integer",
      "minimum": 1,
      "description": "Order among all sizes of the dish, ascending from 1; it counts also the sizes missing from this catalog, so it\ndoes not change with availability.\n",
      "x-description-cs": "Pořadí mezi všemi velikostmi jídla, vzestupně od 1; počítá i velikosti, které v tomto sortimentu nejsou, takže\nse nemění s dostupností.\n"
     },
     "base": {
      "type": "boolean",
      "description": "The base size – the product the size set was assigned to; preselect it.",
      "x-description-cs": "Základní velikost – produkt, kterému byla sada přiřazena; předvolte ji."
     }
    }
   },
   "PosProductInfo": {
    "type": "object",
    "required": [
     "half_price",
     "employee_price",
     "plu",
     "station_id",
     "ticket"
    ],
    "properties": {
     "half_price": {
      "description": "Price of a half portion (`variant` `half`), rounded up to whole crowns; `null` when not sold in halves.",
      "x-description-cs": "Cena půlky (`variant` `half`), zaokrouhlená nahoru na celé koruny; `null`, když se půlky neprodávají.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "employee_price": {
      "description": "Price for employees (`at_employee_price` on a receipt item); `null` when the product has none.",
      "x-description-cs": "Cena pro zaměstnance (`at_employee_price` u položky účtenky); `null`, když ji produkt nemá.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "plu": {
      "type": [
       "string",
       "null"
      ],
      "description": "Short code for typing on the register.",
      "x-description-cs": "Krátký kód pro zadání na pokladně."
     },
     "station_id": {
      "description": "Production station the product is made at (`DeviceSettings.kitchen_stations`).",
      "x-description-cs": "Výrobní stanoviště, kde se produkt dělá (`DeviceSettings.kitchen_stations`).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "ticket": {
      "type": "string",
      "description": "Where an item ordered at the register goes: `kitchen` – to the kitchen ticket or production (the administration's\n\"send to the kitchen ticket automatically\"), `bar` – it stays at the bar. The shift close splits the takings\nthe same way.\n",
      "x-description-cs": "Kam jde položka objednaná na pokladně: `kitchen` – na kuchyňský bon nebo do řízení výroby (v administraci\n„Automaticky odeslat na kuchyňský bon“), `bar` – zůstává na baru. Stejně dělí tržby i uzávěrka.\n",
      "x-extensible-enum": [
       "kitchen",
       "bar"
      ]
     }
    }
   },
   "ProductAddOn": {
    "type": "object",
    "required": [
     "product_id",
     "name",
     "price",
     "vat_rate",
     "allergens"
    ],
    "properties": {
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "price": {
      "$ref": "#/components/schemas/Money",
      "description": "Surcharge including VAT; may be negative.",
      "x-description-cs": "Příplatek včetně DPH; může být záporný."
     },
     "vat_rate": {
      "$ref": "#/components/schemas/VatRate"
     },
     "allergens": {
      "type": "array",
      "description": "Codes from `Catalog.allergens` (EU regulation 1169/2011).",
      "x-description-cs": "Kódy z `Catalog.allergens` (nařízení EU 1169/2011).",
      "items": {
       "type": "string"
      }
     }
    }
   },
   "RemovableIngredient": {
    "type": "object",
    "description": "An ingredient of a dish the guest may remove („without mushrooms“). In a catalog it is the composition of the\nproduct; in a line of a quote, an order or a tab it is what the guest removed, with the name at that time. The\nkitchen shows it at the dish („WITHOUT: MUSHROOMS“) and the stock does not write it off.\n",
    "x-description-cs": "Surovina jídla, kterou si host smí odebrat („bez žampionů“). V sortimentu je to složení produktu; v řádku\nkalkulace, objednávky nebo účtu to, co host odebral, s názvem z té doby. Kuchyň ji ukáže u jídla\n(„BEZ: ŽAMPIONY“) a sklad ji neodepíše.\n",
    "required": [
     "id",
     "name"
    ],
    "properties": {
     "id": {
      "description": "Stays the same when the restaurant edits the composition (renames or reorders it).",
      "x-description-cs": "Zůstává stejné, když provozovna složení upraví (přejmenuje nebo přeřadí).",
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "maxLength": 48,
      "description": "The name as the guest sees it, in the case the restaurant entered („žampiony“).",
      "x-description-cs": "Název, jak ho uvidí host, s velikostí písmen, jak ho zadala provozovna („žampiony“).",
      "examples": [
       "žampiony"
      ]
     }
    }
   },
   "ProductOptionGroup": {
    "type": "object",
    "description": "A group of options of a product. Limits and included portions count portions – the sum of\n`QuoteItemInput.options[].quantity` of the group's options (double ham = 2).\n\n**Included portions:** the `included_quantity` cheapest paid portions of the group are in the price; with the\nsame price the option earlier in `options` wins, so the order of clicking does not matter. Free and negative\noptions take no included place. A premium option (`base_price`) takes none either – it is paid by the base.\n",
    "x-description-cs": "Skupina voleb produktu. Meze i porce v ceně se počítají v porcích – součet `QuoteItemInput.options[].quantity`\nvoleb skupiny (dvojitá šunka = 2).\n\n**Porce v ceně:** v ceně je `included_quantity` nejlevnějších placených porcí skupiny; při stejné ceně vyhrává\nvolba dřív v `options`, takže na pořadí klikání nezáleží. Volby zdarma a záporné místo v ceně neberou.\nPrémiová volba (`base_price`) také ne – je zaplacená základem.\n",
    "required": [
     "id",
     "name",
     "min_quantity",
     "max_quantity",
     "max_per_option",
     "included_quantity",
     "options"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "Ingredience"
      ]
     },
     "min_quantity": {
      "type": "integer",
      "minimum": 0,
      "description": "At least this many portions; `0` = the group is optional, `1` and more = a required choice.",
      "x-description-cs": "Nejméně tolik porcí; `0` = skupina je nepovinná, `1` a víc = povinný výběr."
     },
     "max_quantity": {
      "type": [
       "integer",
       "null"
      ],
      "description": "At most this many portions; `null` = no limit.",
      "x-description-cs": "Nejvýš tolik porcí; `null` = bez omezení."
     },
     "max_per_option": {
      "type": "integer",
      "minimum": 1,
      "description": "At most this many portions of one option (`1` = no double portions).",
      "x-description-cs": "Nejvýš tolik porcí jedné volby (`1` = bez dvojitých porcí)."
     },
     "included_quantity": {
      "type": "integer",
      "minimum": 0,
      "description": "Portions in the price of the product (the cheapest ones, see above).",
      "x-description-cs": "Porcí v ceně produktu (nejlevnější, viz výše)."
     },
     "options": {
      "type": "array",
      "description": "In the order the restaurant set; show them so.",
      "x-description-cs": "V pořadí, které nastavila provozovna; tak je i ukažte.",
      "items": {
       "$ref": "#/components/schemas/ProductOption"
      }
     }
    }
   },
   "ProductOption": {
    "type": "object",
    "description": "One option of a group – a product of the catalog (its name, VAT, allergens and portions) with its price per\nportion. The same product may be in several groups as different options with different prices; identify the\noption by `id`.\n",
    "x-description-cs": "Jedna volba skupiny – produkt sortimentu (jeho název, DPH, alergeny a porce) se svou cenou za porci. Stejný\nprodukt může být ve více skupinách jako různé volby s různou cenou; volbu určuje `id`.\n",
    "required": [
     "id",
     "product_id",
     "name",
     "price",
     "base_price",
     "vat_rate",
     "allergens"
    ],
    "properties": {
     "id": {
      "description": "The option, stable across changes of the group – send it as `QuoteItemInput.options[].option_id`.",
      "x-description-cs": "Volba, stálá i po úpravách skupiny – posílejte ji jako `QuoteItemInput.options[].option_id`.",
      "$ref": "#/components/schemas/Id"
     },
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "Šunka"
      ]
     },
     "price": {
      "$ref": "#/components/schemas/Money",
      "description": "Price of one portion including VAT, unless it is included (`ProductOptionGroup.included_quantity`); may be negative or zero.",
      "x-description-cs": "Cena jedné porce včetně DPH, pokud není v ceně (`ProductOptionGroup.included_quantity`); může být záporná i nulová."
     },
     "base_price": {
      "description": "A premium option: when chosen, the base price of the product becomes this amount (`OrderLine.unit_price`;\nwith several premium options the highest) and the option itself costs nothing (`reason` `in_base_price`).\n`null` for an ordinary option.\n",
      "x-description-cs": "Prémiová volba: když je vybraná, cena základu produktu je tato částka (`OrderLine.unit_price`; z víc\nprémiových voleb nejvyšší) a volba sama nestojí nic (`reason` `in_base_price`). `null` u běžné volby.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "vat_rate": {
      "$ref": "#/components/schemas/VatRate"
     },
     "allergens": {
      "type": "array",
      "description": "Codes from `Catalog.allergens`.",
      "x-description-cs": "Kódy z `Catalog.allergens`.",
      "items": {
       "type": "string"
      }
     }
    }
   },
   "ProductSplit": {
    "type": "object",
    "description": "Prices of one part of a pizza from parts, including VAT; the price of the pizza is the sum of its parts, its\nadd-ons and one packaging fee (the highest of the parts).\n",
    "x-description-cs": "Ceny jednoho dílu pizzy z dílů včetně DPH; cena pizzy je součet jejích dílů, jejich příloh a jednoho obalu\n(nejvyššího z dílů).\n",
    "required": [
     "half_price",
     "quarter_price"
    ],
    "properties": {
     "half_price": {
      "$ref": "#/components/schemas/Money",
      "description": "Price of a half (2 parts).",
      "x-description-cs": "Cena půlky (2 díly)."
     },
     "quarter_price": {
      "description": "Price of a quarter (4 parts); `null` when the product is split only into halves.",
      "x-description-cs": "Cena čtvrtky (4 díly); `null`, když se produkt dělí jen na půlky.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "DailyMenu": {
    "type": "object",
    "required": [
     "date",
     "available_from",
     "available_to",
     "items"
    ],
    "properties": {
     "date": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "available_from": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/LocalTime"
       },
       {
        "type": "null"
       }
      ]
     },
     "available_to": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/LocalTime"
       },
       {
        "type": "null"
       }
      ]
     },
     "items": {
      "type": "array",
      "description": "Products of the daily menu. Their `price` in `products` is already the menu price.",
      "x-description-cs": "Produkty denního menu. Jejich `price` v `products` je už cena z menu.",
      "items": {
       "type": "object",
       "required": [
        "product_id",
        "position"
       ],
       "properties": {
        "product_id": {
         "$ref": "#/components/schemas/Id"
        },
        "position": {
         "type": "integer"
        }
       }
      }
     }
    }
   },
   "DailyMenuWeek": {
    "type": "object",
    "description": "The daily menu of one week.",
    "x-description-cs": "Denní menu jednoho týdne.",
    "required": [
     "restaurant_id",
     "week",
     "enabled",
     "available_from",
     "available_to",
     "days"
    ],
    "properties": {
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "week": {
      "type": "string",
      "examples": [
       "2026-W41"
      ]
     },
     "enabled": {
      "type": "boolean"
     },
     "available_from": {
      "description": "When the menu starts each day; `null` = from the opening.",
      "x-description-cs": "Kdy menu každý den začíná; `null` = od otevření.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/LocalTime"
       },
       {
        "type": "null"
       }
      ]
     },
     "available_to": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/LocalTime"
       },
       {
        "type": "null"
       }
      ]
     },
     "days": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "date",
        "items"
       ],
       "properties": {
        "date": {
         "$ref": "#/components/schemas/LocalDate"
        },
        "items": {
         "type": "array",
         "items": {
          "$ref": "#/components/schemas/DailyMenuItem"
         }
        }
       }
      }
     }
    }
   },
   "DailyMenuItem": {
    "type": "object",
    "required": [
     "product_id",
     "name",
     "description",
     "price",
     "vat_rate",
     "allergens",
     "image_url",
     "every_day"
    ],
    "properties": {
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "description": {
      "type": [
       "string",
       "null"
      ]
     },
     "price": {
      "description": "The menu price.",
      "x-description-cs": "Cena z menu.",
      "$ref": "#/components/schemas/Money"
     },
     "vat_rate": {
      "$ref": "#/components/schemas/VatRate"
     },
     "allergens": {
      "type": "array",
      "description": "Allergen codes as in `GET …/catalog`.",
      "x-description-cs": "Kódy alergenů jako v `GET …/catalog`.",
      "items": {
       "type": "string"
      }
     },
     "image_url": {
      "type": [
       "string",
       "null"
      ],
      "format": "uri"
     },
     "every_day": {
      "type": "boolean",
      "description": "From the offer for the whole week, not only for this day.",
      "x-description-cs": "Z nabídky na celý týden, ne jen na tento den."
     }
    }
   },
   "Allergen": {
    "type": "object",
    "required": [
     "code",
     "name"
    ],
    "properties": {
     "code": {
      "type": "string",
      "examples": [
       "1"
      ]
     },
     "name": {
      "type": "string",
      "examples": [
       "Obiloviny obsahující lepek"
      ]
     }
    }
   },
   "SalePage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Sale"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Sale": {
    "type": "object",
    "required": [
     "id",
     "number",
     "kind",
     "source",
     "platform",
     "table_name",
     "created_at",
     "closed_at",
     "employee",
     "lines",
     "items_total",
     "discounts",
     "delivery_fee",
     "price_adjustment",
     "rounding",
     "total",
     "vat",
     "voucher_payments",
     "amount_paid",
     "payment_method",
     "card_at_handover",
     "tip",
     "eet",
     "shift_id",
     "cancels",
     "cancelled_by"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "number": {
      "type": "string",
      "description": "The document number the register or the customer knows (the order ID for the web).",
      "x-description-cs": "Číslo dokladu, pod kterým ho zná pokladna nebo zákazník (u webu ID objednávky)."
     },
     "kind": {
      "type": "string",
      "description": "`sale`, or `cancellation` – a cancellation document with negative amounts (`cancels`).",
      "x-description-cs": "`sale`, nebo `cancellation` – stornovací doklad se zápornými částkami (`cancels`).",
      "x-extensible-enum": [
       "sale",
       "cancellation"
      ]
     },
     "source": {
      "type": "string",
      "description": "`pos` – a register, `web` – the e-shop, an application or a delivery platform, `kitchen` – the kitchen display or a staff application.",
      "x-description-cs": "`pos` – pokladna, `web` – e-shop, aplikace nebo rozvozová platforma, `kitchen` – kuchyňský displej nebo aplikace personálu.",
      "x-extensible-enum": [
       "pos",
       "web",
       "kitchen"
      ]
     },
     "platform": {
      "type": [
       "string",
       "null"
      ],
      "description": "The delivery platform by the start of the order name, as the Statistics of the administration.",
      "x-description-cs": "Rozvozová platforma podle začátku názvu objednávky, jako Statistiky v administraci.",
      "x-extensible-enum": [
       "wolt",
       "bolt",
       "foodora",
       "choice"
      ]
     },
     "table_name": {
      "type": [
       "string",
       "null"
      ],
      "description": "The table or account of a register; `null` for other sources.",
      "x-description-cs": "Stůl nebo účet pokladny; u ostatních zdrojů `null`."
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "closed_at": {
      "description": "When the document was closed (paid on the register, the order placed or closed).",
      "x-description-cs": "Kdy se doklad uzavřel (zaplacení na pokladně, přijetí nebo uzavření objednávky).",
      "$ref": "#/components/schemas/Timestamp"
     },
     "employee": {
      "description": "Who closed the document; `null` when nobody (for example the web).",
      "x-description-cs": "Kdo doklad uzavřel; `null`, když nikdo (třeba web).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/EmployeeRef"
       },
       {
        "type": "null"
       }
      ]
     },
     "lines": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/SaleLine"
      }
     },
     "items_total": {
      "description": "Sum of the lines (gift voucher sales included).",
      "x-description-cs": "Součet řádků (i s prodejem dárkových voucherů).",
      "$ref": "#/components/schemas/Money"
     },
     "discounts": {
      "type": "array",
      "description": "Discounts on the whole bill (positive amounts).",
      "x-description-cs": "Slevy na celý účet (kladné částky).",
      "items": {
       "type": "object",
       "required": [
        "name",
        "amount"
       ],
       "properties": {
        "name": {
         "type": "string"
        },
        "amount": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "delivery_fee": {
      "$ref": "#/components/schemas/Money"
     },
     "price_adjustment": {
      "description": "A stored total differing from the lines by more than one crown (an adjusted price).",
      "x-description-cs": "Uložený součet, který se od řádků liší o víc než korunu (upravená cena).",
      "$ref": "#/components/schemas/Money"
     },
     "rounding": {
      "$ref": "#/components/schemas/Money"
     },
     "total": {
      "description": "The whole bill – the part paid by gift vouchers included.",
      "x-description-cs": "Celý účet – i s částí uhrazenou dárkovými vouchery.",
      "$ref": "#/components/schemas/Money"
     },
     "vat": {
      "type": "array",
      "description": "The VAT breakdown from the highest rate, exactly as the receipt copy and the accounting exports.",
      "x-description-cs": "Rozpis DPH od nejvyšší sazby, přesně jako kopie účtenky a účetní exporty.",
      "items": {
       "$ref": "#/components/schemas/VatBreakdown"
      }
     },
     "voucher_payments": {
      "type": "array",
      "description": "Payments by gift vouchers (no sale, outside VAT); the code is masked.",
      "x-description-cs": "Úhrady dárkovými vouchery (nejsou plnění, mimo DPH); kód je zamaskovaný.",
      "items": {
       "type": "object",
       "required": [
        "code",
        "amount"
       ],
       "properties": {
        "code": {
         "type": [
          "string",
          "null"
         ],
         "examples": [
          "ABC-***"
         ]
        },
        "amount": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "amount_paid": {
      "description": "What was paid other than by gift vouchers.",
      "x-description-cs": "Co se zaplatilo jinak než dárkovými vouchery.",
      "$ref": "#/components/schemas/Money"
     },
     "payment_method": {
      "type": "string",
      "description": "A card paid at handover counts as `card`, like the shift closes and the exports.",
      "x-description-cs": "Karta při převzetí jako `card`, stejně jako uzávěrky a exporty.",
      "x-extensible-enum": [
       "cash",
       "card",
       "meal_voucher",
       "company_account",
       "invoice"
      ]
     },
     "card_at_handover": {
      "type": "boolean"
     },
     "tip": {
      "$ref": "#/components/schemas/Money"
     },
     "eet": {
      "description": "The electronic sales record; `null` when there is none.",
      "x-description-cs": "Evidence tržeb; `null`, když žádná není.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/SaleEet"
       },
       {
        "type": "null"
       }
      ]
     },
     "shift_id": {
      "description": "The shift close of the document (`getShiftClose`); `null` before it.",
      "x-description-cs": "Uzávěrka dokladu (`getShiftClose`); před ní `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "cancels": {
      "description": "The cancelled document, for a `cancellation`.",
      "x-description-cs": "Stornovaný doklad, u `cancellation`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "cancelled_by": {
      "description": "The cancellation document of this one, when it was cancelled.",
      "x-description-cs": "Stornovací doklad k tomuto, když se stornoval.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "SaleLine": {
    "type": "object",
    "required": [
     "type",
     "product_id",
     "name",
     "quantity",
     "unit_price",
     "packaging_unit_price",
     "discount_per_unit",
     "vat_rate",
     "total"
    ],
    "properties": {
     "type": {
      "type": "string",
      "description": "`product`; `voucher_sale` – a gift voucher sold (outside VAT); `minimum_order_surcharge` – the surcharge to the\nminimum order of the delivery zone; `express_delivery` – express delivery. The two charges have no product and\na line per VAT rate of the food (ancillary costs, like the delivery fee in `delivery_fee`).\n",
      "x-description-cs": "`product`; `voucher_sale` – prodaný dárkový voucher (mimo DPH); `minimum_order_surcharge` – doplatek do minimální\nobjednávky rozvozové zóny; `express_delivery` – expresní doručení. Oba poplatky jsou bez produktu a mají řádek\nza každou sazbu DPH jídla (vedlejší výdaje, jako doprava v `delivery_fee`).\n",
      "x-extensible-enum": [
       "product",
       "voucher_sale",
       "minimum_order_surcharge",
       "express_delivery"
      ]
     },
     "product_id": {
      "description": "`null` for a line without a product.",
      "x-description-cs": "U řádku bez produktu `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "name": {
      "type": "string"
     },
     "quantity": {
      "type": "number"
     },
     "unit_price": {
      "description": "Price of one piece after the item discount, without packaging.",
      "x-description-cs": "Cena kusu po slevě na položku, bez obalu.",
      "$ref": "#/components/schemas/Money"
     },
     "packaging_unit_price": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "discount_per_unit": {
      "description": "The discount of one piece (already deducted from `unit_price`).",
      "x-description-cs": "Sleva na kus (už odečtená z `unit_price`).",
      "$ref": "#/components/schemas/Money"
     },
     "vat_rate": {
      "$ref": "#/components/schemas/VatRate"
     },
     "total": {
      "description": "Quantity × (unit price + packaging).",
      "x-description-cs": "Počet × (cena kusu + obal).",
      "$ref": "#/components/schemas/Money"
     }
    }
   },
   "SaleEet": {
    "type": "object",
    "required": [
     "fik",
     "bkp",
     "status",
     "pok"
    ],
    "properties": {
     "fik": {
      "type": [
       "string",
       "null"
      ],
      "description": "FIK of the original EET (registers on API v1).",
      "x-description-cs": "FIK původní EET (pokladny na API v1)."
     },
     "bkp": {
      "type": [
       "string",
       "null"
      ]
     },
     "status": {
      "type": [
       "string",
       "null"
      ],
      "description": "State of the EET 2.0 record Profirest sends; `null` when it does not record the document.",
      "x-description-cs": "Stav záznamu EET 2.0, který odesílá Profirest; `null`, když doklad neeviduje.",
      "x-extensible-enum": [
       "pending",
       "accepted",
       "rejected",
       "skipped"
      ]
     },
     "pok": {
      "type": [
       "string",
       "null"
      ],
      "description": "The confirmation code of EET 2.0 once accepted.",
      "x-description-cs": "Potvrzovací kód EET 2.0 po přijetí."
     }
    }
   },
   "SalesSummary": {
    "type": "object",
    "required": [
     "date_from",
     "date_to",
     "group_by",
     "segment",
     "totals",
     "rows"
    ],
    "properties": {
     "date_from": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "date_to": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "group_by": {
      "type": "string",
      "x-extensible-enum": [
       "day",
       "hour",
       "weekday",
       "payment",
       "source",
       "employee",
       "table",
       "segment"
      ]
     },
     "segment": {
      "type": [
       "string",
       "null"
      ],
      "x-extensible-enum": [
       "food",
       "lodging",
       "tickets"
      ],
      "description": "The kind of revenue from the `segment` parameter; `null` = all.",
      "x-description-cs": "Druh tržby z parametru `segment`; `null` = všechno."
     },
     "totals": {
      "type": "object",
      "required": [
       "revenue",
       "orders",
       "average_order",
       "tips"
      ],
      "properties": {
       "revenue": {
        "description": "Orders including delivery.",
        "x-description-cs": "Objednávky i s dopravou.",
        "$ref": "#/components/schemas/Money"
       },
       "orders": {
        "type": "integer",
        "minimum": 0
       },
       "average_order": {
        "$ref": "#/components/schemas/Money"
       },
       "tips": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "rows": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/SalesSummaryRow"
      }
     }
    }
   },
   "SalesSummaryRow": {
    "type": "object",
    "required": [
     "key",
     "name",
     "revenue",
     "orders"
    ],
    "properties": {
     "key": {
      "type": "string",
      "description": "`day` – the date; `hour` – 0–23; `weekday` – 1–7 (ISO, 1 = Monday); `payment` – `cash`, `card`,\n`meal_voucher`, `company_account`, `invoice`; `source` – `pos`, `web`, `kitchen`, `wolt`, `bolt`, `foodora`,\n`choice`; `employee` – the employee ID (`0` = nobody); `table` – the name of the account; `segment` – `food`,\n`lodging`, `tickets`.\n",
      "x-description-cs": "`day` – datum; `hour` – 0–23; `weekday` – 1–7 (ISO, 1 = pondělí); `payment` – `cash`, `card`,\n`meal_voucher`, `company_account`, `invoice`; `source` – `pos`, `web`, `kitchen`, `wolt`, `bolt`, `foodora`,\n`choice`; `employee` – ID zaměstnance (`0` = nikdo); `table` – název účtu; `segment` – `food`, `lodging`,\n`tickets`.\n"
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "description": "The employee or account name; `null` for the other breakdowns and when unknown.",
      "x-description-cs": "Jméno zaměstnance nebo název účtu; u ostatních rozpadů a když není známé, `null`."
     },
     "revenue": {
      "$ref": "#/components/schemas/Money"
     },
     "orders": {
      "type": "integer",
      "minimum": 0
     }
    }
   },
   "ProductSales": {
    "type": "object",
    "required": [
     "date_from",
     "date_to",
     "group_by",
     "segment",
     "totals",
     "rows"
    ],
    "properties": {
     "date_from": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "date_to": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "group_by": {
      "type": "string",
      "x-extensible-enum": [
       "product",
       "category",
       "sortiment",
       "station"
      ]
     },
     "segment": {
      "type": [
       "string",
       "null"
      ],
      "x-extensible-enum": [
       "food",
       "lodging",
       "tickets"
      ],
      "description": "The kind of revenue from the `segment` parameter; `null` = all.",
      "x-description-cs": "Druh tržby z parametru `segment`; `null` = všechno."
     },
     "totals": {
      "type": "object",
      "required": [
       "quantity",
       "revenue",
       "discounts"
      ],
      "properties": {
       "quantity": {
        "type": "number"
       },
       "revenue": {
        "$ref": "#/components/schemas/Money"
       },
       "discounts": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "rows": {
      "type": "array",
      "description": "From the highest revenue.",
      "x-description-cs": "Od nejvyšší tržby.",
      "items": {
       "$ref": "#/components/schemas/ProductSalesRow"
      }
     }
    }
   },
   "ProductSalesRow": {
    "type": "object",
    "required": [
     "key",
     "name",
     "quantity",
     "revenue",
     "discounts"
    ],
    "properties": {
     "key": {
      "description": "The ID of the product, category, sortiment or production station; `null` for items without a category,\nsortiment or station. Product `0` is a line without a product (for example the surcharge to the minimum\norder), one row per name.\n",
      "x-description-cs": "ID produktu, kategorie, sortimentu nebo výrobního stanoviště; `null` u položek bez kategorie, sortimentu\nnebo stanoviště. Produkt `0` je řádek bez produktu (třeba doplatek do minimální objednávky), řádek pro\nkaždý název.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "name": {
      "type": [
       "string",
       "null"
      ]
     },
     "quantity": {
      "type": "number"
     },
     "revenue": {
      "$ref": "#/components/schemas/Money"
     },
     "discounts": {
      "$ref": "#/components/schemas/Money"
     }
    }
   },
   "ChargesReport": {
    "type": "object",
    "required": [
     "date_from",
     "date_to",
     "rows"
    ],
    "properties": {
     "date_from": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "date_to": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "rows": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ChargesReportRow"
      }
     }
    }
   },
   "ChargesReportRow": {
    "type": "object",
    "required": [
     "type",
     "name",
     "orders",
     "amount"
    ],
    "properties": {
     "type": {
      "type": "string",
      "description": "The charge, as `Charge.type`.",
      "x-description-cs": "Poplatek, jako `Charge.type`.",
      "x-extensible-enum": [
       "delivery_fee",
       "minimum_order_surcharge",
       "express_delivery"
      ]
     },
     "name": {
      "type": "string",
      "description": "The name in Czech, as on the receipt.",
      "x-description-cs": "Název česky, jako na účtence."
     },
     "orders": {
      "type": "integer",
      "description": "Orders with the charge; cancellations by a reverse document are subtracted, so it may be negative.",
      "x-description-cs": "Objednávky s poplatkem; storna protidokladem se odečítají, proto může být i záporné."
     },
     "amount": {
      "$ref": "#/components/schemas/Money",
      "description": "The sum of the charge including VAT.",
      "x-description-cs": "Součet poplatku včetně DPH."
     }
    }
   },
   "TipsReport": {
    "type": "object",
    "required": [
     "date_from",
     "date_to",
     "totals",
     "by_payment",
     "by_employee",
     "by_courier"
    ],
    "properties": {
     "date_from": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "date_to": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "totals": {
      "type": "object",
      "required": [
       "tips",
       "orders_with_tip",
       "orders",
       "revenue"
      ],
      "properties": {
       "tips": {
        "$ref": "#/components/schemas/Money"
       },
       "orders_with_tip": {
        "type": "integer",
        "minimum": 0
       },
       "orders": {
        "type": "integer",
        "minimum": 0
       },
       "revenue": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "by_payment": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "method",
        "tips",
        "orders"
       ],
       "properties": {
        "method": {
         "type": "string",
         "x-extensible-enum": [
          "cash",
          "card",
          "meal_voucher",
          "company_account",
          "invoice"
         ]
        },
        "tips": {
         "$ref": "#/components/schemas/Money"
        },
        "orders": {
         "type": "integer",
         "minimum": 0
        }
       }
      }
     },
     "by_employee": {
      "type": "array",
      "description": "By the employee who closed the order.",
      "x-description-cs": "Podle zaměstnance, který objednávku uzavřel.",
      "items": {
       "$ref": "#/components/schemas/TipsByEmployee"
      }
     },
     "by_courier": {
      "type": "array",
      "description": "By the courier of the delivery.",
      "x-description-cs": "Podle kurýra rozvozu.",
      "items": {
       "$ref": "#/components/schemas/TipsByEmployee"
      }
     }
    }
   },
   "TipsByEmployee": {
    "type": "object",
    "required": [
     "employee",
     "tips",
     "orders"
    ],
    "properties": {
     "employee": {
      "$ref": "#/components/schemas/EmployeeRef"
     },
     "tips": {
      "$ref": "#/components/schemas/Money"
     },
     "orders": {
      "type": "integer",
      "minimum": 0
     }
    }
   },
   "VatReport": {
    "type": "object",
    "required": [
     "date_from",
     "date_to",
     "rates",
     "vouchers_sold"
    ],
    "properties": {
     "date_from": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "date_to": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "rates": {
      "type": "array",
      "description": "From the highest rate; a rate with nothing sold is left out.",
      "x-description-cs": "Od nejvyšší sazby; sazba bez prodeje chybí.",
      "items": {
       "$ref": "#/components/schemas/VatBreakdown"
      }
     },
     "vouchers_sold": {
      "$ref": "#/components/schemas/Money",
      "description": "Gift vouchers sold – not subject to VAT, not in `rates`.",
      "x-description-cs": "Prodané dárkové vouchery – nepodléhají DPH, v `rates` nejsou."
     }
    }
   },
   "ShiftClosePage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ShiftClose"
      }
     },
     "next_cursor": {
      "description": "Cursor of the next page; `null` on the last one.",
      "x-description-cs": "Kurzor další stránky; `null` na poslední.",
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "ShiftClose": {
    "type": "object",
    "description": "A shift close with the totals of the administration's close detail.",
    "x-description-cs": "Uzávěrka se součty z detailu uzávěrky v administraci.",
    "required": [
     "id",
     "restaurant_id",
     "closed_at",
     "closed_by",
     "source",
     "device_id",
     "orders",
     "totals"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "closed_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "closed_by": {
      "description": "The employee who closed the shift; `null` when not recorded.",
      "x-description-cs": "Zaměstnanec, který směnu uzavřel; `null`, když není zapsaný.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/EmployeeRef"
       },
       {
        "type": "null"
       }
      ]
     },
     "source": {
      "type": "string",
      "description": "Where the orders of the close came from: `pos` – registers, `kitchen` – the kitchen (e-shop, phone orders,\napplications), `mixed` – both, `empty` – no order (for example only open tabs were counted).\n",
      "x-description-cs": "Odkud byly objednávky uzávěrky: `pos` – pokladny, `kitchen` – kuchyň (e-shop, telefonické objednávky,\naplikace), `mixed` – obojí, `empty` – žádná objednávka (třeba se počítaly jen otevřené účty).\n",
      "x-extensible-enum": [
       "pos",
       "kitchen",
       "mixed",
       "empty"
      ]
     },
     "device_id": {
      "description": "The register on API v2 that closed the shift (`pos_shift.closed`); `null` for other closes.",
      "x-description-cs": "Pokladna na API v2, která směnu uzavřela (`pos_shift.closed`); u jiných uzávěrek `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "orders": {
      "type": "integer",
      "description": "Orders in the close (deleted ones not counted).",
      "x-description-cs": "Objednávky v uzávěrce (smazané se nepočítají)."
     },
     "totals": {
      "$ref": "#/components/schemas/ShiftCloseTotals"
     }
    }
   },
   "ShiftCloseTotals": {
    "type": "object",
    "required": [
     "completed",
     "by_payment",
     "not_completed",
     "cancelled_orders",
     "cancelled_items",
     "tips",
     "discounts",
     "eet_registered",
     "by_ticket"
    ],
    "properties": {
     "completed": {
      "description": "Takings of the close.",
      "x-description-cs": "Tržba uzávěrky.",
      "$ref": "#/components/schemas/Money"
     },
     "by_payment": {
      "type": "object",
      "description": "Takings by payment method as the close recorded them.",
      "x-description-cs": "Tržba podle způsobu platby, jak ji uzávěrka zapsala.",
      "required": [
       "cash",
       "card",
       "meal_voucher",
       "company_account",
       "invoice"
      ],
      "properties": {
       "cash": {
        "$ref": "#/components/schemas/Money"
       },
       "card": {
        "$ref": "#/components/schemas/Money"
       },
       "meal_voucher": {
        "$ref": "#/components/schemas/Money"
       },
       "company_account": {
        "$ref": "#/components/schemas/Money"
       },
       "invoice": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "not_completed": {
      "description": "Not paid at the close – orders still in the queue, or open tabs of tables.",
      "x-description-cs": "Nezaplaceno při uzávěrce – objednávky ve frontě, nebo otevřené účty stolů.",
      "$ref": "#/components/schemas/Money"
     },
     "cancelled_orders": {
      "description": "Orders cancelled by a cancellation document.",
      "x-description-cs": "Objednávky stornované stornodokladem.",
      "$ref": "#/components/schemas/Money"
     },
     "cancelled_items": {
      "description": "Items removed after they went to the kitchen (item cancellations of tables).",
      "x-description-cs": "Položky odebrané poté, co šly do kuchyně (storna položek u stolů).",
      "$ref": "#/components/schemas/Money"
     },
     "tips": {
      "type": "object",
      "description": "Tips; card payment at handover counts as card.",
      "x-description-cs": "Spropitné; karta při převzetí se počítá jako karta.",
      "required": [
       "total",
       "cash",
       "card"
      ],
      "properties": {
       "total": {
        "$ref": "#/components/schemas/Money"
       },
       "cash": {
        "$ref": "#/components/schemas/Money"
       },
       "card": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "discounts": {
      "type": "object",
      "description": "`order` – discounts on the whole order, `items` – discounts on items.",
      "x-description-cs": "`order` – slevy na celou objednávku, `items` – slevy na položky.",
      "required": [
       "order",
       "items"
      ],
      "properties": {
       "order": {
        "$ref": "#/components/schemas/Money"
       },
       "items": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "eet_registered": {
      "description": "Orders registered in EET (with a FIK).",
      "x-description-cs": "Objednávky zaevidované v EET (s FIK).",
      "$ref": "#/components/schemas/Money"
     },
     "by_ticket": {
      "type": "object",
      "description": "Takings of the items split by `PosProductInfo.ticket` – kitchen and bar, as the close detail and the Statistics\nof the administration count them: the price with packaging after its share of a discount on the whole order.\nDelivery is no item; a gift voucher sale counts in full (bar), a payment by a gift voucher is no sale (the food\nand drinks paid by it count in full).\n",
      "x-description-cs": "Tržba položek podle `PosProductInfo.ticket` – kuchyň a bar, jak je počítá detail uzávěrky a Statistiky\nv administraci: cena s obalem po poměrné části slevy na celý účet. Doprava položka není; prodej dárkového\nvoucheru se počítá celý (bar), platba dárkovým voucherem prodej není (jídlo a pití zaplacené voucherem se\npočítá v plné ceně).\n",
      "required": [
       "kitchen",
       "bar"
      ],
      "properties": {
       "kitchen": {
        "$ref": "#/components/schemas/Money"
       },
       "bar": {
        "$ref": "#/components/schemas/Money"
       }
      }
     }
    }
   },
   "ProductAvailabilityInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "remaining"
    ],
    "properties": {
     "remaining": {
      "description": "Portions left; `0` = sold out, `null` = not limited.",
      "x-description-cs": "Zbývající porce; `0` = vyprodáno, `null` = bez omezení.",
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "maximum": 100000
     }
    }
   },
   "ProductAvailability": {
    "type": "object",
    "required": [
     "product_id",
     "remaining",
     "sold_out",
     "source"
    ],
    "properties": {
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "remaining": {
      "description": "Portions left; `null` = not limited.",
      "x-description-cs": "Zbývající porce; `null` = bez omezení.",
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0
     },
     "sold_out": {
      "type": "boolean"
     },
     "source": {
      "type": "string",
      "description": "Where the number is kept: `daily_menu` – today's daily menu (sales take portions from it first),\n`restaurant` – the restaurant's portions of the product, `none` – not limited.\n",
      "x-description-cs": "Kde číslo je: `daily_menu` – dnešní denní menu (prodej bere porce nejdřív odtud), `restaurant` – porce\nproduktu v provozovně, `none` – bez omezení.\n",
      "x-extensible-enum": [
       "daily_menu",
       "restaurant",
       "none"
      ]
     }
    }
   },
   "Availability": {
    "type": "object",
    "required": [
     "restaurant_id",
     "tracking",
     "generated_at",
     "items"
    ],
    "properties": {
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "tracking": {
      "type": "boolean",
      "description": "`false` means no product is limited for your application; `items` is then empty.",
      "x-description-cs": "`false` znamená, že pro vaši aplikaci žádný produkt omezený není; `items` je pak prázdné."
     },
     "generated_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "items": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "product_id",
        "remaining",
        "sold_out"
       ],
       "properties": {
        "product_id": {
         "$ref": "#/components/schemas/Id"
        },
        "remaining": {
         "type": "integer",
         "minimum": 0
        },
        "sold_out": {
         "type": "boolean"
        }
       }
      }
     }
    }
   },
   "QuoteRequest": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "fulfillment",
     "items"
    ],
    "properties": {
     "fulfillment": {
      "$ref": "#/components/schemas/FulfillmentInput"
     },
     "delivery_address": {
      "description": "Required for `delivery`; must be `null` or missing for `pickup`.",
      "x-description-cs": "Povinná pro `delivery`; u `pickup` musí být `null` nebo chybět.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/AddressInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 100,
      "items": {
       "$ref": "#/components/schemas/QuoteItemInput"
      }
     },
     "customer_id": {
      "description": "Customer link from `POST /customers`, if you have one. The order takes it from the quote. Loyalty points\ngo to the linked customer. The kitchen and the courier see the contact of the order (`customer` of\n`createOrder`) – when its phone differs from the linked customer, for example an order for somebody else,\nthey see the contact, not the linked customer. Promotions for registered customers, first orders, limits per\ncustomer and loyalty cards (`Promotion.conditions.customer`, `max_per_customer`, `effect.nth_item.loyalty`)\napply only with a linked customer whose phone is verified (`phone_verified`).\n",
      "x-description-cs": "Propojení zákazníka z `POST /customers`, pokud ho máte. Objednávka ho převezme z kalkulace. Věrnostní body\ndostane propojený zákazník. Kuchyň a kurýr vidí kontakt objednávky (`customer` z `createOrder`) – když\nmá jiný telefon než propojený zákazník, třeba objednávka pro někoho jiného, vidí kontakt, ne propojeného\nzákazníka. Akce pro registrované zákazníky, na první objednávku, s limitem na zákazníka a věrnostní karty\n(`Promotion.conditions.customer`, `max_per_customer`, `effect.nth_item.loyalty`) platí jen s propojeným\nzákazníkem s ověřeným telefonem (`phone_verified`).\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "vouchers": {
      "type": "array",
      "maxItems": 5,
      "items": {
       "$ref": "#/components/schemas/VoucherInput"
      }
     },
     "promo_codes": {
      "description": "A promo code the customer entered – at most one: the shared code of a promotion or one of its single-use\ncodes (`Promotion.code_type`). Promotions without a code apply by themselves. The code applies when it meets\nits conditions; together with it only promotions that can be combined, and only when the code's promotion can\nbe combined too. Without a code the better of the best promotion that cannot be combined and all that can is\nused. Loyalty cards add up with everything. When the code does not apply you get `promo_code_not_applicable`\nwith the reason in `detail` (show it to the customer); a single-use code already used, or a promotion the\ncustomer used as many times as allowed, gives `promo_code_used_up`. A single-use code is used up by the\norder created from the quote. Only for guest applications and the `web` catalog. Unknown codes count\ntowards the same attempt limits as vouchers.\n",
      "x-description-cs": "Slevový kód, který zákazník zadal – nejvýš jeden: sdílený kód akce nebo jeden z jejích jednorázových kódů\n(`Promotion.code_type`). Akce bez kódu se uplatní samy. Kód se uplatní, když splňuje své podmínky; s ním\njen akce, které jdou kombinovat, a to jen když jde kombinovat i akce kódu. Bez kódu se použije výhodnější\nz nejlepší akce, která kombinovat nejde, a všech, které jdou. Věrnostní karty se sčítají se vším. Když kód\nneplatí, dostanete `promo_code_not_applicable` s důvodem v `detail` (ukažte ho zákazníkovi); už použitý\njednorázový kód nebo akce, kterou zákazník využil, kolikrát mohl, vrátí `promo_code_used_up`. Jednorázový\nkód spotřebuje objednávka vytvořená z kalkulace. Jen pro aplikace hostů a sortiment `web`. Neznámé kódy se\npočítají do stejných limitů pokusů jako vouchery.\n",
      "type": "array",
      "maxItems": 1,
      "items": {
       "$ref": "#/components/schemas/PromoCodeInput"
      }
     },
     "end_user_id": {
      "description": "Your stable, anonymous ID of the shopper. Used for the attempt limits of vouchers and promo codes.",
      "x-description-cs": "Vaše stálé anonymní ID nakupujícího. Slouží k limitům pokusů o vouchery a slevové kódy.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "channel": {
      "description": "The catalog the items come from, as in `GET …/catalog?channel=`. `web` when missing. `kitchen` and `pos` only\nfor applications of the restaurant's staff and a kiosk set to work as staff.\n",
      "x-description-cs": "Sortiment, ze kterého položky jsou, stejně jako `GET …/catalog?channel=`. Když chybí, `web`. `kitchen` a `pos`\njen pro aplikace personálu provozovny a kiosek nastavený jako obsluha.\n",
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "web",
       "kitchen",
       "pos",
       null
      ]
     }
    }
   },
   "FulfillmentInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "type"
    ],
    "properties": {
     "type": {
      "$ref": "#/components/schemas/FulfillmentType"
     },
     "speed": {
      "type": "string",
      "enum": [
       "standard",
       "express"
      ],
      "default": "standard",
      "description": "`standard` – the usual delivery; `express` – express delivery for the restaurant's surcharge\n(`delivery.express_fee`): the kitchen and the courier see the order marked EXPRES and give it priority,\nwithout a promised time. Express only for `delivery` as soon as possible (no `time`) – otherwise `422`\nwith `not_allowed`; to a zone without express `422` `express_unavailable`. The quote adds the charge\n`express_delivery`.\n",
      "x-description-cs": "`standard` – běžný rozvoz; `express` – expresní doručení za příplatek provozovny (`delivery.express_fee`):\nkuchyně a kurýr vidí objednávku označenou EXPRES a dají jí přednost, bez slíbeného času. Expres jen\nu `delivery` co nejdřív (bez `time`) – jinak `422` s `not_allowed`; do zóny bez expresu `422`\n`express_unavailable`. Kalkulace přidá poplatek `express_delivery`.\n"
     },
     "time": {
      "description": "Requested time; `null` or missing means as soon as possible. For `delivery` the time the customer receives\nthe order, for `pickup` and `dine_in` the time it is ready.\n",
      "x-description-cs": "Požadovaný čas; `null` nebo chybějící znamená co nejdřív. U `delivery` čas, kdy zákazník objednávku\ndostane, u `pickup` a `dine_in` čas, kdy je připravená.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "QuoteItemInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "quantity"
    ],
    "description": "One item of the basket.\n\n- **`product`** (default): `product_id`, with `add_ons` – or, for a product with `Product.option_groups`,\n  with `options` (such a product has no add-ons).\n- **`split`** – a pizza from parts: `parts` with 2 halves or 4 quarters, each with its own `add_ons`, no\n  `product_id`. Parts are products with `Product.split` from the same `category_id` and of the same size, at\n  least two different ones; a quarter needs `split.quarter_price`. The parts are listed in the order of the\n  pizza (`OrderLinePart.position`) – the same product may be there more times (2× ¼ + 2× ¼).\n\nA wrong choice (limits of a group, parts that do not fit together, a field that does not belong to the kind)\nanswers `422 validation_failed` with `errors[]` pointing at the field; a product or add-on not offered or sold\nout answers `422 product_unavailable`.\n",
    "x-description-cs": "Jedna položka košíku.\n\n- **`product`** (výchozí): `product_id` s `add_ons` – nebo u produktu s `Product.option_groups` s `options`\n  (takový produkt přílohy nemá).\n- **`split`** – pizza z dílů: `parts` se 2 půlkami nebo 4 čtvrtkami, každý díl s vlastními `add_ons`, bez\n  `product_id`. Díly jsou produkty s `Product.split` ze stejné `category_id` a stejné velikosti, aspoň dva\n  různé; čtvrtka potřebuje `split.quarter_price`. Díly se uvádějí v pořadí na pizze\n  (`OrderLinePart.position`) – stejný produkt tam smí být víckrát (2× ¼ + 2× ¼).\n\nŠpatný výběr (meze skupiny, díly, které k sobě nepatří, pole, které k druhu nepatří) odpoví\n`422 validation_failed` s `errors[]` na dotčené pole; produkt nebo příloha, které se nenabízejí nebo došly,\nodpoví `422 product_unavailable`.\n",
    "properties": {
     "type": {
      "type": "string",
      "enum": [
       "product",
       "split"
      ],
      "default": "product",
      "description": "Kind of item: `product` – a product of the catalog; `split` – a pizza from halves or quarters (`parts`).",
      "x-description-cs": "Druh položky: `product` – produkt ze sortimentu; `split` – pizza z půlek nebo čtvrtek (`parts`)."
     },
     "product_id": {
      "description": "The product; required for `product`, not allowed for `split`.",
      "x-description-cs": "Produkt; povinný u `product`, u `split` nepatří.",
      "$ref": "#/components/schemas/Id"
     },
     "variant": {
      "type": "string",
      "enum": [
       "full",
       "half"
      ],
      "default": "full",
      "description": "`full` (default) – a whole portion; `half` – a half portion at `Product.half_price`, with the packaging and\nadd-ons in full. Only for `product` with `Product.half_price` – that is in the catalogs `kitchen` and `pos`\nof the restaurant staff; otherwise `422 validation_failed` with the code `not_allowed` at\n`/items/{i}/variant`. A half takes one portion like a whole one; the kitchen gets it as `kind` `half`.\n",
      "x-description-cs": "`full` (výchozí) – celá porce; `half` – poloviční porce za `Product.half_price`, obal a přílohy celé. Jen\nu `product` s `Product.half_price` – tedy v sortimentu `kitchen` a `pos` personálu provozovny; jinak\n`422 validation_failed` s kódem `not_allowed` na `/items/{i}/variant`. Půlka ubírá jednu porci jako celá;\nkuchyň ji dostane jako `kind` `half`.\n"
     },
     "quantity": {
      "type": "integer",
      "minimum": 1,
      "maximum": 99
     },
     "add_ons": {
      "type": "array",
      "maxItems": 30,
      "description": "Add-ons from `Product.add_ons`, each at most once (more portions with `quantity`). They follow the quantity\nof the item. Only for `product` without option groups.\n",
      "x-description-cs": "Přílohy a doplňky z `Product.add_ons`, každý nejvýš jednou (víc porcí přes `quantity`). Počet mají podle\npoložky. Jen u `product` bez skupin voleb.\n",
      "items": {
       "$ref": "#/components/schemas/AddOnInput"
      }
     },
     "options": {
      "type": "array",
      "maxItems": 100,
      "description": "The choice for a product with `Product.option_groups`: options of its groups, each at most once (more\nportions with `quantity`). The quote checks `min_quantity`, `max_quantity` and `max_per_option` of every\ngroup – `422 validation_failed` with the codes `option_group_min`, `option_group_max` (pointer\n`/items/{i}/options`), `option_not_in_group` or `too_large`. Only for `product`.\n",
      "x-description-cs": "Výběr u produktu s `Product.option_groups`: volby jeho skupin, každá nejvýš jednou (víc porcí přes\n`quantity`). Kalkulace zkontroluje `min_quantity`, `max_quantity` a `max_per_option` každé skupiny –\n`422 validation_failed` s kódy `option_group_min`, `option_group_max` (pointer `/items/{i}/options`),\n`option_not_in_group` nebo `too_large`. Jen u `product`.\n",
      "items": {
       "$ref": "#/components/schemas/OptionInput"
      }
     },
     "removed_ingredient_ids": {
      "type": "array",
      "maxItems": 30,
      "uniqueItems": true,
      "description": "Ingredients the guest removed from the dish – `Product.removable_ingredients[].id` of the item's product, each\nat most once. The price does not change; the kitchen gets them at the dish (`KitchenItem.removed_ingredients`)\nand the stock does not write them off. An ID the product does not have, or a repeated one, answers\n`422 validation_failed` with the code `ingredient_not_removable` at `/items/{i}/removed_ingredient_ids/{j}`.\nOnly for `product`; for `split` send them at the part (`SplitPartInput.removed_ingredient_ids`).\n",
      "x-description-cs": "Suroviny, které host z jídla odebral – `Product.removable_ingredients[].id` produktu položky, každá nejvýš\njednou. Cena se nemění; kuchyň je dostane u jídla (`KitchenItem.removed_ingredients`) a sklad je\nneodepíše. ID, které produkt nemá, nebo opakované odpoví `422 validation_failed` s kódem\n`ingredient_not_removable` na `/items/{i}/removed_ingredient_ids/{j}`. Jen u `product`; u `split` je\npošlete u dílu (`SplitPartInput.removed_ingredient_ids`).\n",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "parts": {
      "type": "array",
      "minItems": 2,
      "maxItems": 4,
      "description": "The parts of a pizza for `split` – exactly 2 (halves) or 4 (quarters).",
      "x-description-cs": "Díly pizzy u `split` – právě 2 (půlky) nebo 4 (čtvrtky).",
      "items": {
       "$ref": "#/components/schemas/SplitPartInput"
      }
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "description": "Note for the kitchen, shown on the kitchen display.",
      "x-description-cs": "Poznámka pro kuchyň, zobrazí se na kuchyňském displeji."
     }
    }
   },
   "OptionInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "option_id"
    ],
    "properties": {
     "option_id": {
      "description": "`ProductOption.id` of an option of the item's product.",
      "x-description-cs": "`ProductOption.id` volby produktu položky.",
      "$ref": "#/components/schemas/Id"
     },
     "quantity": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10,
      "default": 1,
      "description": "Portions of the option per one piece of the item, at most `ProductOptionGroup.max_per_option`.",
      "x-description-cs": "Porcí volby na jeden kus položky, nejvýš `ProductOptionGroup.max_per_option`."
     }
    }
   },
   "SplitPartInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "product_id"
    ],
    "properties": {
     "product_id": {
      "description": "A product with `Product.split`.",
      "x-description-cs": "Produkt s `Product.split`.",
      "$ref": "#/components/schemas/Id"
     },
     "add_ons": {
      "type": "array",
      "maxItems": 30,
      "description": "Add-ons of this part from `Product.add_ons` of its product, at the full price of the add-on.",
      "x-description-cs": "Přílohy tohoto dílu z `Product.add_ons` jeho produktu, za plnou cenu přílohy.",
      "items": {
       "$ref": "#/components/schemas/AddOnInput"
      }
     },
     "removed_ingredient_ids": {
      "type": "array",
      "maxItems": 30,
      "uniqueItems": true,
      "description": "Ingredients removed from this part – `Product.removable_ingredients[].id` of its product, each at most once\n(`ingredient_not_removable` at `/items/{i}/parts/{k}/removed_ingredient_ids/{j}` otherwise). The kitchen\ngets them at the part.\n",
      "x-description-cs": "Suroviny odebrané z tohoto dílu – `Product.removable_ingredients[].id` jeho produktu, každá nejvýš jednou\n(jinak `ingredient_not_removable` na `/items/{i}/parts/{k}/removed_ingredient_ids/{j}`). Kuchyň je dostane\nu dílu.\n",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     }
    }
   },
   "AddOnInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "product_id"
    ],
    "properties": {
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "quantity": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10,
      "default": 1,
      "description": "Portions of the add-on per one piece of the item (double cheese = 2).",
      "x-description-cs": "Porcí přílohy na jeden kus položky (dvojitý sýr = 2)."
     }
    }
   },
   "VoucherCode": {
    "type": "string",
    "description": "Voucher code, 6 characters; the dash is optional and case does not matter.",
    "x-description-cs": "Kód voucheru, 6 znaků; pomlčka je nepovinná a na velikosti písmen nezáleží.",
    "pattern": "^[A-Za-z0-9]{3}-?[A-Za-z0-9]{3}$",
    "examples": [
     "ABC-DEF"
    ]
   },
   "VoucherInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "code"
    ],
    "properties": {
     "code": {
      "$ref": "#/components/schemas/VoucherCode"
     }
    }
   },
   "PromoCode": {
    "type": "string",
    "description": "A promo code of the restaurant – 3 to 32 letters, digits and dashes; case does not matter and spaces are ignored.",
    "x-description-cs": "Slevový kód provozovny – 3 až 32 písmen, číslic a pomlček; na velikosti písmen nezáleží a mezery se vynechají.",
    "minLength": 3,
    "maxLength": 40,
    "pattern": "^ *[A-Za-z0-9][A-Za-z0-9 -]{2,} *$",
    "examples": [
     "LETO50"
    ]
   },
   "PromoCodeInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "code"
    ],
    "properties": {
     "code": {
      "$ref": "#/components/schemas/PromoCode"
     }
    }
   },
   "PromotionList": {
    "type": "object",
    "required": [
     "restaurant_id",
     "at",
     "promotions"
    ],
    "properties": {
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "at": {
      "$ref": "#/components/schemas/Timestamp",
      "description": "The moment the list is for.",
      "x-description-cs": "Okamžik, pro který seznam platí."
     },
     "promotions": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Promotion"
      }
     }
    }
   },
   "Promotion": {
    "type": "object",
    "description": "A promotion of the restaurant for orders from guest applications. Show it to customers; the quote decides\nwhether it applies and how much it gives.\n\n- **Time:** `valid_from`, `valid_until`, `days` and `time_windows` are judged at the moment the order is sent –\n  when you create the quote – in the time zone of the restaurant, not at the time of delivery or pickup.\n- **Customer:** conditions about the customer (`conditions.customer` other than `any`,\n  `conditions.max_per_customer`) and loyalty cards (`effect.nth_item.loyalty`) apply only with\n  `QuoteRequest.customer_id` of a linked customer whose phone is verified (`startPhoneVerification`,\n  `confirmPhoneVerification`); without it such a promotion does not apply. The customer is recognised by the\n  phone across the whole account: a first order means no earlier order (not cancelled) of a customer with the\n  same phone at any restaurant of the account.\n- **Discounts of items** (`conditions.scope` set, `nth_item`, `bundle`) are taken from the price of the product\n  only – add-ons and packaging are paid in full – and come in the quote as `applies_to: line`.\n",
    "x-description-cs": "Akce provozovny pro objednávky z aplikací hostů. Ukažte ji zákazníkům; jestli se uplatní a kolik dá, rozhodne\nkalkulace.\n\n- **Čas:** `valid_from`, `valid_until`, `days` a `time_windows` se posuzují v okamžiku odeslání objednávky –\n  když vytváříte kalkulaci – v časové zóně provozovny, ne podle času doručení nebo odběru.\n- **Zákazník:** podmínky na zákazníka (`conditions.customer` jiné než `any`, `conditions.max_per_customer`)\n  a věrnostní karty (`effect.nth_item.loyalty`) platí jen s `QuoteRequest.customer_id` propojeného zákazníka\n  s ověřeným telefonem (`startPhoneVerification`, `confirmPhoneVerification`); bez něj se taková akce\n  neuplatní. Zákazník se pozná podle telefonu v celém účtu: první objednávka znamená, že zákazník se stejným\n  telefonem nemá v žádné provozovně účtu dřívější (nezrušenou) objednávku.\n- **Slevy na položky** (vyplněné `conditions.scope`, `nth_item`, `bundle`) jsou jen z ceny produktu – přílohy\n  a obal se platí celé – a v kalkulaci jsou jako `applies_to: line`.\n",
    "required": [
     "id",
     "name",
     "description",
     "requires_code",
     "code_type",
     "effect",
     "conditions",
     "combinable"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "description": "The name for the customer, as the restaurant entered it.",
      "x-description-cs": "Název pro zákazníka, jak ho provozovna zadala."
     },
     "description": {
      "type": [
       "string",
       "null"
      ],
      "description": "Details for the customer; `null` when empty.",
      "x-description-cs": "Podrobnosti pro zákazníka; `null`, když chybí."
     },
     "requires_code": {
      "type": "boolean",
      "description": "Applies only with a promo code (`QuoteRequest.promo_codes`) – a shared code or a single-use code, see\n`code_type`; otherwise it applies by itself.\n",
      "x-description-cs": "Platí jen se slevovým kódem (`QuoteRequest.promo_codes`) – sdíleným nebo jednorázovým, viz `code_type`;\njinak se uplatní sama.\n"
     },
     "code_type": {
      "type": [
       "string",
       "null"
      ],
      "description": "`shared` – one code for everybody (for example from a leaflet); `single_use` – a series of unique codes the\nrestaurant hands out, each valid for one order; `null` when `requires_code` is `false`. The code itself is\nnever returned.\n",
      "x-description-cs": "`shared` – jeden kód pro všechny (třeba z letáku); `single_use` – série jedinečných kódů, které provozovna\nrozdává, každý platí na jednu objednávku; `null`, když je `requires_code` `false`. Kód samotný se nikdy\nnevrací.\n",
      "x-extensible-enum": [
       "shared",
       "single_use"
      ]
     },
     "effect": {
      "$ref": "#/components/schemas/PromotionEffect"
     },
     "conditions": {
      "$ref": "#/components/schemas/PromotionConditions"
     },
     "combinable": {
      "type": "boolean",
      "description": "Can be used together with other promotions that can be combined. Always `true` for a loyalty card – it adds\nup with everything.\n",
      "x-description-cs": "Jde použít spolu s jinými akcemi, které jdou kombinovat. U věrnostní karty vždy `true` – sčítá se se vším.\n"
     }
    }
   },
   "PromotionEffect": {
    "type": "object",
    "description": "What the customer gets. Only the field of the `type` is filled; the others are `null`.",
    "x-description-cs": "Co zákazník dostane. Vyplněné je jen pole podle `type`; ostatní jsou `null`.",
    "required": [
     "type",
     "percent",
     "amount",
     "max_discount",
     "nth_item",
     "gift",
     "bundle"
    ],
    "properties": {
     "type": {
      "type": "string",
      "description": "`percent` – a percentage off the price of the items (of the whole order, or of the items in\n`conditions.scope`); `amount` – a fixed amount off the items (split over the items in the scope in proportion\nto their prices); `free_delivery` – free delivery (the delivery fee of the zone only, not the surcharge to the\nminimum order nor express delivery); `nth_item` – every N-th piece of the scope at a discount, also as a\nloyalty card (`nth_item`); `gift` – a product added to the order for free (`gift`); `bundle` – a fixed price\nfor a set of one piece from each group (`bundle`).\n",
      "x-description-cs": "`percent` – procento z ceny položek (celé objednávky, nebo položek z `conditions.scope`); `amount` – pevná\nčástka z ceny položek (na položky rozsahu se rozdělí poměrem jejich cen); `free_delivery` – doprava zdarma\n(jen cena dopravy zóny, ne doplatek do minima ani expres); `nth_item` – každý N-tý kus z rozsahu se slevou,\ni jako věrnostní karta (`nth_item`); `gift` – produkt zdarma, který se do objednávky přidá sám (`gift`);\n`bundle` – pevná cena za sadu z jednoho kusu z každé skupiny (`bundle`).\n",
      "x-extensible-enum": [
       "percent",
       "amount",
       "free_delivery",
       "nth_item",
       "gift",
       "bundle"
      ]
     },
     "percent": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 1,
      "maximum": 100,
      "description": "The percentage for `percent`; otherwise `null`.",
      "x-description-cs": "Procento u `percent`; jinak `null`."
     },
     "amount": {
      "description": "The amount for `amount`; otherwise `null`.",
      "x-description-cs": "Částka u `amount`; jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "max_discount": {
      "description": "The highest discount for `percent`; `null` without a cap.",
      "x-description-cs": "Nejvyšší sleva u `percent`; `null` bez stropu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "nth_item": {
      "description": "Every N-th piece for `nth_item`; otherwise `null`.",
      "x-description-cs": "Každý N-tý kus u `nth_item`; jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/PromotionNthItem"
       },
       {
        "type": "null"
       }
      ]
     },
     "gift": {
      "description": "The gift for `gift`; otherwise `null` – and also when the product of the gift no longer exists (then the\npromotion gives nothing).\n",
      "x-description-cs": "Dárek u `gift`; jinak `null` – a také když produkt dárku už neexistuje (pak akce nic nedá).\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/PromotionGift"
       },
       {
        "type": "null"
       }
      ]
     },
     "bundle": {
      "description": "The set for `bundle`; otherwise `null`.",
      "x-description-cs": "Sada u `bundle`; jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/PromotionBundle"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "PromotionNthItem": {
    "type": "object",
    "description": "Every `every`-th piece of the items in `conditions.scope` gets `percent` off (100 = free); the cheapest pieces\nare discounted. For example 2+1 free is `every` 3 and `percent` 100, the second for half price `every` 2 and\n`percent` 50. Without `loyalty` the order needs at least `every` pieces of the scope.\n",
    "x-description-cs": "Každý `every`-tý kus z položek `conditions.scope` má slevu `percent` (100 = zdarma); zlevní se nejlevnější kusy.\nTřeba 2+1 zdarma je `every` 3 a `percent` 100, druhý za polovic `every` 2 a `percent` 50. Bez `loyalty` musí mít\nobjednávka aspoň `every` kusů z rozsahu.\n",
    "required": [
     "every",
     "percent",
     "loyalty"
    ],
    "properties": {
     "every": {
      "type": "integer",
      "minimum": 2,
      "description": "Which piece is discounted – every 2nd, 3rd, … piece.",
      "x-description-cs": "Kolikátý kus je se slevou – každý 2., 3., … kus."
     },
     "percent": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "description": "The discount of that piece in percent; 100 = free.",
      "x-description-cs": "Sleva toho kusu v procentech; 100 = zdarma."
     },
     "loyalty": {
      "type": "boolean",
      "description": "A loyalty card: the pieces are counted across the customer's orders – the pieces of the scope in the\ncustomer's earlier orders since the promotion was created plus this order – so the discounted piece may come\nin a later order (for example every 7th pizza free, spread over several orders). Cancelled and reversed\norders do not count. Only for a linked customer with a verified phone (see `Promotion`); the order records\nthe pieces also when it gets no discount itself.\n",
      "x-description-cs": "Věrnostní karta: kusy se počítají napříč objednávkami zákazníka – kusy z rozsahu v jeho dřívějších\nobjednávkách od vzniku akce plus tato objednávka –, takže kus se slevou může přijít v pozdější objednávce\n(třeba každá 7. pizza zdarma, rozprostřeno do více objednávek). Zrušené a stornované objednávky se\nnepočítají. Jen pro propojeného zákazníka s ověřeným telefonem (viz `Promotion`); objednávka zapíše kusy\ni tehdy, když sama slevu nedostane.\n"
     }
    }
   },
   "PromotionGift": {
    "type": "object",
    "description": "A product the customer gets for free, one piece. The quote adds it as a line with `gift_of` and the full price,\nand a discount `applies_to: line` of the same amount. When the product is not in the catalog at the time of the\norder (hidden, sold out), the gift is not added.\n",
    "x-description-cs": "Produkt, který zákazník dostane zdarma, jeden kus. Kalkulace ho přidá jako řádek s `gift_of` a plnou cenou\na slevu `applies_to: line` ve stejné výši. Když produkt v čase objednávky v sortimentu není (skrytý, vyprodaný),\ndárek se nepřidá.\n",
    "required": [
     "product_id",
     "name"
    ],
    "properties": {
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "description": "The name of the product.",
      "x-description-cs": "Název produktu."
     }
    }
   },
   "PromotionBundle": {
    "type": "object",
    "description": "A fixed price for a set: one piece from each group in `groups` together cost `price`. The quote makes as many\nsets as the basket allows, takes the most expensive pieces of each group and uses a set only when it is cheaper\nthan its pieces; the difference is a discount of the lines of the set (`applies_to: line`).\n",
    "x-description-cs": "Pevná cena za sadu: jeden kus z každé skupiny v `groups` stojí dohromady `price`. Kalkulace složí tolik sad,\nkolik košík dovolí, vezme nejdražší kusy každé skupiny a sadu použije, jen když je levnější než její kusy;\nrozdíl je sleva na řádky sady (`applies_to: line`).\n",
    "required": [
     "price",
     "groups"
    ],
    "properties": {
     "price": {
      "$ref": "#/components/schemas/Money",
      "description": "The price of one set including VAT.",
      "x-description-cs": "Cena jedné sady včetně DPH."
     },
     "groups": {
      "type": "array",
      "description": "The parts of the set, at least two.",
      "x-description-cs": "Části sady, aspoň dvě.",
      "items": {
       "$ref": "#/components/schemas/PromotionBundleGroup"
      }
     }
    }
   },
   "PromotionBundleGroup": {
    "type": "object",
    "description": "One part of a set – a piece of any of these categories or products.",
    "x-description-cs": "Jedna část sady – kus z kterékoli z těchto kategorií nebo produktů.",
    "required": [
     "category_ids",
     "product_ids"
    ],
    "properties": {
     "category_ids": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "product_ids": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     }
    }
   },
   "PromotionScope": {
    "type": "object",
    "description": "The items the promotion counts and discounts: products of the categories in `category_ids` and the products in\n`product_ids`, except those in `exclude_product_ids`.\n",
    "x-description-cs": "Položky, které akce počítá a zlevňuje: produkty z kategorií `category_ids` a produkty `product_ids`, kromě\nproduktů v `exclude_product_ids`.\n",
    "required": [
     "category_ids",
     "product_ids",
     "exclude_product_ids"
    ],
    "properties": {
     "category_ids": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "product_ids": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "exclude_product_ids": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     }
    }
   },
   "PromotionTimeWindow": {
    "type": "object",
    "description": "A time of day when the promotion applies, from `from` (inclusive) to `to` (exclusive), in the time zone of the\nrestaurant. `to` may be `24:00`. A window never crosses midnight – a night window is two windows (`22:00`–`24:00`\nand `00:00`–`02:00`).\n",
    "x-description-cs": "Denní doba, kdy akce platí, od `from` (včetně) do `to` (bez), v časové zóně provozovny. `to` může být `24:00`.\nOkno nikdy nepřekračuje půlnoc – noční okno jsou dvě okna (`22:00`–`24:00` a `00:00`–`02:00`).\n",
    "required": [
     "from",
     "to"
    ],
    "properties": {
     "from": {
      "$ref": "#/components/schemas/LocalTime"
     },
     "to": {
      "$ref": "#/components/schemas/LocalTime"
     }
    }
   },
   "PromotionConditions": {
    "type": "object",
    "required": [
     "min_order",
     "min_items",
     "scope",
     "fulfillment",
     "valid_from",
     "valid_until",
     "days",
     "time_windows",
     "customer",
     "max_per_customer",
     "uses_left"
    ],
    "properties": {
     "min_order": {
      "description": "The lowest price of the items before discounts – of the items in `scope` when it is set; `null` without\na minimum.\n",
      "x-description-cs": "Nejnižší cena položek před slevou – položek z `scope`, když je vyplněný; `null` bez minima.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "min_items": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 1,
      "description": "The lowest number of pieces – of the items in `scope` when it is set, otherwise of the whole order; `null`\nwithout a minimum.\n",
      "x-description-cs": "Nejmenší počet kusů – z položek `scope`, když je vyplněný, jinak z celé objednávky; `null` bez minima.\n"
     },
     "scope": {
      "description": "The items the promotion is for (categories and products); `null` = the whole order. Always set for\n`nth_item`; a `bundle` has its parts in `effect.bundle.groups` instead.\n",
      "x-description-cs": "Položky, na které akce platí (kategorie a produkty); `null` = celá objednávka. U `nth_item` vždy vyplněný;\n`bundle` má místo toho své části v `effect.bundle.groups`.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/PromotionScope"
       },
       {
        "type": "null"
       }
      ]
     },
     "fulfillment": {
      "type": "string",
      "description": "`any`, `delivery` – delivery only, `pickup` – pickup only.",
      "x-description-cs": "`any`, `delivery` – jen rozvoz, `pickup` – jen osobní odběr.",
      "x-extensible-enum": [
       "any",
       "delivery",
       "pickup"
      ]
     },
     "valid_from": {
      "description": "Valid from (inclusive), by the moment the order is sent; `null` = already valid.",
      "x-description-cs": "Platí od (včetně), podle okamžiku odeslání objednávky; `null` = už platí.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "valid_until": {
      "description": "Valid until (exclusive), by the moment the order is sent; `null` = without an end.",
      "x-description-cs": "Platí do (bez), podle okamžiku odeslání objednávky; `null` = bez konce.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "days": {
      "type": "array",
      "description": "The days of the week when the promotion applies, by the moment the order is sent – ISO numbers, 1 = Monday\n… 7 = Sunday, in ascending order. All seven = every day.\n",
      "x-description-cs": "Dny v týdnu, kdy akce platí, podle okamžiku odeslání objednávky – čísla ISO, 1 = pondělí … 7 = neděle,\nvzestupně. Všech sedm = každý den.\n",
      "items": {
       "type": "integer",
       "minimum": 1,
       "maximum": 7
      }
     },
     "time_windows": {
      "type": "array",
      "description": "The times of day when the promotion applies (for example a happy hour), by the moment the order is sent,\nin ascending order; empty = at any time of day.\n",
      "x-description-cs": "Denní doba, kdy akce platí (třeba happy hour), podle okamžiku odeslání objednávky, vzestupně; prázdné =\nkdykoli během dne.\n",
      "items": {
       "$ref": "#/components/schemas/PromotionTimeWindow"
      }
     },
     "customer": {
      "type": "string",
      "description": "Who the promotion is for: `any` – everybody; `registered` – a registered customer only (a linked customer\nwith a verified phone, `QuoteRequest.customer_id`); `first_order` – the first order of a registered customer\nonly (no earlier order, not cancelled, of a customer with the same phone at any restaurant of the account).\nA loyalty card is always at least `registered`.\n",
      "x-description-cs": "Pro koho akce je: `any` – pro všechny; `registered` – jen registrovaný zákazník (propojený zákazník\ns ověřeným telefonem, `QuoteRequest.customer_id`); `first_order` – jen první objednávka registrovaného\nzákazníka (zákazník se stejným telefonem nemá v žádné provozovně účtu dřívější nezrušenou objednávku).\nVěrnostní karta je vždy aspoň `registered`.\n",
      "x-extensible-enum": [
       "any",
       "registered",
       "first_order"
      ]
     },
     "max_per_customer": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 1,
      "description": "How many orders of one registered customer can use the promotion (counted by the phone across the account;\ncancelled orders do not count); `null` = without a limit. Set only with `customer` other than `any`.\n",
      "x-description-cs": "Kolik objednávek jednoho registrovaného zákazníka může akci použít (počítá se podle telefonu v celém účtu;\nzrušené objednávky se nepočítají); `null` = bez omezení. Jen u `customer` jiného než `any`.\n"
     },
     "uses_left": {
      "type": [
       "integer",
       "null"
      ],
      "minimum": 0,
      "description": "How many more orders can use the promotion; `null` = without a limit.",
      "x-description-cs": "Kolik objednávek ještě akci může použít; `null` = bez omezení."
     }
    }
   },
   "OrderCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "quote_id",
     "payments"
    ],
    "properties": {
     "quote_id": {
      "$ref": "#/components/schemas/Id"
     },
     "customer": {
      "description": "Required, with `phone`. Only a kiosk (`Connection.client.order_channel` `kiosk`) may leave it out – the guest\nwaits at the restaurant for the order number – except for a `delivery`. Without it the order has the name\n`Kiosek` and an empty phone. Missing where required: `422` with `required`.\n",
      "x-description-cs": "Povinný, s `phone`. Vynechat ho smí jen kiosek (`Connection.client.order_channel` `kiosk`) – host čeká\nv provozovně na číslo objednávky – kromě `delivery`. Bez něj má objednávka jméno `Kiosek` a prázdný\ntelefon. Když chybí tam, kde je povinný: `422` s `required`.\n",
      "$ref": "#/components/schemas/OrderCustomerInput"
     },
     "payments": {
      "type": "array",
      "description": "How the quote's `amount_due` is paid; the amounts must add up to it exactly. Empty when vouchers cover\neverything. At most one `pending` payment. One method only – online, cash or card – because the kitchen and\nits shift close know one payment method per order (a part paid online and the rest in cash would be expected\nin cash in full).\n",
      "x-description-cs": "Jak se zaplatí `amount_due` kalkulace; částky ho musí přesně dát dohromady. Prázdné, když vše pokryjí\nvouchery. Nejvýš jedna platba `pending`. Jen jeden způsob – online, hotově, nebo kartou –, protože kuchyň\na její uzávěrka znají u objednávky jeden způsob platby (část online a zbytek hotově by uzávěrka čekala celé\nv hotovosti).\n",
      "maxItems": 3,
      "items": {
       "$ref": "#/components/schemas/PaymentInput"
      }
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64,
      "description": "Note for the kitchen and the courier.",
      "x-description-cs": "Poznámka pro kuchyň a kurýra."
     },
     "external_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/MetadataInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "eet": {
      "description": "Leave it out – Profirest records the sale in EET 2.0 itself. Send it only when another system of the restaurant\n(its own register or kiosk) already recorded this sale in EET 2.0: Profirest then never sends it and keeps your\nconfirmation with the restaurant's records. The payment collected that way goes as `online` + `paid`.\n",
      "x-description-cs": "Vynechte – tržbu do EET 2.0 eviduje Profirest sám. Pošlete jen tehdy, když tuto tržbu už do EET 2.0 zaevidoval jiný\nsystém provozovny (její vlastní pokladna nebo kiosek): Profirest ji pak nikdy neodešle a vaše potvrzení si uloží\nk evidenci provozovny. Takto vybraná platba jde jako `online` + `paid`.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/EetRecordedInput"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "EetRecordedInput": {
    "type": "object",
    "description": "The sale as another system of the restaurant recorded it in EET 2.0.",
    "x-description-cs": "Tržba tak, jak ji do EET 2.0 zaevidoval jiný systém provozovny.",
    "additionalProperties": false,
    "required": [
     "pok",
     "recorded_at",
     "total"
    ],
    "properties": {
     "pok": {
      "type": "string",
      "pattern": "^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}-[0-9A-Fa-f]{2}$",
      "description": "The confirmation code of the tax administration (POK).",
      "x-description-cs": "Potvrzovací kód finanční správy (POK).",
      "examples": [
       "57c70e45-29d3-4063-beae-986a62bc6b63-03"
      ]
     },
     "recorded_at": {
      "$ref": "#/components/schemas/Timestamp",
      "description": "The time of the sale as recorded (dat_trzby); not in the future.",
      "x-description-cs": "Čas tržby tak, jak se evidoval (dat_trzby); ne v budoucnosti."
     },
     "total": {
      "$ref": "#/components/schemas/MoneyInput",
      "description": "The recorded amount (celk_trzba).",
      "x-description-cs": "Evidovaná částka (celk_trzba)."
     },
     "register_id": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 20,
      "description": "The register's identifier in the record (id_pokl).",
      "x-description-cs": "Označení pokladny v evidenci (id_pokl)."
     },
     "sequence": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 25,
      "description": "The sequence number in the record (porad_cis).",
      "x-description-cs": "Pořadové číslo v evidenci (porad_cis)."
     }
    }
   },
   "OrderEet": {
    "type": "object",
    "description": "A sale of the order that another system of the restaurant recorded in EET 2.0 (sent as `OrderCreate.eet`).",
    "x-description-cs": "Tržba objednávky, kterou do EET 2.0 zaevidoval jiný systém provozovny (poslaná jako `OrderCreate.eet`).",
    "required": [
     "recorded_by",
     "pok",
     "recorded_at",
     "total",
     "register_id",
     "sequence"
    ],
    "properties": {
     "recorded_by": {
      "type": "string",
      "description": "`other_system` – another system of the restaurant recorded the sale (the only value today).",
      "x-description-cs": "`other_system` – tržbu zaevidoval jiný systém provozovny (dnes jediná hodnota).",
      "x-extensible-enum": [
       "other_system"
      ]
     },
     "pok": {
      "type": "string",
      "description": "The confirmation code (POK) as sent, in lower case.",
      "x-description-cs": "Potvrzovací kód (POK), jak přišel, malými písmeny."
     },
     "recorded_at": {
      "description": "The time of the sale as sent, with its offset.",
      "x-description-cs": "Čas tržby, jak přišel, s jeho posunem.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "total": {
      "description": "The recorded amount as sent; not compared with the order.",
      "x-description-cs": "Evidovaná částka, jak přišla; s objednávkou se neporovnává.",
      "$ref": "#/components/schemas/Money"
     },
     "register_id": {
      "type": [
       "string",
       "null"
      ],
      "description": "The register's identifier in the record (id_pokl), as sent.",
      "x-description-cs": "Označení pokladny v evidenci (id_pokl), jak přišlo."
     },
     "sequence": {
      "type": [
       "string",
       "null"
      ],
      "description": "The sequence number in the record (porad_cis), as sent.",
      "x-description-cs": "Pořadové číslo v evidenci (porad_cis), jak přišlo."
     }
    }
   },
   "OrderCustomerInput": {
    "type": "object",
    "description": "Contact for this order, shown to the kitchen and the courier.",
    "x-description-cs": "Kontakt pro tuto objednávku, uvidí ho kuchyně a kurýr.",
    "additionalProperties": false,
    "required": [
     "name"
    ],
    "properties": {
     "name": {
      "type": "string",
      "minLength": 2,
      "maxLength": 64
     },
     "phone": {
      "description": "Required, except for a kiosk without a `delivery` (see `OrderCreate.customer`).",
      "x-description-cs": "Povinný, kromě kiosku bez `delivery` (viz `OrderCreate.customer`).",
      "$ref": "#/components/schemas/Phone"
     },
     "email": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Email"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "PaymentInput": {
    "type": "object",
    "description": "`online` + `paid` – you already collected it; `online` + `pending` – you collect it after creating the order and\nthen call `confirm-payment`; `cash` or `card` + `unpaid` – the customer pays the courier or at pickup; `card` +\n`paid` – only a kiosk (`Connection.client.order_channel` `kiosk`): the guest paid on the kiosk's own card terminal.\nIt must cover the whole amount (not mixed with `unpaid`); the kitchen sees the order as paid and Profirest records\nthe sale in EET 2.0 within minutes when the restaurant has it enabled (a cancelled order as a negative sale) –\na refund on the terminal is up to you.\n",
    "x-description-cs": "`online` + `paid` – už jste ji vybrali; `online` + `pending` – vyberete ji po vytvoření objednávky a pak zavoláte\n`confirm-payment`; `cash` nebo `card` + `unpaid` – zákazník zaplatí kurýrovi nebo při odběru; `card` + `paid` –\njen kiosek (`Connection.client.order_channel` `kiosk`): host zaplatil na vlastním platebním terminálu kiosku.\nMusí pokrýt celou částku (ne spolu s `unpaid`); kuchyň vidí objednávku jako zaplacenou a Profirest tržbu do pár\nminut zaeviduje v EET 2.0, když ho má provozovna zapnuté (zrušenou objednávku jako zápornou tržbu) – vrácení\npeněz na terminálu je na vás.\n",
    "additionalProperties": false,
    "required": [
     "method",
     "status",
     "amount"
    ],
    "properties": {
     "method": {
      "type": "string",
      "enum": [
       "online",
       "cash",
       "card"
      ],
      "description": "`online` – paid to you over the internet; `cash` – in cash to the courier or at pickup; `card` – by card to\nthe courier or at pickup, or on a kiosk's terminal.\n",
      "x-description-cs": "`online` – zaplaceno vám přes internet; `cash` – hotově kurýrovi nebo při odběru; `card` – kartou kurýrovi\nnebo při odběru, případně na terminálu kiosku.\n"
     },
     "status": {
      "type": "string",
      "enum": [
       "paid",
       "pending",
       "unpaid"
      ],
      "description": "`paid` – collected already (`online`; `card` only for a kiosk); `pending` – you collect it after creating the\norder and confirm it (only `online`); `unpaid` – collected at delivery or pickup (only `cash` and `card`).\nOther combinations answer `422` with `invalid_value`.\n",
      "x-description-cs": "`paid` – už vybráno (`online`; `card` jen kiosek); `pending` – vyberete po vytvoření objednávky a potvrdíte\n(jen `online`); `unpaid` – vybere se při doručení nebo odběru (jen `cash` a `card`). Jiné kombinace odpoví\n`422` s `invalid_value`.\n"
     },
     "amount": {
      "$ref": "#/components/schemas/MoneyInput"
     },
     "provider": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "description": "Your payment provider, for example `gopay`.",
      "x-description-cs": "Váš poskytovatel plateb, například `gopay`."
     },
     "reference": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 128,
      "description": "Payment ID at your provider.",
      "x-description-cs": "ID platby u vašeho poskytovatele."
     }
    }
   },
   "PaymentConfirmation": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
     "provider": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32
     },
     "reference": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 128,
      "description": "Payment ID at your provider, if you did not know it when creating the order.",
      "x-description-cs": "ID platby u vašeho poskytovatele, pokud jste ho při vytvoření objednávky neznali."
     }
    }
   },
   "OrderCancel": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
     "reason": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 255
     }
    }
   },
   "Fulfillment": {
    "type": "object",
    "required": [
     "type",
     "speed",
     "asap",
     "time",
     "estimated_at"
    ],
    "properties": {
     "type": {
      "type": "string",
      "description": "`delivery` – delivered to the address in `delivery`; `pickup` – the customer picks it up at the restaurant; `dine_in` – eaten at the restaurant (see `FulfillmentType`).",
      "x-description-cs": "`delivery` – rozvoz na adresu v `delivery`; `pickup` – zákazník si objednávku vyzvedne v provozovně; `dine_in` – jídlo na místě (viz `FulfillmentType`).",
      "x-extensible-enum": [
       "delivery",
       "pickup",
       "dine_in"
      ]
     },
     "speed": {
      "type": "string",
      "description": "`standard` – the usual delivery; `express` – express delivery with priority in the kitchen and at the courier, without a promised time (see `FulfillmentInput.speed`).",
      "x-description-cs": "`standard` – běžný rozvoz; `express` – expresní doručení s předností v kuchyni a u kurýra, bez slíbeného času (viz `FulfillmentInput.speed`).",
      "x-extensible-enum": [
       "standard",
       "express"
      ]
     },
     "asap": {
      "type": "boolean",
      "description": "As soon as possible (no `time`); also after an online payment confirmed after the chosen time.",
      "x-description-cs": "Co nejdřív (bez `time`); také po online platbě potvrzené až po zvoleném čase."
     },
     "time": {
      "description": "The requested time; `null` for as soon as possible. For `delivery` when the customer receives the order, for\n`pickup` when it is ready.\n",
      "x-description-cs": "Požadovaný čas; `null` pro co nejdřív. U `delivery` kdy zákazník objednávku dostane, u `pickup` kdy je\npřipravená.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "estimated_at": {
      "description": "Profirest's estimate of the same moment; `null` while no estimate is available. Profirest does not estimate\nyet: today it is the requested `time` itself, `null` for as soon as possible.\n",
      "x-description-cs": "Odhad Profirestu pro stejný okamžik; `null`, dokud odhad není k dispozici. Profirest zatím neodhaduje: dnes je\nto přímo požadovaný `time`, u co nejdřív `null`.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "DeliveryInfo": {
    "type": "object",
    "required": [
     "zone",
     "address",
     "location",
     "fee",
     "minimum_order",
     "express_fee"
    ],
    "properties": {
     "zone": {
      "type": "object",
      "required": [
       "id",
       "name"
      ],
      "properties": {
       "id": {
        "$ref": "#/components/schemas/Id"
       },
       "name": {
        "type": "string"
       }
      }
     },
     "address": {
      "$ref": "#/components/schemas/Address"
     },
     "location": {
      "$ref": "#/components/schemas/GeoPoint"
     },
     "fee": {
      "$ref": "#/components/schemas/Money"
     },
     "minimum_order": {
      "$ref": "#/components/schemas/Money"
     },
     "express_fee": {
      "description": "The surcharge for express delivery to this zone; `null` when the zone does not offer it. Shown also in\na quote without express, so you can offer it to the customer and price the basket again with\n`fulfillment.speed` `express`.\n",
      "x-description-cs": "Příplatek za expresní doručení do této zóny; `null`, když ho zóna nenabízí. Je i v kalkulaci bez expresu,\nabyste ho mohli zákazníkovi nabídnout a spočítat košík znovu s `fulfillment.speed` `express`.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "OrderLine": {
    "type": "object",
    "required": [
     "id",
     "type",
     "variant",
     "product_id",
     "name",
     "quantity",
     "base_unit_price",
     "unit_price",
     "packaging_unit_price",
     "vat_rate",
     "add_ons",
     "options",
     "parts",
     "removed_ingredients",
     "note",
     "total",
     "gift_of"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "type": {
      "type": "string",
      "description": "`product` – a product of the catalog; `split` – a pizza from parts (`parts`), as `QuoteItemInput.type`.",
      "x-description-cs": "`product` – produkt ze sortimentu; `split` – pizza z dílů (`parts`), jako `QuoteItemInput.type`.",
      "x-extensible-enum": [
       "product",
       "split"
      ]
     },
     "variant": {
      "type": [
       "string",
       "null"
      ],
      "description": "`full` – a whole portion, `half` – a half portion (`QuoteItemInput.variant`) for `product`; `null` for `split`.",
      "x-description-cs": "`full` – celá porce, `half` – poloviční porce (`QuoteItemInput.variant`) u `product`; u `split` `null`.",
      "x-extensible-enum": [
       "full",
       "half"
      ]
     },
     "product_id": {
      "description": "The product of the line; `null` for `split` (the products are in `parts`) and for lines without a product.",
      "x-description-cs": "Produkt řádku; `null` u `split` (produkty jsou v `parts`) a u řádků bez produktu.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "name": {
      "type": "string",
      "description": "Product name at the time of the quote; for `split` the parts („½ Margherita + ½ Hawaii“).",
      "x-description-cs": "Název produktu v okamžiku kalkulace; u `split` díly („½ Margherita + ½ Hawaii“)."
     },
     "quantity": {
      "type": "number",
      "description": "A whole number for orders of this API today (`QuoteItemInput.quantity`); may become fractional for items sold by weight.",
      "x-description-cs": "U objednávek tohoto API dnes celé číslo (`QuoteItemInput.quantity`); u položek prodávaných na váhu může být desetinné."
     },
     "base_unit_price": {
      "$ref": "#/components/schemas/Money",
      "description": "The catalog price of the product per piece; for `split` the sum of the parts. It differs from `unit_price`\nonly when a premium option raised the base (`OrderLineOption.reason` `in_base_price`).\n",
      "x-description-cs": "Ceníková cena produktu za kus; u `split` součet dílů. Od `unit_price` se liší, jen když základ zvedla\nprémiová volba (`OrderLineOption.reason` `in_base_price`).\n"
     },
     "unit_price": {
      "$ref": "#/components/schemas/Money",
      "description": "The charged price of the product per piece, without packaging, add-ons and options; for `split` the sum of\nthe parts. Discounts of items are taken from this price only.\n",
      "x-description-cs": "Účtovaná cena produktu za kus bez obalu, příloh a voleb; u `split` součet dílů. Slevy na položky se berou\njen z této ceny.\n"
     },
     "packaging_unit_price": {
      "description": "Packaging per piece; for `split` once per pizza – the highest of the parts.",
      "x-description-cs": "Obal za kus; u `split` jednou za pizzu – nejvyšší z dílů.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "vat_rate": {
      "description": "The rate of the product; for `split` the rate of the first part (each part has its own `vat_rate`).",
      "x-description-cs": "Sazba produktu; u `split` sazba prvního dílu (každý díl má svou `vat_rate`).",
      "$ref": "#/components/schemas/VatRate"
     },
     "add_ons": {
      "type": "array",
      "description": "The add-ons of a `product`; empty for `split` (the add-ons of parts are in `parts`).",
      "x-description-cs": "Přílohy u `product`; u `split` prázdné (přílohy dílů jsou v `parts`).",
      "items": {
       "type": "object",
       "required": [
        "product_id",
        "name",
        "quantity",
        "unit_price",
        "vat_rate"
       ],
       "properties": {
        "product_id": {
         "anyOf": [
          {
           "$ref": "#/components/schemas/Id"
          },
          {
           "type": "null"
          }
         ]
        },
        "name": {
         "type": "string"
        },
        "quantity": {
         "type": "integer",
         "description": "Portions per one piece of the line (`AddOnInput.quantity`).",
         "x-description-cs": "Porcí na jeden kus řádku (`AddOnInput.quantity`)."
        },
        "unit_price": {
         "$ref": "#/components/schemas/Money",
         "description": "Price of one portion.",
         "x-description-cs": "Cena jedné porce."
        },
        "vat_rate": {
         "description": "The rate of the add-on; a negative add-on has the rate of its product.",
         "x-description-cs": "Sazba přílohy; záporná příloha má sazbu svého produktu.",
         "$ref": "#/components/schemas/VatRate"
        }
       }
      }
     },
     "options": {
      "type": "array",
      "description": "The chosen options of a product with option groups, in the order of the groups and their options; otherwise empty.",
      "x-description-cs": "Vybrané volby produktu se skupinami voleb v pořadí skupin a jejich voleb; jinak prázdné.",
      "items": {
       "$ref": "#/components/schemas/OrderLineOption"
      }
     },
     "parts": {
      "description": "The parts of a `split` pizza in their order; `null` for other lines.",
      "x-description-cs": "Díly pizzy `split` v jejich pořadí; u ostatních řádků `null`.",
      "type": [
       "array",
       "null"
      ],
      "items": {
       "$ref": "#/components/schemas/OrderLinePart"
      }
     },
     "removed_ingredients": {
      "type": "array",
      "description": "Ingredients the guest removed from the dish (`QuoteItemInput.removed_ingredient_ids`) with their names at the\ntime of the quote, in the order of the composition; show them as „Without: mushrooms, onion“. Empty when\nnothing was removed, for `split` (the parts have their own) and for gifts. The price is the same.\n",
      "x-description-cs": "Suroviny, které host z jídla odebral (`QuoteItemInput.removed_ingredient_ids`), s názvy z okamžiku kalkulace,\nv pořadí složení; ukažte je jako „Bez: žampiony, cibule“. Prázdné, když host nic neodebral, u `split` (díly\nmají vlastní) a u dárků. Cena je stejná.\n",
      "items": {
       "$ref": "#/components/schemas/RemovableIngredient"
      }
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "total": {
      "$ref": "#/components/schemas/Money",
      "description": "quantity × (unit price + packaging + unit prices × portions of the add-ons + `total` of the options), for\n`split` with the parts and their add-ons, before discounts – discounts of the line are in `discounts`\n(`applies_to: line`, `line_id`).\n",
      "x-description-cs": "počet × (jednotková cena + obal + jednotkové ceny × porce příloh a doplňků + `total` voleb), u `split`\ns díly a jejich přílohami, před slevou – slevy řádku jsou v `discounts` (`applies_to: line`, `line_id`).\n"
     },
     "gift_of": {
      "description": "The promotion (`Promotion.id`) that added this line as a gift (`effect.type` `gift`): the line has the full\nprice and a discount `applies_to: line` of the same promotion takes it back. Show it as a gift and do not\nlet the customer change or remove it – it comes and goes with the promotion in the next quote. Do not send\nit in `items` of the next quote; the quote adds it by itself. `null` for the lines of the customer.\n",
      "x-description-cs": "Akce (`Promotion.id`), která řádek přidala jako dárek (`effect.type` `gift`): řádek má plnou cenu a sleva\n`applies_to: line` téže akce ji vrací. Ukažte ho jako dárek a nedovolte zákazníkovi ho měnit ani odebrat –\npřichází a odchází s akcí v další kalkulaci. Do `items` další kalkulace ho neposílejte; kalkulace ho přidá\nsama. U řádků zákazníka `null`.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "OrderLineOption": {
    "type": "object",
    "description": "A chosen option, per one piece of the line: `total` = `charged_quantity` × `unit_price`. The name and price are\nthose at the time of the quote.\n",
    "x-description-cs": "Vybraná volba na jeden kus řádku: `total` = `charged_quantity` × `unit_price`. Název a cena jsou ty z okamžiku\nkalkulace.\n",
    "required": [
     "option_id",
     "group_id",
     "group_name",
     "product_id",
     "name",
     "quantity",
     "included_quantity",
     "charged_quantity",
     "list_unit_price",
     "unit_price",
     "total",
     "vat_rate",
     "reason"
    ],
    "properties": {
     "option_id": {
      "$ref": "#/components/schemas/Id"
     },
     "group_id": {
      "$ref": "#/components/schemas/Id"
     },
     "group_name": {
      "type": "string"
     },
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "quantity": {
      "type": "integer",
      "description": "Portions chosen.",
      "x-description-cs": "Vybraných porcí."
     },
     "included_quantity": {
      "type": "integer",
      "description": "Portions in the price of the product.",
      "x-description-cs": "Porcí v ceně produktu."
     },
     "charged_quantity": {
      "type": "integer",
      "description": "Portions charged (`quantity` − `included_quantity`).",
      "x-description-cs": "Účtovaných porcí (`quantity` − `included_quantity`)."
     },
     "list_unit_price": {
      "$ref": "#/components/schemas/Money",
      "description": "The price of one portion in the catalog (`ProductOption.price`).",
      "x-description-cs": "Cena jedné porce ze sortimentu (`ProductOption.price`)."
     },
     "unit_price": {
      "$ref": "#/components/schemas/Money",
      "description": "The charged price of one portion; `0` for a premium option (`in_base_price`).",
      "x-description-cs": "Účtovaná cena jedné porce; u prémiové volby (`in_base_price`) `0`."
     },
     "total": {
      "$ref": "#/components/schemas/Money"
     },
     "vat_rate": {
      "description": "The rate of the option; a negative option has the rate of its product.",
      "x-description-cs": "Sazba volby; záporná volba má sazbu svého produktu.",
      "$ref": "#/components/schemas/VatRate"
     },
     "reason": {
      "type": [
       "string",
       "null"
      ],
      "description": "Why it costs less than `quantity` × `list_unit_price`: `included` – all portions in the price;\n`partly_included` – some of them; `in_base_price` – a premium option, paid in `OrderLine.unit_price`;\n`null` – charged in full.\n",
      "x-description-cs": "Proč stojí míň než `quantity` × `list_unit_price`: `included` – všechny porce v ceně; `partly_included` –\nčást z nich; `in_base_price` – prémiová volba zaplacená v `OrderLine.unit_price`; `null` – účtuje se celá.\n",
      "x-extensible-enum": [
       "included",
       "partly_included",
       "in_base_price",
       null
      ]
     }
    }
   },
   "OrderLinePart": {
    "type": "object",
    "required": [
     "position",
     "fraction",
     "product_id",
     "name",
     "unit_price",
     "vat_rate",
     "add_ons",
     "removed_ingredients"
    ],
    "properties": {
     "position": {
      "type": "integer",
      "minimum": 1,
      "description": "Order of the part on the pizza, from 1 (as `QuoteItemInput.parts`).",
      "x-description-cs": "Pořadí dílu na pizze od 1 (jako `QuoteItemInput.parts`)."
     },
     "fraction": {
      "type": "string",
      "description": "`1/2` – a half; `1/4` – a quarter.",
      "x-description-cs": "`1/2` – půlka; `1/4` – čtvrtka.",
      "x-extensible-enum": [
       "1/2",
       "1/4"
      ]
     },
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "description": "Product name at the time of the quote.",
      "x-description-cs": "Název produktu v okamžiku kalkulace."
     },
     "unit_price": {
      "$ref": "#/components/schemas/Money",
      "description": "The price of the part (`Product.split`).",
      "x-description-cs": "Cena dílu (`Product.split`)."
     },
     "vat_rate": {
      "$ref": "#/components/schemas/VatRate"
     },
     "add_ons": {
      "type": "array",
      "description": "The add-ons of this part.",
      "x-description-cs": "Přílohy tohoto dílu.",
      "items": {
       "type": "object",
       "required": [
        "product_id",
        "name",
        "quantity",
        "unit_price",
        "vat_rate"
       ],
       "properties": {
        "product_id": {
         "anyOf": [
          {
           "$ref": "#/components/schemas/Id"
          },
          {
           "type": "null"
          }
         ]
        },
        "name": {
         "type": "string"
        },
        "quantity": {
         "type": "integer",
         "description": "Portions per one piece of the line (`AddOnInput.quantity`).",
         "x-description-cs": "Porcí na jeden kus řádku (`AddOnInput.quantity`)."
        },
        "unit_price": {
         "$ref": "#/components/schemas/Money",
         "description": "Price of one portion.",
         "x-description-cs": "Cena jedné porce."
        },
        "vat_rate": {
         "description": "The rate of the add-on; a negative add-on has the rate of its product.",
         "x-description-cs": "Sazba přílohy; záporná příloha má sazbu svého produktu.",
         "$ref": "#/components/schemas/VatRate"
        }
       }
      }
     },
     "removed_ingredients": {
      "type": "array",
      "description": "Ingredients removed from this part (`SplitPartInput.removed_ingredient_ids`), as `OrderLine.removed_ingredients`.",
      "x-description-cs": "Suroviny odebrané z tohoto dílu (`SplitPartInput.removed_ingredient_ids`), jako `OrderLine.removed_ingredients`.",
      "items": {
       "$ref": "#/components/schemas/RemovableIngredient"
      }
     }
    }
   },
   "Charge": {
    "type": "object",
    "description": "A charge on top of the items. Delivery and similar charges are ancillary costs under § 36(3) of Czech Act\n235/2004 Coll.: they take the VAT rate of the items and are split in proportion to the items' amounts including\nVAT when the items have several rates, like the receipt (see *Money and VAT*); `vat` shows the split.\n",
    "x-description-cs": "Poplatek navíc k položkám. Doprava a podobné poplatky jsou vedlejší výdaje podle § 36 odst. 3 zákona\nč. 235/2004 Sb.: daní se sazbou položek, a když mají položky více sazeb, rozdělí se v poměru jejich částek\ns DPH jako na účtence (viz *Peníze a DPH*); rozdělení ukazuje `vat`.\n",
    "required": [
     "type",
     "name",
     "amount",
     "vat"
    ],
    "properties": {
     "type": {
      "type": "string",
      "description": "`delivery_fee` – the delivery fee of the zone; `minimum_order_surcharge` tops the order up to the minimum\norder of the delivery zone; `express_delivery` – the surcharge for express delivery of the zone\n(`fulfillment.speed` `express`). Express does not count towards the minimum order, and promotions do not\ndiscount it.\n",
      "x-description-cs": "`delivery_fee` – cena dopravy zóny; `minimum_order_surcharge` doplácí objednávku do minimální objednávky\nrozvozové zóny; `express_delivery` – příplatek zóny za expresní doručení (`fulfillment.speed` `express`).\nExpres se do minimální objednávky nepočítá a akce ho nezlevní.\n",
      "x-extensible-enum": [
       "delivery_fee",
       "minimum_order_surcharge",
       "express_delivery"
      ]
     },
     "name": {
      "type": "string",
      "description": "The name for the customer, always in Czech (\"Doprava\", \"Doplatek do minimální objednávky\", \"Expresní doručení\").",
      "x-description-cs": "Název pro zákazníka, vždy česky („Doprava“, „Doplatek do minimální objednávky“, „Expresní doručení“)."
     },
     "amount": {
      "$ref": "#/components/schemas/Money"
     },
     "vat": {
      "type": "array",
      "description": "The charge split by VAT rate. The parts add up to `amount`.",
      "x-description-cs": "Poplatek rozdělený podle sazeb DPH. Části dávají dohromady `amount`.",
      "items": {
       "$ref": "#/components/schemas/VatBreakdown"
      }
     }
    }
   },
   "Discount": {
    "type": "object",
    "description": "A discount from a promotion of the restaurant (`GET …/promotions`). It lowers the price and the VAT base and is\nsplit into the VAT rates exactly like on the receipt.\n\n- `applies_to: line` – a discount of items for one line (`line_id`), in the VAT rate of that line. It is taken\n  from the price of the product; add-ons and packaging are paid in full. There is one discount for every line\n  and promotion (a discount of items in a scope, every N-th piece, a set). A gift is a line with `gift_of` and\n  a `line` discount of its full price.\n- `applies_to: order` lowers the price of the items of the whole order; it is split over the VAT rates of the\n  items after the discounts of lines.\n- `applies_to: delivery_fee` is free delivery – the delivery charge stays in `charges` and the discount takes\n  it back.\n\nThe order in the list: discounts of lines (by line, then by promotion), gifts, discounts of the order, free\ndelivery. Gift vouchers are payments, not discounts.\n",
    "x-description-cs": "Sleva z akce provozovny (`GET …/promotions`). Snižuje cenu i základ daně a do sazeb DPH se dělí přesně jako na\núčtence.\n\n- `applies_to: line` – sleva na položky jednoho řádku (`line_id`) v sazbě DPH toho řádku. Je z ceny produktu;\n  přílohy a obal se platí celé. Za každý řádek a akci je jedna sleva (sleva na položky z rozsahu, každý N-tý\n  kus, sada). Dárek je řádek s `gift_of` a slevou `line` ve výši jeho plné ceny.\n- `applies_to: order` snižuje cenu položek celé objednávky; do sazeb DPH se dělí podle položek po slevách na\n  řádky.\n- `applies_to: delivery_fee` je doprava zdarma – poplatek za dopravu zůstává v `charges` a sleva ho vrací.\n\nPořadí v seznamu: slevy řádků (podle řádku, pak podle akce), dárky, slevy objednávky, doprava zdarma. Dárkové\nvouchery jsou platby, ne slevy.\n",
    "required": [
     "type",
     "name",
     "amount",
     "vat",
     "promotion",
     "applies_to",
     "line_id"
    ],
    "properties": {
     "type": {
      "type": "string",
      "description": "`restaurant` – given by the restaurant.",
      "x-description-cs": "`restaurant` – od provozovny.",
      "x-extensible-enum": [
       "restaurant"
      ]
     },
     "name": {
      "type": "string",
      "description": "The name of the promotion for the customer.",
      "x-description-cs": "Název akce pro zákazníka."
     },
     "amount": {
      "$ref": "#/components/schemas/Money",
      "description": "Negative amount.",
      "x-description-cs": "Záporná částka."
     },
     "vat": {
      "type": "array",
      "description": "The split into the VAT rates, negative.",
      "x-description-cs": "Rozdělení do sazeb DPH, záporně.",
      "items": {
       "$ref": "#/components/schemas/VatBreakdown"
      }
     },
     "promotion": {
      "description": "The promotion that gave the discount; `null` for a discount without a promotion (none today).",
      "x-description-cs": "Akce, která slevu dala; `null` u slevy bez akce (dnes žádná).",
      "anyOf": [
       {
        "$ref": "#/components/schemas/DiscountPromotion"
       },
       {
        "type": "null"
       }
      ]
     },
     "applies_to": {
      "type": "string",
      "description": "`order` – the price of the items of the whole order; `delivery_fee` – free delivery; `line` – the price of one line (`line_id`).",
      "x-description-cs": "`order` – cena položek celé objednávky; `delivery_fee` – doprava zdarma; `line` – cena jednoho řádku (`line_id`).",
      "x-extensible-enum": [
       "order",
       "delivery_fee",
       "line"
      ]
     },
     "line_id": {
      "description": "The discounted line (`OrderLine.id`) for `applies_to: line`; `null` for a discount of the whole order and free delivery.",
      "x-description-cs": "Zlevněný řádek (`OrderLine.id`) u `applies_to: line`; `null` u slevy celé objednávky a dopravy zdarma.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "DiscountPromotion": {
    "type": "object",
    "required": [
     "id",
     "name",
     "code"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "code": {
      "type": [
       "string",
       "null"
      ],
      "description": "The promo code, masked (`LET***`); `null` for a promotion without a code.",
      "x-description-cs": "Slevový kód maskovaně (`LET***`); `null` u akce bez kódu."
     }
    }
   },
   "Totals": {
    "type": "object",
    "description": "`total = items + charges + discounts + rounding` (discounts are negative). In quotes and orders `rounding` is\nzero; on receipts `charges` is always zero.\n",
    "x-description-cs": "`total = items + charges + discounts + rounding` (slevy jsou záporné). V kalkulacích a objednávkách je\n`rounding` nulové; na účtenkách je `charges` vždy nula.\n",
    "required": [
     "items",
     "charges",
     "discounts",
     "rounding",
     "total",
     "vat"
    ],
    "properties": {
     "items": {
      "description": "The sum of the lines (`total` of every line, before discounts – gift lines at their full price).",
      "x-description-cs": "Součet řádků (`total` každého řádku, před slevou – řádky dárků s plnou cenou).",
      "$ref": "#/components/schemas/Money"
     },
     "charges": {
      "description": "The sum of the charges (delivery, surcharge to the minimum order, express delivery).",
      "x-description-cs": "Součet poplatků (doprava, doplatek do minima, expresní doručení).",
      "$ref": "#/components/schemas/Money"
     },
     "discounts": {
      "description": "The sum of the discounts, negative or zero.",
      "x-description-cs": "Součet slev, záporný nebo nula.",
      "$ref": "#/components/schemas/Money"
     },
     "rounding": {
      "$ref": "#/components/schemas/Money",
      "description": "Rounding of a cash payment to whole CZK – on a receipt; zero otherwise (always in quotes and orders).",
      "x-description-cs": "Zaokrouhlení platby v hotovosti na celé koruny – na účtence; jinak nula (v kalkulacích a objednávkách vždy)."
     },
     "total": {
      "$ref": "#/components/schemas/Money",
      "description": "Price of the order including VAT, before vouchers.",
      "x-description-cs": "Cena objednávky včetně DPH, před vouchery."
     },
     "vat": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/VatBreakdown"
      }
     }
    }
   },
   "Payment": {
    "type": "object",
    "description": "One way the order is paid. Vouchers are payments too: they lower what is left to pay, not the price or the VAT.\nIn a quote the voucher payments are `pending` until the order is created.\n",
    "x-description-cs": "Jeden způsob, jak se objednávka platí. Vouchery jsou také platby: snižují, kolik zbývá zaplatit, ne cenu ani DPH.\nV kalkulaci jsou platby vouchery `pending`, dokud objednávka nevznikne.\n",
    "required": [
     "id",
     "method",
     "status",
     "amount",
     "provider",
     "reference",
     "voucher_code",
     "forfeited"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "method": {
      "type": "string",
      "description": "`online` – paid to you over the internet (`provider`, `reference`); `cash`, `card` – collected at delivery or\npickup; `voucher` – a gift voucher (`voucher_code`, `forfeited`).\n",
      "x-description-cs": "`online` – zaplaceno vám přes internet (`provider`, `reference`); `cash`, `card` – vybírá se při doručení nebo\nodběru; `voucher` – dárkový voucher (`voucher_code`, `forfeited`).\n",
      "x-extensible-enum": [
       "online",
       "cash",
       "card",
       "voucher"
      ]
     },
     "status": {
      "type": "string",
      "description": "`pending` – an online payment waiting for `confirm-payment`, or a voucher in a quote; `paid` – collected (an\nonline payment collected or confirmed, a voucher used; cash and card once the order is delivered); `unpaid` – cash or card\nstill to collect; `voided` – returned after a cancellation (vouchers) or never collected. When the order is\ncancelled, every payment not yet paid becomes `voided`, and so do the vouchers – after a cancellation in the\nkitchen only when the kitchen returned them. A paid online payment is never voided; refunding it is up to you.\n",
      "x-description-cs": "`pending` – online platba čekající na `confirm-payment`, nebo voucher v kalkulaci; `paid` – vybráno (vybraná\nnebo potvrzená online platba, použitý voucher; hotově a kartou, jakmile je objednávka doručená); `unpaid` – hotově nebo\nkartou, ještě k vybrání; `voided` – vráceno po zrušení (vouchery) nebo nikdy nevybráno. Při zrušení objednávky\nse `voided` stane každá ještě nezaplacená platba a také vouchery – po zrušení v kuchyni jen tehdy, když je\nkuchyně vrátila. Zaplacená online platba se nikdy neruší; vrácení peněz je na vás.\n",
      "x-extensible-enum": [
       "pending",
       "paid",
       "unpaid",
       "voided"
      ]
     },
     "amount": {
      "$ref": "#/components/schemas/Money"
     },
     "provider": {
      "type": [
       "string",
       "null"
      ]
     },
     "reference": {
      "type": [
       "string",
       "null"
      ]
     },
     "voucher_code": {
      "type": [
       "string",
       "null"
      ],
      "description": "Masked voucher code, for example `ABC-***`.",
      "x-description-cs": "Maskovaný kód voucheru, například `ABC-***`.",
      "examples": [
       "ABC-***"
      ]
     },
     "forfeited": {
      "description": "For a one-time voucher, the unused rest that is lost. Warn the customer before ordering.",
      "x-description-cs": "U jednorázového voucheru nevyužitý zbytek, který propadne. Upozorněte zákazníka před objednáním.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "Quote": {
    "type": "object",
    "required": [
     "id",
     "restaurant_id",
     "created_at",
     "expires_at",
     "customer_id",
     "fulfillment",
     "delivery",
     "lines",
     "charges",
     "discounts",
     "totals",
     "payments",
     "amount_due"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "expires_at": {
      "$ref": "#/components/schemas/Timestamp",
      "description": "Until then the prices are guaranteed and the order can be created.",
      "x-description-cs": "Do té doby jsou ceny zaručené a lze vytvořit objednávku."
     },
     "customer_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "fulfillment": {
      "$ref": "#/components/schemas/Fulfillment"
     },
     "delivery": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/DeliveryInfo"
       },
       {
        "type": "null"
       }
      ]
     },
     "lines": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/OrderLine"
      }
     },
     "charges": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Charge"
      }
     },
     "discounts": {
      "type": "array",
      "description": "Discounts from promotions of the restaurant (see `Discount`).",
      "x-description-cs": "Slevy z akcí provozovny (viz `Discount`).",
      "items": {
       "$ref": "#/components/schemas/Discount"
      }
     },
     "totals": {
      "$ref": "#/components/schemas/Totals"
     },
     "payments": {
      "type": "array",
      "description": "Vouchers that will be used, as `pending` payments.",
      "x-description-cs": "Vouchery, které se použijí, jako platby `pending`.",
      "items": {
       "$ref": "#/components/schemas/Payment"
      }
     },
     "amount_due": {
      "$ref": "#/components/schemas/Money",
      "description": "What your customer pays you or the courier. `totals.total` minus the voucher payments.",
      "x-description-cs": "Kolik zaplatí zákazník vám nebo kurýrovi. `totals.total` minus platby vouchery."
     }
    }
   },
   "Order": {
    "type": "object",
    "description": "An order your connection placed through this API, with the prices of its quote and its state in the kitchen.\nMoney is in minor units.\n",
    "x-description-cs": "Objednávka, kterou vaše připojení vytvořilo přes toto API, s cenami své kalkulace a stavem v kuchyni. Peníze\njsou v nejmenších jednotkách.\n",
    "required": [
     "id",
     "restaurant_id",
     "kitchen_number",
     "status",
     "status_changed_at",
     "created_at",
     "payment_deadline",
     "fulfillment",
     "customer",
     "delivery",
     "lines",
     "charges",
     "discounts",
     "totals",
     "payments",
     "amount_to_collect",
     "loyalty_points_earned",
     "note",
     "cancellation",
     "eet",
     "external_id",
     "metadata"
    ],
    "properties": {
     "id": {
      "description": "Our ID of the order (`order_id` in the paths); it differs from `KitchenTicket.order_id`.",
      "x-description-cs": "Naše ID objednávky (`order_id` v adresách); liší se od `KitchenTicket.order_id`.",
      "$ref": "#/components/schemas/Id"
     },
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "kitchen_number": {
      "type": [
       "string",
       "null"
      ],
      "description": "Short number shown in the kitchen and to the customer. It restarts every shift, so never use it as an ID.",
      "x-description-cs": "Krátké číslo pro kuchyň a zákazníka. Začíná znovu každou směnu, proto ho nikdy nepoužívejte jako ID."
     },
     "status": {
      "type": "string",
      "description": "`awaiting_payment` – waiting for `confirm-payment`, not in the kitchen yet;\n`received` – in the kitchen queue, not started;\n`preparing` – the kitchen started preparing it (a cook or a production station took it, or a part is done);\n  printing the ticket does not count, kitchens print every order as soon as it arrives;\n`ready` – ready for pickup, or waiting for a courier;\n`out_for_delivery` – a courier has it;\n`delivered` – handed over (without the courier app some restaurants confirm it when closing the shift);\n`not_delivered` – the courier could not hand it over (the customer was not there, refused it…); the\n  restaurant decides what next – it becomes `cancelled`, `out_for_delivery` again or `delivered`;\n`cancelled` – see `cancellation`.\n",
      "x-description-cs": "`awaiting_payment` – čeká na `confirm-payment`, v kuchyni ještě není;\n`received` – ve frontě kuchyně, nezačatá;\n`preparing` – kuchyně ji začala připravovat (vzal ji kuchař nebo výroba, nebo je něco hotové); vytištěný\n  bon se nepočítá, kuchyně tisknou každou objednávku hned po příchodu;\n`ready` – připravená k odběru nebo čeká na kurýra;\n`out_for_delivery` – veze ji kurýr;\n`delivered` – předaná (bez kurýrní aplikace ji některé provozovny potvrzují až při uzávěrce směny);\n`not_delivered` – kurýr ji nemohl předat (zákazník nebyl doma, odmítl ji…); co dál, rozhodne provozovna –\n  stane se `cancelled`, znovu `out_for_delivery`, nebo `delivered`;\n`cancelled` – viz `cancellation`.\n",
      "x-extensible-enum": [
       "awaiting_payment",
       "received",
       "preparing",
       "ready",
       "out_for_delivery",
       "delivered",
       "not_delivered",
       "cancelled"
      ]
     },
     "status_changed_at": {
      "$ref": "#/components/schemas/Timestamp",
      "description": "When the order got its current status. The kitchen does not report its steps, so for changes made in the\nkitchen it is the moment Profirest noticed them – usually within a minute.\n",
      "x-description-cs": "Kdy objednávka dostala aktuální stav. Kuchyň své kroky nehlásí, proto je u změn v kuchyni okamžikem, kdy si\njich Profirest všiml – obvykle do minuty.\n"
     },
     "created_at": {
      "description": "When the order was created.",
      "x-description-cs": "Kdy objednávka vznikla.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "payment_deadline": {
      "description": "In `awaiting_payment`, the moment the order is cancelled without `confirm-payment`; otherwise `null`.",
      "x-description-cs": "Ve stavu `awaiting_payment` okamžik, kdy se objednávka bez `confirm-payment` zruší; jinak `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "fulfillment": {
      "$ref": "#/components/schemas/Fulfillment"
     },
     "customer": {
      "type": "object",
      "description": "The contact of the order as you sent it (`OrderCustomerInput`) and the linked customer from the quote\n(`customer_id`). When the restaurant erases that customer in the administration, the name becomes\n`Smazaný zákazník`, the phone an empty string and the e-mail `null`. A kiosk order without a contact has the\nname `Kiosek` and an empty phone.\n",
      "x-description-cs": "Kontakt objednávky, jak jste ho poslali (`OrderCustomerInput`), a propojený zákazník z kalkulace\n(`customer_id`). Když provozovna tohoto zákazníka v administraci smaže, jméno se změní na `Smazaný zákazník`,\ntelefon na prázdný řetězec a e-mail na `null`. Objednávka z kiosku bez kontaktu má jméno `Kiosek` a prázdný\ntelefon.\n",
      "required": [
       "customer_id",
       "name",
       "phone",
       "email"
      ],
      "properties": {
       "customer_id": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/Id"
         },
         {
          "type": "null"
         }
        ]
       },
       "name": {
        "type": "string"
       },
       "phone": {
        "type": "string",
        "description": "Phone number in E.164 format; an empty string after the customer was erased and for a kiosk order without one.",
        "x-description-cs": "Telefon ve formátu E.164; po výmazu zákazníka a u objednávky z kiosku bez telefonu prázdný řetězec.",
        "pattern": "^(\\+[1-9][0-9]{6,14})?$",
        "examples": [
         "+420777123456"
        ]
       },
       "email": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/Email"
         },
         {
          "type": "null"
         }
        ]
       }
      }
     },
     "delivery": {
      "description": "The zone, address, location, fee and minimum order of a `delivery`; `null` for `pickup` and `dine_in`.",
      "x-description-cs": "Zóna, adresa, poloha, cena dopravy a minimální objednávka u `delivery`; u `pickup` a `dine_in` `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/DeliveryInfo"
       },
       {
        "type": "null"
       }
      ]
     },
     "lines": {
      "type": "array",
      "description": "The items with the prices of the quote; items added later in the kitchen (`addKitchenTicketItems`) are appended.",
      "x-description-cs": "Položky s cenami kalkulace; položky přidané později v kuchyni (`addKitchenTicketItems`) se připojí na konec.",
      "items": {
       "$ref": "#/components/schemas/OrderLine"
      }
     },
     "charges": {
      "type": "array",
      "description": "Delivery, the surcharge to the minimum order of the zone and express delivery.",
      "x-description-cs": "Doprava, doplatek do minimální objednávky zóny a expresní doručení.",
      "items": {
       "$ref": "#/components/schemas/Charge"
      }
     },
     "discounts": {
      "type": "array",
      "description": "Discounts from promotions of the restaurant (see `Discount`).",
      "x-description-cs": "Slevy z akcí provozovny (viz `Discount`).",
      "items": {
       "$ref": "#/components/schemas/Discount"
      }
     },
     "totals": {
      "$ref": "#/components/schemas/Totals"
     },
     "payments": {
      "type": "array",
      "description": "The payments, gift voucher payments included (codes masked).",
      "x-description-cs": "Platby včetně plateb dárkovými vouchery (kódy maskovaně).",
      "items": {
       "$ref": "#/components/schemas/Payment"
      }
     },
     "amount_to_collect": {
      "$ref": "#/components/schemas/Money",
      "description": "What the courier or the restaurant still collects at delivery or pickup. Zero when prepaid.",
      "x-description-cs": "Kolik ještě vybere kurýr nebo provozovna při doručení či odběru. Nula, když je předplaceno."
     },
     "loyalty_points_earned": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Points added to the linked customer for this order; `null` without a linked customer.",
      "x-description-cs": "Body připsané propojenému zákazníkovi za tuto objednávku; `null` bez propojeného zákazníka."
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "description": "Your `note` for the kitchen and the courier; `null` when empty.",
      "x-description-cs": "Vaše `note` pro kuchyň a kurýra; `null`, když je prázdná."
     },
     "cancellation": {
      "description": "Who cancelled the order, when and why; `null` unless `status` is `cancelled`.",
      "x-description-cs": "Kdo objednávku zrušil, kdy a proč; `null`, pokud `status` není `cancelled`.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "at",
         "by",
         "reason_code",
         "reason"
        ],
        "properties": {
         "at": {
          "$ref": "#/components/schemas/Timestamp"
         },
         "by": {
          "type": "string",
          "description": "`integrator` – your application (`cancelOrder`, `reason` as you sent it); `system` – Profirest when\n`payment_deadline` passed (`reason_code` `payment_timeout`); `restaurant` – cancelled in the kitchen, by\na cancellation document of a register or in the administration (no reason).\n",
          "x-description-cs": "`integrator` – vaše aplikace (`cancelOrder`, `reason`, jak jste ho poslali); `system` – Profirest po\nuplynutí `payment_deadline` (`reason_code` `payment_timeout`); `restaurant` – zrušeno v kuchyni,\nprotidokladem pokladny nebo v administraci (bez důvodu).\n",
          "x-extensible-enum": [
           "restaurant",
           "integrator",
           "system"
          ]
         },
         "reason_code": {
          "type": [
           "string",
           "null"
          ],
          "description": "`payment_timeout` when `payment_deadline` passed.",
          "x-description-cs": "`payment_timeout`, když uplynul `payment_deadline`.",
          "x-extensible-enum": [
           "payment_timeout"
          ]
         },
         "reason": {
          "type": [
           "string",
           "null"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "eet": {
      "description": "The sale as another system of the restaurant recorded it in EET 2.0; `null` – Profirest records it.",
      "x-description-cs": "Tržba, jak ji do EET 2.0 zaevidoval jiný systém provozovny; `null` – eviduje ji Profirest.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/OrderEet"
       },
       {
        "type": "null"
       }
      ]
     },
     "external_id": {
      "description": "Your own ID of the order (`OrderCreate.external_id` or `putExternalRef`); `null` when you set none.",
      "x-description-cs": "Vaše vlastní ID objednávky (`OrderCreate.external_id` nebo `putExternalRef`); `null`, když žádné nenastavíte.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "description": "Your own key–value pairs on the order.",
      "x-description-cs": "Vaše vlastní dvojice klíč–hodnota u objednávky.",
      "$ref": "#/components/schemas/Metadata"
     }
    }
   },
   "OrderPage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Order"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "CustomerCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "phone"
    ],
    "properties": {
     "phone": {
      "$ref": "#/components/schemas/Phone"
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64
     },
     "email": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Email"
       },
       {
        "type": "null"
       }
      ]
     },
     "external_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/MetadataInput"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "CustomerUpdate": {
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "properties": {
     "phone": {
      "$ref": "#/components/schemas/Phone"
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 64
     },
     "email": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Email"
       },
       {
        "type": "null"
       }
      ]
     },
     "external_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "$ref": "#/components/schemas/MetadataPatch"
     }
    }
   },
   "Customer": {
    "type": "object",
    "description": "Your customer linked to the account's customer database. Contains only data you sent.",
    "x-description-cs": "Váš zákazník propojený s databází klientů účtu. Obsahuje jen údaje, které jste poslali.",
    "required": [
     "id",
     "phone",
     "name",
     "email",
     "phone_verified",
     "created_at",
     "external_id",
     "metadata"
    ],
    "properties": {
     "id": {
      "description": "Our ID of the customer link (`customer_id` in the paths); each connection has its own links.",
      "x-description-cs": "Naše ID propojení zákazníka (`customer_id` v adresách); každé připojení má svá propojení.",
      "$ref": "#/components/schemas/Id"
     },
     "phone": {
      "description": "The phone number as you sent it.",
      "x-description-cs": "Telefonní číslo, jak jste ho poslali.",
      "$ref": "#/components/schemas/Phone"
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "description": "The name as you sent it; `null` when none.",
      "x-description-cs": "Jméno, jak jste ho poslali; `null`, když žádné."
     },
     "email": {
      "description": "The e-mail as you sent it; `null` when none.",
      "x-description-cs": "E-mail, jak jste ho poslali; `null`, když žádný.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Email"
       },
       {
        "type": "null"
       }
      ]
     },
     "phone_verified": {
      "type": "boolean",
      "description": "The phone was verified by an SMS code (`confirmPhoneVerification`); changing the phone sets it back to `false`.",
      "x-description-cs": "Telefon je ověřený kódem z SMS (`confirmPhoneVerification`); změna telefonu ho vrátí na `false`."
     },
     "created_at": {
      "description": "When your connection linked the customer.",
      "x-description-cs": "Kdy vaše připojení zákazníka propojilo.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "external_id": {
      "description": "Your own ID of the customer; `null` when you set none.",
      "x-description-cs": "Vaše vlastní ID zákazníka; `null`, když žádné nenastavíte.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "description": "Your own key–value pairs on the customer.",
      "x-description-cs": "Vaše vlastní dvojice klíč–hodnota u zákazníka.",
      "$ref": "#/components/schemas/Metadata"
     }
    }
   },
   "CustomerPage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Customer"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "PhoneVerification": {
    "type": "object",
    "required": [
     "id",
     "expires_at",
     "resend_after"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "expires_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "resend_after": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "PhoneVerificationConfirm": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "code"
    ],
    "properties": {
     "code": {
      "type": "string",
      "pattern": "^[0-9]{6}$"
     }
    }
   },
   "Loyalty": {
    "type": "object",
    "required": [
     "customer_id",
     "points",
     "points_value",
     "redeemable"
    ],
    "properties": {
     "customer_id": {
      "$ref": "#/components/schemas/Id"
     },
     "points": {
      "type": "integer",
      "minimum": 0
     },
     "points_value": {
      "$ref": "#/components/schemas/Money",
      "description": "Value of the points. 1 point = 1 CZK.",
      "x-description-cs": "Hodnota bodů. 1 bod = 1 Kč."
     },
     "redeemable": {
      "type": "boolean",
      "description": "Points can be redeemed through the API. `false` until redemption is launched.",
      "x-description-cs": "Body lze uplatnit přes API. `false`, dokud se uplatňování nespustí."
     }
    }
   },
   "VoucherCheck": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "code"
    ],
    "properties": {
     "code": {
      "$ref": "#/components/schemas/VoucherCode"
     },
     "end_user_id": {
      "description": "Your stable, anonymous ID of the shopper. Used for the attempt limits.",
      "x-description-cs": "Vaše stálé anonymní ID nakupujícího. Slouží k limitům pokusů.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "Voucher": {
    "type": "object",
    "required": [
     "code",
     "status",
     "value",
     "balance",
     "valid_until",
     "partial_redemption",
     "accepted_here"
    ],
    "properties": {
     "code": {
      "type": "string",
      "description": "Masked code.",
      "x-description-cs": "Maskovaný kód.",
      "examples": [
       "ABC-***"
      ]
     },
     "status": {
      "type": "string",
      "description": "`active` – can be used; `expired`; `used` – no balance left; `blocked` – blocked by the restaurant;\n`for_sale` – not sold yet, can be sold at `value` (only for a paired register, since 26.11.26).\n",
      "x-description-cs": "`active` – lze použít; `expired` – vypršel; `used` – bez zůstatku; `blocked` – zablokovaný provozovnou;\n`for_sale` – zatím neprodaný, jde prodat za `value` (jen pro spárovanou pokladnu, od 26.11.26).\n",
      "x-extensible-enum": [
       "active",
       "expired",
       "used",
       "blocked",
       "for_sale"
      ]
     },
     "value": {
      "$ref": "#/components/schemas/Money",
      "description": "Original value.",
      "x-description-cs": "Původní hodnota."
     },
     "balance": {
      "$ref": "#/components/schemas/Money"
     },
     "valid_until": {
      "description": "Last day of validity, inclusive.",
      "x-description-cs": "Poslední den platnosti včetně.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/LocalDate"
       },
       {
        "type": "null"
       }
      ]
     },
     "partial_redemption": {
      "type": "boolean",
      "description": "`true` – can be used gradually; `false` – used at once and the rest is lost (see `Payment.forfeited`).",
      "x-description-cs": "`true` – lze čerpat postupně; `false` – použije se najednou a zbytek propadne (viz `Payment.forfeited`)."
     },
     "accepted_here": {
      "type": "boolean",
      "description": "The voucher can be used at this restaurant.",
      "x-description-cs": "Voucher lze použít na této provozovně."
     }
    }
   },
   "ExternalRef": {
    "type": "object",
    "required": [
     "object_type",
     "object_id",
     "external_id",
     "metadata",
     "updated_at"
    ],
    "properties": {
     "object_type": {
      "type": "string",
      "description": "The type of the object, as in the path: `restaurant` (`Restaurant.id`), `category` (`Category.id`), `product`\n(`Product.id`), `order` (`Order.id` of your connection), `customer` (`Customer.id` of your connection).\n",
      "x-description-cs": "Typ objektu jako v adrese: `restaurant` (`Restaurant.id`), `category` (`Category.id`), `product`\n(`Product.id`), `order` (`Order.id` vašeho připojení), `customer` (`Customer.id` vašeho připojení).\n",
      "x-extensible-enum": [
       "restaurant",
       "category",
       "product",
       "order",
       "customer"
      ]
     },
     "object_id": {
      "$ref": "#/components/schemas/Id"
     },
     "external_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "$ref": "#/components/schemas/Metadata"
     },
     "updated_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ExternalRefUpdate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "external_id",
     "metadata"
    ],
    "properties": {
     "external_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/ExternalId"
       },
       {
        "type": "null"
       }
      ]
     },
     "metadata": {
      "$ref": "#/components/schemas/MetadataInput"
     }
    }
   },
   "ExternalRefPage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ExternalRef"
      }
     },
     "next_cursor": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Event": {
    "type": "object",
    "description": "One change. The same object comes from `GET /events` and from webhooks. `data` depends on `type`:\n`order.created`, `order.updated`, `order.status_changed` – the whole `Order` as it was at `occurred_at`;\n`catalog.changed`, `availability.changed`, `restaurant.changed` – `EventRestaurantData`, reload the resource (the\nserver compares the catalog and the remaining portions of every restaurant an application reads about once a\nminute, so these two come within about two minutes of the change, whoever made it – the administration,\na register or an import; `restaurant.changed` comes when the administration saves the restaurant, see\n`getRestaurant`); `promotions.changed` – `EventRestaurantData`, the restaurant changed its promotions, reload\n`GET …/promotions`; `grant.changed`, `grant.revoked` – `EventGrantData`; `attendance.updated` –\n`EventAttendanceData` (an employee\narrived, left, started or ended a break); `kitchen.ticket_created`, `kitchen.ticket_updated` –\n`EventKitchenTicketData` (a new kitchen ticket from any source, or a changed one; changes made through this API\ncome at once, tickets and changes from elsewhere – registers, the web kitchen display, the e-shop, delivery\nplatforms – within about two minutes; reload the ticket); `kitchen.shift_closed` – `EventKitchenShiftData` (the kitchen shift was\nclosed; reload the history); `call.received` – `IncomingCall` (the restaurant's phone reported a call);\n`receipt.created`, `receipt.cancelled` – `Receipt` (a receipt or a cancellation document issued through this API\nby any register of the restaurant; registers on API v1 send no receipt events); `receipt.updated` – `Receipt`\n(a register changed the payment of a receipt, `changeReceiptPayment`);\n`pos_shift.closed` – `PosShiftClose`; `tab.updated` – `Tab`; `tab.closed` – `EventTabClosedData`;\n`sale.created` – `Sale` (a new sales or cancellation document from any source – registers on API v1 and v2, the\nkiosk, the e-shop and applications, the web kitchen display, phone orders, delivery platforms – within about\nthree minutes, the same as `getSale`); `sale.cancelled` – `Sale` (the original document after its cancellation\ndocument was issued, with `cancelled_by`); `shift.closed` – `ShiftClose` (a shift close from any source, the same\nas `getShiftClose`, within about three minutes); `table.inbox_received` – `EventTableInboxData` (a request of a\nguest waits in the inbox of ordering from the table, see `listTableInbox`; only with `table:sync`);\n`reservation.created`, `reservation.updated`, `reservation.status_changed` – `Reservation` (from any source – the\nadministration, registers, guests online, other applications; the guest's phone and e-mail and `note_internal` are\n`null`, read them with `getReservation`; `status_changed` adds `previous_status`); `courier.position` –\n`CourierPosition` (a courier's phone sent a new location, at most one every 10 seconds per courier – only in\n`GET /events` and the stream, never in webhooks, kept for 24 hours); `courier.shift_changed` – `Courier`\n(a courier checked in for the shift or out of it). Ignore event types you do not know.\n",
    "x-description-cs": "Jedna změna. Stejný objekt přichází z `GET /events` i z webhooků. `data` závisí na `type`:\n`order.created`, `order.updated`, `order.status_changed` – celá `Order` tak, jak byla v `occurred_at`;\n`catalog.changed`, `availability.changed`, `restaurant.changed` – `EventRestaurantData`, načtěte zdroj znovu\n(server porovnává sortiment a zbývající porce každé provozovny, kterou nějaká aplikace čte, zhruba jednou\nza minutu, takže tyto dvě přijdou nejpozději asi dvě minuty po změně, ať ji udělal kdokoli – administrace,\npokladna nebo import; `restaurant.changed` přijde, když administrace uloží provozovnu, viz `getRestaurant`);\n`promotions.changed` – `EventRestaurantData`, provozovna změnila akce, načtěte znovu `GET …/promotions`;\n`grant.changed`, `grant.revoked` – `EventGrantData`; `attendance.updated` –\n`EventAttendanceData` (zaměstnanec\npřišel, odešel, začal nebo skončil přestávku); `kitchen.ticket_created`, `kitchen.ticket_updated` –\n`EventKitchenTicketData` (nový kuchyňský bon z jakéhokoli zdroje, nebo změněný; změny přes toto API přicházejí\nhned, bony a změny odjinud – pokladny, webový kuchyňský displej, e-shop, rozvozové platformy – do zhruba dvou\nminut; bon načtěte znovu); `kitchen.shift_closed` – `EventKitchenShiftData` (směna kuchyně se\nuzavřela; načtěte historii znovu); `call.received` – `IncomingCall` (telefon provozovny nahlásil hovor);\n`receipt.created`, `receipt.cancelled` – `Receipt` (účtenka nebo storno doklad, které přes toto API vystavila\nkterákoli pokladna provozovny; pokladny na API v1 události účtenek nevydávají); `receipt.updated` – `Receipt`\n(pokladna změnila platbu účtenky, `changeReceiptPayment`);\n`pos_shift.closed` – `PosShiftClose`; `tab.updated` – `Tab`; `tab.closed` – `EventTabClosedData`;\n`sale.created` – `Sale` (nový doklad prodeje nebo storno doklad z jakéhokoli zdroje – pokladny na API v1 i v2,\nkiosek, e-shop a aplikace, webový kuchyňský displej, telefonické objednávky, rozvozové platformy – do zhruba tří\nminut, stejný jako `getSale`); `sale.cancelled` – `Sale` (původní doklad po vystavení storno dokladu,\ns `cancelled_by`); `shift.closed` – `ShiftClose` (uzávěrka z jakéhokoli zdroje, stejná jako `getShiftClose`, do\nzhruba tří minut); `table.inbox_received` – `EventTableInboxData` (žádost hosta čeká ve schránce objednávání\nod stolu, viz `listTableInbox`; jen s `table:sync`); `reservation.created`, `reservation.updated`,\n`reservation.status_changed` – `Reservation` (z jakéhokoli zdroje – administrace, pokladny, hosté online, jiné\naplikace; telefon a e-mail hosta a `note_internal` jsou `null`, načtěte je přes `getReservation`; `status_changed`\npřidá `previous_status`); `courier.position` – `CourierPosition` (telefon kurýra poslal novou polohu, nejvýš\njednou za 10 sekund na kurýra – jen v `GET /events` a v proudu, nikdy ve webhoocích, drží se 24 hodin);\n`courier.shift_changed` – `Courier` (kurýr se přihlásil na směnu nebo z ní odhlásil). Typy událostí, které\nneznáte, ignorujte.\n",
    "required": [
     "id",
     "api_version",
     "sequence",
     "type",
     "occurred_at",
     "connection_id",
     "account_id",
     "restaurant_id",
     "data"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "api_version": {
      "type": "string",
      "description": "Version of the payload format. Always `2` in API v2.",
      "x-description-cs": "Verze formátu obsahu. V API v2 vždy `2`.",
      "examples": [
       "2"
      ]
     },
     "sequence": {
      "type": "integer",
      "description": "Grows in the order events are written; the feed and webhooks never hand out a higher one before a lower one of your connection. Gaps are possible. Use it to order webhook deliveries.",
      "x-description-cs": "Roste v pořadí zápisu událostí; proud ani webhooky nevydají vyšší dřív než nižší z vašeho připojení. Mezery jsou možné. Podle něj řaďte doručené webhooky."
     },
     "type": {
      "type": "string",
      "description": "What happened; the description of `Event` says what every type means and what `data` it carries.",
      "x-description-cs": "Co se stalo; popis `Event` říká, co který typ znamená a jaká `data` nese.",
      "x-extensible-enum": [
       "order.created",
       "order.updated",
       "order.status_changed",
       "catalog.changed",
       "availability.changed",
       "promotions.changed",
       "restaurant.changed",
       "grant.changed",
       "grant.revoked",
       "attendance.updated",
       "kitchen.ticket_created",
       "kitchen.ticket_updated",
       "kitchen.shift_closed",
       "call.received",
       "receipt.created",
       "receipt.cancelled",
       "receipt.updated",
       "pos_shift.closed",
       "tab.updated",
       "tab.closed",
       "sale.created",
       "sale.cancelled",
       "shift.closed",
       "table.inbox_received",
       "reservation.created",
       "reservation.updated",
       "reservation.status_changed",
       "courier.position",
       "courier.shift_changed"
      ]
     },
     "occurred_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "connection_id": {
      "$ref": "#/components/schemas/Id"
     },
     "account_id": {
      "$ref": "#/components/schemas/Id"
     },
     "restaurant_id": {
      "description": "The restaurant the event belongs to; `null` for connection-level events.",
      "x-description-cs": "Provozovna, ke které událost patří; `null` u událostí celého připojení.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "data": {
      "type": "object",
      "description": "See the event description.",
      "x-description-cs": "Viz popis události."
     }
    }
   },
   "Reservation": {
    "type": "object",
    "description": "A reservation of a table (`kind=table`) or of a service with an employee (`kind=service`). States: `requested`\n(waits for the restaurant's confirmation or for the deposit), `confirmed`, `seated` (the guests are here),\n`completed` (they left), `cancelled`, `rejected`, `no_show`, `expired` (nobody confirmed or paid it in time).\nA reservation in `requested`, `confirmed` or `seated` holds its tables, employee and room until\n`blocked_until`.\n",
    "x-description-cs": "Rezervace stolu (`kind=table`), nebo služby u pracovníka (`kind=service`). Stavy: `requested` (čeká na\npotvrzení provozovnou nebo na zálohu), `confirmed`, `seated` (hosté jsou tu), `completed` (odešli),\n`cancelled`, `rejected`, `no_show`, `expired` (nikdo ji včas nepotvrdil ani nezaplatil). Rezervace ve stavu\n`requested`, `confirmed` nebo `seated` drží stoly, pracovníka a místnost do `blocked_until`.\n",
    "required": [
     "id",
     "uuid",
     "restaurant_id",
     "kind",
     "status",
     "source",
     "party_size",
     "starts_at",
     "ends_at",
     "blocked_until",
     "table_ids",
     "service_id",
     "employee_id",
     "employee_any",
     "resource_id",
     "guest",
     "note_guest",
     "note_internal",
     "tags",
     "deposit",
     "confirm_due_at",
     "tab_id",
     "cancel_reason",
     "version",
     "created_at",
     "updated_at"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "uuid": {
      "type": "string",
      "format": "uuid",
      "description": "The UUID of the reservation – yours when you sent one to `createReservation`. The path accepts it too.",
      "x-description-cs": "UUID rezervace – vaše, pokud jste ho poslali do `createReservation`. Adresa ho přijme také."
     },
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     },
     "kind": {
      "type": "string",
      "x-extensible-enum": [
       "table",
       "service"
      ],
      "examples": [
       "table"
      ]
     },
     "status": {
      "type": "string",
      "x-extensible-enum": [
       "requested",
       "confirmed",
       "seated",
       "completed",
       "cancelled",
       "rejected",
       "no_show",
       "expired"
      ],
      "examples": [
       "confirmed"
      ]
     },
     "source": {
      "type": "string",
      "description": "Where it came from – `admin` (the administration), `pos` (a register), `phone` (taken by phone), `online` (a guest booking online), `api` (an application of the staff).",
      "x-description-cs": "Odkud přišla – `admin` (administrace), `pos` (pokladna), `phone` (po telefonu), `online` (host rezervuje online), `api` (aplikace obsluhy).",
      "x-extensible-enum": [
       "admin",
       "pos",
       "phone",
       "online",
       "api"
      ],
      "examples": [
       "online"
      ]
     },
     "party_size": {
      "type": "integer",
      "minimum": 1,
      "examples": [
       4
      ]
     },
     "starts_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "ends_at": {
      "description": "End of the visit or of the service.",
      "x-description-cs": "Konec návštěvy nebo služby.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "blocked_until": {
      "description": "End plus cleaning or preparation – until then the tables, the employee and the room are taken.",
      "x-description-cs": "Konec plus úklid nebo příprava – do té doby jsou stoly, pracovník a místnost obsazené.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "table_ids": {
      "type": "array",
      "description": "Tables of the map (`Room.tables[].id`); more than one when tables are joined. Empty for a service.",
      "x-description-cs": "Stoly z mapy (`Room.tables[].id`); víc, když se stoly spojí. U služby prázdné.",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "service_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "employee_id": {
      "description": "The employee doing the service; `null` for a table.",
      "x-description-cs": "Pracovník, který službu dělá; u stolu `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "employee_any": {
      "type": "boolean",
      "description": "The guest wanted any free employee; the server picked one.",
      "x-description-cs": "Host chtěl kohokoli volného; server vybral."
     },
     "resource_id": {
      "description": "The room or equipment the service needs.",
      "x-description-cs": "Místnost nebo zařízení, které služba potřebuje.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "guest": {
      "$ref": "#/components/schemas/ReservationGuest"
     },
     "note_guest": {
      "type": [
       "string",
       "null"
      ],
      "description": "The guest's wish (a highchair, gluten-free).",
      "x-description-cs": "Přání hosta (dětská židlička, bezlepkové)."
     },
     "note_internal": {
      "type": [
       "string",
       "null"
      ],
      "description": "A note for the staff only; `null` in events.",
      "x-description-cs": "Poznámka jen pro obsluhu; v událostech `null`."
     },
     "tags": {
      "type": "array",
      "description": "Labels of the staff (birthday, VIP, allergy).",
      "x-description-cs": "Štítky obsluhy (narozeniny, VIP, alergie).",
      "items": {
       "type": "string",
       "maxLength": 32
      }
     },
     "deposit": {
      "$ref": "#/components/schemas/ReservationDeposit"
     },
     "confirm_due_at": {
      "description": "A `requested` reservation expires at this time when nobody confirms or pays it.",
      "x-description-cs": "Rezervace `requested` v tuto chvíli propadne, když ji nikdo nepotvrdí ani nezaplatí.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "tab_id": {
      "type": [
       "string",
       "null"
      ],
      "format": "uuid",
      "description": "The tab of the table after seating (`Tab.id`), when the register sent it.",
      "x-description-cs": "Účet stolu po usazení (`Tab.id`), když ho pokladna poslala."
     },
     "cancel_reason": {
      "type": [
       "string",
       "null"
      ],
      "description": "Why it was cancelled or rejected.",
      "x-description-cs": "Proč byla zrušena nebo odmítnuta."
     },
     "version": {
      "type": "integer",
      "description": "Grows with every change; the `ETag` carries it.",
      "x-description-cs": "Roste s každou změnou; nese ji `ETag`."
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "updated_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "ReservationGuest": {
    "type": "object",
    "description": "The guest. In events `phone` and `email` are `null` – read them with `getReservation`.",
    "x-description-cs": "Host. V událostech jsou `phone` a `email` `null` – načtěte je přes `getReservation`.",
    "required": [
     "name",
     "phone",
     "email",
     "customer_id"
    ],
    "properties": {
     "name": {
      "type": "string",
      "examples": [
       "Jana Svobodová"
      ]
     },
     "phone": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "+420777123456"
      ]
     },
     "email": {
      "type": [
       "string",
       "null"
      ],
      "format": "email"
     },
     "customer_id": {
      "description": "The customer of the account (`Customer.id`), when linked.",
      "x-description-cs": "Zákazník účtu (`Customer.id`), je-li propojený.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReservationDeposit": {
    "type": "object",
    "description": "The deposit the rules require – `none`, `pending` (waits for payment), `paid`, `refunded`, `forfeited` (no-show).",
    "x-description-cs": "Záloha podle pravidel – `none`, `pending` (čeká na zaplacení), `paid`, `refunded`, `forfeited` (nepřišli).",
    "required": [
     "amount",
     "status",
     "due_at"
    ],
    "properties": {
     "amount": {
      "$ref": "#/components/schemas/Money"
     },
     "status": {
      "type": "string",
      "x-extensible-enum": [
       "none",
       "pending",
       "paid",
       "refunded",
       "forfeited"
      ]
     },
     "due_at": {
      "description": "An unpaid deposit expires the reservation at this time.",
      "x-description-cs": "Nezaplacená záloha v tuto chvíli nechá rezervaci propadnout.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReservationGuestInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "name"
    ],
    "properties": {
     "name": {
      "type": "string",
      "minLength": 2,
      "maxLength": 100
     },
     "phone": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "description": "Required for `channel=online`.",
      "x-description-cs": "Povinný u `channel=online`."
     },
     "email": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 190,
      "description": "Required for `channel=online`.",
      "x-description-cs": "Povinný u `channel=online`."
     },
     "customer_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReservationCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "starts_at",
     "guest"
    ],
    "properties": {
     "uuid": {
      "type": "string",
      "format": "uuid",
      "description": "Your own UUID of the reservation; a second create with it returns the existing one.",
      "x-description-cs": "Vaše vlastní UUID rezervace; druhé založení s ním vrátí existující."
     },
     "channel": {
      "type": "string",
      "enum": [
       "online",
       "staff"
      ],
      "description": "`online` (default) – a guest books through your application; `staff` – an application of the staff.",
      "x-description-cs": "`online` (výchozí) – host rezervuje přes vaši aplikaci; `staff` – aplikace obsluhy."
     },
     "kind": {
      "type": "string",
      "enum": [
       "table",
       "service"
      ],
      "description": "`table` (default) or `service`.",
      "x-description-cs": "`table` (výchozí), nebo `service`."
     },
     "party_size": {
      "type": "integer",
      "minimum": 1,
      "maximum": 500,
      "examples": [
       4
      ]
     },
     "starts_at": {
      "type": "string",
      "description": "The start – RFC 3339 (`2026-11-10T19:00:00+01:00`), or local time of the restaurant without a zone (`2026-11-10T19:00`). Seconds are dropped. Online it must be one of the free times.",
      "x-description-cs": "Začátek – RFC 3339 (`2026-11-10T19:00:00+01:00`), nebo místní čas provozovny bez zóny (`2026-11-10T19:00`). Sekundy se zahodí. Online musí být jedním z volných časů.",
      "examples": [
       "2026-11-10T19:00:00+01:00"
      ]
     },
     "service_id": {
      "$ref": "#/components/schemas/Id"
     },
     "employee_id": {
      "description": "Only this employee; leave it out for any free one.",
      "x-description-cs": "Jen tento pracovník; bez něj kdokoli volný.",
      "$ref": "#/components/schemas/Id"
     },
     "table_ids": {
      "type": "array",
      "description": "The tables (only `channel=staff`); leave it out and the server picks them.",
      "x-description-cs": "Stoly (jen `channel=staff`); bez nich je vybere server.",
      "maxItems": 20,
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "guest": {
      "$ref": "#/components/schemas/ReservationGuestInput"
     },
     "note_guest": {
      "type": "string",
      "maxLength": 500
     },
     "note_internal": {
      "type": "string",
      "maxLength": 500
     },
     "tags": {
      "type": "array",
      "maxItems": 10,
      "items": {
       "type": "string",
       "maxLength": 32
      }
     },
     "duration_minutes": {
      "type": "integer",
      "minimum": 15,
      "maximum": 1440,
      "description": "Only `channel=staff`, tables – the length of the visit instead of the rules (by the party size).",
      "x-description-cs": "Jen `channel=staff`, stoly – délka návštěvy místo pravidel (podle počtu osob).",
      "examples": [
       240
      ]
     },
     "walk_in": {
      "type": "boolean",
      "description": "Only `channel=staff` – guests without a reservation are here now; the reservation is seated at once.",
      "x-description-cs": "Jen `channel=staff` – hosté bez rezervace jsou tady; rezervace se rovnou usadí."
     },
     "deposit": {
      "type": "boolean",
      "description": "Only `channel=staff` – `false` = no deposit even when the rules require one. Default `true`.",
      "x-description-cs": "Jen `channel=staff` – `false` = bez zálohy, i když ji pravidla chtějí. Výchozí `true`."
     }
    }
   },
   "ReservationUpdate": {
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "description": "Only the fields that change.",
    "x-description-cs": "Jen pole, která se mění.",
    "properties": {
     "party_size": {
      "type": "integer",
      "minimum": 1,
      "maximum": 500
     },
     "starts_at": {
      "type": "string",
      "description": "As in `ReservationCreate`.",
      "x-description-cs": "Jako v `ReservationCreate`."
     },
     "service_id": {
      "$ref": "#/components/schemas/Id"
     },
     "employee_id": {
      "description": "Another employee; `null` = any free one.",
      "x-description-cs": "Jiný pracovník; `null` = kdokoli volný.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "table_ids": {
      "type": "array",
      "maxItems": 20,
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "guest": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "name": {
        "type": "string",
        "minLength": 2,
        "maxLength": 100
       },
       "phone": {
        "type": [
         "string",
         "null"
        ],
        "maxLength": 32
       },
       "email": {
        "type": [
         "string",
         "null"
        ],
        "maxLength": 190
       },
       "customer_id": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/Id"
         },
         {
          "type": "null"
         }
        ]
       }
      }
     },
     "note_guest": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 500
     },
     "note_internal": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 500
     },
     "tags": {
      "type": "array",
      "maxItems": 10,
      "items": {
       "type": "string",
       "maxLength": 32
      }
     },
     "duration_minutes": {
      "type": "integer",
      "minimum": 15,
      "maximum": 1440,
      "description": "Tables – a new length of the visit; checked against the capacity again.",
      "x-description-cs": "Stoly – nová délka návštěvy; znovu se porovná s kapacitou."
     }
    }
   },
   "ReservationPaymentLink": {
    "type": "object",
    "required": [
     "url",
     "emailed",
     "due_at"
    ],
    "properties": {
     "url": {
      "type": "string",
      "format": "uri",
      "description": "The page of the reservation for the guest – the deposit is paid there by card (and the guest can cancel the reservation). Send it by SMS or a message; an older link of the reservation stops working.",
      "x-description-cs": "Stránka rezervace pro hosta – tam zálohu zaplatí kartou (a může rezervaci zrušit). Pošlete ji SMS nebo zprávou; starší odkaz rezervace přestane platit."
     },
     "emailed": {
      "type": "boolean",
      "description": "`true` = Profirest sent the link to the guest's e-mail.",
      "x-description-cs": "`true` = Profirest odkaz poslal na e-mail hosta."
     },
     "due_at": {
      "description": "Unpaid by this time, the reservation expires.",
      "x-description-cs": "Nezaplacená do této doby rezervace propadne.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "ReservationGuestHistory": {
    "type": "object",
    "description": "What the restaurant knows about the guest from earlier reservations of all restaurants of the account.",
    "x-description-cs": "Co provozovna ví o hostovi z dřívějších rezervací všech provozoven účtu.",
    "required": [
     "known",
     "name",
     "phone",
     "email",
     "visits",
     "no_shows",
     "cancelled",
     "upcoming",
     "last_visit_at",
     "tags"
    ],
    "properties": {
     "known": {
      "type": "boolean",
      "description": "`false` = a new guest.",
      "x-description-cs": "`false` = nový host."
     },
     "name": {
      "type": [
       "string",
       "null"
      ],
      "description": "The latest name.",
      "x-description-cs": "Poslední jméno."
     },
     "phone": {
      "type": [
       "string",
       "null"
      ]
     },
     "email": {
      "type": [
       "string",
       "null"
      ]
     },
     "visits": {
      "type": "integer",
      "description": "Came (seated or finished).",
      "x-description-cs": "Přišel (usazen nebo odešel)."
     },
     "no_shows": {
      "type": "integer",
      "description": "Did not come without cancelling.",
      "x-description-cs": "Nepřišel bez zrušení."
     },
     "cancelled": {
      "type": "integer"
     },
     "upcoming": {
      "type": "integer",
      "description": "Valid reservations in the future.",
      "x-description-cs": "Platné rezervace v budoucnu."
     },
     "last_visit_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "tags": {
      "type": "array",
      "description": "Tags from earlier reservations (allergies, VIP …).",
      "x-description-cs": "Štítky z dřívějších rezervací (alergie, VIP …).",
      "items": {
       "type": "string"
      }
     }
    }
   },
   "WaitlistEntry": {
    "type": "object",
    "required": [
     "id",
     "name",
     "phone",
     "party_size",
     "note",
     "status",
     "created_at",
     "notified_at",
     "can_sms"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "phone": {
      "type": [
       "string",
       "null"
      ]
     },
     "party_size": {
      "type": "integer"
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "status": {
      "type": "string",
      "x-extensible-enum": [
       "waiting",
       "notified"
      ],
      "description": "`notified` = the SMS that the table is ready was sent.",
      "x-description-cs": "`notified` = odešla SMS, že je stůl připravený."
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "notified_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "can_sms": {
      "type": "boolean",
      "description": "The guest has a Czech mobile number for `notifyWaitlistEntry`.",
      "x-description-cs": "Host má české mobilní číslo pro `notifyWaitlistEntry`."
     }
    }
   },
   "WaitlistList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/WaitlistEntry"
      }
     }
    }
   },
   "WaitlistEntryCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "party_size"
    ],
    "properties": {
     "name": {
      "type": "string",
      "maxLength": 100
     },
     "phone": {
      "type": "string",
      "maxLength": 32
     },
     "party_size": {
      "type": "integer",
      "minimum": 1,
      "maximum": 500,
      "examples": [
       4
      ]
     },
     "note": {
      "type": "string",
      "maxLength": 255
     }
    }
   },
   "WaitlistClose": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "status"
    ],
    "properties": {
     "status": {
      "type": "string",
      "enum": [
       "seated",
       "left"
      ]
     },
     "reservation_id": {
      "description": "With `seated` – the reservation of the guest.",
      "x-description-cs": "U `seated` – rezervace hosta.",
      "$ref": "#/components/schemas/Id"
     }
    }
   },
   "ReservationFeedback": {
    "type": "object",
    "required": [
     "reservation_id",
     "starts_at",
     "guest_name",
     "rating",
     "comment",
     "rated_at"
    ],
    "properties": {
     "reservation_id": {
      "$ref": "#/components/schemas/Id"
     },
     "starts_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "guest_name": {
      "type": "string"
     },
     "rating": {
      "type": "integer",
      "minimum": 1,
      "maximum": 5
     },
     "comment": {
      "type": [
       "string",
       "null"
      ]
     },
     "rated_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "ReservationFeedbackList": {
    "type": "object",
    "required": [
     "data",
     "count",
     "average"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ReservationFeedback"
      }
     },
     "count": {
      "type": "integer"
     },
     "average": {
      "type": [
       "number",
       "null"
      ],
      "description": "The average rating, one decimal place; `null` without ratings.",
      "x-description-cs": "Průměrné hodnocení na jedno desetinné místo; bez hodnocení `null`."
     }
    }
   },
   "ReservationAction": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
     "reason": {
      "type": "string",
      "maxLength": 255,
      "description": "Why it is cancelled or rejected – the guest sees it.",
      "x-description-cs": "Proč se ruší nebo odmítá – uvidí to host."
     },
     "tab_id": {
      "type": "string",
      "format": "uuid",
      "description": "`seatReservation`: the tab your register opened for the guests.",
      "x-description-cs": "`seatReservation`: účet, který hostům otevřela vaše pokladna."
     }
    }
   },
   "ReservationList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Reservation"
      }
     }
    }
   },
   "ReservationSettings": {
    "type": "object",
    "required": [
     "slot_step_minutes",
     "table_durations",
     "table_buffer_minutes",
     "last_seating_before_close_minutes",
     "use_opening_hours",
     "max_guests_per_slot",
     "closed_dates",
     "online",
     "services_enabled",
     "deposit",
     "reminders",
     "feedback_enabled",
     "guest_max_moves"
    ],
    "properties": {
     "slot_step_minutes": {
      "type": "integer",
      "description": "Times are offered in this step (5–60 minutes).",
      "x-description-cs": "Časy se nabízejí po tomto kroku (5–60 minut).",
      "examples": [
       15
      ]
     },
     "table_durations": {
      "type": "array",
      "description": "How long guests sit at a table by the size of the party, ascending; a bigger party sits as the last row.",
      "x-description-cs": "Jak dlouho hosté sedí u stolu podle velikosti skupiny, vzestupně; větší skupina sedí jako poslední řádek.",
      "items": {
       "type": "object",
       "required": [
        "up_to_party_size",
        "minutes"
       ],
       "properties": {
        "up_to_party_size": {
         "type": "integer",
         "examples": [
          2
         ]
        },
        "minutes": {
         "type": "integer",
         "examples": [
          90
         ]
        }
       }
      }
     },
     "table_buffer_minutes": {
      "type": "integer",
      "description": "Cleaning of a table after the guests leave.",
      "x-description-cs": "Úklid stolu po odchodu hostů."
     },
     "last_seating_before_close_minutes": {
      "type": "integer",
      "description": "The last table reservation starts this many minutes before closing.",
      "x-description-cs": "Poslední rezervace stolu začíná tolik minut před zavřením."
     },
     "use_opening_hours": {
      "type": "boolean",
      "description": "Tables are reserved only within the opening hours (`getOpeningHours`).",
      "x-description-cs": "Stoly se rezervují jen v otevírací době (`getOpeningHours`)."
     },
     "max_guests_per_slot": {
      "type": [
       "integer",
       "null"
      ],
      "description": "At most this many guests may arrive in one step; `null` = no limit.",
      "x-description-cs": "Nejvýš tolik hostů smí přijít v jednom kroku; `null` = bez omezení."
     },
     "closed_dates": {
      "type": "array",
      "description": "Days without reservations.",
      "x-description-cs": "Dny bez rezervací.",
      "items": {
       "$ref": "#/components/schemas/LocalDate"
      }
     },
     "online": {
      "type": "object",
      "required": [
       "enabled",
       "confirmation",
       "confirm_within_minutes",
       "lead_minutes",
       "horizon_days",
       "max_party_size",
       "guest_cancel_hours"
      ],
      "properties": {
       "enabled": {
        "type": "boolean",
        "description": "The restaurant takes reservations of guests online.",
        "x-description-cs": "Provozovna přijímá rezervace hostů online."
       },
       "confirmation": {
        "type": "string",
        "description": "`auto` – confirmed at once when free; `manual` – waits for the restaurant (`requested`).",
        "x-description-cs": "`auto` – hned potvrzená, když je volno; `manual` – čeká na provozovnu (`requested`).",
        "x-extensible-enum": [
         "auto",
         "manual"
        ]
       },
       "confirm_within_minutes": {
        "type": "integer",
        "description": "An unconfirmed reservation expires after this time.",
        "x-description-cs": "Nepotvrzená rezervace po této době propadne."
       },
       "lead_minutes": {
        "type": "integer",
        "description": "Not sooner than this many minutes from now.",
        "x-description-cs": "Ne dřív než za tolik minut od teď."
       },
       "horizon_days": {
        "type": "integer",
        "description": "At most this many days ahead.",
        "x-description-cs": "Nejvýš tolik dní dopředu."
       },
       "max_party_size": {
        "type": "integer",
        "description": "Bigger parties book by phone.",
        "x-description-cs": "Větší skupiny rezervují telefonicky."
       },
       "guest_cancel_hours": {
        "type": "integer",
        "description": "The guest may cancel at the latest this many hours before the start.",
        "x-description-cs": "Host smí zrušit nejpozději tolik hodin před začátkem."
       }
      }
     },
     "services_enabled": {
      "type": "boolean",
      "description": "The licence includes reservations of services with employees.",
      "x-description-cs": "Licence zahrnuje rezervace služeb u pracovníků."
     },
     "deposit": {
      "type": "object",
      "description": "The deposit rules. A deposit is taken only when `available` (a payment gateway of the restaurant's e-shop is on).\nThe amount of a reservation is in `ReservationDeposit` once it exists.\n",
      "x-description-cs": "Pravidla záloh. Záloha se vybírá jen při `available` (zapnutá platební brána e-shopu provozovny). Částku\nkonkrétní rezervace nese `ReservationDeposit`, jakmile rezervace vznikne.\n",
      "required": [
       "mode",
       "available",
       "from_party_size",
       "per_person",
       "per_reservation",
       "service_percent",
       "pay_within_minutes",
       "refund_until_hours",
       "no_show_guests"
      ],
      "properties": {
       "mode": {
        "type": "string",
        "description": "`none`; `from_party` – tables from `from_party_size` guests and every service; `always`.",
        "x-description-cs": "`none`; `from_party` – stoly od `from_party_size` osob a každá služba; `always`.",
        "x-extensible-enum": [
         "none",
         "from_party",
         "always"
        ]
       },
       "available": {
        "type": "boolean",
        "description": "A payment gateway is on, so deposits can be paid.",
        "x-description-cs": "Platební brána je zapnutá, zálohy jde zaplatit."
       },
       "from_party_size": {
        "type": "integer",
        "examples": [
         6
        ]
       },
       "per_person": {
        "description": "Table deposit per guest; zero when the deposit is per reservation.",
        "x-description-cs": "Záloha stolu za osobu; nula, když je za rezervaci.",
        "$ref": "#/components/schemas/Money"
       },
       "per_reservation": {
        "description": "Table deposit per reservation; zero when it is per guest.",
        "x-description-cs": "Záloha stolu za rezervaci; nula, když je za osobu.",
        "$ref": "#/components/schemas/Money"
       },
       "service_percent": {
        "type": "integer",
        "minimum": 0,
        "maximum": 100,
        "description": "Service deposit as a percentage of the price, whole crowns; 0 = the full price.",
        "x-description-cs": "Záloha služby v procentech ceny, na celé koruny; 0 = celá cena."
       },
       "pay_within_minutes": {
        "type": "integer",
        "description": "An unpaid reservation expires after this time.",
        "x-description-cs": "Nezaplacená rezervace po této době propadne."
       },
       "refund_until_hours": {
        "type": "integer",
        "description": "When the guest cancels at least this many hours before the start, the deposit is refunded.",
        "x-description-cs": "Zruší-li host aspoň tolik hodin před začátkem, záloha se vrací."
       },
       "no_show_guests": {
        "type": "boolean",
        "description": "Online, a guest who has a `no_show` reservation in the account (by phone or e-mail) pays the deposit even\nwhen `mode` would not ask for it.\n",
        "x-description-cs": "Online zaplatí zálohu host, který má v účtu rezervaci `no_show` (podle telefonu nebo e-mailu), i když by\nji `mode` nechtěl.\n"
       }
      }
     },
     "reminders": {
      "type": "object",
      "required": [
       "email_hours",
       "sms_hours"
      ],
      "properties": {
       "email_hours": {
        "type": "integer",
        "description": "E-mail reminder to online guests this many hours before; 0 = off.",
        "x-description-cs": "Připomínka e-mailem online hostům tolik hodin předem; 0 = vypnutá."
       },
       "sms_hours": {
        "type": "integer",
        "description": "SMS reminder to confirmed reservations with a Czech mobile this many hours before; 0 = off.",
        "x-description-cs": "SMS připomínka potvrzeným rezervacím s českým mobilem tolik hodin předem; 0 = vypnutá."
       }
      }
     },
     "feedback_enabled": {
      "type": "boolean",
      "description": "Guests are asked for a rating after the visit (`listReservationFeedback`).",
      "x-description-cs": "Hosté jsou po návštěvě požádáni o hodnocení (`listReservationFeedback`)."
     },
     "guest_max_moves": {
      "type": "integer",
      "description": "How many times a guest may move the reservation online with the link from the e-mail; then by phone.",
      "x-description-cs": "Kolikrát smí host rezervaci přesunout online odkazem z e-mailu; pak telefonicky.",
      "examples": [
       3
      ]
     }
    }
   },
   "ReservationStats": {
    "type": "object",
    "required": [
     "from",
     "to",
     "reservations",
     "guests",
     "arrived",
     "arrived_guests",
     "no_show",
     "no_show_rate",
     "cancelled",
     "rejected",
     "expired",
     "upcoming",
     "unresolved",
     "avg_party_size",
     "avg_lead_days",
     "returning_guests",
     "sources",
     "weekdays",
     "hours",
     "deposits",
     "ratings",
     "services",
     "employees",
     "table_turn"
    ],
    "properties": {
     "from": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "to": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "reservations": {
      "type": "integer",
      "description": "Reservations starting in the period, blocked tables excluded.",
      "x-description-cs": "Rezervace začínající v období, bez blokací stolů."
     },
     "guests": {
      "type": "integer",
      "description": "Guests of reservations that came, are coming, or did not show up.",
      "x-description-cs": "Hosté rezervací, které přišly, přijdou, nebo nepřišly."
     },
     "arrived": {
      "type": "integer"
     },
     "arrived_guests": {
      "type": "integer"
     },
     "no_show": {
      "type": "integer"
     },
     "no_show_rate": {
      "type": "number",
      "description": "`no_show` of (`arrived` + `no_show`) in percent, one decimal place.",
      "x-description-cs": "`no_show` z (`arrived` + `no_show`) v procentech, na jedno desetinné místo."
     },
     "cancelled": {
      "type": "integer"
     },
     "rejected": {
      "type": "integer"
     },
     "expired": {
      "type": "integer"
     },
     "upcoming": {
      "type": "integer"
     },
     "unresolved": {
      "type": "integer",
      "description": "Past reservations nobody marked as seated, left, or no-show.",
      "x-description-cs": "Minulé rezervace, které nikdo neoznačil jako usazené, odešlé ani nepřišlé."
     },
     "avg_party_size": {
      "type": "number"
     },
     "avg_lead_days": {
      "type": "number",
      "description": "How many days ahead guests book, on average.",
      "x-description-cs": "Kolik dní dopředu se v průměru rezervuje."
     },
     "returning_guests": {
      "type": "integer",
      "description": "Guests (by phone or e-mail) with more than one reservation in the period.",
      "x-description-cs": "Hosté (podle telefonu nebo e-mailu) s víc než jednou rezervací v období."
     },
     "sources": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "source",
        "count"
       ],
       "properties": {
        "source": {
         "type": "string",
         "x-extensible-enum": [
          "admin",
          "pos",
          "online",
          "phone",
          "api"
         ]
        },
        "count": {
         "type": "integer"
        }
       }
      }
     },
     "weekdays": {
      "type": "array",
      "description": "Guests by weekday, Monday first (7 items).",
      "x-description-cs": "Hosté podle dne v týdnu od pondělí (7 položek).",
      "items": {
       "type": "integer"
      }
     },
     "hours": {
      "type": "array",
      "description": "Guests by the hour of arrival.",
      "x-description-cs": "Hosté podle hodiny příchodu.",
      "items": {
       "type": "object",
       "required": [
        "hour",
        "guests"
       ],
       "properties": {
        "hour": {
         "type": "integer",
         "minimum": 0,
         "maximum": 23
        },
        "guests": {
         "type": "integer"
        }
       }
      }
     },
     "deposits": {
      "type": "object",
      "required": [
       "paid",
       "refunded",
       "forfeited"
      ],
      "properties": {
       "paid": {
        "$ref": "#/components/schemas/Money"
       },
       "refunded": {
        "$ref": "#/components/schemas/Money"
       },
       "forfeited": {
        "$ref": "#/components/schemas/Money"
       }
      }
     },
     "ratings": {
      "type": "object",
      "required": [
       "count",
       "average",
       "low"
      ],
      "properties": {
       "count": {
        "type": "integer"
       },
       "average": {
        "type": [
         "number",
         "null"
        ]
       },
       "low": {
        "type": "integer",
        "description": "Ratings of 1–3 stars.",
        "x-description-cs": "Hodnocení 1–3 hvězdičky."
       }
      }
     },
     "services": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "service_id",
        "name",
        "count"
       ],
       "properties": {
        "service_id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string"
        },
        "count": {
         "type": "integer"
        }
       }
      }
     },
     "employees": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "employee_id",
        "name",
        "count"
       ],
       "properties": {
        "employee_id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string"
        },
        "count": {
         "type": "integer"
        }
       }
      }
     },
     "table_turn": {
      "type": "object",
      "description": "How long guests really sit at a table – from seating to leaving, 10 to 600 minutes.",
      "x-description-cs": "Skutečná doba u stolu – od usazení do odchodu, 10 až 600 minut.",
      "required": [
       "measured",
       "groups",
       "suggestions"
      ],
      "properties": {
       "measured": {
        "type": "integer"
       },
       "groups": {
        "type": "array",
        "description": "One per row of `ReservationSettings.table_durations`.",
        "x-description-cs": "Jedna na řádek `ReservationSettings.table_durations`.",
        "items": {
         "type": "object",
         "required": [
          "up_to_party_size",
          "planned_minutes",
          "measured",
          "median_minutes"
         ],
         "properties": {
          "up_to_party_size": {
           "type": "integer"
          },
          "planned_minutes": {
           "type": "integer"
          },
          "measured": {
           "type": "integer"
          },
          "median_minutes": {
           "type": [
            "integer",
            "null"
           ]
          }
         }
        }
       },
       "suggestions": {
        "type": "array",
        "items": {
         "type": "object",
         "required": [
          "up_to_party_size",
          "planned_minutes",
          "median_minutes",
          "suggested_minutes",
          "measured"
         ],
         "properties": {
          "up_to_party_size": {
           "type": "integer"
          },
          "planned_minutes": {
           "type": "integer"
          },
          "median_minutes": {
           "type": "integer"
          },
          "suggested_minutes": {
           "type": "integer",
           "description": "The median rounded to 15 minutes.",
           "x-description-cs": "Medián zaokrouhlený na 15 minut."
          },
          "measured": {
           "type": "integer"
          }
         }
        }
       }
      }
     }
    }
   },
   "ReservationServiceList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/ReservationService"
      }
     }
    }
   },
   "ReservationService": {
    "type": "object",
    "required": [
     "id",
     "name",
     "category",
     "description",
     "duration_minutes",
     "buffer_minutes",
     "price",
     "max_party_size",
     "online",
     "staff"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "Pánský střih"
      ]
     },
     "category": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "Vlasy"
      ]
     },
     "description": {
      "type": [
       "string",
       "null"
      ]
     },
     "duration_minutes": {
      "type": "integer",
      "examples": [
       30
      ]
     },
     "buffer_minutes": {
      "type": "integer",
      "description": "Preparation after the service – the employee is busy until then.",
      "x-description-cs": "Příprava po službě – do té doby má pracovník obsazeno.",
      "examples": [
       10
      ]
     },
     "price": {
      "$ref": "#/components/schemas/Money"
     },
     "max_party_size": {
      "type": "integer",
      "examples": [
       1
      ]
     },
     "online": {
      "type": "boolean",
      "description": "Guests may book it online.",
      "x-description-cs": "Hosté si ji mohou rezervovat online."
     },
     "staff": {
      "type": "array",
      "description": "Employees who do it.",
      "x-description-cs": "Pracovníci, kteří ji dělají.",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "examples": [
          "Pavla Horáková"
         ]
        }
       }
      }
     }
    }
   },
   "ReservationAvailability": {
    "type": "object",
    "required": [
     "date",
     "slots"
    ],
    "properties": {
     "date": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "slots": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "starts_at",
        "available",
        "reason",
        "table_ids",
        "employee_id"
       ],
       "properties": {
        "starts_at": {
         "$ref": "#/components/schemas/Timestamp"
        },
        "available": {
         "type": "boolean"
        },
        "reason": {
         "type": [
          "string",
          "null"
         ],
         "description": "Why not – `no_table`, `table_unavailable`, `employee_unavailable`, `resource_unavailable`, `pacing` (too many guests arrive then), `outside_hours`, `closed`.",
         "x-description-cs": "Proč ne – `no_table`, `table_unavailable`, `employee_unavailable`, `resource_unavailable`, `pacing` (v tu dobu přichází příliš hostů), `outside_hours`, `closed`."
        },
        "table_ids": {
         "type": "array",
         "description": "Tables the reservation would get.",
         "x-description-cs": "Stoly, které by rezervace dostala.",
         "items": {
          "$ref": "#/components/schemas/Id"
         }
        },
        "employee_id": {
         "description": "The employee the service would get.",
         "x-description-cs": "Pracovník, který by službu dostal.",
         "anyOf": [
          {
           "$ref": "#/components/schemas/Id"
          },
          {
           "type": "null"
          }
         ]
        }
       }
      }
     }
    }
   },
   "TableStatus": {
    "type": "object",
    "required": [
     "at",
     "tables"
    ],
    "properties": {
     "at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "tables": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name",
        "room",
        "seats_min",
        "seats_max",
        "state",
        "tab_id",
        "reservation_id",
        "next_reservation"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "examples": [
          "Stůl 4"
         ]
        },
        "room": {
         "type": "string",
         "examples": [
          "Hlavní sál"
         ]
        },
        "seats_min": {
         "type": [
          "integer",
          "null"
         ],
         "description": "`null` – the table is not reserved.",
         "x-description-cs": "`null` – stůl se nerezervuje."
        },
        "seats_max": {
         "type": [
          "integer",
          "null"
         ]
        },
        "state": {
         "type": "string",
         "x-extensible-enum": [
          "free",
          "reserved",
          "occupied"
         ],
         "examples": [
          "reserved"
         ]
        },
        "tab_id": {
         "type": [
          "string",
          "null"
         ],
         "description": "The open tab of the table (`Tab.id`).",
         "x-description-cs": "Otevřený účet stolu (`Tab.id`)."
        },
        "reservation_id": {
         "description": "The reservation holding the table now.",
         "x-description-cs": "Rezervace, která stůl teď drží.",
         "anyOf": [
          {
           "$ref": "#/components/schemas/Id"
          },
          {
           "type": "null"
          }
         ]
        },
        "next_reservation": {
         "description": "The next reservation of the day.",
         "x-description-cs": "Další rezervace dne.",
         "anyOf": [
          {
           "type": "object",
           "required": [
            "id",
            "starts_at",
            "party_size"
           ],
           "properties": {
            "id": {
             "$ref": "#/components/schemas/Id"
            },
            "starts_at": {
             "$ref": "#/components/schemas/Timestamp"
            },
            "party_size": {
             "type": "integer"
            }
           }
          },
          {
           "type": "null"
          }
         ]
        }
       }
      }
     }
    }
   },
   "LodgingStats": {
    "type": "object",
    "required": [
     "from",
     "to",
     "kpi",
     "previous",
     "days",
     "room_types",
     "sources",
     "countries",
     "ages",
     "services",
     "packages",
     "guest_pass_entries",
     "reviews"
    ],
    "properties": {
     "from": {
      "type": "string",
      "format": "date"
     },
     "to": {
      "type": "string",
      "format": "date"
     },
     "kpi": {
      "$ref": "#/components/schemas/LodgingStatsKpi"
     },
     "previous": {
      "description": "The same period a year before.",
      "x-description-cs": "Stejné období o rok dřív.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/LodgingStatsKpi"
       },
       {
        "type": "null"
       }
      ]
     },
     "days": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "date",
        "sold",
        "tentative",
        "occupancy",
        "arrivals",
        "departures",
        "revenue"
       ],
       "properties": {
        "date": {
         "type": "string",
         "format": "date"
        },
        "sold": {
         "type": "integer",
         "examples": [
          7
         ]
        },
        "tentative": {
         "type": "integer",
         "examples": [
          1
         ]
        },
        "occupancy": {
         "type": "number",
         "examples": [
          70
         ]
        },
        "arrivals": {
         "type": "integer",
         "examples": [
          2
         ]
        },
        "departures": {
         "type": "integer",
         "examples": [
          1
         ]
        },
        "revenue": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "room_types": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name",
        "rooms",
        "nights",
        "occupancy",
        "adr",
        "revenue"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "examples": [
          "Dvoulůžkový"
         ]
        },
        "rooms": {
         "type": "integer",
         "examples": [
          6
         ]
        },
        "nights": {
         "type": "integer",
         "examples": [
          96
         ]
        },
        "occupancy": {
         "type": "number",
         "examples": [
          53.3
         ]
        },
        "adr": {
         "$ref": "#/components/schemas/Money"
        },
        "revenue": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "sources": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "source",
        "stays",
        "nights",
        "revenue"
       ],
       "properties": {
        "source": {
         "type": "string",
         "x-extensible-enum": [
          "admin",
          "phone",
          "email",
          "online",
          "api",
          "channel"
         ],
         "examples": [
          "online"
         ]
        },
        "stays": {
         "type": "integer",
         "examples": [
          12
         ]
        },
        "nights": {
         "type": "integer",
         "examples": [
          31
         ]
        },
        "revenue": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "countries": {
      "type": "array",
      "description": "By guest nights; `country` `null` – guests not in the register.",
      "x-description-cs": "Podle přenocování; `country` `null` – hosté nejsou v evidenci.",
      "items": {
       "type": "object",
       "required": [
        "country",
        "guests",
        "nights"
       ],
       "properties": {
        "country": {
         "type": [
          "string",
          "null"
         ],
         "examples": [
          "DE"
         ]
        },
        "guests": {
         "type": "integer",
         "examples": [
          9
         ]
        },
        "nights": {
         "type": "integer",
         "examples": [
          21
         ]
        }
       }
      }
     },
     "ages": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "group",
        "guests",
        "nights"
       ],
       "properties": {
        "group": {
         "type": [
          "string",
          "null"
         ],
         "description": "`0-17`, `18-29`, `30-44`, `45-59`, `60+`; `null` – unknown.",
         "x-description-cs": "`0-17`, `18-29`, `30-44`, `45-59`, `60+`; `null` – neuvedeno.",
         "examples": [
          "30-44"
         ]
        },
        "guests": {
         "type": "integer",
         "examples": [
          7
         ]
        },
        "nights": {
         "type": "integer",
         "examples": [
          16
         ]
        }
       }
      }
     },
     "services": {
      "type": "array",
      "description": "Services and charges on room accounts by category, in the same share as the accommodation.",
      "x-description-cs": "Služby a útraty na účtech pokojů podle druhu, stejným dílem jako ubytování.",
      "items": {
       "type": "object",
       "required": [
        "category",
        "revenue"
       ],
       "properties": {
        "category": {
         "type": "string",
         "x-extensible-enum": [
          "breakfast",
          "board",
          "extra_bed",
          "drink",
          "food",
          "wellness",
          "parking",
          "other"
         ],
         "examples": [
          "breakfast"
         ]
        },
        "revenue": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "packages": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name",
        "stays",
        "revenue"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "examples": [
          "3 + 1 noc zdarma s wellness"
         ]
        },
        "stays": {
         "type": "integer",
         "examples": [
          3
         ]
        },
        "revenue": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "guest_pass_entries": {
      "type": "array",
      "description": "Entries recorded through the guest's QR code.",
      "x-description-cs": "Vstupy zapsané přes QR kód hosta.",
      "items": {
       "type": "object",
       "required": [
        "place",
        "entries"
       ],
       "properties": {
        "place": {
         "type": "string",
         "x-extensible-enum": [
          "wellness",
          "breakfast",
          "board",
          "parking"
         ],
         "examples": [
          "wellness"
         ]
        },
        "entries": {
         "type": "integer",
         "examples": [
          42
         ]
        }
       }
      }
     },
     "reviews": {
      "anyOf": [
       {
        "type": "object",
        "required": [
         "count",
         "average"
        ],
        "properties": {
         "count": {
          "type": "integer",
          "examples": [
           5
          ]
         },
         "average": {
          "type": [
           "number",
           "null"
          ],
          "examples": [
           4.6
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "LodgingStatsKpi": {
    "type": "object",
    "required": [
     "rooms",
     "days",
     "available_nights",
     "sold_nights",
     "tentative_nights",
     "occupancy",
     "revenue",
     "services_revenue",
     "adr",
     "revpar",
     "guest_nights",
     "guests",
     "stays",
     "avg_length",
     "avg_lead_days",
     "cancelled",
     "no_show",
     "cancel_rate"
    ],
    "properties": {
     "rooms": {
      "type": "integer",
      "examples": [
       10
      ]
     },
     "days": {
      "type": "integer",
      "examples": [
       30
      ]
     },
     "available_nights": {
      "type": "integer",
      "examples": [
       300
      ]
     },
     "sold_nights": {
      "type": "integer",
      "examples": [
       184
      ]
     },
     "tentative_nights": {
      "type": "integer",
      "examples": [
       3
      ]
     },
     "occupancy": {
      "type": "number",
      "description": "Percent.",
      "x-description-cs": "Procenta.",
      "examples": [
       61.3
      ]
     },
     "revenue": {
      "description": "Accommodation revenue of the nights in the period.",
      "x-description-cs": "Tržba za ubytování nocí v období.",
      "$ref": "#/components/schemas/Money"
     },
     "services_revenue": {
      "$ref": "#/components/schemas/Money"
     },
     "adr": {
      "description": "Average daily rate – revenue per sold night.",
      "x-description-cs": "Průměrná cena za prodanou noc.",
      "$ref": "#/components/schemas/Money"
     },
     "revpar": {
      "description": "Revenue per available room night.",
      "x-description-cs": "Tržba na dostupnou noc pokoje.",
      "$ref": "#/components/schemas/Money"
     },
     "guest_nights": {
      "type": "integer",
      "examples": [
       352
      ]
     },
     "guests": {
      "type": "integer",
      "examples": [
       131
      ]
     },
     "stays": {
      "type": "integer",
      "examples": [
       68
      ]
     },
     "avg_length": {
      "type": "number",
      "examples": [
       2.7
      ]
     },
     "avg_lead_days": {
      "type": "number",
      "examples": [
       18.5
      ]
     },
     "cancelled": {
      "type": "integer",
      "examples": [
       4
      ]
     },
     "no_show": {
      "type": "integer",
      "examples": [
       1
      ]
     },
     "cancel_rate": {
      "type": "number",
      "description": "Cancelled and no-show stays in percent of booked stays arriving in the period.",
      "x-description-cs": "Zrušené a nepřijeté pobyty v procentech rezervovaných s příjezdem v období.",
      "examples": [
       6.8
      ]
     }
    }
   },
   "LodgingReviewList": {
    "type": "object",
    "required": [
     "summary",
     "data"
    ],
    "properties": {
     "summary": {
      "type": "object",
      "required": [
       "count",
       "average",
       "unanswered",
       "low_unanswered",
       "distribution",
       "sources",
       "categories"
      ],
      "properties": {
       "count": {
        "type": "integer",
        "examples": [
         8
        ]
       },
       "average": {
        "type": [
         "number",
         "null"
        ],
        "description": "1–5; `null` without reviews.",
        "x-description-cs": "1–5; `null` bez recenzí.",
        "examples": [
         4.3
        ]
       },
       "unanswered": {
        "type": "integer",
        "examples": [
         6
        ]
       },
       "low_unanswered": {
        "type": "integer",
        "description": "Up to 3 stars without a reply.",
        "x-description-cs": "Do 3 hvězdiček bez odpovědi.",
        "examples": [
         1
        ]
       },
       "distribution": {
        "type": "array",
        "description": "Counts of 1 to 5 stars (rounded), index 0 = 1 star.",
        "x-description-cs": "Počty 1 až 5 hvězdiček (zaokrouhleně), index 0 = 1 hvězdička.",
        "items": {
         "type": "integer"
        },
        "examples": [
         [
          0,
          1,
          0,
          2,
          5
         ]
        ]
       },
       "sources": {
        "type": "array",
        "items": {
         "type": "object",
         "required": [
          "source",
          "count",
          "average"
         ],
         "properties": {
          "source": {
           "type": "string",
           "examples": [
            "booking"
           ]
          },
          "count": {
           "type": "integer",
           "examples": [
            2
           ]
          },
          "average": {
           "type": "number",
           "examples": [
            4.4
           ]
          }
         }
        }
       },
       "categories": {
        "type": "array",
        "items": {
         "type": "object",
         "required": [
          "key",
          "average",
          "count"
         ],
         "properties": {
          "key": {
           "type": "string",
           "x-extensible-enum": [
            "cleanliness",
            "staff",
            "comfort",
            "location",
            "breakfast",
            "value"
           ],
           "examples": [
            "cleanliness"
           ]
          },
          "average": {
           "type": "number",
           "examples": [
            4.5
           ]
          },
          "count": {
           "type": "integer",
           "examples": [
            6
           ]
          }
         }
        }
       }
      }
     },
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/LodgingReview"
      }
     }
    }
   },
   "LodgingReview": {
    "type": "object",
    "required": [
     "id",
     "stay_id",
     "source",
     "rating",
     "categories",
     "comment",
     "guest_name",
     "country",
     "date",
     "public",
     "reply",
     "replied_at",
     "reply_sent",
     "link"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "stay_id": {
      "description": "The stay of a guest's rating; `null` for portals.",
      "x-description-cs": "Pobyt u hodnocení hosta; `null` u portálů.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "source": {
      "type": "string",
      "x-extensible-enum": [
       "direct",
       "booking",
       "google",
       "airbnb",
       "tripadvisor",
       "other"
      ],
      "examples": [
       "direct"
      ]
     },
     "rating": {
      "type": "number",
      "description": "1–5 (Booking 1–10 is divided by two).",
      "x-description-cs": "1–5 (Booking 1–10 se dělí dvěma).",
      "examples": [
       5
      ]
     },
     "categories": {
      "type": "object",
      "description": "Sub-ratings 1–5 – `cleanliness`, `staff`, `comfort`, `location`, `breakfast`, `value`.",
      "x-description-cs": "Dílčí hodnocení 1–5 – `cleanliness`, `staff`, `comfort`, `location`, `breakfast`, `value`.",
      "additionalProperties": {
       "type": "integer"
      },
      "examples": [
       {
        "cleanliness": 5,
        "staff": 4
       }
      ]
     },
     "comment": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "Krásný pokoj, výborné snídaně."
      ]
     },
     "guest_name": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "Jana S."
      ]
     },
     "country": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "SK"
      ]
     },
     "date": {
      "type": [
       "string",
       "null"
      ],
      "format": "date",
      "description": "The departure / the date of the review on the portal.",
      "x-description-cs": "Den odjezdu / datum recenze na portálu."
     },
     "public": {
      "type": "boolean",
      "description": "Shown on the booking page (the guest agreed and the restaurant did not hide it).",
      "x-description-cs": "Ukazuje se na stránce rezervace (host souhlasil a provozovna ji neskryla)."
     },
     "reply": {
      "type": [
       "string",
       "null"
      ]
     },
     "replied_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "reply_sent": {
      "type": "boolean",
      "description": "The reply went to the guest by e-mail.",
      "x-description-cs": "Odpověď odešla hostovi e-mailem."
     },
     "link": {
      "type": [
       "string",
       "null"
      ],
      "description": "The review on the portal.",
      "x-description-cs": "Recenze na portálu."
     }
    }
   },
   "LodgingReviewReplyInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "reply"
    ],
    "properties": {
     "reply": {
      "type": "string",
      "minLength": 1,
      "maxLength": 3000,
      "examples": [
       "Děkujeme za krásné hodnocení, těšíme se na příště!"
      ]
     },
     "send_to_guest": {
      "type": "boolean",
      "default": false,
      "description": "Also e-mail it to the guest (ratings of guests only).",
      "x-description-cs": "Poslat ji i hostovi e-mailem (jen u hodnocení hostů)."
     }
    }
   },
   "LodgingPackageList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/LodgingPackage"
      }
     }
    }
   },
   "LodgingPackage": {
    "type": "object",
    "required": [
     "id",
     "name",
     "description",
     "room_type_ids",
     "min_nights",
     "pay_nights",
     "free_nights",
     "discount_percent",
     "price_extra",
     "services",
     "valid_from",
     "valid_to",
     "online"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "3 + 1 noc zdarma s wellness"
      ]
     },
     "description": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "Čtvrtou noc máte od nás. Wellness bez omezení a snídaně v ceně."
      ]
     },
     "room_type_ids": {
      "type": "array",
      "description": "Room types the package is for; empty – all.",
      "x-description-cs": "Typy pokojů, pro které balíček je; prázdné – všechny.",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "min_nights": {
      "type": "integer",
      "examples": [
       4
      ]
     },
     "pay_nights": {
      "type": "integer",
      "description": "Paid nights of the rule „pay X, get Y free“; 0 – no free nights.",
      "x-description-cs": "Placené noci pravidla „X placených, Y zdarma“; 0 – bez nocí zdarma.",
      "examples": [
       3
      ]
     },
     "free_nights": {
      "type": "integer",
      "examples": [
       1
      ]
     },
     "discount_percent": {
      "type": "number",
      "examples": [
       0
      ]
     },
     "price_extra": {
      "description": "A surcharge per stay.",
      "x-description-cs": "Příplatek za pobyt.",
      "$ref": "#/components/schemas/Money"
     },
     "services": {
      "type": "array",
      "description": "Services included in the price (they go to the account of the room for 0).",
      "x-description-cs": "Služby v ceně (jdou na účet pokoje za 0).",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name",
        "category"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "examples": [
          "Snídaně"
         ]
        },
        "category": {
         "type": "string",
         "x-extensible-enum": [
          "breakfast",
          "board",
          "extra_bed",
          "drink",
          "food",
          "wellness",
          "parking",
          "other"
         ],
         "examples": [
          "breakfast"
         ]
        }
       }
      }
     },
     "valid_from": {
      "type": [
       "string",
       "null"
      ],
      "format": "date",
      "description": "For arrivals from.",
      "x-description-cs": "Pro příjezdy od."
     },
     "valid_to": {
      "type": [
       "string",
       "null"
      ],
      "format": "date"
     },
     "online": {
      "type": "boolean"
     }
    }
   },
   "GuestPassCheckInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "code",
     "place"
    ],
    "properties": {
     "code": {
      "type": "string",
      "maxLength": 40,
      "description": "The text of the QR code (`PRU-{stay}-{signature}`).",
      "x-description-cs": "Text QR kódu (`PRU-{pobyt}-{podpis}`).",
      "examples": [
       "PRU-300-3EE8T62F7H"
      ]
     },
     "place": {
      "type": "string",
      "enum": [
       "wellness",
       "breakfast",
       "board",
       "parking"
      ],
      "examples": [
       "wellness"
      ]
     },
     "persons": {
      "type": "integer",
      "minimum": 1,
      "maximum": 20,
      "default": 1,
      "description": "How many persons go in at once.",
      "x-description-cs": "Kolik osob vstupuje najednou."
     },
     "record": {
      "type": "boolean",
      "default": true,
      "description": "`false` – only check, do not record the entry.",
      "x-description-cs": "`false` – jen ověřit, vstup nezapsat."
     },
     "device": {
      "type": "string",
      "maxLength": 60,
      "description": "Where it was read.",
      "x-description-cs": "Kde se četlo.",
      "examples": [
       "Vstup do wellness"
      ]
     }
    }
   },
   "GuestPassCheck": {
    "type": "object",
    "required": [
     "result",
     "title",
     "text",
     "check_id",
     "stay",
     "used_today",
     "allowed_today"
    ],
    "properties": {
     "result": {
      "type": "string",
      "x-extensible-enum": [
       "ok",
       "denied"
      ],
      "examples": [
       "ok"
      ]
     },
     "title": {
      "type": "string",
      "description": "A short headline for the reader's screen.",
      "x-description-cs": "Krátký nadpis pro displej čtečky.",
      "examples": [
       "Pokoj 201 · 2 osoby"
      ]
     },
     "text": {
      "type": "string",
      "examples": [
       "Wellness neomezeně do 5. 11."
      ]
     },
     "check_id": {
      "description": "The recorded entry (for `undoGuestPassCheck`); `null` when nothing was recorded.",
      "x-description-cs": "Zapsaný vstup (pro `undoGuestPassCheck`); `null`, když se nic nezapsalo.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "stay": {
      "description": "The stay of the code; `null` for an unknown code.",
      "x-description-cs": "Pobyt kódu; `null` u neznámého kódu.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "id",
         "room",
         "persons",
         "arrival",
         "departure",
         "package"
        ],
        "properties": {
         "id": {
          "$ref": "#/components/schemas/Id"
         },
         "room": {
          "type": "string",
          "examples": [
           "201"
          ]
         },
         "persons": {
          "type": "integer",
          "examples": [
           2
          ]
         },
         "arrival": {
          "type": "string",
          "format": "date"
         },
         "departure": {
          "type": "string",
          "format": "date"
         },
         "package": {
          "type": [
           "string",
           "null"
          ],
          "examples": [
           "3 + 1 noc zdarma s wellness"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "used_today": {
      "type": "integer",
      "examples": [
       2
      ]
     },
     "allowed_today": {
      "type": [
       "integer",
       "null"
      ],
      "description": "The limit of the day; `null` – unlimited or counted per stay.",
      "x-description-cs": "Limit dne; `null` – neomezeně nebo za celý pobyt."
     }
    }
   },
   "LodgingRooms": {
    "type": "object",
    "required": [
     "room_types",
     "rooms"
    ],
    "properties": {
     "room_types": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/LodgingRoomType"
      }
     },
     "rooms": {
      "type": "array",
      "description": "In the order of the occupancy plan – by the type (`sort`), then by the room (`sort`, name).",
      "x-description-cs": "V pořadí plánu obsazenosti – podle typu (`sort`), pak podle pokoje (`sort`, název).",
      "items": {
       "$ref": "#/components/schemas/LodgingRoom"
      }
     }
    }
   },
   "LodgingRoomType": {
    "type": "object",
    "required": [
     "id",
     "name",
     "description",
     "beds",
     "extra_beds",
     "price_night",
     "price_extra_bed",
     "min_nights",
     "online",
     "sort"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "Dvoulůžkový"
      ]
     },
     "description": {
      "type": [
       "string",
       "null"
      ]
     },
     "beds": {
      "type": "integer",
      "description": "Fixed beds.",
      "x-description-cs": "Pevná lůžka.",
      "examples": [
       2
      ]
     },
     "extra_beds": {
      "type": "integer",
      "description": "Extra beds the room can take above `beds`.",
      "x-description-cs": "Kolik přistýlek se vejde nad `beds`.",
      "examples": [
       1
      ]
     },
     "price_night": {
      "$ref": "#/components/schemas/Money"
     },
     "price_extra_bed": {
      "$ref": "#/components/schemas/Money"
     },
     "min_nights": {
      "type": "integer",
      "examples": [
       1
      ]
     },
     "online": {
      "type": "boolean",
      "description": "Guests can book the type online.",
      "x-description-cs": "Typ jde rezervovat online."
     },
     "sort": {
      "type": "integer",
      "examples": [
       1
      ]
     }
    }
   },
   "LodgingRoom": {
    "type": "object",
    "required": [
     "id",
     "type_id",
     "name",
     "floor",
     "sort",
     "status",
     "note",
     "open_issues"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "type_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "104"
      ]
     },
     "floor": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "1"
      ]
     },
     "sort": {
      "type": "integer",
      "examples": [
       4
      ]
     },
     "status": {
      "type": "string",
      "description": "`clean`, `dirty` (to be cleaned), `inspected`, `out_of_order` (cannot be booked).",
      "x-description-cs": "`clean` uklizený, `dirty` k úklidu, `inspected` zkontrolovaný, `out_of_order` mimo provoz (nejde rezervovat).",
      "x-extensible-enum": [
       "clean",
       "dirty",
       "inspected",
       "out_of_order"
      ],
      "examples": [
       "clean"
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "open_issues": {
      "type": "integer",
      "description": "Faults of the room not fixed yet (`listRoomIssues`).",
      "x-description-cs": "Neopravené závady pokoje (`listRoomIssues`).",
      "examples": [
       0
      ]
     }
    }
   },
   "LodgingStayList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/LodgingStay"
      }
     }
    }
   },
   "LodgingStay": {
    "type": "object",
    "required": [
     "id",
     "uuid",
     "status",
     "source",
     "arrival",
     "departure",
     "nights",
     "adults",
     "children",
     "rooms",
     "price_total",
     "price_manual",
     "package",
     "guest",
     "company",
     "note_guest",
     "note_internal",
     "tags",
     "registered_guests",
     "deposit",
     "channel",
     "cancel_reason",
     "checked_in_at",
     "checked_out_at",
     "actions",
     "balance",
     "version",
     "created_at",
     "updated_at"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "uuid": {
      "type": "string",
      "format": "uuid"
     },
     "status": {
      "type": "string",
      "description": "`tentative` (not confirmed yet), `confirmed`, `checked_in` (the guests are staying), `checked_out` (left),\n`cancelled`, `no_show` (did not come).\n",
      "x-description-cs": "`tentative` předběžný (nepotvrzený), `confirmed` potvrzený, `checked_in` ubytovaný, `checked_out` odjel,\n`cancelled` zrušený, `no_show` nepřijel.\n",
      "x-extensible-enum": [
       "tentative",
       "confirmed",
       "checked_in",
       "checked_out",
       "cancelled",
       "no_show"
      ],
      "examples": [
       "confirmed"
      ]
     },
     "source": {
      "type": "string",
      "description": "Where the stay came from: `admin` (the reception), `phone`, `email`, `online` (the booking page of the\nrestaurant), `api` (an application), `channel` (a portal such as Booking.com or Airbnb – see `channel`).\n",
      "x-description-cs": "Odkud pobyt přišel: `admin` (recepce), `phone` telefon, `email` e-mail, `online` (rezervační stránka\nprovozovny), `api` (aplikace), `channel` (portál jako Booking.com nebo Airbnb – viz `channel`).\n",
      "x-extensible-enum": [
       "admin",
       "phone",
       "email",
       "online",
       "api",
       "channel"
      ],
      "examples": [
       "phone"
      ]
     },
     "arrival": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "departure": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "nights": {
      "type": "integer",
      "examples": [
       2
      ]
     },
     "adults": {
      "type": "integer",
      "examples": [
       2
      ]
     },
     "children": {
      "type": "integer",
      "examples": [
       0
      ]
     },
     "rooms": {
      "type": "array",
      "description": "Parts of the stay by room, by date (a guest who moves has more). `date_to` is the morning the guest leaves\nthe room.\n",
      "x-description-cs": "Úseky pobytu po pokojích podle data (host, který se stěhuje, jich má víc). `date_to` je ráno, kdy host pokoj\nopouští.\n",
      "items": {
       "type": "object",
       "required": [
        "room_id",
        "room",
        "type_id",
        "type",
        "date_from",
        "date_to"
       ],
       "properties": {
        "room_id": {
         "$ref": "#/components/schemas/Id"
        },
        "room": {
         "type": "string",
         "examples": [
          "104"
         ]
        },
        "type_id": {
         "$ref": "#/components/schemas/Id"
        },
        "type": {
         "type": "string",
         "examples": [
          "Dvoulůžkový"
         ]
        },
        "date_from": {
         "$ref": "#/components/schemas/LocalDate"
        },
        "date_to": {
         "$ref": "#/components/schemas/LocalDate"
        }
       }
      }
     },
     "price_total": {
      "$ref": "#/components/schemas/Money"
     },
     "price_manual": {
      "type": "boolean",
      "description": "The reception set the price by hand – the server does not count it again after changes.",
      "x-description-cs": "Cenu zadala recepce ručně – server ji po změnách znovu nepočítá."
     },
     "package": {
      "anyOf": [
       {
        "type": "object",
        "required": [
         "id",
         "name"
        ],
        "properties": {
         "id": {
          "$ref": "#/components/schemas/Id"
         },
         "name": {
          "type": "string",
          "examples": [
           "3 + 1 noc zdarma s wellness"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "guest": {
      "type": "object",
      "description": "The guest who booked (contact of the stay); the registered guests are in `getStay`.",
      "x-description-cs": "Host, který rezervoval (kontakt pobytu); zapsaní hosté jsou v `getStay`.",
      "required": [
       "name",
       "phone",
       "email",
       "lang"
      ],
      "properties": {
       "name": {
        "type": "string",
        "examples": [
         "Jana Svobodová"
        ]
       },
       "phone": {
        "type": [
         "string",
         "null"
        ],
        "examples": [
         "+420777123456"
        ]
       },
       "email": {
        "type": [
         "string",
         "null"
        ],
        "examples": [
         "jana@example.com"
        ]
       },
       "lang": {
        "type": "string",
        "examples": [
         "cs"
        ]
       }
      }
     },
     "company": {
      "type": [
       "string",
       "null"
      ]
     },
     "note_guest": {
      "type": [
       "string",
       "null"
      ],
      "description": "The guest's note.",
      "x-description-cs": "Poznámka hosta."
     },
     "note_internal": {
      "type": [
       "string",
       "null"
      ],
      "description": "The reception's note – never shown to the guest.",
      "x-description-cs": "Poznámka recepce – host ji nikdy neuvidí."
     },
     "tags": {
      "type": "array",
      "items": {
       "type": "string"
      }
     },
     "registered_guests": {
      "type": "integer",
      "description": "Guests registered with their documents (`getStay` lists them).",
      "x-description-cs": "Hosté zapsaní s doklady (`getStay` je vypíše).",
      "examples": [
       0
      ]
     },
     "deposit": {
      "type": "object",
      "required": [
       "amount",
       "status",
       "due_at"
      ],
      "properties": {
       "amount": {
        "$ref": "#/components/schemas/Money"
       },
       "status": {
        "type": "string",
        "description": "`none`, `pending` (waits for the payment), `paid`, `refunded`, `forfeited` (kept).",
        "x-description-cs": "`none` bez zálohy, `pending` čeká na zaplacení, `paid` zaplacená, `refunded` vrácená, `forfeited` propadla.",
        "x-extensible-enum": [
         "none",
         "pending",
         "paid",
         "refunded",
         "forfeited"
        ]
       },
       "due_at": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/Timestamp"
         },
         {
          "type": "null"
         }
        ]
       }
      }
     },
     "channel": {
      "description": "The portal of a stay with `source` `channel` and its booking number there.",
      "x-description-cs": "Portál pobytu se `source` `channel` a číslo rezervace na něm.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "name",
         "ref"
        ],
        "properties": {
         "name": {
          "type": "string",
          "examples": [
           "Booking.com"
          ]
         },
         "ref": {
          "type": "string",
          "examples": [
           "4218877310"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "cancel_reason": {
      "type": [
       "string",
       "null"
      ]
     },
     "checked_in_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "checked_out_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "actions": {
      "type": "array",
      "description": "Steps the server allows now: `confirm`, `check_in` (from the day of arrival), `check_out`, `cancel`,\n`no_show` (from the day of arrival). Other steps answer `409 stay_state_conflict`.\n",
      "x-description-cs": "Kroky, které server teď dovolí: `confirm` potvrdit, `check_in` ubytovat (ode dne příjezdu), `check_out`\nodhlásit, `cancel` zrušit, `no_show` nepřijel (ode dne příjezdu). Jiné kroky vrátí `409\nstay_state_conflict`.\n",
      "items": {
       "type": "string",
       "x-extensible-enum": [
        "confirm",
        "check_in",
        "check_out",
        "cancel",
        "no_show"
       ]
      },
      "examples": [
       [
        "check_in",
        "cancel"
       ]
      ]
     },
     "balance": {
      "description": "What is left to pay on the account of the room (since 26.11.22; negative when the guest paid more);\n`null` for a cancelled stay and a no-show.\n",
      "x-description-cs": "Co zbývá zaplatit na účtu pokoje (od 26.11.22; záporné při přeplatku); u zrušeného pobytu a nepřijetí\n`null`.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Money"
       },
       {
        "type": "null"
       }
      ]
     },
     "version": {
      "type": "integer",
      "description": "Grows with every change; the `ETag` of `getStay` is made of it.",
      "x-description-cs": "Roste s každou změnou; z ní je `ETag` u `getStay`.",
      "examples": [
       3
      ]
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "updated_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "LodgingStayDetail": {
    "type": "object",
    "required": [
     "stay",
     "balance",
     "guests",
     "receipt",
     "history"
    ],
    "properties": {
     "stay": {
      "$ref": "#/components/schemas/LodgingStay"
     },
     "balance": {
      "$ref": "#/components/schemas/Money"
     },
     "guests": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/LodgingGuest"
      }
     },
     "receipt": {
      "description": "The receipt for the stay (made at the departure from a settled account); `null` before it. A cancelled\nreceipt is not here.\n",
      "x-description-cs": "Doklad za pobyt (vzniká při odjezdu z vyrovnaného účtu); předtím `null`. Stornovaný doklad tu není.\n",
      "anyOf": [
       {
        "$ref": "#/components/schemas/LodgingReceipt"
       },
       {
        "type": "null"
       }
      ]
     },
     "history": {
      "type": "array",
      "description": "Changes of the stay, oldest first.",
      "x-description-cs": "Změny pobytu od nejstarší.",
      "items": {
       "type": "object",
       "required": [
        "at",
        "actor",
        "employee_id",
        "action",
        "from_status",
        "to_status"
       ],
       "properties": {
        "at": {
         "$ref": "#/components/schemas/Timestamp"
        },
        "actor": {
         "type": "string",
         "description": "`owner`, `employee`, `guest`, `api` (an application), `system`, `channel` (a portal).",
         "x-description-cs": "`owner` majitel, `employee` zaměstnanec, `guest` host, `api` aplikace, `system` systém, `channel` portál.",
         "x-extensible-enum": [
          "owner",
          "employee",
          "guest",
          "api",
          "system",
          "channel"
         ]
        },
        "employee_id": {
         "anyOf": [
          {
           "$ref": "#/components/schemas/Id"
          },
          {
           "type": "null"
          }
         ]
        },
        "action": {
         "type": "string",
         "x-extensible-enum": [
          "created",
          "updated",
          "moved",
          "confirmed",
          "checked_in",
          "checked_out",
          "cancelled",
          "no_show"
         ],
         "examples": [
          "checked_in"
         ]
        },
        "from_status": {
         "type": [
          "string",
          "null"
         ],
         "examples": [
          "confirmed"
         ]
        },
        "to_status": {
         "type": [
          "string",
          "null"
         ],
         "examples": [
          "checked_in"
         ]
        }
       }
      }
     }
    }
   },
   "LodgingGuest": {
    "type": "object",
    "description": "A guest registered with the stay (the guest book, the city tax, Ubyport for foreigners).",
    "x-description-cs": "Host zapsaný k pobytu (domovní kniha, poplatek z pobytu, Ubyport u cizinců).",
    "required": [
     "id",
     "first_name",
     "last_name",
     "birth_date",
     "nationality",
     "nationality_name",
     "foreigner",
     "document_type",
     "document_no",
     "visa_no",
     "address",
     "purpose",
     "arrival",
     "departure",
     "fee_exempt",
     "note",
     "ubyport"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "first_name": {
      "type": "string",
      "examples": [
       "Jana"
      ]
     },
     "last_name": {
      "type": "string",
      "examples": [
       "Svobodová"
      ]
     },
     "birth_date": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/LocalDate"
       },
       {
        "type": "null"
       }
      ]
     },
     "nationality": {
      "type": "string",
      "description": "ISO 3166-1 alpha-2.",
      "x-description-cs": "ISO 3166-1 alpha-2.",
      "examples": [
       "CZ"
      ]
     },
     "nationality_name": {
      "type": "string",
      "examples": [
       "Česko"
      ]
     },
     "foreigner": {
      "type": "boolean",
      "description": "Not a Czech citizen – reported to the foreign police (Ubyport).",
      "x-description-cs": "Není občan ČR – hlásí se cizinecké policii (Ubyport)."
     },
     "document_type": {
      "type": [
       "string",
       "null"
      ],
      "description": "`id` identity card, `passport`, `visa`, `residence` (residence permit), `other`.",
      "x-description-cs": "`id` občanský průkaz, `passport` pas, `visa` vízum, `residence` povolení k pobytu, `other` jiný.",
      "x-extensible-enum": [
       "id",
       "passport",
       "visa",
       "residence",
       "other"
      ]
     },
     "document_no": {
      "type": [
       "string",
       "null"
      ]
     },
     "visa_no": {
      "type": [
       "string",
       "null"
      ]
     },
     "address": {
      "type": [
       "string",
       "null"
      ]
     },
     "purpose": {
      "type": [
       "string",
       "null"
      ],
      "description": "The purpose of the stay (a code of the Ubyport list).",
      "x-description-cs": "Účel pobytu (kód číselníku Ubyportu)."
     },
     "arrival": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "departure": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "fee_exempt": {
      "type": [
       "string",
       "null"
      ],
      "description": "Why the guest does not pay the city tax; `null` pays.",
      "x-description-cs": "Proč host neplatí poplatek z pobytu; `null` platí."
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "ubyport": {
      "type": "object",
      "required": [
       "state",
       "sent_at",
       "error"
      ],
      "properties": {
       "state": {
        "type": "string",
        "description": "`none` (not reported – a Czech citizen), `pending` (waits for sending), `sent`, `error`.",
        "x-description-cs": "`none` nehlásí se (občan ČR), `pending` čeká na odeslání, `sent` odesláno, `error` chyba.",
        "x-extensible-enum": [
         "none",
         "pending",
         "sent",
         "error"
        ]
       },
       "sent_at": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/Timestamp"
         },
         {
          "type": "null"
         }
        ]
       },
       "error": {
        "type": [
         "string",
         "null"
        ]
       }
      }
     }
    }
   },
   "LodgingAvailability": {
    "type": "object",
    "required": [
     "arrival",
     "departure",
     "nights",
     "adults",
     "children",
     "room_types"
    ],
    "properties": {
     "arrival": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "departure": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "nights": {
      "type": "integer",
      "examples": [
       2
      ]
     },
     "adults": {
      "type": "integer",
      "examples": [
       2
      ]
     },
     "children": {
      "type": "integer",
      "examples": [
       0
      ]
     },
     "room_types": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "type_id",
        "name",
        "free_rooms",
        "quote",
        "unavailable",
        "message"
       ],
       "properties": {
        "type_id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "examples": [
          "Dvoulůžkový"
         ]
        },
        "free_rooms": {
         "type": "array",
         "description": "Free rooms of the type in the order of the plan; pick one for `room_id`, or send `room_type_id` and the server picks the first.",
         "x-description-cs": "Volné pokoje typu v pořadí plánu; jeden pošlete jako `room_id`, nebo pošlete `room_type_id` a server vybere první.",
         "items": {
          "type": "object",
          "required": [
           "id",
           "name"
          ],
          "properties": {
           "id": {
            "$ref": "#/components/schemas/Id"
           },
           "name": {
            "type": "string",
            "examples": [
             "104"
            ]
           }
          }
         }
        },
        "quote": {
         "description": "The price of the stay; `null` when the type cannot take the guests.",
         "x-description-cs": "Cena pobytu; `null`, když se hosté do typu nevejdou.",
         "anyOf": [
          {
           "$ref": "#/components/schemas/LodgingQuote"
          },
          {
           "type": "null"
          }
         ]
        },
        "unavailable": {
         "type": [
          "string",
          "null"
         ],
         "description": "Why the type cannot be booked: `no_room` (all rooms taken or out of order), `too_many_guests`, `package_not_applicable`; `null` = it can.",
         "x-description-cs": "Proč typ rezervovat nejde: `no_room` (všechny pokoje obsazené nebo mimo provoz), `too_many_guests` (hosté se nevejdou), `package_not_applicable` (balíček na typ nebo termín nejde); `null` = jde.",
         "x-extensible-enum": [
          "no_room",
          "too_many_guests",
          "package_not_applicable"
         ]
        },
        "message": {
         "type": [
          "string",
          "null"
         ],
         "description": "A sentence for the reception when `unavailable` is set.",
         "x-description-cs": "Věta pro recepci, když je `unavailable` vyplněné."
        }
       }
      }
     }
    }
   },
   "LodgingQuote": {
    "type": "object",
    "required": [
     "total",
     "list_total",
     "nights",
     "extra_persons",
     "per_night",
     "package"
    ],
    "properties": {
     "total": {
      "$ref": "#/components/schemas/Money"
     },
     "list_total": {
      "description": "The price by the price list before the package.",
      "x-description-cs": "Cena podle ceníku před balíčkem.",
      "$ref": "#/components/schemas/Money"
     },
     "nights": {
      "type": "integer",
      "examples": [
       2
      ]
     },
     "extra_persons": {
      "type": "integer",
      "description": "Guests on extra beds.",
      "x-description-cs": "Hostů na přistýlce.",
      "examples": [
       0
      ]
     },
     "per_night": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "date",
        "price",
        "rate"
       ],
       "properties": {
        "date": {
         "$ref": "#/components/schemas/LocalDate"
        },
        "price": {
         "$ref": "#/components/schemas/Money"
        },
        "rate": {
         "type": [
          "string",
          "null"
         ],
         "description": "The season of the price list; `null` = the basic price of the type.",
         "x-description-cs": "Sezóna ceníku; `null` = základní cena typu.",
         "examples": [
          "Vánoce"
         ]
        }
       }
      }
     },
     "package": {
      "anyOf": [
       {
        "type": "object",
        "required": [
         "id",
         "name",
         "free_nights",
         "free_amount",
         "discount",
         "extra"
        ],
        "properties": {
         "id": {
          "$ref": "#/components/schemas/Id"
         },
         "name": {
          "type": "string",
          "examples": [
           "3 + 1 noc zdarma s wellness"
          ]
         },
         "free_nights": {
          "type": "integer",
          "examples": [
           1
          ]
         },
         "free_amount": {
          "$ref": "#/components/schemas/Money"
         },
         "discount": {
          "$ref": "#/components/schemas/Money"
         },
         "extra": {
          "$ref": "#/components/schemas/Money"
         }
        }
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "LodgingRegistrationLists": {
    "type": "object",
    "required": [
     "countries",
     "document_types",
     "purposes",
     "city_tax"
    ],
    "properties": {
     "countries": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "code",
        "name"
       ],
       "properties": {
        "code": {
         "type": "string",
         "examples": [
          "DE"
         ]
        },
        "name": {
         "type": "string",
         "examples": [
          "Německo"
         ]
        }
       }
      }
     },
     "document_types": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "code",
        "name"
       ],
       "properties": {
        "code": {
         "type": "string",
         "x-extensible-enum": [
          "id",
          "passport",
          "residence",
          "visa",
          "other"
         ]
        },
        "name": {
         "type": "string",
         "examples": [
          "cestovní pas"
         ]
        }
       }
      }
     },
     "purposes": {
      "type": "array",
      "description": "Purposes of the stay of the foreign police (Ubyport); empty until the restaurant sets Ubyport up.",
      "x-description-cs": "Účely pobytu cizinecké policie (Ubyport); prázdné, dokud provozovna Ubyport nenastaví.",
      "items": {
       "type": "object",
       "required": [
        "code",
        "name"
       ],
       "properties": {
        "code": {
         "type": "string",
         "examples": [
          "10"
         ]
        },
        "name": {
         "type": "string",
         "examples": [
          "turistika"
         ]
        }
       }
      }
     },
     "city_tax": {
      "type": "object",
      "required": [
       "enabled",
       "exempt_under_age"
      ],
      "properties": {
       "enabled": {
        "type": "boolean"
       },
       "exempt_under_age": {
        "type": "integer",
        "description": "Guests younger than this do not pay (by law).",
        "x-description-cs": "Mladší hosté neplatí (ze zákona).",
        "examples": [
         18
        ]
       }
      }
     }
    }
   },
   "LodgingStayCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "arrival",
     "departure",
     "guest"
    ],
    "properties": {
     "room_id": {
      "description": "The room (`getLodgingAvailability`); or send `room_type_id`.",
      "x-description-cs": "Pokoj (`getLodgingAvailability`); nebo pošlete `room_type_id`.",
      "$ref": "#/components/schemas/Id"
     },
     "room_type_id": {
      "description": "The server picks the first free room of the type.",
      "x-description-cs": "Server vybere první volný pokoj typu.",
      "$ref": "#/components/schemas/Id"
     },
     "arrival": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "departure": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "adults": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "default": 1
     },
     "children": {
      "type": "integer",
      "minimum": 0,
      "maximum": 50,
      "default": 0
     },
     "guest": {
      "$ref": "#/components/schemas/LodgingStayGuestInput"
     },
     "company": {
      "type": "string",
      "maxLength": 150
     },
     "note_guest": {
      "type": "string",
      "maxLength": 1000
     },
     "note_internal": {
      "type": "string",
      "maxLength": 1000
     },
     "tags": {
      "type": "array",
      "maxItems": 10,
      "items": {
       "type": "string",
       "maxLength": 30
      }
     },
     "status": {
      "type": "string",
      "description": "`confirmed` (default) or `tentative` (holds the room until confirmed or cancelled).",
      "x-description-cs": "`confirmed` potvrzený (výchozí), nebo `tentative` předběžný (drží pokoj, dokud ho nepotvrdíte nebo nezrušíte).",
      "enum": [
       "confirmed",
       "tentative"
      ]
     },
     "source": {
      "type": "string",
      "description": "How the guest booked at the reception.",
      "x-description-cs": "Jak host rezervoval na recepci.",
      "enum": [
       "admin",
       "phone",
       "email"
      ]
     },
     "price_total": {
      "description": "A price set by hand – the server does not count it again; without it the price list counts.",
      "x-description-cs": "Cena zadaná ručně – server ji znovu nepočítá; bez ní počítá ceník.",
      "$ref": "#/components/schemas/MoneyInput"
     },
     "package_id": {
      "$ref": "#/components/schemas/Id"
     },
     "uuid": {
      "type": "string",
      "format": "uuid",
      "description": "Your ID of the stay; a second create with it returns the existing stay.",
      "x-description-cs": "Vaše ID pobytu; druhé založení s ním vrátí existující pobyt."
     }
    }
   },
   "LodgingStayGuestInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "name"
    ],
    "properties": {
     "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100
     },
     "phone": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 30
     },
     "email": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 150
     },
     "lang": {
      "type": "string",
      "enum": [
       "cs",
       "en"
      ]
     }
    }
   },
   "LodgingStayUpdate": {
    "type": "object",
    "additionalProperties": false,
    "minProperties": 1,
    "description": "Only what changes. The dates and the room change with `moveStay`.",
    "x-description-cs": "Jen to, co se mění. Termín a pokoj mění `moveStay`.",
    "properties": {
     "guest": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
       "name": {
        "type": "string",
        "minLength": 1,
        "maxLength": 100
       },
       "phone": {
        "type": [
         "string",
         "null"
        ],
        "maxLength": 30
       },
       "email": {
        "type": [
         "string",
         "null"
        ],
        "maxLength": 150
       },
       "lang": {
        "type": "string",
        "enum": [
         "cs",
         "en"
        ]
       }
      }
     },
     "adults": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50
     },
     "children": {
      "type": "integer",
      "minimum": 0,
      "maximum": 50
     },
     "company": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 150
     },
     "note_guest": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 1000
     },
     "note_internal": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 1000
     },
     "tags": {
      "type": "array",
      "maxItems": 10,
      "items": {
       "type": "string",
       "maxLength": 30
      }
     },
     "price_total": {
      "description": "A price by hand; `null` = count by the price list again.",
      "x-description-cs": "Cena ručně; `null` = znovu podle ceníku.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/MoneyInput"
       },
       {
        "type": "null"
       }
      ]
     },
     "package_id": {
      "description": "The stay package; `null` = without a package.",
      "x-description-cs": "Pobytový balíček; `null` = bez balíčku.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "LodgingStayMove": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "room_id",
     "arrival",
     "departure"
    ],
    "properties": {
     "room_id": {
      "$ref": "#/components/schemas/Id"
     },
     "arrival": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "departure": {
      "$ref": "#/components/schemas/LocalDate"
     }
    }
   },
   "LodgingStayCancel": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
     "reason": {
      "type": "string",
      "maxLength": 255
     },
     "keep_deposit": {
      "type": "boolean",
      "description": "Keep a paid deposit as a cancellation fee; without it the deposit goes back to the guest.",
      "x-description-cs": "Ponechat zaplacenou zálohu jako storno poplatek; bez toho se záloha hostovi vrátí."
     }
    }
   },
   "LodgingGuestInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "first_name",
     "last_name",
     "nationality"
    ],
    "description": "A foreigner (not `CZ`) needs `birth_date` and `document_no` (the server reports them to Ubyport). A child in\nthe passport of a parent has `document_no` `INPASS` and the parent's document in `note`.\n",
    "x-description-cs": "Cizinec (ne `CZ`) potřebuje `birth_date` a `document_no` (server je hlásí do Ubyportu). Dítě zapsané v pasu\nrodiče má `document_no` `INPASS` a doklad rodiče v `note`.\n",
    "properties": {
     "first_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 60
     },
     "last_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 60
     },
     "birth_date": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "nationality": {
      "type": "string",
      "minLength": 2,
      "maxLength": 2,
      "examples": [
       "DE"
      ]
     },
     "document_type": {
      "type": "string",
      "enum": [
       "id",
       "passport",
       "residence",
       "visa",
       "other"
      ]
     },
     "document_no": {
      "type": "string",
      "maxLength": 30
     },
     "visa_no": {
      "type": "string",
      "maxLength": 15
     },
     "address": {
      "type": "string",
      "maxLength": 128
     },
     "purpose": {
      "type": "string",
      "maxLength": 4
     },
     "arrival": {
      "description": "Default the arrival of the stay.",
      "x-description-cs": "Výchozí příjezd pobytu.",
      "$ref": "#/components/schemas/LocalDate"
     },
     "departure": {
      "description": "Default the departure of the stay.",
      "x-description-cs": "Výchozí odjezd pobytu.",
      "$ref": "#/components/schemas/LocalDate"
     },
     "fee_exempt": {
      "type": "string",
      "maxLength": 32,
      "description": "Why the guest does not pay the city tax (empty = pays); guests under `exempt_under_age` do not pay by themselves.",
      "x-description-cs": "Proč host neplatí poplatek z pobytu (prázdné = platí); hosté pod `exempt_under_age` neplatí sami od sebe."
     },
     "note": {
      "type": "string",
      "maxLength": 255
     }
    }
   },
   "LodgingReceipt": {
    "type": "object",
    "required": [
     "id",
     "kind",
     "number",
     "total",
     "invoice",
     "eet",
     "issued_at"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "kind": {
      "type": "string",
      "description": "`sale` the receipt, `storno` the cancelling receipt (negative).",
      "x-description-cs": "`sale` doklad, `storno` protidoklad (záporný).",
      "x-extensible-enum": [
       "sale",
       "storno"
      ]
     },
     "number": {
      "type": "integer",
      "examples": [
       1042
      ]
     },
     "total": {
      "$ref": "#/components/schemas/Money"
     },
     "invoice": {
      "type": "boolean",
      "description": "An invoice for a company (bank transfer).",
      "x-description-cs": "Faktura pro firmu (převodem)."
     },
     "eet": {
      "type": "boolean",
      "description": "The cash or card part was recorded in EET.",
      "x-description-cs": "Hotovostní nebo kartová část je evidovaná v EET."
     },
     "issued_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "LodgingServiceList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name",
        "category",
        "unit",
        "price",
        "vat_rate",
        "online"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "examples": [
          "Snídaně"
         ]
        },
        "category": {
         "type": "string",
         "x-extensible-enum": [
          "breakfast",
          "board",
          "extra_bed",
          "pet",
          "drink",
          "food",
          "wellness",
          "parking",
          "other"
         ]
        },
        "unit": {
         "type": "string",
         "description": "`stay` per stay, `night` per night, `person_night` per person and night, `item` per piece.",
         "x-description-cs": "`stay` za pobyt, `night` za noc, `person_night` za osobu a noc, `item` za kus.",
         "x-extensible-enum": [
          "stay",
          "night",
          "person_night",
          "item"
         ]
        },
        "price": {
         "$ref": "#/components/schemas/Money"
        },
        "vat_rate": {
         "type": "number",
         "examples": [
          12
         ]
        },
        "online": {
         "type": "boolean",
         "description": "Guests can order it on the page of their stay.",
         "x-description-cs": "Hosté si ji mohou objednat na stránce pobytu."
        }
       }
      }
     }
    }
   },
   "StayServiceInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "service_id"
    ],
    "properties": {
     "service_id": {
      "$ref": "#/components/schemas/Id"
     },
     "quantity": {
      "type": "integer",
      "minimum": 1,
      "maximum": 1000
     },
     "persons": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50
     },
     "date_from": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "date_to": {
      "$ref": "#/components/schemas/LocalDate"
     },
     "note": {
      "type": "string",
      "maxLength": 255
     }
    }
   },
   "StayChargeInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "name",
     "amount",
     "vat_rate"
    ],
    "properties": {
     "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 150,
      "description": "What the charge is for, as the guest sees it on the account.",
      "x-description-cs": "Za co útrata je, jak ji host uvidí na účtu.",
      "examples": [
       "Restaurace – účet 2026/1184"
      ]
     },
     "amount": {
      "description": "The total of the bill with VAT. Negative for a refund.",
      "x-description-cs": "Celková částka útraty s DPH. Záporná při vrácení.",
      "$ref": "#/components/schemas/MoneyInput"
     },
     "vat_rate": {
      "type": "number",
      "description": "One rate for the whole charge; a bill with more rates is sent as more charges.",
      "x-description-cs": "Jedna sazba pro celou útratu; účet s více sazbami pošlete jako více útrat.",
      "enum": [
       0,
       12,
       21
      ],
      "examples": [
       12
      ]
     },
     "reference": {
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "description": "Your ID of the bill; the same `reference` is never charged twice.",
      "x-description-cs": "Vaše ID útraty; stejná `reference` se nikdy nezapíše dvakrát.",
      "examples": [
       "pokladna-1:2026/1184"
      ]
     }
    }
   },
   "StayPaymentInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "amount",
     "method"
    ],
    "properties": {
     "amount": {
      "$ref": "#/components/schemas/MoneyInput"
     },
     "method": {
      "type": "string",
      "description": "`cash`, `card` (a terminal of the reception), `transfer`, `invoice` (the company pays by an invoice), `voucher`, `other`.",
      "x-description-cs": "`cash` hotově, `card` kartou (terminál recepce), `transfer` převodem, `invoice` fakturou (platí firma), `voucher` voucherem, `other` jinak.",
      "enum": [
       "cash",
       "card",
       "transfer",
       "invoice",
       "voucher",
       "other"
      ]
     },
     "note": {
      "type": "string",
      "maxLength": 255
     }
    }
   },
   "StayReceiptCancel": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "reason"
    ],
    "properties": {
     "reason": {
      "type": "string",
      "minLength": 3,
      "maxLength": 255
     }
    }
   },
   "StayGuestPass": {
    "type": "object",
    "required": [
     "code",
     "places"
    ],
    "properties": {
     "code": {
      "type": "string",
      "description": "The content of the QR code. Keep it with the guest only – it opens the wellness and the breakfast.",
      "x-description-cs": "Obsah QR kódu. Dejte ho jen hostovi – otevírá wellness i snídaně.",
      "examples": [
       "PRU-197-3fa1c09b"
      ]
     },
     "places": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "place",
        "label",
        "text",
        "from",
        "to"
       ],
       "properties": {
        "place": {
         "type": "string",
         "x-extensible-enum": [
          "wellness",
          "breakfast",
          "board",
          "parking"
         ]
        },
        "label": {
         "type": "string",
         "examples": [
          "Wellness"
         ]
        },
        "text": {
         "type": "string",
         "description": "What the guest may, as a sentence.",
         "x-description-cs": "Co host smí, větou.",
         "examples": [
          "2 vstupy denně"
         ]
        },
        "from": {
         "anyOf": [
          {
           "$ref": "#/components/schemas/LocalDate"
          },
          {
           "type": "null"
          }
         ]
        },
        "to": {
         "anyOf": [
          {
           "$ref": "#/components/schemas/LocalDate"
          },
          {
           "type": "null"
          }
         ]
        }
       }
      }
     }
    }
   },
   "UbyportStatus": {
    "type": "object",
    "required": [
     "configured",
     "test",
     "pending"
    ],
    "properties": {
     "configured": {
      "type": "boolean",
      "description": "Reporting is on and the account of the web service is filled in (Accommodation › Settings).",
      "x-description-cs": "Hlášení je zapnuté a účet webové služby vyplněný (Ubytování › Nastavení)."
     },
     "test": {
      "type": "boolean",
      "description": "Reports go to Ubyport-TEST, not to the police.",
      "x-description-cs": "Hlášení jdou do Ubyport-TEST, ne policii."
     },
     "pending": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "guest_id",
        "stay_id",
        "name",
        "nationality",
        "arrival",
        "deadline",
        "late",
        "state",
        "error"
       ],
       "properties": {
        "guest_id": {
         "$ref": "#/components/schemas/Id"
        },
        "stay_id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "examples": [
          "Anna Müller"
         ]
        },
        "nationality": {
         "type": "string",
         "examples": [
          "DE"
         ]
        },
        "arrival": {
         "$ref": "#/components/schemas/LocalDate"
        },
        "deadline": {
         "$ref": "#/components/schemas/LocalDate"
        },
        "late": {
         "type": "boolean"
        },
        "state": {
         "type": "string",
         "x-extensible-enum": [
          "pending",
          "error"
         ]
        },
        "error": {
         "type": [
          "string",
          "null"
         ]
        }
       }
      }
     }
    }
   },
   "UbyportSendResult": {
    "type": "object",
    "required": [
     "sent",
     "errors",
     "failure"
    ],
    "properties": {
     "sent": {
      "type": "integer",
      "examples": [
       3
      ]
     },
     "errors": {
      "type": "integer",
      "description": "Guests the police refused – fix them (`updateStayGuest`), they go again.",
      "x-description-cs": "Hosté, které policie odmítla – opravte je (`updateStayGuest`), půjdou znovu.",
      "examples": [
       0
      ]
     },
     "failure": {
      "type": [
       "string",
       "null"
      ],
      "description": "The service of the police does not answer; the next hourly run tries again.",
      "x-description-cs": "Služba policie neodpovídá; další hodinový běh to zkusí znovu."
     }
    }
   },
   "InHouseStays": {
    "type": "object",
    "required": [
     "stays"
    ],
    "properties": {
     "stays": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/InHouseStay"
      }
     }
    }
   },
   "InHouseStay": {
    "type": "object",
    "required": [
     "id",
     "room",
     "guest_name",
     "arrival",
     "departure",
     "guests",
     "balance",
     "package"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "room": {
      "type": "string",
      "description": "The room the guests sleep in now.",
      "x-description-cs": "Pokoj, ve kterém hosté právě bydlí.",
      "examples": [
       "101"
      ]
     },
     "guest_name": {
      "type": "string",
      "examples": [
       "Jana Svobodová"
      ]
     },
     "arrival": {
      "type": "string",
      "format": "date",
      "examples": [
       "2026-11-10"
      ]
     },
     "departure": {
      "type": "string",
      "format": "date",
      "examples": [
       "2026-11-12"
      ]
     },
     "guests": {
      "type": "integer",
      "description": "Adults and children.",
      "x-description-cs": "Dospělí a děti.",
      "examples": [
       2
      ]
     },
     "balance": {
      "$ref": "#/components/schemas/Money"
     },
     "package": {
      "description": "The stay package (since 26.11.15).",
      "x-description-cs": "Pobytový balíček (od 26.11.15).",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "id",
         "name"
        ],
        "properties": {
         "id": {
          "$ref": "#/components/schemas/Id"
         },
         "name": {
          "type": "string",
          "examples": [
           "3 + 1 noc zdarma s wellness"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "StayFolio": {
    "type": "object",
    "required": [
     "stay_id",
     "status",
     "package",
     "room",
     "guest_name",
     "arrival",
     "departure",
     "accommodation",
     "city_tax",
     "lines",
     "total",
     "payments",
     "paid",
     "balance"
    ],
    "properties": {
     "stay_id": {
      "$ref": "#/components/schemas/Id"
     },
     "status": {
      "type": "string",
      "x-extensible-enum": [
       "tentative",
       "confirmed",
       "checked_in",
       "checked_out",
       "cancelled",
       "no_show"
      ],
      "examples": [
       "checked_in"
      ]
     },
     "package": {
      "description": "The stay package (since 26.11.15); its services are lines with `total` 0.",
      "x-description-cs": "Pobytový balíček (od 26.11.15); jeho služby jsou položky s `total` 0.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "id",
         "name"
        ],
        "properties": {
         "id": {
          "$ref": "#/components/schemas/Id"
         },
         "name": {
          "type": "string",
          "examples": [
           "3 + 1 noc zdarma s wellness"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "room": {
      "type": "string",
      "examples": [
       "101"
      ]
     },
     "guest_name": {
      "type": "string",
      "examples": [
       "Jana Svobodová"
      ]
     },
     "arrival": {
      "type": "string",
      "format": "date",
      "examples": [
       "2026-11-10"
      ]
     },
     "departure": {
      "type": "string",
      "format": "date",
      "examples": [
       "2026-11-12"
      ]
     },
     "accommodation": {
      "description": "The price of the accommodation (VAT 12 %).",
      "x-description-cs": "Cena ubytování (DPH 12 %).",
      "$ref": "#/components/schemas/Money"
     },
     "city_tax": {
      "description": "The city tax (no VAT); `null` – the restaurant does not collect it.",
      "x-description-cs": "Poplatek z pobytu (bez DPH); `null` – provozovna ho nevybírá.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "amount",
         "estimate"
        ],
        "properties": {
         "amount": {
          "$ref": "#/components/schemas/Money"
         },
         "estimate": {
          "type": "boolean",
          "description": "`true` – counted from the number of guests, not all guests are registered yet.",
          "x-description-cs": "`true` – spočítaný z počtu osob, ještě nejsou zapsaní všichni hosté."
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "lines": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/FolioLine"
      }
     },
     "total": {
      "$ref": "#/components/schemas/Money"
     },
     "payments": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/FolioPayment"
      }
     },
     "paid": {
      "$ref": "#/components/schemas/Money"
     },
     "balance": {
      "description": "Left to pay; negative when the guest paid more.",
      "x-description-cs": "Zbývá zaplatit; záporný při přeplatku.",
      "$ref": "#/components/schemas/Money"
     }
    }
   },
   "FolioLine": {
    "type": "object",
    "required": [
     "id",
     "kind",
     "name",
     "quantity",
     "unit_price",
     "total",
     "vat_rate",
     "date_from",
     "date_to",
     "reference",
     "created_at"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "kind": {
      "type": "string",
      "description": "`service` from the price list of services, `pos` a charge from a register, `manual` added by the reception.",
      "x-description-cs": "`service` z ceníku služeb, `pos` útrata z pokladny, `manual` zapsaná recepcí.",
      "x-extensible-enum": [
       "service",
       "pos",
       "manual"
      ],
      "examples": [
       "pos"
      ]
     },
     "name": {
      "type": "string",
      "examples": [
       "Restaurace – účet 2026/1184"
      ]
     },
     "quantity": {
      "type": "number",
      "examples": [
       1
      ]
     },
     "unit_price": {
      "$ref": "#/components/schemas/Money"
     },
     "total": {
      "$ref": "#/components/schemas/Money"
     },
     "vat_rate": {
      "type": "number",
      "examples": [
       12
      ]
     },
     "date_from": {
      "type": [
       "string",
       "null"
      ],
      "format": "date",
      "description": "The first night of a service charged per night.",
      "x-description-cs": "První noc služby účtované za noc."
     },
     "date_to": {
      "type": [
       "string",
       "null"
      ],
      "format": "date",
      "description": "The day after the last night.",
      "x-description-cs": "Den po poslední noci."
     },
     "reference": {
      "type": [
       "string",
       "null"
      ],
      "description": "Your `reference` from `chargeToStay`.",
      "x-description-cs": "Vaše `reference` z `chargeToStay`."
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "FolioPayment": {
    "type": "object",
    "required": [
     "id",
     "amount",
     "method",
     "note",
     "paid_at"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "amount": {
      "$ref": "#/components/schemas/Money"
     },
     "method": {
      "type": "string",
      "x-extensible-enum": [
       "cash",
       "card",
       "transfer",
       "invoice",
       "voucher",
       "other"
      ],
      "examples": [
       "card"
      ]
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "paid_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "HousekeepingDay": {
    "type": "object",
    "required": [
     "date",
     "inspection",
     "summary",
     "rooms"
    ],
    "properties": {
     "date": {
      "type": "string",
      "format": "date",
      "examples": [
       "2026-11-05"
      ]
     },
     "inspection": {
      "type": "boolean",
      "description": "The restaurant inspects rooms after cleaning (task `inspect`).",
      "x-description-cs": "Provozovna pokoje po úklidu kontroluje (úkol `inspect`)."
     },
     "summary": {
      "type": "object",
      "required": [
       "tasks",
       "done",
       "rooms",
       "arrivals",
       "waiting"
      ],
      "properties": {
       "tasks": {
        "type": "integer",
        "examples": [
         8
        ]
       },
       "done": {
        "type": "integer",
        "examples": [
         3
        ]
       },
       "rooms": {
        "type": "integer",
        "description": "Rooms with at least one task.",
        "x-description-cs": "Pokoje aspoň s jedním úkolem.",
        "examples": [
         6
        ]
       },
       "arrivals": {
        "type": "integer",
        "examples": [
         2
        ]
       },
       "waiting": {
        "type": "integer",
        "description": "Tasks that cannot be done yet.",
        "x-description-cs": "Úkoly, které ještě nejde udělat.",
        "examples": [
         1
        ]
       }
      }
     },
     "rooms": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/HousekeepingRoom"
      }
     }
    }
   },
   "HousekeepingRoom": {
    "type": "object",
    "required": [
     "id",
     "name",
     "floor",
     "type",
     "status",
     "occupied",
     "arrival",
     "departure",
     "tasks",
     "assigned_employee_id",
     "issues"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "104"
      ]
     },
     "floor": {
      "type": "string",
      "examples": [
       "1"
      ]
     },
     "type": {
      "type": "string",
      "examples": [
       "Dvoulůžkový"
      ]
     },
     "status": {
      "type": "string",
      "description": "`clean`, `dirty` (to be cleaned), `inspected`, `out_of_order`.",
      "x-description-cs": "`clean` uklizený, `dirty` k úklidu, `inspected` zkontrolovaný, `out_of_order` mimo provoz.",
      "x-extensible-enum": [
       "clean",
       "dirty",
       "inspected",
       "out_of_order"
      ],
      "examples": [
       "dirty"
      ]
     },
     "occupied": {
      "type": "boolean",
      "description": "Guests sleep in the room (also a guest who leaves today and has not left yet).",
      "x-description-cs": "V pokoji bydlí hosté (i host, který dnes odjíždí a ještě neodjel)."
     },
     "arrival": {
      "description": "Guests arriving to the room this day.",
      "x-description-cs": "Hosté, kteří do pokoje ten den přijíždějí.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "persons",
         "extra_beds",
         "from",
         "checked_in"
        ],
        "properties": {
         "persons": {
          "type": "integer",
          "examples": [
           3
          ]
         },
         "extra_beds": {
          "type": "integer",
          "description": "Persons above the fixed beds of the room type.",
          "x-description-cs": "Osoby nad stálá lůžka typu pokoje.",
          "examples": [
           1
          ]
         },
         "from": {
          "type": "string",
          "description": "Check-in from (HH:MM).",
          "x-description-cs": "Příjezd od (HH:MM).",
          "examples": [
           "14:00"
          ]
         },
         "checked_in": {
          "type": "boolean"
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "departure": {
      "description": "Guests leaving the room this day; `left` – they have left.",
      "x-description-cs": "Hosté, kteří ten den z pokoje odjíždějí; `left` – už odjeli.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "left"
        ],
        "properties": {
         "left": {
          "type": "boolean"
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "tasks": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/HousekeepingTask"
      }
     },
     "assigned_employee_id": {
      "description": "The housekeeper the room is assigned to this day.",
      "x-description-cs": "Pokojská, které je pokoj ten den přidělený.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "issues": {
      "type": "array",
      "description": "Open faults of the room.",
      "x-description-cs": "Otevřené závady pokoje.",
      "items": {
       "$ref": "#/components/schemas/RoomIssue"
      }
     }
    }
   },
   "HousekeepingTask": {
    "type": "object",
    "required": [
     "key",
     "name",
     "done",
     "done_at",
     "done_by_employee_id",
     "waiting",
     "note",
     "manual"
    ],
    "properties": {
     "key": {
      "type": "string",
      "description": "`checkout`, `inspect`, `stay`, `extra_bed`, `rule:{id}` or `task:{id}`.",
      "x-description-cs": "`checkout`, `inspect`, `stay`, `extra_bed`, `rule:{id}` nebo `task:{id}`.",
      "examples": [
       "checkout"
      ]
     },
     "name": {
      "type": "string",
      "examples": [
       "Úklid po odjezdu"
      ]
     },
     "done": {
      "type": "boolean"
     },
     "done_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "done_by_employee_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "waiting": {
      "type": "boolean",
      "description": "Cannot be done yet – `note` says why.",
      "x-description-cs": "Ještě nejde udělat – proč, říká `note`."
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "examples": [
       "Host ještě neodjel (odjezd do 10:00)"
      ]
     },
     "manual": {
      "type": "boolean",
      "description": "A one-off task from the reception.",
      "x-description-cs": "Jednorázový úkol od recepce."
     }
    }
   },
   "HousekeepingTaskInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "task"
    ],
    "properties": {
     "task": {
      "type": "string",
      "maxLength": 40,
      "description": "`HousekeepingTask.key`.",
      "examples": [
       "checkout"
      ]
     },
     "date": {
      "type": "string",
      "format": "date",
      "description": "The day of the task; today when missing.",
      "x-description-cs": "Den úkolu; bez něj dnešek."
     }
    }
   },
   "RoomIssue": {
    "type": "object",
    "required": [
     "id",
     "room_id",
     "room",
     "text",
     "blocks_room",
     "status",
     "created_at",
     "created_by_employee_id",
     "fixed_at",
     "fix_note"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "room_id": {
      "$ref": "#/components/schemas/Id"
     },
     "room": {
      "type": "string",
      "examples": [
       "102"
      ]
     },
     "text": {
      "type": "string",
      "examples": [
       "Kape kohoutek v koupelně"
      ]
     },
     "blocks_room": {
      "type": "boolean",
      "description": "The room is out of order because of the fault.",
      "x-description-cs": "Pokoj je kvůli závadě mimo provoz."
     },
     "status": {
      "type": "string",
      "x-extensible-enum": [
       "open",
       "fixed"
      ],
      "examples": [
       "open"
      ]
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "created_by_employee_id": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "fixed_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "fix_note": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "RoomIssueList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/RoomIssue"
      }
     }
    }
   },
   "RoomIssueInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "room_id",
     "text"
    ],
    "properties": {
     "room_id": {
      "$ref": "#/components/schemas/Id"
     },
     "text": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500,
      "examples": [
       "Kape kohoutek v koupelně"
      ]
     },
     "blocks_room": {
      "type": "boolean",
      "default": false,
      "description": "The room cannot be sold until the fault is fixed.",
      "x-description-cs": "Pokoj nejde prodat, dokud se závada neopraví."
     }
    }
   },
   "RoomIssueReported": {
    "type": "object",
    "required": [
     "issue",
     "warning"
    ],
    "properties": {
     "issue": {
      "$ref": "#/components/schemas/RoomIssue"
     },
     "warning": {
      "type": [
       "string",
       "null"
      ],
      "description": "The room out of order still has stays – move them.",
      "x-description-cs": "Pokoj mimo provoz má ještě pobyty – přesuňte je."
     }
    }
   },
   "RoomIssueFixInput": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
     "note": {
      "type": "string",
      "maxLength": 255,
      "description": "What was done.",
      "x-description-cs": "Co se udělalo.",
      "examples": [
       "Vyměněn ventil"
      ]
     }
    }
   },
   "EventRestaurantData": {
    "type": "object",
    "required": [
     "restaurant_id"
    ],
    "properties": {
     "restaurant_id": {
      "$ref": "#/components/schemas/Id"
     }
    }
   },
   "EventGrantData": {
    "type": "object",
    "required": [
     "restaurant_ids",
     "scopes"
    ],
    "properties": {
     "restaurant_ids": {
      "type": "array",
      "description": "Restaurants the connection can access after the change (empty after `grant.revoked`).",
      "x-description-cs": "Provozovny, ke kterým má připojení přístup po změně (po `grant.revoked` prázdné).",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "scopes": {
      "type": "array",
      "items": {
       "type": "string"
      }
     }
    }
   },
   "EventPage": {
    "type": "object",
    "required": [
     "data",
     "next_cursor"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Event"
      }
     },
     "next_cursor": {
      "type": "string",
      "description": "Always present. Send it in the next request.",
      "x-description-cs": "Vždy vyplněný. Pošlete ho v dalším požadavku."
     }
    }
   },
   "StreamReady": {
    "type": "object",
    "description": "Data of the first message `ready` of `streamEvents`. Its `id` is the cursor of the current position.",
    "x-description-cs": "Data první zprávy `ready` proudu `streamEvents`. Její `id` je kurzor aktuálního místa.",
    "required": [
     "connection_id",
     "restaurant_ids",
     "expires_at",
     "keepalive_interval"
    ],
    "properties": {
     "connection_id": {
      "$ref": "#/components/schemas/Id"
     },
     "restaurant_ids": {
      "type": "array",
      "description": "Restaurants whose events the stream gives (only the one of `restaurant_id` when you asked for it).",
      "x-description-cs": "Provozovny, jejichž události proud dává (jen ta z `restaurant_id`, když jste o ni požádali).",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "expires_at": {
      "$ref": "#/components/schemas/Timestamp",
      "description": "The access token expires then and the stream ends with `closing` `token_expired`.",
      "x-description-cs": "Tehdy vyprší access token a proud skončí zprávou `closing` `token_expired`."
     },
     "keepalive_interval": {
      "type": "integer",
      "description": "Seconds without a message after which a comment `: ping` comes.",
      "x-description-cs": "Po kolika sekundách bez zprávy přijde komentář `: ping`.",
      "examples": [
       25
      ]
     }
    }
   },
   "StreamClosing": {
    "type": "object",
    "description": "Data of the last message `closing` of `streamEvents` – why the stream ends and what to do.",
    "x-description-cs": "Data poslední zprávy `closing` proudu `streamEvents` – proč proud končí a co udělat.",
    "required": [
     "reason"
    ],
    "properties": {
     "reason": {
      "type": "string",
      "x-extensible-enum": [
       "max_age",
       "token_expired",
       "token_revoked",
       "restart",
       "forbidden"
      ],
      "description": "`max_age` – reconnect at once; `token_expired`, `token_revoked` – refresh the access token, then reconnect;\n`restart` – reconnect in 1–10 seconds at random; `forbidden` – the restaurant of `restaurant_id` is no longer\nin the connection, do not repeat the request. An unknown value: reconnect after a few seconds.\n",
      "x-description-cs": "`max_age` – připojit se hned znovu; `token_expired`, `token_revoked` – obnovit access token a pak se připojit;\n`restart` – znovu za 1–10 sekund náhodně; `forbidden` – provozovna z `restaurant_id` už v připojení není,\npožadavek neopakovat. Neznámá hodnota: připojit se znovu za pár sekund.\n",
      "examples": [
       "max_age"
      ]
     }
    }
   },
   "TableGuestEvent": {
    "type": "object",
    "description": "Data of one message of `streamTableEvents` – only what changed, not how (the same as on the main register).\n`event:` of the message is the same as `type`.\n",
    "x-description-cs": "Data jedné zprávy `streamTableEvents` – jen co se změnilo, ne jak (stejně jako na hlavní kase). `event:` zprávy\nje stejné jako `type`.\n",
    "required": [
     "type",
     "id"
    ],
    "properties": {
     "type": {
      "type": "string",
      "x-extensible-enum": [
       "session",
       "orders",
       "calls",
       "tab",
       "visit_ended"
      ],
      "description": "What to read again – `getTableSession`, `listTableOrders`, `getTableSession` (calls), `getTableTab`; `visit_ended` is the last message.",
      "x-description-cs": "Co si načíst znovu – `getTableSession`, `listTableOrders`, `getTableSession` (volání), `getTableTab`; `visit_ended` je poslední zpráva.",
      "examples": [
       "orders"
      ]
     },
     "id": {
      "type": [
       "string",
       "null"
      ],
      "description": "The order (`orders`) or the call (`calls`), otherwise `null`.",
      "x-description-cs": "Objednávka (`orders`) nebo volání (`calls`), jinak `null`.",
      "examples": [
       "0192f3a4-5b6c-7d8e-9f01-23456789abcd"
      ]
     }
    }
   },
   "TableSessionStart": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "table_code"
    ],
    "properties": {
     "table_code": {
      "type": "string",
      "description": "The code of the table from its QR code – 8 characters, as printed (`K7M2 Q9XB`). Spaces and dashes are\nignored, small letters are read as capitals, `O` as `0`, `I` and `L` as `1`.\n",
      "x-description-cs": "Kód stolu z jeho QR kódu – 8 znaků, jak je vytištěný (`K7M2 Q9XB`). Mezery a pomlčky se nečtou, malá písmena\nse berou jako velká, `O` jako `0`, `I` a `L` jako `1`.\n",
      "minLength": 8,
      "maxLength": 12,
      "pattern": "^[0-9A-Za-z -]+$",
      "examples": [
       "K7M2Q9XB"
      ]
     }
    }
   },
   "TableSessionCreated": {
    "type": "object",
    "required": [
     "token",
     "expires_at",
     "session"
    ],
    "properties": {
     "token": {
      "type": "string",
      "description": "The token of this phone at this table. Keep it in the browser of the guest (under the code of the table) and\nsend it as `Authorization: Bearer …`; never put it in an address.\n",
      "x-description-cs": "Token tohoto telefonu u tohoto stolu. Držte ho v prohlížeči hosta (pod kódem stolu) a posílejte jako\n`Authorization: Bearer …`; nikdy ho nedávejte do adresy.\n",
      "examples": [
       "pfg_Zm9vYmFyYmF6cXV4cXV1eHF1dXhxdXV4cXV1eA"
      ]
     },
     "expires_at": {
      "description": "When the token ends at the latest; the end of the visit ends it sooner.",
      "x-description-cs": "Kdy token nejpozději skončí; konec návštěvy ho ukončí dřív.",
      "$ref": "#/components/schemas/Timestamp"
     },
     "session": {
      "$ref": "#/components/schemas/TableSession"
     }
    }
   },
   "TableSession": {
    "type": "object",
    "description": "One phone's view of its table.",
    "x-description-cs": "Pohled jednoho telefonu na jeho stůl.",
    "required": [
     "path",
     "restaurant",
     "table",
     "visit",
     "device",
     "ordering",
     "join",
     "calls"
    ],
    "properties": {
     "path": {
      "type": "string",
      "description": "`cloud` – this is the backup path through the cloud (the local API of the main register says `local`).",
      "x-description-cs": "`cloud` – toto je záložní cesta přes cloud (místní API hlavní kasy říká `local`).",
      "x-extensible-enum": [
       "local",
       "cloud"
      ]
     },
     "restaurant": {
      "type": "object",
      "required": [
       "name"
      ],
      "properties": {
       "name": {
        "type": "string",
        "examples": [
         "Bistro U Lípy"
        ]
       }
      }
     },
     "table": {
      "type": "object",
      "required": [
       "id",
       "name",
       "room"
      ],
      "properties": {
       "id": {
        "$ref": "#/components/schemas/Id"
       },
       "name": {
        "type": "string",
        "examples": [
         "Stůl 5"
        ]
       },
       "room": {
        "type": [
         "string",
         "null"
        ],
        "description": "The room of the map; `null` without a name.",
        "x-description-cs": "Místnost mapy; `null` bez názvu.",
        "examples": [
         "Zahrádka"
        ]
       }
      }
     },
     "visit": {
      "description": "The visit of the table on the main register; `null` until the register takes this phone over.",
      "x-description-cs": "Návštěva stolu na hlavní kase; `null`, dokud si kasa tento telefon nepřevezme.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/TableVisit"
       },
       {
        "type": "null"
       }
      ]
     },
     "device": {
      "$ref": "#/components/schemas/TableDevice"
     },
     "ordering": {
      "$ref": "#/components/schemas/TableOrderingState"
     },
     "join": {
      "type": "object",
      "required": [
       "enabled",
       "code"
      ],
      "properties": {
       "enabled": {
        "type": "boolean",
        "description": "The restaurant uses codes from friends.",
        "x-description-cs": "Podnik používá kód od kamaráda."
       },
       "code": {
        "type": [
         "string",
         "null"
        ],
        "description": "The code for friends at the table – only for a verified phone of an open visit, `null` otherwise.",
        "x-description-cs": "Kód pro kamarády u stolu – jen pro ověřený telefon otevřené návštěvy, jinak `null`.",
        "examples": [
         "4821"
        ]
       }
      }
     },
     "calls": {
      "type": "array",
      "description": "Open calls of this phone (`submitted`, `open`, `acknowledged`).",
      "x-description-cs": "Otevřená volání tohoto telefonu (`submitted`, `open`, `acknowledged`).",
      "items": {
       "$ref": "#/components/schemas/TableCall"
      }
     }
    }
   },
   "TableVisit": {
    "type": "object",
    "description": "One party at a table, from the first phone or the tab to the payment. Ends when the tab is paid or the staff\nends it; the tokens of its phones end with it.\n",
    "x-description-cs": "Jedna skupina u stolu, od prvního telefonu nebo účtu po zaplacení. Skončí zaplacením účtu nebo ji ukončí obsluha;\ntokeny jejích telefonů skončí s ní.\n",
    "required": [
     "id",
     "state",
     "tab_open",
     "opened_at",
     "closed_at"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "state": {
      "type": "string",
      "x-extensible-enum": [
       "open",
       "closed"
      ]
     },
     "tab_open": {
      "type": "boolean",
      "description": "The table has an open tab on the register.",
      "x-description-cs": "Stůl má na kase otevřený účet."
     },
     "opened_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "closed_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "TableDevice": {
    "type": "object",
    "required": [
     "id",
     "nickname",
     "verified",
     "verified_by",
     "join_locked",
     "join_attempts_left"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "nickname": {
      "type": "string",
      "description": "The name of the phone the staff sees (`Host 2`); the register gives it.",
      "x-description-cs": "Jméno telefonu, které vidí obsluha (`Host 2`); dává ho kasa.",
      "examples": [
       "Host 2"
      ]
     },
     "verified": {
      "type": "boolean",
      "description": "The phone belongs to the party at the table – it sees the tab and the code for friends.",
      "x-description-cs": "Telefon patří ke skupině u stolu – vidí účet a kód pro kamarády."
     },
     "verified_by": {
      "type": [
       "string",
       "null"
      ],
      "description": "`join_code` – it entered the code from a friend; `staff_accept` – the staff accepted its first order;\n`staff` – the staff verified it by hand; `null` when not verified.\n",
      "x-description-cs": "`join_code` – zadal kód od kamaráda; `staff_accept` – obsluha přijala jeho první objednávku; `staff` – obsluha\nho ověřila ručně; `null`, když ověřený není.\n",
      "x-extensible-enum": [
       "join_code",
       "staff_accept",
       "staff"
      ]
     },
     "join_locked": {
      "type": "boolean",
      "description": "Too many wrong codes from friends; the staff unlocks it.",
      "x-description-cs": "Příliš mnoho špatných kódů od kamaráda; odemkne ho obsluha."
     },
     "join_attempts_left": {
      "type": "integer",
      "minimum": 0,
      "maximum": 5
     }
    }
   },
   "TableOrderingState": {
    "type": "object",
    "description": "Whether and how this phone can order now. The app shows the sentence and enables the buttons by it.",
    "x-description-cs": "Jestli a jak tento telefon teď může objednat. Aplikace podle toho ukáže větu a povolí tlačítka.",
    "required": [
     "enabled",
     "paused",
     "can_order",
     "blocked_reason",
     "confirm_mode",
     "needs_confirmation",
     "max_quantity",
     "note_max_length",
     "empty_table"
    ],
    "properties": {
     "enabled": {
      "type": "boolean",
      "description": "The restaurant takes orders from the table.",
      "x-description-cs": "Podnik objednávky od stolu bere."
     },
     "paused": {
      "type": "boolean",
      "description": "The staff paused new orders for a while; calling the staff works.",
      "x-description-cs": "Obsluha na chvíli pozastavila nové objednávky; zavolat obsluhu jde."
     },
     "can_order": {
      "type": "boolean"
     },
     "blocked_reason": {
      "type": [
       "string",
       "null"
      ],
      "description": "Why ordering is not possible now, `null` when it is: `ordering_disabled`, `ordering_paused`,\n`restaurant_offline` (the main register is not connected – only on the backup path), `connecting` (the\nregister has not taken this phone over yet – try again in a few seconds), `visit_closed`, `restaurant_closed`\n(outside the opening hours), `table_not_open` (the staff opens the tab first).\n",
      "x-description-cs": "Proč teď objednat nejde, `null`, když jde: `ordering_disabled`, `ordering_paused`, `restaurant_offline`\n(hlavní kasa není připojená – jen na záložní cestě), `connecting` (kasa si telefon ještě nepřevzala – zkuste\nto za pár sekund), `visit_closed`, `restaurant_closed` (mimo otevírací dobu), `table_not_open` (účet nejdřív\notevře obsluha).\n",
      "x-extensible-enum": [
       "ordering_disabled",
       "ordering_paused",
       "restaurant_offline",
       "connecting",
       "visit_closed",
       "restaurant_closed",
       "table_not_open"
      ]
     },
     "confirm_mode": {
      "type": "string",
      "description": "`each` – the staff confirms every order; `first` – only the first order of a phone that is not verified yet;\n`none` – no order waits for the staff.\n",
      "x-description-cs": "`each` – obsluha potvrzuje každou objednávku; `first` – jen první objednávku telefonu, který ještě není\nověřený; `none` – žádná objednávka na obsluhu nečeká.\n",
      "x-extensible-enum": [
       "each",
       "first",
       "none"
      ]
     },
     "needs_confirmation": {
      "type": "boolean",
      "description": "The next order of this phone will wait for the staff.",
      "x-description-cs": "Další objednávka tohoto telefonu bude čekat na obsluhu."
     },
     "max_quantity": {
      "type": "integer",
      "description": "At most this many pieces of one product in one order.",
      "x-description-cs": "Nejvýš tolik kusů jednoho produktu v jedné objednávce.",
      "examples": [
       10
      ]
     },
     "note_max_length": {
      "type": "integer",
      "examples": [
       32
      ]
     },
     "empty_table": {
      "type": "string",
      "description": "`staff` – orders go only to a tab the staff opened; `guest` – the first accepted order opens it.",
      "x-description-cs": "`staff` – objednávky jdou jen na účet, který otevřela obsluha; `guest` – první přijatá objednávka ho otevře.",
      "x-extensible-enum": [
       "staff",
       "guest"
      ]
     }
    }
   },
   "TableJoinInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "code"
    ],
    "properties": {
     "code": {
      "type": "string",
      "pattern": "^[0-9]{4}$",
      "examples": [
       "4821"
      ]
     }
    }
   },
   "TableRequest": {
    "type": "object",
    "description": "A request of a phone that the main register decides through the cloud.",
    "x-description-cs": "Žádost telefonu, o které rozhoduje hlavní kasa přes cloud.",
    "required": [
     "id",
     "kind",
     "status",
     "result",
     "error"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "kind": {
      "type": "string",
      "x-extensible-enum": [
       "join_requested",
       "order_cancel_requested",
       "call_cancel_requested"
      ]
     },
     "status": {
      "type": "string",
      "description": "`queued` – waits for the main register; `done`, `failed` – decided.",
      "x-description-cs": "`queued` – čeká na hlavní kasu; `done`, `failed` – rozhodnuto.",
      "x-extensible-enum": [
       "queued",
       "done",
       "failed"
      ]
     },
     "result": {
      "type": [
       "object",
       "null"
      ],
      "description": "What the register answered with `done` (`{}`, or `order` / `call` as it is now); `null` otherwise.",
      "x-description-cs": "Co kasa odpověděla s `done` (`{}`, nebo `order` / `call`, jak je teď); jinak `null`."
     },
     "error": {
      "description": "Why the register said no; `null` unless `failed`.",
      "x-description-cs": "Proč kasa odmítla; `null`, pokud není `failed`.",
      "anyOf": [
       {
        "type": "object",
        "required": [
         "code",
         "detail",
         "attempts_left"
        ],
        "properties": {
         "code": {
          "type": "string",
          "description": "A code of the error catalog, for example `join_code_invalid`.",
          "x-description-cs": "Kód z katalogu chyb, například `join_code_invalid`."
         },
         "detail": {
          "type": [
           "string",
           "null"
          ],
          "description": "A sentence for the guest.",
          "x-description-cs": "Věta pro hosta."
         },
         "attempts_left": {
          "type": [
           "integer",
           "null"
          ],
          "description": "With `join_code_invalid`, how many attempts are left.",
          "x-description-cs": "U `join_code_invalid`, kolik pokusů zbývá."
         }
        }
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "TableMenu": {
    "type": "object",
    "required": [
     "currency",
     "generated_at",
     "categories",
     "products",
     "allergens"
    ],
    "properties": {
     "currency": {
      "type": "string",
      "examples": [
       "CZK"
      ]
     },
     "generated_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "categories": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TableMenuCategory"
      }
     },
     "products": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TableMenuProduct"
      }
     },
     "allergens": {
      "type": "array",
      "description": "The allergens the products use, with their names.",
      "x-description-cs": "Alergeny, které produkty používají, s jejich názvy.",
      "items": {
       "$ref": "#/components/schemas/Allergen"
      }
     }
    }
   },
   "TableMenuCategory": {
    "type": "object",
    "required": [
     "id",
     "name",
     "position"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "Pivo"
      ]
     },
     "position": {
      "type": "integer"
     }
    }
   },
   "TableMenuProduct": {
    "type": "object",
    "required": [
     "id",
     "category_id",
     "name",
     "description",
     "image_url",
     "price",
     "weight",
     "allergens",
     "add_ons",
     "removable_ingredients",
     "available",
     "age_restricted",
     "position"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "category_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "examples": [
       "Plzeňský ležák 12° 0,5 l"
      ]
     },
     "description": {
      "type": [
       "string",
       "null"
      ]
     },
     "image_url": {
      "type": [
       "string",
       "null"
      ],
      "format": "uri"
     },
     "price": {
      "$ref": "#/components/schemas/Money"
     },
     "weight": {
      "type": [
       "integer",
       "null"
      ],
      "description": "Grams of a meal, millilitres of a drink, as in the catalog.",
      "x-description-cs": "Gramy u jídla, mililitry u nápoje, jak je v sortimentu."
     },
     "allergens": {
      "type": "array",
      "items": {
       "type": "string",
       "examples": [
        "1"
       ]
      }
     },
     "add_ons": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name",
        "price"
       ],
       "properties": {
        "id": {
         "description": "The product of the add-on (`ProductAddOn.product_id` of the catalog).",
         "x-description-cs": "Produkt přílohy (`ProductAddOn.product_id` ze sortimentu).",
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string"
        },
        "price": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "removable_ingredients": {
      "type": "array",
      "description": "Ingredients the guest may remove („without onion“), as `Product.removable_ingredients`; send the unticked ones\nin `TableOrderLineInput.removed_ingredient_ids`. The price does not change. Empty when the product has none.\n",
      "x-description-cs": "Suroviny, které si host smí odebrat („bez cibule“), jako `Product.removable_ingredients`; odškrtnuté pošlete\nv `TableOrderLineInput.removed_ingredient_ids`. Cena se nemění. Prázdné, když je produkt nemá.\n",
      "items": {
       "$ref": "#/components/schemas/RemovableIngredient"
      }
     },
     "available": {
      "type": "boolean",
      "description": "`false` – sold out now: show it, but do not let the guest add it.",
      "x-description-cs": "`false` – teď vyprodané: ukažte ho, ale nedovolte ho přidat."
     },
     "age_restricted": {
      "type": "boolean",
      "description": "Sold only to adults (18+); the staff checks the age when serving.",
      "x-description-cs": "Jen pro dospělé (18+); věk kontroluje obsluha při podání."
     },
     "position": {
      "type": "integer"
     }
    }
   },
   "TableOrderCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "lines"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid",
      "description": "A UUID the app makes when the guest taps „order“ (version 7 recommended); keep it when you repeat.",
      "x-description-cs": "UUID, které aplikace vytvoří, když host klepne na „objednat“ (doporučeně verze 7); při opakování ho zachovejte."
     },
     "lines": {
      "type": "array",
      "minItems": 1,
      "maxItems": 30,
      "items": {
       "$ref": "#/components/schemas/TableOrderLineInput"
      }
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "pattern": "^[^\\x00-\\x1F\\x7F-\\x9F]*$",
      "description": "A note for the bar, at most `note_max_length` characters, no control characters and no emoji.",
      "x-description-cs": "Poznámka pro bar, nejvýš `note_max_length` znaků, bez řídicích znaků a bez emoji."
     }
    }
   },
   "TableOrderLineInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "product_id",
     "quantity"
    ],
    "properties": {
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "quantity": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "description": "At most `TableOrderingState.max_quantity`.",
      "x-description-cs": "Nejvýš `TableOrderingState.max_quantity`."
     },
     "add_on_ids": {
      "type": "array",
      "maxItems": 10,
      "uniqueItems": true,
      "description": "`TableMenuProduct.add_ons[].id` of this product.",
      "x-description-cs": "`TableMenuProduct.add_ons[].id` tohoto produktu.",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "removed_ingredient_ids": {
      "type": "array",
      "maxItems": 30,
      "uniqueItems": true,
      "description": "`TableMenuProduct.removable_ingredients[].id` of this product the guest unticked, each at most once\n(`ingredient_not_removable` otherwise). The main register gets them in the order.\n",
      "x-description-cs": "`TableMenuProduct.removable_ingredients[].id` tohoto produktu, které host odškrtl, každé nejvýš jednou\n(jinak `ingredient_not_removable`). Hlavní kasa je dostane v objednávce.\n",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     }
    }
   },
   "TableOrder": {
    "type": "object",
    "description": "An order from the table as the main register decided it. Until the register takes it over (`submitted`), the\nnames and prices come from the catalog; the register's own count wins.\n",
    "x-description-cs": "Objednávka od stolu, jak o ní rozhodla hlavní kasa. Dokud si ji kasa nepřevezme (`submitted`), jsou názvy a ceny\nze sortimentu; platí to, co spočítá kasa.\n",
    "required": [
     "id",
     "visit_id",
     "device_id",
     "device_nickname",
     "from_verified_device",
     "status",
     "reason_code",
     "reason",
     "lines",
     "note",
     "total",
     "created_at",
     "decided_at"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "visit_id": {
      "description": "The visit of the table; `null` while the register has not taken the order over.",
      "x-description-cs": "Návštěva stolu; `null`, dokud si kasa objednávku nepřevzala.",
      "anyOf": [
       {
        "type": "string",
        "format": "uuid"
       },
       {
        "type": "null"
       }
      ]
     },
     "device_id": {
      "type": "string",
      "format": "uuid"
     },
     "device_nickname": {
      "type": "string",
      "examples": [
       "Host 2"
      ]
     },
     "from_verified_device": {
      "type": "boolean",
      "description": "The phone was verified when it ordered; the staff sees „phone of the table“ or „new phone“.",
      "x-description-cs": "Telefon byl ověřený, když objednával; obsluha vidí „telefon stolu“, nebo „nový telefon“."
     },
     "status": {
      "type": "string",
      "description": "`submitted` – only on the backup path: waits until the main register takes it over; `pending_confirmation` –\nwaits for the staff; `accepted` – on the tab of the table and sent to be made; `preparing`, `ready` – from\nthe kitchen or the bar; `served` – brought to the table; `rejected` – the staff or the rules said no;\n`cancelled` – the guest cancelled it or the visit ended; `expired` – nobody took it over in time.\n",
      "x-description-cs": "`submitted` – jen na záložní cestě: čeká, až si ji hlavní kasa převezme; `pending_confirmation` – čeká na\nobsluhu; `accepted` – na účtu stolu a poslaná k přípravě; `preparing`, `ready` – z kuchyně nebo baru;\n`served` – přineseno ke stolu; `rejected` – obsluha nebo pravidla ji odmítla; `cancelled` – zrušil ji host,\nnebo skončila návštěva; `expired` – nikdo ji včas nepřevzal.\n",
      "x-extensible-enum": [
       "submitted",
       "pending_confirmation",
       "accepted",
       "preparing",
       "ready",
       "served",
       "rejected",
       "cancelled",
       "expired"
      ]
     },
     "reason_code": {
      "type": [
       "string",
       "null"
      ],
      "description": "Why it was `rejected`, `cancelled` or `expired`, for the app: `staff_rejected`, `guest_cancelled`,\n`staff_cancelled`, `visit_ended`, `expired`, `tab_closed` or a code of the error catalog (for example\n`product_unavailable`, `table_not_open`); `null` otherwise.\n",
      "x-description-cs": "Proč je `rejected`, `cancelled` nebo `expired`, pro aplikaci: `staff_rejected`, `guest_cancelled`,\n`staff_cancelled`, `visit_ended`, `expired`, `tab_closed` nebo kód z katalogu chyb (například\n`product_unavailable`, `table_not_open`); jinak `null`.\n",
      "x-extensible-enum": [
       "staff_rejected",
       "guest_cancelled",
       "staff_cancelled",
       "visit_ended",
       "expired",
       "tab_closed",
       "ordering_disabled",
       "ordering_paused",
       "table_not_open",
       "restaurant_closed",
       "product_unavailable",
       "product_not_orderable",
       "device_not_verified"
      ]
     },
     "reason": {
      "type": [
       "string",
       "null"
      ],
      "description": "The sentence for the guest with `reason_code`.",
      "x-description-cs": "Věta pro hosta k `reason_code`."
     },
     "lines": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TableOrderLine"
      }
     },
     "note": {
      "type": [
       "string",
       "null"
      ]
     },
     "total": {
      "$ref": "#/components/schemas/Money"
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "decided_at": {
      "description": "When the staff or the rules decided; `null` before.",
      "x-description-cs": "Kdy rozhodla obsluha nebo pravidla; předtím `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "TableOrderLine": {
    "type": "object",
    "required": [
     "product_id",
     "name",
     "quantity",
     "add_ons",
     "removed_ingredients",
     "unit_price",
     "total"
    ],
    "properties": {
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string"
     },
     "quantity": {
      "type": "integer"
     },
     "add_ons": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "id",
        "name",
        "price"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string"
        },
        "price": {
         "$ref": "#/components/schemas/Money"
        }
       }
      }
     },
     "removed_ingredients": {
      "type": "array",
      "description": "Ingredients the guest removed („Without: onion“); empty when nothing was removed, or when the main register\ndid not send them.\n",
      "x-description-cs": "Suroviny, které host odebral („Bez: cibule“); prázdné, když nic neodebral, nebo když je hlavní kasa\nneposlala.\n",
      "items": {
       "$ref": "#/components/schemas/RemovableIngredient"
      }
     },
     "unit_price": {
      "description": "The price of one piece with its add-ons.",
      "x-description-cs": "Cena jednoho kusu i s přílohami.",
      "$ref": "#/components/schemas/Money"
     },
     "total": {
      "$ref": "#/components/schemas/Money"
     }
    }
   },
   "TableOrderList": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TableOrder"
      }
     }
    }
   },
   "TableCallCreate": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "kind"
    ],
    "properties": {
     "kind": {
      "type": "string",
      "enum": [
       "waiter",
       "bill"
      ],
      "description": "`waiter` – come to the table; `bill` – the guest wants to pay at the staff.",
      "x-description-cs": "`waiter` – přijďte ke stolu; `bill` – host chce platit u obsluhy."
     }
    }
   },
   "TableCall": {
    "type": "object",
    "required": [
     "id",
     "kind",
     "status",
     "created_at",
     "acknowledged_at"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "kind": {
      "type": "string",
      "x-extensible-enum": [
       "waiter",
       "bill"
      ]
     },
     "status": {
      "type": "string",
      "description": "`submitted` – only on the backup path, until the main register takes it over; `open` – waits for the staff;\n`acknowledged` – the staff is on the way; `cancelled`; `closed` – the visit ended.\n",
      "x-description-cs": "`submitted` – jen na záložní cestě, dokud si ho hlavní kasa nepřevezme; `open` – čeká na obsluhu;\n`acknowledged` – obsluha jde; `cancelled`; `closed` – návštěva skončila.\n",
      "x-extensible-enum": [
       "submitted",
       "open",
       "acknowledged",
       "cancelled",
       "closed"
      ]
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "acknowledged_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "TableTab": {
    "type": "object",
    "description": "The tab of the table as the main register sent it last.",
    "x-description-cs": "Účet stolu, jak ho naposledy poslala hlavní kasa.",
    "required": [
     "visit_id",
     "items",
     "total",
     "updated_at"
    ],
    "properties": {
     "visit_id": {
      "type": "string",
      "format": "uuid"
     },
     "items": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "name",
        "quantity",
        "total",
        "by"
       ],
       "properties": {
        "name": {
         "type": "string",
         "examples": [
          "Utopenec s cibulí 150 g"
         ]
        },
        "quantity": {
         "type": "number",
         "description": "May be a fraction (halves, sold by weight).",
         "x-description-cs": "Může být desetinné (půlky, prodej na váhu)."
        },
        "total": {
         "$ref": "#/components/schemas/Money"
        },
        "by": {
         "type": [
          "string",
          "null"
         ],
         "description": "The name of the phone that ordered it; `null` – the staff entered it.",
         "x-description-cs": "Jméno telefonu, který ji objednal; `null` – namarkovala ji obsluha."
        }
       }
      }
     },
     "total": {
      "$ref": "#/components/schemas/Money"
     },
     "updated_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "TableHeartbeatInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "paused"
    ],
    "properties": {
     "paused": {
      "type": "boolean",
      "description": "The staff paused new orders from the table.",
      "x-description-cs": "Obsluha pozastavila nové objednávky od stolu."
     },
     "local": {
      "description": "The local API of the register as guests reach it (for support and the administration).",
      "x-description-cs": "Místní API kasy, jak se k němu dostanou hosté (pro podporu a administraci).",
      "anyOf": [
       {
        "type": "object",
        "additionalProperties": false,
        "properties": {
         "host": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 80,
          "examples": [
           "profirest-184.local"
          ]
         },
         "port": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 1,
          "maximum": 65535,
          "examples": [
           8080
          ]
         },
         "ip": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 45,
          "examples": [
           "192.168.50.10"
          ]
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "app_version": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "examples": [
       "3.2.0"
      ]
     },
     "guest_app_version": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32,
      "examples": [
       "1.0.4"
      ]
     }
    }
   },
   "TableHeartbeat": {
    "type": "object",
    "required": [
     "server_time",
     "inbox_pending",
     "online_seconds"
    ],
    "properties": {
     "server_time": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "inbox_pending": {
      "type": "integer",
      "description": "Requests of guests waiting in the inbox (`listTableInbox`).",
      "x-description-cs": "Žádosti hostů čekající ve schránce (`listTableInbox`)."
     },
     "online_seconds": {
      "type": "integer",
      "description": "How long after the last heartbeat the register counts as online.",
      "x-description-cs": "Jak dlouho po posledním heartbeatu se kasa počítá jako online.",
      "examples": [
       90
      ]
     }
    }
   },
   "TableInboxPage": {
    "type": "object",
    "required": [
     "data"
    ],
    "properties": {
     "data": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/TableInboxItem"
      }
     }
    }
   },
   "TableInboxItem": {
    "type": "object",
    "description": "A request of a guest from the backup path; `listTableInbox` says what `payload` carries for each `kind`.",
    "x-description-cs": "Žádost hosta ze záložní cesty; co nese `payload` u kterého `kind`, říká `listTableInbox`.",
    "required": [
     "id",
     "kind",
     "created_at",
     "device_id",
     "ref_id",
     "payload"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "kind": {
      "type": "string",
      "x-extensible-enum": [
       "session_started",
       "join_requested",
       "order_submitted",
       "order_cancel_requested",
       "call_requested",
       "call_cancel_requested",
       "staff_action"
      ]
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "device_id": {
      "description": "The phone that made the request; `null` for `staff_action`.",
      "x-description-cs": "Telefon, který žádost poslal; `null` u `staff_action`.",
      "anyOf": [
       {
        "type": "string",
        "format": "uuid"
       },
       {
        "type": "null"
       }
      ]
     },
     "ref_id": {
      "description": "The order or call the request is about; `null` otherwise.",
      "x-description-cs": "Objednávka nebo volání, kterého se žádost týká; jinak `null`.",
      "anyOf": [
       {
        "type": "string",
        "format": "uuid"
       },
       {
        "type": "null"
       }
      ]
     },
     "payload": {
      "type": "object"
     }
    }
   },
   "TableInboxResultInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "status"
    ],
    "properties": {
     "status": {
      "type": "string",
      "enum": [
       "done",
       "failed"
      ]
     },
     "result": {
      "description": "With `done`; see `listTableInbox`.",
      "x-description-cs": "U `done`; viz `listTableInbox`.",
      "anyOf": [
       {
        "type": "object",
        "additionalProperties": false,
        "properties": {
         "visit_id": {
          "anyOf": [
           {
            "type": "string",
            "format": "uuid"
           },
           {
            "type": "null"
           }
          ]
         },
         "nickname": {
          "type": "string",
          "minLength": 1,
          "maxLength": 20
         },
         "order": {
          "$ref": "#/components/schemas/TableOrderState"
         },
         "call": {
          "$ref": "#/components/schemas/TableCallState"
         }
        }
       },
       {
        "type": "null"
       }
      ]
     },
     "error": {
      "description": "With `failed` – the code and the sentence for the guest.",
      "x-description-cs": "U `failed` – kód a věta pro hosta.",
      "anyOf": [
       {
        "type": "object",
        "additionalProperties": false,
        "required": [
         "code"
        ],
        "properties": {
         "code": {
          "type": "string",
          "pattern": "^[a-z_]{1,64}$",
          "examples": [
           "join_code_invalid"
          ]
         },
         "detail": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 160
         },
         "attempts_left": {
          "type": [
           "integer",
           "null"
          ],
          "minimum": 0,
          "maximum": 5
         }
        }
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "TableInboxCompletion": {
    "type": "object",
    "required": [
     "id",
     "kind",
     "status",
     "error_code",
     "done_at"
    ],
    "properties": {
     "id": {
      "$ref": "#/components/schemas/Id"
     },
     "kind": {
      "type": "string"
     },
     "status": {
      "type": "string",
      "x-extensible-enum": [
       "done",
       "failed"
      ]
     },
     "error_code": {
      "type": [
       "string",
       "null"
      ]
     },
     "done_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "TableStateInput": {
    "type": "object",
    "additionalProperties": false,
    "properties": {
     "visits": {
      "type": "array",
      "maxItems": 200,
      "items": {
       "$ref": "#/components/schemas/TableVisitState"
      }
     },
     "devices": {
      "type": "array",
      "maxItems": 200,
      "items": {
       "$ref": "#/components/schemas/TableDeviceState"
      }
     },
     "orders": {
      "type": "array",
      "maxItems": 200,
      "items": {
       "$ref": "#/components/schemas/TableOrderState"
      }
     },
     "calls": {
      "type": "array",
      "maxItems": 200,
      "items": {
       "$ref": "#/components/schemas/TableCallState"
      }
     }
    }
   },
   "TableVisitState": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "table_id",
     "state",
     "tab_open",
     "opened_at",
     "version"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "table_id": {
      "$ref": "#/components/schemas/Id"
     },
     "state": {
      "type": "string",
      "enum": [
       "open",
       "closed"
      ]
     },
     "tab_open": {
      "type": "boolean"
     },
     "join_code": {
      "type": [
       "string",
       "null"
      ],
      "pattern": "^[0-9]{4}$"
     },
     "opened_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "closed_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "tab": {
      "description": "The tab of the table for verified phones; `null` while the table has none.",
      "x-description-cs": "Účet stolu pro ověřené telefony; `null`, dokud ho stůl nemá.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/TableTabState"
       },
       {
        "type": "null"
       }
      ]
     },
     "version": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
     }
    }
   },
   "TableTabState": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "items",
     "total",
     "updated_at"
    ],
    "properties": {
     "items": {
      "type": "array",
      "maxItems": 300,
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "name",
        "quantity",
        "total"
       ],
       "properties": {
        "name": {
         "type": "string",
         "minLength": 1,
         "maxLength": 100
        },
        "quantity": {
         "type": "number",
         "minimum": 0,
         "maximum": 9999,
         "multipleOf": 0.001
        },
        "total": {
         "$ref": "#/components/schemas/MoneyInput"
        },
        "by": {
         "type": [
          "string",
          "null"
         ],
         "maxLength": 20
        }
       }
      }
     },
     "total": {
      "$ref": "#/components/schemas/MoneyInput"
     },
     "updated_at": {
      "$ref": "#/components/schemas/Timestamp"
     }
    }
   },
   "TableDeviceState": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "table_id",
     "path",
     "nickname",
     "verified",
     "version"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "table_id": {
      "$ref": "#/components/schemas/Id"
     },
     "visit_id": {
      "anyOf": [
       {
        "type": "string",
        "format": "uuid"
       },
       {
        "type": "null"
       }
      ]
     },
     "path": {
      "type": "string",
      "enum": [
       "local",
       "cloud"
      ]
     },
     "nickname": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20
     },
     "verified": {
      "type": "boolean"
     },
     "verified_by": {
      "type": [
       "string",
       "null"
      ],
      "enum": [
       "join_code",
       "staff_accept",
       "staff",
       null
      ]
     },
     "join_locked": {
      "type": "boolean",
      "default": false
     },
     "join_attempts_left": {
      "type": "integer",
      "minimum": 0,
      "maximum": 5,
      "default": 5
     },
     "last_seen_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "revoked": {
      "type": "boolean",
      "default": false,
      "description": "The staff removed the phone from the table; its token on the backup path ends.",
      "x-description-cs": "Obsluha telefon od stolu odebrala; jeho token na záložní cestě skončí."
     },
     "version": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
     }
    }
   },
   "TableOrderState": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "table_id",
     "device_id",
     "device_nickname",
     "from_verified_device",
     "status",
     "lines",
     "total",
     "created_at",
     "version"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "table_id": {
      "$ref": "#/components/schemas/Id"
     },
     "visit_id": {
      "anyOf": [
       {
        "type": "string",
        "format": "uuid"
       },
       {
        "type": "null"
       }
      ]
     },
     "device_id": {
      "type": "string",
      "format": "uuid"
     },
     "device_nickname": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20
     },
     "from_verified_device": {
      "type": "boolean"
     },
     "status": {
      "type": "string",
      "enum": [
       "pending_confirmation",
       "accepted",
       "preparing",
       "ready",
       "served",
       "rejected",
       "cancelled",
       "expired"
      ]
     },
     "reason_code": {
      "type": [
       "string",
       "null"
      ],
      "pattern": "^[a-z_]{1,64}$"
     },
     "reason": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 160
     },
     "lines": {
      "type": "array",
      "maxItems": 30,
      "items": {
       "$ref": "#/components/schemas/TableOrderLineState"
      }
     },
     "note": {
      "type": [
       "string",
       "null"
      ],
      "maxLength": 32
     },
     "total": {
      "$ref": "#/components/schemas/MoneyInput"
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "decided_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "version": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
     }
    }
   },
   "TableOrderLineState": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "product_id",
     "name",
     "quantity",
     "unit_price",
     "total"
    ],
    "properties": {
     "product_id": {
      "$ref": "#/components/schemas/Id"
     },
     "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100
     },
     "quantity": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50
     },
     "add_ons": {
      "type": "array",
      "maxItems": 10,
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "id",
        "name",
        "price"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "minLength": 1,
         "maxLength": 100
        },
        "price": {
         "$ref": "#/components/schemas/MoneyInput"
        }
       }
      }
     },
     "removed_ingredients": {
      "type": "array",
      "maxItems": 30,
      "description": "Ingredients the guest removed, for `TableOrderLine.removed_ingredients`.",
      "x-description-cs": "Suroviny, které host odebral, pro `TableOrderLine.removed_ingredients`.",
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "id",
        "name"
       ],
       "properties": {
        "id": {
         "$ref": "#/components/schemas/Id"
        },
        "name": {
         "type": "string",
         "minLength": 1,
         "maxLength": 48
        }
       }
      }
     },
     "unit_price": {
      "$ref": "#/components/schemas/MoneyInput"
     },
     "total": {
      "$ref": "#/components/schemas/MoneyInput"
     }
    }
   },
   "TableCallState": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "id",
     "table_id",
     "device_id",
     "kind",
     "status",
     "created_at",
     "version"
    ],
    "properties": {
     "id": {
      "type": "string",
      "format": "uuid"
     },
     "table_id": {
      "$ref": "#/components/schemas/Id"
     },
     "visit_id": {
      "anyOf": [
       {
        "type": "string",
        "format": "uuid"
       },
       {
        "type": "null"
       }
      ]
     },
     "device_id": {
      "type": "string",
      "format": "uuid"
     },
     "kind": {
      "type": "string",
      "enum": [
       "waiter",
       "bill"
      ]
     },
     "status": {
      "type": "string",
      "enum": [
       "open",
       "acknowledged",
       "cancelled",
       "closed"
      ]
     },
     "created_at": {
      "$ref": "#/components/schemas/Timestamp"
     },
     "acknowledged_at": {
      "anyOf": [
       {
        "$ref": "#/components/schemas/Timestamp"
       },
       {
        "type": "null"
       }
      ]
     },
     "version": {
      "type": "integer",
      "minimum": 1,
      "maximum": 9007199254740991
     }
    }
   },
   "TableStateResult": {
    "type": "object",
    "required": [
     "applied",
     "skipped"
    ],
    "properties": {
     "applied": {
      "type": "integer",
      "description": "Objects written.",
      "x-description-cs": "Zapsané objekty."
     },
     "skipped": {
      "type": "integer",
      "description": "Objects skipped – an older or equal `version`, or a table of another restaurant.",
      "x-description-cs": "Přeskočené objekty – starší nebo stejná `version`, nebo stůl jiné provozovny."
     }
    }
   },
   "TableOrderApplyInput": {
    "type": "object",
    "additionalProperties": false,
    "required": [
     "tab_id",
     "table_name",
     "device_nickname",
     "lines"
    ],
    "properties": {
     "tab_id": {
      "type": "string",
      "format": "uuid",
      "description": "The tab of the visit; a new UUID opens a new tab.",
      "x-description-cs": "Účet návštěvy; nové UUID otevře nový účet."
     },
     "table_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 32,
      "description": "The table of a new tab, as on the register.",
      "x-description-cs": "Stůl nového účtu, jak je na kase."
     },
     "accepted_by_id": {
      "description": "The employee who accepted the order; `null` – the rules of the restaurant accepted it.",
      "x-description-cs": "Zaměstnanec, který objednávku přijal; `null` – přijala ji pravidla podniku.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/Id"
       },
       {
        "type": "null"
       }
      ]
     },
     "device_nickname": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20,
      "description": "The name of the phone, for the log of the table.",
      "x-description-cs": "Jméno telefonu do logu stolu."
     },
     "lines": {
      "type": "array",
      "minItems": 1,
      "maxItems": 30,
      "items": {
       "type": "object",
       "additionalProperties": false,
       "required": [
        "id",
        "product_id",
        "quantity"
       ],
       "properties": {
        "id": {
         "type": "string",
         "minLength": 1,
         "maxLength": 36,
         "description": "The ID of the new line on the tab (`TabLine.id`).",
         "x-description-cs": "ID nového řádku na účtu (`TabLine.id`)."
        },
        "product_id": {
         "$ref": "#/components/schemas/Id"
        },
        "quantity": {
         "type": "integer",
         "minimum": 1,
         "maximum": 50
        },
        "add_ons": {
         "type": "array",
         "maxItems": 10,
         "items": {
          "type": "object",
          "additionalProperties": false,
          "required": [
           "product_id"
          ],
          "properties": {
           "product_id": {
            "$ref": "#/components/schemas/Id"
           }
          }
         }
        },
        "removed_ingredient_ids": {
         "type": "array",
         "maxItems": 30,
         "uniqueItems": true,
         "description": "Ingredients the guest removed – `Product.removable_ingredients[].id` of the product in the `pos` catalog\n(`ingredient_not_removable` otherwise); they go to the tab line and to the kitchen ticket.\n",
         "x-description-cs": "Suroviny, které host odebral – `Product.removable_ingredients[].id` produktu v sortimentu `pos` (jinak\n`ingredient_not_removable`); jdou na řádek účtu i na kuchyňský bon.\n",
         "items": {
          "$ref": "#/components/schemas/Id"
         }
        },
        "note": {
         "type": [
          "string",
          "null"
         ],
         "maxLength": 32,
         "pattern": "^[^\\x00-\\x1F\\x7F-\\x9F]*$"
        },
        "course": {
         "type": "integer",
         "minimum": 0,
         "maximum": 20,
         "default": 0
        }
       }
      }
     },
     "kitchen": {
      "description": "Also make the kitchen ticket of these lines; `null` – the register sends them to the kitchen itself.",
      "x-description-cs": "Udělat i kuchyňský bon těchto řádků; `null` – do kuchyně je pošle kasa sama.",
      "anyOf": [
       {
        "type": "object",
        "additionalProperties": false,
        "required": [
         "ticket_id",
         "line_ids"
        ],
        "properties": {
         "ticket_id": {
          "type": "string",
          "format": "uuid",
          "description": "The UUID of the kitchen ticket (`KitchenTicketCreate.id`).",
          "x-description-cs": "UUID kuchyňského bonu (`KitchenTicketCreate.id`)."
         },
         "line_ids": {
          "type": "array",
          "minItems": 1,
          "maxItems": 30,
          "uniqueItems": true,
          "description": "The lines of this order that go to the kitchen.",
          "x-description-cs": "Řádky této objednávky, které jdou do kuchyně.",
          "items": {
           "type": "string",
           "minLength": 1,
           "maxLength": 36
          }
         },
         "note": {
          "type": [
           "string",
           "null"
          ],
          "maxLength": 500,
          "description": "The note of the ticket (the note of the guest and the name of the phone).",
          "x-description-cs": "Poznámka bonu (poznámka hosta a jméno telefonu)."
         }
        }
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "TableOrderApplied": {
    "type": "object",
    "required": [
     "tab",
     "kitchen_ticket"
    ],
    "properties": {
     "tab": {
      "$ref": "#/components/schemas/Tab"
     },
     "kitchen_ticket": {
      "description": "The kitchen ticket made with `kitchen`; `null` without it.",
      "x-description-cs": "Kuchyňský bon udělaný s `kitchen`; bez něj `null`.",
      "anyOf": [
       {
        "$ref": "#/components/schemas/KitchenTicket"
       },
       {
        "type": "null"
       }
      ]
     }
    }
   },
   "TableOrderingSettings": {
    "type": "object",
    "description": "The rules of ordering from the table set in the administration. The main register enforces them on the local\npath and for requests from the backup path alike.\n",
    "x-description-cs": "Pravidla objednávání od stolu nastavená v administraci. Hlavní kasa je vynucuje na místní cestě i u žádostí\nze záložní cesty.\n",
    "required": [
     "enabled",
     "confirm_mode",
     "empty_table",
     "join_code_enabled",
     "max_quantity",
     "expire_minutes",
     "respect_opening_hours",
     "category_ids",
     "note_max_length",
     "wifi_ssid"
    ],
    "properties": {
     "enabled": {
      "type": "boolean"
     },
     "confirm_mode": {
      "type": "string",
      "description": "`each`, `first` or `none` – see `TableOrderingState.confirm_mode`.",
      "x-description-cs": "`each`, `first` nebo `none` – viz `TableOrderingState.confirm_mode`.",
      "x-extensible-enum": [
       "each",
       "first",
       "none"
      ]
     },
     "empty_table": {
      "type": "string",
      "description": "`staff` or `guest` – see `TableOrderingState.empty_table`.",
      "x-description-cs": "`staff` nebo `guest` – viz `TableOrderingState.empty_table`.",
      "x-extensible-enum": [
       "staff",
       "guest"
      ]
     },
     "join_code_enabled": {
      "type": "boolean",
      "description": "A verified phone shows a four-digit code for friends at the table.",
      "x-description-cs": "Ověřený telefon ukazuje čtyřmístný kód pro kamarády u stolu."
     },
     "max_quantity": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50
     },
     "expire_minutes": {
      "type": "integer",
      "minimum": 2,
      "maximum": 60,
      "description": "How long an order waits for the staff before it is `expired`.",
      "x-description-cs": "Jak dlouho objednávka čeká na obsluhu, než skončí jako `expired`."
     },
     "respect_opening_hours": {
      "type": "boolean",
      "description": "Orders only within the opening hours (calling the staff always works).",
      "x-description-cs": "Objednávky jen v otevírací době (zavolat obsluhu jde vždy)."
     },
     "category_ids": {
      "type": "array",
      "description": "The categories of the catalog guests can order from; empty – nothing.",
      "x-description-cs": "Kategorie sortimentu, ze kterých hosté mohou objednat; prázdné – nic.",
      "items": {
       "$ref": "#/components/schemas/Id"
      }
     },
     "note_max_length": {
      "type": "integer",
      "examples": [
       32
      ]
     },
     "wifi_ssid": {
      "type": [
       "string",
       "null"
      ],
      "description": "The name of the guest Wi-Fi to print next to the QR code; `null` when not set.",
      "x-description-cs": "Název Wi-Fi pro hosty k vytištění vedle QR kódu; `null`, když není nastavený."
     }
    }
   },
   "EventTableInboxData": {
    "type": "object",
    "required": [
     "item_id",
     "kind"
    ],
    "properties": {
     "item_id": {
      "description": "`TableInboxItem.id`.",
      "x-description-cs": "`TableInboxItem.id`.",
      "$ref": "#/components/schemas/Id"
     },
     "kind": {
      "type": "string"
     }
    }
   }
  }
 },
 "x-error-catalog": [
  {
   "code": "malformed_request",
   "status": 400,
   "title_en": "Malformed request",
   "title_cs": "Chybný požadavek",
   "hint_en": "The request cannot be read – broken JSON, a bad header or parameter (`detail` says what). Fix it; sent unchanged it fails again.",
   "hint_cs": "Požadavek nejde přečíst – rozbitý JSON, špatná hlavička nebo parametr (co přesně, říká `detail`). Opravte ho; beze změny skončí znovu stejně."
  },
  {
   "code": "idempotency_key_missing",
   "status": 400,
   "title_en": "Idempotency-Key header is required",
   "title_cs": "Chybí hlavička Idempotency-Key",
   "hint_en": "Add the `Idempotency-Key` header: a new random UUID for every new write, the same key when you repeat it.",
   "hint_cs": "Přidejte hlavičku `Idempotency-Key`: nové náhodné UUID pro každý nový zápis, stejný klíč při jeho opakování."
  },
  {
   "code": "invalid_token",
   "status": 401,
   "title_en": "Access token is missing, invalid or expired",
   "title_cs": "Access token chybí, je neplatný nebo vypršel",
   "hint_en": "Get a new access token with the refresh token and repeat the request. When the refresh ends with `invalid_grant`, the access was revoked or has expired: authorize again (a device must be paired again).",
   "hint_cs": "Získejte refresh tokenem nový access token a požadavek zopakujte. Skončí-li obnova chybou `invalid_grant`, přístup byl zrušen nebo vypršel: autorizujte znovu (zařízení je třeba znovu spárovat)."
  },
  {
   "code": "insufficient_scope",
   "status": 403,
   "title_en": "The access token lacks the required scope",
   "title_cs": "Token nemá potřebné oprávnění",
   "hint_en": "The token lacks the scope named in `detail`. Ask for it in a new authorization – the owner has to confirm it; a device has to be paired again.",
   "hint_cs": "Token nemá oprávnění uvedené v `detail`. Požádejte o něj v nové autorizaci – majitel ho musí potvrdit; zařízení je třeba spárovat znovu."
  },
  {
   "code": "not_found",
   "status": 404,
   "title_en": "Not found",
   "title_cs": "Nenalezeno",
   "hint_en": "The object does not exist, or your connection may not see it (for example the owner did not share the restaurant with your application). Check the ID; repeating will not help.",
   "hint_cs": "Objekt neexistuje, nebo ho vaše připojení nesmí vidět (např. majitel vaší aplikaci provozovnu nezpřístupnil). Zkontrolujte ID; opakování nepomůže."
  },
  {
   "code": "method_not_allowed",
   "status": 405,
   "title_en": "Method not allowed",
   "title_cs": "Metoda není povolena",
   "hint_en": "Use one of the methods listed in the `Allow` header.",
   "hint_cs": "Použijte některou z metod v hlavičce `Allow`."
  },
  {
   "code": "not_acceptable",
   "status": 406,
   "title_en": "The requested response type is not available",
   "title_cs": "Požadovaný typ odpovědi není k dispozici",
   "hint_en": "Send `Accept: application/json` (for a file download the type of the file), or leave `Accept` out.",
   "hint_cs": "Pošlete `Accept: application/json` (u stažení souboru jeho typ), nebo `Accept` vynechte."
  },
  {
   "code": "conflict",
   "status": 409,
   "title_en": "Conflict with the current state",
   "title_cs": "Konflikt s aktuálním stavem",
   "hint_en": "The request clashes with the current state – `detail` says how; `existing_id`, when filled in, points at the object in the way. Read the current state before you decide what to do.",
   "hint_cs": "Požadavek se nesnese s aktuálním stavem – jak, říká `detail`; `existing_id`, je-li vyplněné, ukazuje na objekt, který překáží. Než se rozhodnete, načtěte aktuální stav."
  },
  {
   "code": "idempotency_in_progress",
   "status": 409,
   "title_en": "A request with this Idempotency-Key is still being processed",
   "title_cs": "Požadavek se stejným Idempotency-Key se ještě zpracovává",
   "hint_en": "The first request with this key is still running. After `Retry-After` seconds repeat it with the same key and body – you get its result.",
   "hint_cs": "První požadavek s tímto klíčem ještě běží. Po `Retry-After` sekundách ho zopakujte se stejným klíčem i tělem – dostanete jeho výsledek."
  },
  {
   "code": "external_id_conflict",
   "status": 409,
   "title_en": "Another object already has this external_id",
   "title_cs": "Toto external_id už má jiný objekt",
   "hint_en": "Another object already has this `external_id`; its ID is in `existing_id`. Use that object, or choose another `external_id`.",
   "hint_cs": "Toto `external_id` už má jiný objekt, jeho ID je v `existing_id`. Použijte ten objekt, nebo zvolte jiné `external_id`."
  },
  {
   "code": "cursor_expired",
   "status": 410,
   "title_en": "The cursor has expired",
   "title_cs": "Kurzor vypršel",
   "hint_en": "The cursor is older than 30 days and some events may be gone. Reload the data you keep, then read events again without a cursor.",
   "hint_cs": "Kurzor je starší než 30 dní a část událostí už nemusí být k dispozici. Načtěte znovu data, která si držíte, a události čtěte znovu bez kurzoru."
  },
  {
   "code": "precondition_failed",
   "status": 412,
   "title_en": "The object has changed since you read it",
   "title_cs": "Záznam se mezitím změnil",
   "hint_en": "Someone changed the object after you read it. Read it again, apply your change to the new state and send it with the new `ETag` in `If-Match`.",
   "hint_cs": "Objekt se po vašem načtení změnil. Načtěte ho znovu, změnu proveďte nad novým stavem a pošlete ji s novým `ETag` v `If-Match`."
  },
  {
   "code": "payload_too_large",
   "status": 413,
   "title_en": "Request body is too large",
   "title_cs": "Požadavek je příliš velký",
   "hint_en": "The body is over the limit of the operation. Send less at once – for example split a batch into several requests.",
   "hint_cs": "Tělo překračuje limit operace. Posílejte méně najednou – třeba dávku rozdělte do více požadavků."
  },
  {
   "code": "unsupported_media_type",
   "status": 415,
   "title_en": "Unsupported type of the request body",
   "title_cs": "Nepodporovaný typ těla požadavku",
   "hint_en": "Send the body in the type the operation takes – usually `application/json` with the header `Content-Type: application/json`.",
   "hint_cs": "Pošlete tělo v typu, který operace bere – obvykle `application/json` s hlavičkou `Content-Type: application/json`."
  },
  {
   "code": "validation_failed",
   "status": 422,
   "title_en": "Validation failed",
   "title_cs": "Neplatná data",
   "hint_en": "Fix the fields listed in `errors` (`pointer` says which field, `code` why) and send the request again. Unchanged it fails again.",
   "hint_cs": "Opravte pole uvedená v `errors` (`pointer` říká které, `code` proč) a požadavek pošlete znovu. Beze změny skončí stejně."
  },
  {
   "code": "idempotency_key_mismatch",
   "status": 422,
   "title_en": "Idempotency-Key was already used for a different request",
   "title_cs": "Idempotency-Key už byl použit pro jiný požadavek",
   "hint_en": "This key was already used for a different request (method, path or body). Generate a new random key for a new request; reuse a key only to repeat the identical request.",
   "hint_cs": "Tento klíč už patří jinému požadavku (jiná metoda, cesta nebo tělo). Pro nový požadavek vygenerujte nový náhodný klíč; stejný klíč jen při opakování téhož požadavku."
  },
  {
   "code": "precondition_required",
   "status": 428,
   "title_en": "If-Match header is required",
   "title_cs": "Chybí hlavička If-Match",
   "hint_en": "Send `If-Match` with the `ETag` from your last read of the object.",
   "hint_cs": "Pošlete `If-Match` s hodnotou `ETag` z posledního načtení objektu."
  },
  {
   "code": "rate_limited",
   "status": 429,
   "title_en": "Too many requests",
   "title_cs": "Příliš mnoho požadavků",
   "hint_en": "Wait `Retry-After` seconds and slow down – the `RateLimit-*` headers show what is left. Instead of polling, follow `GET /events` or webhooks.",
   "hint_cs": "Počkejte `Retry-After` sekund a zpomalte – kolik zbývá, ukazují hlavičky `RateLimit-*`. Místo opakovaného dotazování sledujte `GET /events` nebo webhooky."
  },
  {
   "code": "internal_error",
   "status": 500,
   "title_en": "Internal error",
   "title_cs": "Chyba serveru",
   "hint_en": "An error on our side. Repeat the request later with the same `Idempotency-Key` – a write is never done twice. If it keeps happening, give `request_id` to the support.",
   "hint_cs": "Chyba na naší straně. Požadavek zopakujte později se stejným `Idempotency-Key` – zápis se nikdy neprovede dvakrát. Opakuje-li se to, pošlete podpoře `request_id`."
  },
  {
   "code": "not_implemented",
   "status": 501,
   "title_en": "This operation is not available yet",
   "title_cs": "Tato operace zatím není k dispozici",
   "hint_en": "The operation is in the contract but does not run yet. Do not call it yet.",
   "hint_cs": "Operace je ve smlouvě, ale zatím neběží. Zatím ji nevolejte."
  },
  {
   "code": "service_unavailable",
   "status": 503,
   "title_en": "Service temporarily unavailable",
   "title_cs": "Služba je dočasně nedostupná",
   "hint_en": "A service we need (SMS gateway, map service, backup storage) does not answer. Repeat after `Retry-After` seconds.",
   "hint_cs": "Služba, kterou potřebujeme (SMS brána, mapy, úložiště záloh), neodpovídá. Zopakujte po `Retry-After` sekundách."
  },
  {
   "code": "restaurant_closed",
   "status": 422,
   "title_en": "The restaurant is closed",
   "title_cs": "Provozovna má zavřeno",
   "hint_en": "The restaurant is closed now. Show the customer the opening hours and let them order when it opens.",
   "hint_cs": "Provozovna má teď zavřeno. Ukažte zákazníkovi otevírací dobu a nechte ho objednat, až otevře."
  },
  {
   "code": "ordering_disabled",
   "status": 422,
   "title_en": "The restaurant does not accept online orders now",
   "title_cs": "Provozovna teď nepřijímá objednávky",
   "hint_en": "The restaurant does not take orders from applications now (paused in the administration, or its licence does not allow it). Tell the customer; do not retry in a loop.",
   "hint_cs": "Provozovna teď objednávky z aplikací nepřijímá (pozastavené v administraci, nebo to licence nedovoluje). Řekněte to zákazníkovi; nezkoušejte to dokola."
  },
  {
   "code": "delivery_unavailable",
   "status": 422,
   "title_en": "Delivery is not available",
   "title_cs": "Rozvoz není k dispozici",
   "hint_en": "Delivery is not available now or at that time. Offer pickup, or another time from `listTimeSlots`.",
   "hint_cs": "Rozvoz teď nebo v tu dobu není k dispozici. Nabídněte osobní odběr, nebo jiný čas z `listTimeSlots`."
  },
  {
   "code": "pickup_unavailable",
   "status": 422,
   "title_en": "Pickup is not available",
   "title_cs": "Osobní odběr není k dispozici",
   "hint_en": "The restaurant does not offer pickup. Offer delivery.",
   "hint_cs": "Osobní odběr provozovna nenabízí. Nabídněte rozvoz."
  },
  {
   "code": "outside_delivery_zone",
   "status": 422,
   "title_en": "The address is outside all delivery zones",
   "title_cs": "Adresa je mimo rozvozové zóny",
   "hint_en": "The address is outside all delivery zones. Offer pickup, or let the customer enter another address.",
   "hint_cs": "Adresa leží mimo rozvozové zóny. Nabídněte osobní odběr, nebo ať zákazník zadá jinou adresu."
  },
  {
   "code": "time_unavailable",
   "status": 422,
   "title_en": "The requested time cannot be served",
   "title_cs": "Požadovaný čas nelze splnit",
   "hint_en": "The restaurant cannot serve the chosen time. Let the customer pick a time from `listTimeSlots` and create a new quote.",
   "hint_cs": "Zvolený čas provozovna nestihne nebo nenabízí. Ať si zákazník vybere čas z `listTimeSlots`, a vytvořte novou kalkulaci."
  },
  {
   "code": "express_unavailable",
   "status": 422,
   "title_en": "Express delivery is not available",
   "title_cs": "Expresní doručení není k dispozici",
   "hint_en": "The restaurant does not offer express delivery to the zone of this address (`delivery.express_fee` of a quote without express is `null`). Create the quote again without `fulfillment.speed` – standard delivery.",
   "hint_cs": "Do zóny této adresy provozovna expres nenabízí (`delivery.express_fee` kalkulace bez expresu je `null`). Spočítejte košík znovu bez `fulfillment.speed` – běžný rozvoz."
  },
  {
   "code": "product_unavailable",
   "status": 422,
   "title_en": "A product is sold out or not offered",
   "title_cs": "Produkt je vyprodaný nebo se nenabízí",
   "hint_en": "A product is sold out or no longer offered (`errors` points at the item when it is known). Reload the catalog, remove the item or lower its quantity and try again – an order needs a new quote.",
   "hint_cs": "Produkt je vyprodaný nebo se už nenabízí (`errors` ukazuje na položku, když je známá). Načtěte sortiment znovu, položku odeberte nebo snižte množství a zkuste to znovu – objednávka potřebuje novou kalkulaci."
  },
  {
   "code": "quote_expired",
   "status": 409,
   "title_en": "The quote has expired",
   "title_cs": "Kalkulace vypršela",
   "hint_en": "A quote is valid 15 minutes. Create a new one and show the customer its amount before you create the order.",
   "hint_cs": "Kalkulace platí 15 minut. Vytvořte novou a před založením objednávky ukažte zákazníkovi její částku."
  },
  {
   "code": "quote_already_used",
   "status": 409,
   "title_en": "The quote was already used for an order",
   "title_cs": "Kalkulace už byla použita pro objednávku",
   "hint_en": "An order already exists for this quote; its ID is in `existing_id`. Read it with `getOrder` instead of ordering again.",
   "hint_cs": "Z této kalkulace už objednávka vznikla, její ID je v `existing_id`. Načtěte ji přes `getOrder`, neobjednávejte znovu."
  },
  {
   "code": "payment_amount_mismatch",
   "status": 422,
   "title_en": "The payments do not add up to the amount due",
   "title_cs": "Platby neodpovídají částce k úhradě",
   "hint_en": "The payments must add up exactly to the amount due – `amount_due` of the quote, `totals.total` of the receipt (where only the cash part may be rounded to whole CZK). Recompute them to the minor unit.",
   "hint_cs": "Platby musí přesně dát částku k úhradě – `amount_due` kalkulace, `totals.total` účtenky (kde se smí zaokrouhlit jen hotovostní část na celé koruny). Přepočítejte je na haléře."
  },
  {
   "code": "order_not_cancellable",
   "status": 409,
   "title_en": "The order can no longer be cancelled",
   "title_cs": "Objednávku už nelze zrušit",
   "hint_en": "The kitchen has started, or the order is already handed out or cancelled. `getOrder` shows its state; a change now goes through the restaurant (by phone).",
   "hint_cs": "Kuchyň už začala, nebo je objednávka vydaná či zrušená. Stav ukáže `getOrder`; změnu teď řeší provozovna (telefonicky)."
  },
  {
   "code": "order_not_awaiting_payment",
   "status": 409,
   "title_en": "The order is not waiting for payment",
   "title_cs": "Objednávka nečeká na platbu",
   "hint_en": "The order is not waiting for an online payment – it is paid, cancelled or paid another way. Read its state with `getOrder`.",
   "hint_cs": "Objednávka nečeká na online platbu – je zaplacená, zrušená nebo placená jinak. Stav načtěte přes `getOrder`."
  },
  {
   "code": "customer_not_verified",
   "status": 403,
   "title_en": "The customer's phone number is not verified",
   "title_cs": "Telefon zákazníka není ověřený",
   "hint_en": "Verify the customer's phone first: `startPhoneVerification` sends a code by SMS, `confirmPhoneVerification` checks it.",
   "hint_cs": "Nejdřív ověřte telefon zákazníka: `startPhoneVerification` pošle kód SMS, `confirmPhoneVerification` ho ověří."
  },
  {
   "code": "verification_failed",
   "status": 422,
   "title_en": "The verification code is wrong or expired",
   "title_cs": "Ověřovací kód je špatný nebo vypršel",
   "hint_en": "The code is wrong or older than 10 minutes. Let the customer type it again; after 5 wrong tries, or once it has expired, send a new code.",
   "hint_cs": "Kód je špatný nebo starší než 10 minut. Ať ho zákazník zadá znovu; po 5 chybných pokusech nebo po vypršení pošlete nový."
  },
  {
   "code": "verification_resend_too_early",
   "status": 429,
   "title_en": "A new code can be sent later",
   "title_cs": "Nový kód lze poslat až později",
   "hint_en": "A new code can go out 60 seconds after the previous one. Wait `Retry-After` seconds.",
   "hint_cs": "Nový kód lze poslat 60 sekund po předchozím. Počkejte `Retry-After` sekund."
  },
  {
   "code": "sms_quota_exceeded",
   "status": 429,
   "title_en": "The SMS limit was reached",
   "title_cs": "Limit SMS je vyčerpaný",
   "hint_en": "The daily limit of verification SMS is used up (5 codes a day to one phone from your connection, 15 from all applications, or the daily quota of your connection). Wait `Retry-After` seconds – until midnight.",
   "hint_cs": "Denní limit ověřovacích SMS je vyčerpaný (5 kódů denně na jeden telefon z vašeho připojení, 15 ze všech aplikací, nebo denní kvóta vašeho připojení). Počkejte `Retry-After` sekund – do půlnoci."
  },
  {
   "code": "sms_country_not_supported",
   "status": 422,
   "title_en": "SMS cannot be sent to this country",
   "title_cs": "Do této země SMS neposíláme",
   "hint_en": "Verification SMS go only to Czech (+420) and Slovak (+421) numbers. Ask the customer for such a number.",
   "hint_cs": "Ověřovací SMS posíláme jen na česká (+420) a slovenská (+421) čísla. Požádejte zákazníka o takové číslo."
  },
  {
   "code": "voucher_invalid",
   "status": 422,
   "title_en": "The voucher code is not valid",
   "title_cs": "Kód voucheru neplatí",
   "hint_en": "No voucher has this code. Let the customer check it; repeated wrong codes end in `voucher_attempts_exceeded`.",
   "hint_cs": "Voucher s tímto kódem neexistuje. Ať zákazník kód zkontroluje; opakované špatné kódy skončí `voucher_attempts_exceeded`."
  },
  {
   "code": "voucher_expired",
   "status": 422,
   "title_en": "The voucher has expired",
   "title_cs": "Voucher vypršel",
   "hint_en": "The validity of the voucher has ended. Remove it from the payments; the customer pays another way.",
   "hint_cs": "Platnost voucheru skončila. Odeberte ho z plateb; zákazník zaplatí jinak."
  },
  {
   "code": "voucher_used_up",
   "status": 422,
   "title_en": "The voucher has no balance left",
   "title_cs": "Voucher je vyčerpaný",
   "hint_en": "Nothing is left on the voucher. Remove it from the payments.",
   "hint_cs": "Na voucheru nic nezbývá. Odeberte ho z plateb."
  },
  {
   "code": "voucher_blocked",
   "status": 422,
   "title_en": "The voucher is blocked",
   "title_cs": "Voucher je zablokovaný",
   "hint_en": "The restaurant blocked the voucher. Remove it from the payments; the customer has to contact the restaurant.",
   "hint_cs": "Provozovna voucher zablokovala. Odeberte ho z plateb; zákazník se musí obrátit na provozovnu."
  },
  {
   "code": "voucher_not_accepted_here",
   "status": 422,
   "title_en": "The voucher cannot be used at this restaurant",
   "title_cs": "Voucher na této provozovně neplatí",
   "hint_en": "The voucher is valid only at other restaurants of the account. Remove it from the payments.",
   "hint_cs": "Voucher platí jen na jiných provozovnách účtu. Odeberte ho z plateb."
  },
  {
   "code": "voucher_attempts_exceeded",
   "status": 429,
   "title_en": "Too many invalid voucher attempts",
   "title_cs": "Příliš mnoho neplatných pokusů o voucher",
   "hint_en": "Too many wrong voucher codes. Wait `Retry-After` seconds and do not let anyone try codes in a loop.",
   "hint_cs": "Příliš mnoho špatných kódů voucherů. Počkejte `Retry-After` sekund a nedovolte zkoušet kódy dokola."
  },
  {
   "code": "promo_code_invalid",
   "status": 422,
   "title_en": "The promo code is not valid",
   "title_cs": "Slevový kód neplatí",
   "hint_en": "The restaurant has no such code here (or turned it off). Let the customer check it; repeated wrong codes end in `promo_code_attempts_exceeded`.",
   "hint_cs": "Provozovna takový kód nemá (nebo ho vypnula). Ať zákazník kód zkontroluje; opakované špatné kódy skončí `promo_code_attempts_exceeded`."
  },
  {
   "code": "promo_code_expired",
   "status": 422,
   "title_en": "The promo code has expired",
   "title_cs": "Slevový kód už neplatí",
   "hint_en": "The promotion of the code has ended. Remove the code from the quote; the order works without it.",
   "hint_cs": "Akce kódu skončila. Odeberte kód z kalkulace; objednávka jde i bez něj."
  },
  {
   "code": "promo_code_not_applicable",
   "status": 422,
   "title_en": "The promo code does not apply to this order",
   "title_cs": "Slevový kód na tuto objednávku neplatí",
   "hint_en": "`detail` says why – the lowest price of the items (and how much is missing), the lowest number of items, a missing part of a set, nothing in the basket the code is for, delivery or pickup only, not valid yet, not valid on this day or at this time, registered customers only (a linked customer with a verified phone) or the first order only. Show it to the customer.",
   "hint_cs": "`detail` říká proč – nejnižší cena položek (a kolik chybí), nejmenší počet kusů, chybějící část sady, v košíku není nic, na co kód platí, jen rozvoz nebo odběr, platí až později, neplatí v tento den nebo čas, jen pro registrované zákazníky (propojený zákazník s ověřeným telefonem) nebo jen na první objednávku. Ukažte ho zákazníkovi."
  },
  {
   "code": "promo_code_used_up",
   "status": 422,
   "title_en": "The promo code has been used up",
   "title_cs": "Slevový kód je vyčerpaný",
   "hint_en": "The promotion reached its number of uses, the single-use code has already been used, or the customer has used the promotion as many times as allowed (`max_per_customer`). Remove the code from the quote.",
   "hint_cs": "Akce dosáhla svého počtu použití, jednorázový kód už byl použitý, nebo zákazník akci využil, kolikrát mohl (`max_per_customer`). Odeberte kód z kalkulace."
  },
  {
   "code": "promo_code_attempts_exceeded",
   "status": 429,
   "title_en": "Too many invalid promo code attempts",
   "title_cs": "Příliš mnoho neplatných pokusů o slevový kód",
   "hint_en": "Too many wrong codes (the limits are shared with vouchers). Wait `Retry-After` seconds and do not let anyone try codes in a loop.",
   "hint_cs": "Příliš mnoho špatných kódů (limity jsou společné s vouchery). Počkejte `Retry-After` sekund a nedovolte zkoušet kódy dokola."
  },
  {
   "code": "promotion_changed",
   "status": 409,
   "title_en": "A promotion of the quote has changed",
   "title_cs": "Akce z kalkulace se změnila",
   "hint_en": "After the quote the restaurant turned a promotion off or it ran out, the customer reached its limit per customer, or another order used the single-use code. Create a new quote and show the customer the new price.",
   "hint_cs": "Po kalkulaci provozovna akci vypnula nebo se vyčerpala, zákazník dosáhl jejího limitu na zákazníka, nebo jednorázový kód použila jiná objednávka. Spočítejte košík znovu a ukažte zákazníkovi novou cenu."
  },
  {
   "code": "device_required",
   "status": 403,
   "title_en": "Only a paired device may do this",
   "title_cs": "Tohle smí jen spárované zařízení",
   "hint_en": "Only a device paired in the administration may do this (the register, KDS or attendance terminal of Profirest); a token of an integration may not.",
   "hint_cs": "Tohle smí jen zařízení spárované v administraci (pokladna, KDS nebo píchačka Profirestu); token integrace ne."
  },
  {
   "code": "legacy_identity_unsupported",
   "status": 403,
   "title_en": "This application has no API v1 identity",
   "title_cs": "Tato aplikace identitu API v1 nemá",
   "hint_en": "Only Profirest's own register, kitchen display and courier apps move between API v1 and API v2. Other applications stay on API v2.",
   "hint_cs": "Mezi API v1 a API v2 přecházejí jen vlastní aplikace Profirestu pro pokladnu, kuchyňský displej a kurýra. Ostatní aplikace zůstávají na API v2."
  },
  {
   "code": "no_legacy_identity",
   "status": 404,
   "title_en": "The restaurant has no API v1 identity for this app",
   "title_cs": "Provozovna pro tuto aplikaci identitu API v1 nemá",
   "hint_en": "The courier app signs in to API v1 with the password of the web kitchen – the restaurant has none. The device stays on API v2; set up the web kitchen and call again.",
   "hint_cs": "Aplikace kurýra se v API v1 přihlašuje heslem webové kuchyně – provozovna ho nemá. Zařízení zůstává na API v2; založte webovou kuchyni a zavolejte znovu."
  },
  {
   "code": "staff_session_required",
   "status": 403,
   "title_en": "An employee must sign in on the device first",
   "title_cs": "Nejdřív se musí na zařízení přihlásit zaměstnanec",
   "hint_en": "An employee has to sign in on the device with a PIN or card (`createStaffSession`); send the session in `Profirest-Staff-Token`.",
   "hint_cs": "Na zařízení se musí přihlásit zaměstnanec PINem nebo čipem (`createStaffSession`); relaci posílejte v `Profirest-Staff-Token`."
  },
  {
   "code": "staff_session_expired",
   "status": 403,
   "title_en": "The employee sign-in has expired",
   "title_cs": "Přihlášení zaměstnance vypršelo",
   "hint_en": "The sign-in of the employee has ended – unused for `idle_timeout_seconds`, past `max_expires_at`, signed out, or the PIN or card changed. Let the employee sign in again.",
   "hint_cs": "Přihlášení zaměstnance skončilo – nepoužité po `idle_timeout_seconds`, po `max_expires_at`, odhlášené, nebo se změnil PIN či čip. Ať se zaměstnanec přihlásí znovu."
  },
  {
   "code": "license_expired",
   "status": 403,
   "title_en": "The licence of the restaurant has expired",
   "title_cs": "Licence provozovny vypršela",
   "hint_en": "The licence ended (`DeviceSettings.paid_until`) and could not be renewed from the credit. Lock the device and let the owner renew the licence in the administration; the device settings, backups, diagnostics and offline receipts issued before the end still work. Since 26.11.27.",
   "hint_cs": "Licence skončila (`DeviceSettings.paid_until`) a z kreditu ji obnovit nešlo. Zařízení zamkněte a ať majitel licenci obnoví v administraci; nastavení zařízení, zálohy, diagnostika a offline účtenky vystavené před koncem fungují dál. Od 26.11.27."
  },
  {
   "code": "staff_credentials_invalid",
   "status": 422,
   "title_en": "Wrong PIN or unknown card",
   "title_cs": "Špatný PIN nebo neznámý čip",
   "hint_en": "Wrong PIN or an unknown card. Let the employee try again; repeated failures lock the sign-in (`staff_locked`).",
   "hint_cs": "Špatný PIN nebo neznámý čip. Ať to zaměstnanec zkusí znovu; opakované chyby přihlašování zamknou (`staff_locked`)."
  },
  {
   "code": "staff_ambiguous",
   "status": 409,
   "title_en": "Several employees share this PIN; choose one",
   "title_cs": "Tento PIN má víc zaměstnanců; vyberte jednoho",
   "hint_en": "Several employees have this PIN. Offer the `candidates` and repeat the sign-in with the chosen `employee_id`.",
   "hint_cs": "Tento PIN má víc zaměstnanců. Nabídněte `candidates` a přihlášení zopakujte se zvoleným `employee_id`."
  },
  {
   "code": "staff_locked",
   "status": 429,
   "title_en": "Too many wrong PINs or cards",
   "title_cs": "Příliš mnoho špatných PINů nebo čipů",
   "hint_en": "Too many wrong PINs or cards. Wait `Retry-After` seconds; a forgotten PIN is changed by a manager in the administration.",
   "hint_cs": "Příliš mnoho špatných PINů nebo čipů. Počkejte `Retry-After` sekund; zapomenutý PIN změní vedoucí v administraci."
  },
  {
   "code": "staff_role_missing",
   "status": 403,
   "title_en": "The signed-in employee may not do this",
   "title_cs": "Přihlášený zaměstnanec tohle nesmí",
   "hint_en": "The signed-in employee lacks the permission for this (for example a register or kitchen manager). Sign in an employee who has it; permissions are set in the administration (Employees).",
   "hint_cs": "Přihlášený zaměstnanec na tohle nemá oprávnění (např. vedoucí pokladny nebo kuchyně). Přihlaste zaměstnance, který ho má; oprávnění se nastavují v administraci (Zaměstnanci)."
  },
  {
   "code": "module_not_licensed",
   "status": 403,
   "title_en": "The restaurant's licence does not include this module",
   "title_cs": "Licence provozovny tento modul nezahrnuje",
   "hint_en": "The licence of the restaurant does not include this module (for example Attendance). The owner adds it in the administration (Licence).",
   "hint_cs": "Licence provozovny tento modul (např. Docházku) nezahrnuje. Majitel ho přidá v administraci (Licence)."
  },
  {
   "code": "reservation_unavailable",
   "status": 409,
   "title_en": "The time is not free",
   "title_cs": "Termín není volný",
   "hint_en": "No table, employee or room is free at that time (`detail` says which). Offer another time from `getReservationAvailability`.",
   "hint_cs": "V tu dobu není volný stůl, pracovník ani místnost (co přesně, říká `detail`). Nabídněte jiný čas z `getReservationAvailability`."
  },
  {
   "code": "reservation_not_allowed",
   "status": 422,
   "title_en": "The rules of the restaurant do not allow this reservation",
   "title_cs": "Pravidla provozovny tuto rezervaci nedovolí",
   "hint_en": "Too soon, too far ahead, outside the opening hours, a closed day, too big a party, or online reservations are off – `detail` starts with the reason. See `getReservationSettings`; repeating will not help.",
   "hint_cs": "Příliš brzy, příliš dopředu, mimo otevírací dobu, zavřený den, příliš velká skupina, nebo jsou online rezervace vypnuté – `detail` začíná důvodem. Viz `getReservationSettings`; opakování nepomůže."
  },
  {
   "code": "reservation_state_conflict",
   "status": 409,
   "title_en": "The reservation is in another state",
   "title_cs": "Rezervace je v jiném stavu",
   "hint_en": "The reservation cannot do this in its state (for example confirm a cancelled one). Read it again with `getReservation`.",
   "hint_cs": "Rezervace to ve svém stavu neumí (třeba potvrdit zrušenou). Načtěte ji znovu přes `getReservation`."
  },
  {
   "code": "lodging_state_conflict",
   "status": 409,
   "title_en": "The guest is not staying now",
   "title_cs": "Host teď není ubytovaný",
   "hint_en": "Charges go only to stays checked in now; the guest has not arrived yet or has left. Offer the rooms from `listInHouseStays`; the reception adds other charges in the administration.",
   "hint_cs": "Útrata jde jen na pobyt, který je právě ubytovaný; host ještě nepřijel nebo už odjel. Nabídněte pokoje z `listInHouseStays`; ostatní útraty zapíše recepce v administraci."
  },
  {
   "code": "stay_state_conflict",
   "status": 409,
   "title_en": "The stay does not allow this step now",
   "title_cs": "Pobyt tento krok teď nedovolí",
   "hint_en": "The step does not fit the state of the stay (for example checking out a stay that has not arrived), or the receipt for the stay is issued and the account is closed. `detail` says why; read the stay again with `getStay` and offer only its `actions`.",
   "hint_cs": "Krok nesedí na stav pobytu (třeba odhlásit pobyt, který nepřijel), nebo je vystavený doklad za pobyt a účet je uzavřený. Proč, říká `detail`; načtěte pobyt znovu přes `getStay` a nabídněte jen jeho `actions`."
  },
  {
   "code": "lodging_room_unavailable",
   "status": 409,
   "title_en": "The room is not free in these dates",
   "title_cs": "Pokoj v tomto termínu není volný",
   "hint_en": "Another stay holds the room in these dates, the room is out of order, or no room of the type is free. Read `getLodgingAvailability` and pick a free room.",
   "hint_cs": "Pokoj v tomto termínu drží jiný pobyt, je mimo provoz, nebo není volný žádný pokoj typu. Načtěte `getLodgingAvailability` a vyberte volný pokoj."
  },
  {
   "code": "attendance_not_enabled",
   "status": 422,
   "title_en": "The employee is not kept in attendance at this restaurant",
   "title_cs": "Zaměstnanec se na této provozovně nevede v docházce",
   "hint_en": "The employee is not kept in attendance at this restaurant. It is switched on in the employee card in the administration.",
   "hint_cs": "Zaměstnanec se na této provozovně v docházce nevede. Zapíná se v kartě zaměstnance v administraci."
  },
  {
   "code": "attendance_state_conflict",
   "status": 409,
   "title_en": "The punch does not fit the current attendance state",
   "title_cs": "Záznam nesedí na aktuální stav docházky",
   "hint_en": "The punch does not fit the current state of the employee (for example a break end without a break). `detail` says what is wrong; read `listAttendancePresence` and offer the punch that fits.",
   "hint_cs": "Píchnutí nesedí na aktuální stav zaměstnance (např. konec přestávky bez přestávky). Co nesedí, říká `detail`; načtěte `listAttendancePresence` a nabídněte píchnutí, které sedí."
  },
  {
   "code": "offline_records_disabled",
   "status": 422,
   "title_en": "The restaurant does not accept offline records",
   "title_cs": "Provozovna nepřijímá záznamy pořízené offline",
   "hint_en": "The restaurant does not accept punches recorded offline. Punch online; a missed record is added in the administration by hand, or offline records are allowed in the attendance settings.",
   "hint_cs": "Provozovna nepřijímá píchnutí pořízená offline. Píchejte online; chybějící záznam se doplní v administraci ručně, nebo se offline záznamy povolí v nastavení docházky."
  },
  {
   "code": "occurred_at_out_of_range",
   "status": 422,
   "title_en": "The time of the record is too old or in the future",
   "title_cs": "Čas záznamu je moc starý nebo v budoucnosti",
   "hint_en": "The time is in the future (check the clock of the device) or older than the restaurant accepts for offline records. Add such a record in the administration by hand.",
   "hint_cs": "Čas je v budoucnosti (zkontrolujte hodiny zařízení), nebo je starší, než provozovna u offline záznamů přijímá. Takový záznam doplňte v administraci ručně."
  },
  {
   "code": "punch_id_conflict",
   "status": 409,
   "title_en": "Another record already uses this id",
   "title_cs": "Toto id už má jiný záznam",
   "hint_en": "This `id` belongs to another punch. Give every new punch a new UUID; repeat a punch only with its own `id`.",
   "hint_cs": "Toto `id` patří jinému píchnutí. Každé nové píchnutí potřebuje nové UUID; píchnutí opakujte jen s jeho vlastním `id`."
  },
  {
   "code": "absence_requests_disabled",
   "status": 403,
   "title_en": "The restaurant does not accept requests for time off",
   "title_cs": "Provozovna žádosti o volno nepřijímá",
   "hint_en": "Requests for time off at the terminal are switched off (`AttendanceTerminal.absence_requests.enabled`). The owner or a manager switches them on in the administration (Attendance › Requests for time off).",
   "hint_cs": "Žádosti o volno na terminálu jsou vypnuté (`AttendanceTerminal.absence_requests.enabled`). Zapne je majitel nebo vedoucí v administraci (Docházka › Žádosti o volno)."
  },
  {
   "code": "absence_request_not_allowed",
   "status": 422,
   "title_en": "The request breaks a rule of the restaurant",
   "title_cs": "Žádost porušuje pravidlo provozovny",
   "hint_en": "The request breaks a rule of the restaurant (kind, notice, length, how far ahead, people of the section off). `detail` says which one; show it to the employee and let them change the dates.",
   "hint_cs": "Žádost porušuje pravidlo provozovny (druh volna, předstih, délka, jak daleko dopředu, kolik lidí ze sekce má volno). Které, říká `detail`; ukažte ho zaměstnanci a nechte ho změnit termín."
  },
  {
   "code": "absence_request_conflict",
   "status": 409,
   "title_en": "The employee already has time off then",
   "title_cs": "Zaměstnanec už v tu dobu volno má",
   "hint_en": "The employee already asked for or has time off on some of the days (`detail` says when). Read `listMyAbsenceRequests`; a pending request can be withdrawn first.",
   "hint_cs": "Zaměstnanec už na některé z dnů o volno požádal nebo ho má (kdy, říká `detail`). Načtěte `listMyAbsenceRequests`; čekající žádost jde nejdřív vzít zpět."
  },
  {
   "code": "absence_request_decided",
   "status": 409,
   "title_en": "The request is already decided",
   "title_cs": "Žádost už je vyřízená",
   "hint_en": "The request was already approved or refused and cannot be withdrawn at the terminal. Approved time off is cancelled by a manager in the administration.",
   "hint_cs": "Žádost už je schválená nebo zamítnutá a na terminálu ji vzít zpět nejde. Schválené volno zruší vedoucí v administraci."
  },
  {
   "code": "portion_tracking_disabled",
   "status": 409,
   "title_en": "The restaurant does not track portions for you",
   "title_cs": "Provozovna pro vás porce nehlídá",
   "hint_en": "The restaurant does not limit portions, or only at its registers (guest applications then cannot change them). Turn tracking on in the administration, or leave availability alone.",
   "hint_cs": "Provozovna porce nehlídá, nebo jen na pokladnách (aplikace hostů je pak měnit nemohou). Zapněte hlídání v administraci, nebo dostupnost neměňte."
  },
  {
   "code": "ticket_cancelled",
   "status": 409,
   "title_en": "The order was cancelled in the kitchen",
   "title_cs": "Objednávka je v kuchyni zrušená",
   "hint_en": "The order was cancelled meanwhile. Reload the ticket and stop working on it.",
   "hint_cs": "Objednávka byla mezitím zrušena. Načtěte bon znovu a dál na něm nepracujte."
  },
  {
   "code": "ticket_already_delivered",
   "status": 409,
   "title_en": "The order is already delivered",
   "title_cs": "Objednávka je už doručená",
   "hint_en": "The order was delivered (perhaps marked on another device). Reload the route; a mistaken delivery is put right by the kitchen display.",
   "hint_cs": "Objednávka je doručená (třeba označená na jiném zařízení). Načtěte trasu znovu; omylem označené doručení opraví kuchyňský displej."
  },
  {
   "code": "already_paid",
   "status": 409,
   "title_en": "The order is already paid",
   "title_cs": "Objednávka je už zaplacená",
   "hint_en": "The payment at the door was already recorded – `paid_by` says how and when. Show the order as paid and take no payment again; the restaurant settles anything else.",
   "hint_cs": "Platba u dveří už je zapsaná – čím a kdy, říká `paid_by`. Ukažte objednávku jako zaplacenou a platbu znovu neberte; cokoli dalšího vyřeší provozovna."
  },
  {
   "code": "payment_method_not_changeable",
   "status": 409,
   "title_en": "Nothing is collected at the door for this order",
   "title_cs": "U této objednávky se u dveří nic nevybírá",
   "hint_en": "The order was paid in advance (by card or online, at the register) or is paid by meal vouchers, the company account or an invoice. Take no payment; hand the order over.",
   "hint_cs": "Objednávka je zaplacená předem (kartou nebo online, u pokladny), nebo se platí stravenkami, účtem podniku či fakturou. Platbu neberte; objednávku předejte."
  },
  {
   "code": "amount_mismatch",
   "status": 422,
   "title_en": "The amount does not match the order",
   "title_cs": "Částka nesedí s objednávkou",
   "hint_en": "`amount` must be `amount_due` + `tip` of the ticket. Reload the ticket – the order may have changed – and send the amount actually paid.",
   "hint_cs": "`amount` musí být `amount_due` + `tip` bonu. Načtěte bon znovu – objednávka se mohla změnit – a pošlete skutečně zaplacenou částku."
  },
  {
   "code": "note_required",
   "status": 422,
   "title_en": "A note is required for this reason",
   "title_cs": "K tomuto důvodu chybí poznámka",
   "hint_en": "The reason `other` needs `note` saying what happened. Ask the courier for it and send the report again.",
   "hint_cs": "Důvod `other` potřebuje `note`, co se stalo. Vyžádejte ji od kurýra a hlášení pošlete znovu."
  },
  {
   "code": "ticket_not_amendable",
   "status": 409,
   "title_en": "Items cannot be added to this order",
   "title_cs": "K této objednávce nejde přidat položky",
   "hint_en": "Items can no longer be added – the order is done or handed out, or paid in advance (card, online). Create a new ticket for the extra items.",
   "hint_cs": "Položky už přidat nejde – objednávka je hotová nebo vydaná, nebo zaplacená předem (kartou, online). Na další položky založte nový bon."
  },
  {
   "code": "nothing_to_complete",
   "status": 409,
   "title_en": "Nothing is open in this segment",
   "title_cs": "V tomto segmentu nic otevřeného není",
   "hint_en": "Nothing is open in this part any more – someone else completed or handed it out. Reload the view.",
   "hint_cs": "V této části už nic otevřeného není – dokončil nebo vydal ji někdo jiný. Načtěte zobrazení znovu."
  },
  {
   "code": "action_already_undone",
   "status": 409,
   "title_en": "The action was already taken back",
   "title_cs": "Akce už byla vzata zpět",
   "hint_en": "The action was already taken back (perhaps on another device). Reload the list of actions.",
   "hint_cs": "Akce už byla vzata zpět (třeba na jiném zařízení). Načtěte seznam akcí znovu."
  },
  {
   "code": "price_changed",
   "status": 409,
   "title_en": "A price changed; reload the catalog",
   "title_cs": "Cena se změnila; načtěte sortiment znovu",
   "hint_en": "A price differs from the catalog. Reload the catalog (`getCatalog`) and build the receipt again; a different price needs a register manager.",
   "hint_cs": "Cena se liší od sortimentu. Načtěte sortiment znovu (`getCatalog`) a účtenku sestavte znovu; jinou cenu musí schválit vedoucí pokladny."
  },
  {
   "code": "manager_approval_required",
   "status": 403,
   "title_en": "A register manager must approve this",
   "title_cs": "Tohle musí schválit vedoucí pokladny",
   "hint_en": "This needs a register manager: sign one in on the device, or send `manager_credential` (the PIN or card of the manager) with the request.",
   "hint_cs": "Tohle musí schválit vedoucí pokladny: přihlaste ho na zařízení, nebo s požadavkem pošlete `manager_credential` (jeho PIN nebo čip)."
  },
  {
   "code": "receipt_id_conflict",
   "status": 409,
   "title_en": "Another receipt already has this id",
   "title_cs": "Toto id už má jiná účtenka",
   "hint_en": "This `id` belongs to another receipt (another device or number). Give every new receipt a new UUID; repeat a receipt only unchanged with its own `id`.",
   "hint_cs": "Toto `id` patří jiné účtence (jiné zařízení nebo číslo). Každá nová účtenka potřebuje nové UUID; účtenku opakujte jen beze změny s jejím `id`."
  },
  {
   "code": "receipt_number_conflict",
   "status": 409,
   "title_en": "The device already used this receipt number",
   "title_cs": "Toto číslo účtenky zařízení už použilo",
   "hint_en": "The device already issued another receipt with this number (`existing_id`). Fix the counter of the device – continue after the highest number it issued – and issue the receipt with the next number.",
   "hint_cs": "Zařízení už s tímto číslem vystavilo jinou účtenku (`existing_id`). Opravte čítač zařízení – pokračujte za nejvyšším vystaveným číslem – a účtenku vystavte s dalším číslem."
  },
  {
   "code": "receipt_already_cancelled",
   "status": 409,
   "title_en": "The receipt is already cancelled",
   "title_cs": "Účtenka už je stornovaná",
   "hint_en": "The receipt already has a storno; there is nothing more to do. `getReceipt` shows it.",
   "hint_cs": "Účtenka už je stornovaná; není co dalšího dělat. Storno ukáže `getReceipt`."
  },
  {
   "code": "receipt_not_cancellable",
   "status": 409,
   "title_en": "The receipt cannot be cancelled",
   "title_cs": "Účtenku nejde stornovat",
   "hint_en": "The receipt cannot be cancelled – `detail` says why (it is a storno itself, a sold voucher was already used, a voucher payment cannot be returned). Settle the cause first, or issue a new receipt.",
   "hint_cs": "Účtenku nejde stornovat – proč, říká `detail` (sama je storno, prodaný voucher se už použil, platbu voucherem nejde vrátit). Nejdřív vyřešte příčinu, nebo vystavte novou účtenku."
  },
  {
   "code": "receipt_payment_not_changeable",
   "status": 409,
   "title_en": "The payment of this receipt cannot change",
   "title_cs": "Platbu této účtenky změnit nejde",
   "hint_en": "Only cash, meal voucher, company account and invoice payments change – `detail` says why this one cannot (it is a cancellation document, or the receipt is paid only by card or gift voucher). A refund to a card or a voucher goes only through a cancellation (`cancelReceipt`) and a new receipt.",
   "hint_cs": "Měnit jdou jen platby hotově, stravenkami, na firemní účet a fakturou – proč tahle ne, říká `detail` (je to storno doklad, nebo je účtenka zaplacená jen kartou či dárkovým voucherem). Vrácení na kartu nebo na voucher jde jen stornem (`cancelReceipt`) a novou účtenkou."
  },
  {
   "code": "pos_shift_closed",
   "status": 409,
   "title_en": "The shift of the receipt is already closed",
   "title_cs": "Směna účtenky je už uzavřená",
   "hint_en": "The receipt belongs to a closed shift – its cash was already counted, so the register cannot change its payment. Let the administration change it, or cancel the receipt and issue a new one.",
   "hint_cs": "Účtenka patří do uzavřené směny – hotovost už je spočítaná, pokladna její platbu změnit nesmí. Změnu udělá administrace, nebo účtenku stornujte a vystavte novou."
  },
  {
   "code": "issued_at_out_of_range",
   "status": 422,
   "title_en": "The receipt is too old or in the future",
   "title_cs": "Účtenka je moc stará nebo v budoucnosti",
   "hint_en": "`issued_at` is more than 7 days old (62 days for a receipt recorded offline) or more than 5 minutes ahead of the server. Check the clock of the device.",
   "hint_cs": "`issued_at` je starší než 7 dní (u účtenky pořízené offline 62 dní) nebo víc než 5 minut napřed proti serveru. Zkontrolujte hodiny zařízení."
  },
  {
   "code": "pos_shift_empty",
   "status": 409,
   "title_en": "There is nothing to close in this shift",
   "title_cs": "Ve směně není co uzavřít",
   "hint_en": "There is nothing to close in the shift; no close is needed.",
   "hint_cs": "Ve směně není co uzavřít; uzávěrka není potřeba."
  },
  {
   "code": "cash_book_not_started",
   "status": 409,
   "title_en": "The cash book has not started",
   "title_cs": "Pokladní kniha ještě nezačala",
   "hint_en": "Record the opening balance first – a register manager with `kind` `opening`, or the owner in the administration (Statistics → Cash book). Then send the movement again.",
   "hint_cs": "Nejdřív zapište počáteční stav – vedoucí pokladny s `kind` `opening`, nebo majitel v administraci (Statistiky → Pokladní kniha). Pak pohyb pošlete znovu."
  },
  {
   "code": "cash_book_already_started",
   "status": 409,
   "title_en": "The cash book already has an opening balance",
   "title_cs": "Pokladní kniha už má počáteční stav",
   "hint_en": "The opening balance is recorded once. When the drawer does not match the book, do a cash check in the administration (Statistics → Cash book).",
   "hint_cs": "Počáteční stav se zapisuje jednou. Když kasa nesedí s knihou, udělejte kontrolu pokladny v administraci (Statistiky → Pokladní kniha)."
  },
  {
   "code": "voucher_not_for_sale",
   "status": 422,
   "title_en": "The voucher cannot be sold",
   "title_cs": "Voucher nejde prodat",
   "hint_en": "This voucher cannot be sold – it is already sold or used, its sale is not allowed, or the price is above its value. Choose another voucher.",
   "hint_cs": "Tento voucher nejde prodat – už je prodaný nebo použitý, jeho prodej není povolený, nebo je cena vyšší než jeho hodnota. Zvolte jiný voucher."
  },
  {
   "code": "tab_closed",
   "status": 409,
   "title_en": "The tab is already closed",
   "title_cs": "Účet stolu je už uzavřený",
   "hint_en": "The tab is already closed (perhaps on another device). Open a new tab for further orders.",
   "hint_cs": "Účet stolu je už uzavřený (třeba na jiném zařízení). Na další objednávky otevřete nový účet."
  },
  {
   "code": "stock_taking_id_conflict",
   "status": 409,
   "title_en": "Another stock taking already has this id",
   "title_cs": "Toto id už má jiná inventura",
   "hint_en": "This `id` belongs to another stock taking. Give every new stock taking a new UUID.",
   "hint_cs": "Toto `id` patří jiné inventuře. Každá nová inventura potřebuje nové UUID."
  },
  {
   "code": "table_not_found",
   "status": 404,
   "title_en": "No table has this code",
   "title_cs": "Žádný stůl nemá tento kód",
   "hint_en": "Check the code under the QR code (8 characters). The restaurant may have printed new codes – scan the QR code on the table again.",
   "hint_cs": "Zkontrolujte kód pod QR kódem (8 znaků). Podnik možná vytiskl nové kódy – naskenujte znovu QR kód na stole."
  },
  {
   "code": "visit_ended",
   "status": 410,
   "title_en": "The visit of the table has ended",
   "title_cs": "Návštěva stolu skončila",
   "hint_en": "The tab was paid or the staff ended the visit, and the token of the phone ended with it. Do not start a new session by yourself; offer the guest to scan the QR code again.",
   "hint_cs": "Účet se zaplatil nebo obsluha návštěvu ukončila a s ní skončil i token telefonu. Novou relaci nezakládejte sami; nabídněte hostovi, ať QR kód naskenuje znovu."
  },
  {
   "code": "ordering_paused",
   "status": 422,
   "title_en": "Orders from the table are paused",
   "title_cs": "Objednávky od stolu jsou pozastavené",
   "hint_en": "The staff paused new orders for a while; calling the staff still works. Try again later.",
   "hint_cs": "Obsluha na chvíli pozastavila nové objednávky; zavolat obsluhu jde dál. Zkuste to později."
  },
  {
   "code": "table_not_open",
   "status": 422,
   "title_en": "The table has no open tab",
   "title_cs": "Stůl nemá otevřený účet",
   "hint_en": "The restaurant takes orders from the table only to a tab the staff opened. Call the staff.",
   "hint_cs": "Podnik bere objednávky od stolu jen na účet, který otevřela obsluha. Zavolejte obsluhu."
  },
  {
   "code": "device_not_verified",
   "status": 403,
   "title_en": "This phone is not verified at the table",
   "title_cs": "Telefon u stolu není ověřený",
   "hint_en": "Only a phone of the party sees the tab: enter the code from a friend at the table, or wait until the staff accepts the first order of this phone.",
   "hint_cs": "Účet vidí jen telefon skupiny: zadejte kód od kamaráda u stolu, nebo počkejte, až obsluha přijme první objednávku tohoto telefonu."
  },
  {
   "code": "join_code_invalid",
   "status": 422,
   "title_en": "Wrong code from a friend",
   "title_cs": "Špatný kód od kamaráda",
   "hint_en": "The code does not match the code of the table. Ask a friend at the table for the current code; `attempts_left` says how many attempts are left.",
   "hint_cs": "Kód nesedí s kódem stolu. Zeptejte se kamaráda u stolu na aktuální kód; `attempts_left` říká, kolik pokusů zbývá."
  },
  {
   "code": "join_locked",
   "status": 423,
   "title_en": "Too many wrong codes",
   "title_cs": "Příliš mnoho špatných kódů",
   "hint_en": "This phone entered a wrong code too many times. The staff unlocks it; ordering still works and the orders wait for the staff.",
   "hint_cs": "Tento telefon zadal špatný kód příliš mnohokrát. Odemkne ho obsluha; objednávat jde dál a objednávky čekají na obsluhu."
  },
  {
   "code": "join_not_available",
   "status": 409,
   "title_en": "Joining by a code is not available",
   "title_cs": "Přidání kódem není k dispozici",
   "hint_en": "The restaurant does not use codes from friends, or the table has no open visit. Order as usual – the staff confirms the first order.",
   "hint_cs": "Podnik kód od kamaráda nepoužívá, nebo stůl nemá otevřenou návštěvu. Objednejte jako obvykle – první objednávku potvrdí obsluha."
  },
  {
   "code": "product_not_orderable",
   "status": 422,
   "title_en": "This product cannot be ordered from the table",
   "title_cs": "Tento produkt nejde objednat od stolu",
   "hint_en": "The product is not in the menu for the table (`errors` points at the line). Reload the menu; order this product from the staff.",
   "hint_cs": "Produkt není v menu pro stůl (`errors` ukazuje na řádek). Načtěte menu znovu; tento produkt objednejte u obsluhy."
  },
  {
   "code": "too_many_pending_orders",
   "status": 409,
   "title_en": "Too many orders wait for the staff",
   "title_cs": "Na obsluhu čeká příliš mnoho objednávek",
   "hint_en": "Orders of this phone still wait for the staff. Wait until the staff decides about them, then order again.",
   "hint_cs": "Objednávky tohoto telefonu ještě čekají na obsluhu. Počkejte, až o nich rozhodne, a pak objednejte znovu."
  },
  {
   "code": "order_not_pending",
   "status": 409,
   "title_en": "The order no longer waits for the staff",
   "title_cs": "Objednávka už na obsluhu nečeká",
   "hint_en": "Someone decided about the order meanwhile – it was accepted, rejected, cancelled or it expired. Read its state again.",
   "hint_cs": "O objednávce mezitím někdo rozhodl – byla přijata, odmítnuta, zrušena nebo propadla. Načtěte znovu její stav."
  },
  {
   "code": "restaurant_offline",
   "status": 503,
   "title_en": "The main register of the restaurant is not connected",
   "title_cs": "Hlavní kasa podniku není připojená",
   "hint_en": "Nobody would take the request over now. Try again in a minute or ask the staff; on the Wi-Fi of the restaurant ordering may work.",
   "hint_cs": "Žádost by teď nikdo nepřevzal. Zkuste to za minutu, nebo požádejte obsluhu; na Wi-Fi podniku objednávání fungovat může."
  },
  {
   "code": "inbox_item_conflict",
   "status": 409,
   "title_en": "The request was already decided differently",
   "title_cs": "Žádost už je rozhodnutá jinak",
   "hint_en": "This item of the inbox already has another result. Do not change it; send later states with `putTableState`.",
   "hint_cs": "Tato položka schránky už má jiný výsledek. Neměňte ho; pozdější stavy posílejte přes `putTableState`."
  },
  {
   "code": "main_device_conflict",
   "status": 409,
   "title_en": "Another device is the main register",
   "title_cs": "Hlavní kasou je jiné zařízení",
   "hint_en": "Another device of the restaurant sends the heartbeat of ordering from the table. Turn ordering from the table off on this device, or take over 90 seconds after the other one stops.",
   "hint_cs": "Heartbeat objednávání od stolu posílá jiné zařízení provozovny. Na tomto zařízení objednávání od stolu vypněte, nebo převezměte 90 sekund po tom, co to druhé přestane."
  },
  {
   "code": "upload_closed",
   "status": 409,
   "title_en": "The log upload is finished or expired",
   "title_cs": "Nahrávání logu je dokončené nebo prošlé",
   "hint_en": "The upload was completed, given up, withdrawn or its request expired. Send nothing more to it; wait for a new `upload_logs` command.",
   "hint_cs": "Nahrávání bylo dokončené, vzdané, stažené nebo jeho žádost vypršela. Nic dalšího do něj neposílejte; počkejte na nový příkaz `upload_logs`."
  },
  {
   "code": "upload_incomplete",
   "status": 422,
   "title_en": "Parts of the log upload are missing",
   "title_cs": "Části nahrávání logu chybí",
   "hint_en": "`detail` lists the numbers of the missing parts. Send them with `putLogUploadPart` and complete the upload again.",
   "hint_cs": "`detail` vypisuje čísla chybějících částí. Pošlete je přes `putLogUploadPart` a nahrávání dokončete znovu."
  }
 ]
}
