# OpenAPI popis REST API

> Kde je strojový popis REST API ve formátu OpenAPI 3.1, jak z něj vygenerovat klienta a ověřovat odpovědi, a co slibujeme o změnách rozhraní.

- Sekce: Pro vývojáře
- Stránka: https://shopzi.cz/dokumentace/vyvojari/openapi
- Ověřeno: 2026-10-20

---

REST API má strojový popis ve formátu OpenAPI 3.1.0. Leží v souboru
`/openapi-v1.json` na doméně vašeho obchodu, tedy třeba
`https://muj-eshop.cz/openapi-v1.json`, a popisuje každou cestu, každý parametr, tvar každé
odpovědi i chyby, které cesta vrací. Chybí v něm jen odpověď 503 na doméně pozastaveného obchodu:
tu posílá ochranná vrstva ještě před API a nemá tvar chyby API, viz článek
[Chybové odpovědi](/dokumentace/vyvojari/chybove-odpovedi).

## Odkud se bere [#odkud-se-bere]

Soubor se **generuje** ze stejné smlouvy, podle které API dotaz čte a odpověď skládá. Při každé
změně rozhraní se přegeneruje a automatická kontrola kódu neprojde, dokud uložený soubor s kódem
nesouhlasí. Popis tedy nemůže slibovat pole, které odpověď nenese, ani zamlčet cestu, která běží.

Soubor je pro všechny obchody stejný: popisuje rozhraní, žádná data obchodu v něm nejsou, a stáhne
se bez klíče.

## Adresa serveru [#adresa-serveru]

Server je v dokumentu zapsaný jako šablona `https://{shop}.shopzi.cz/api/v1` s výchozí hodnotou
`muj-eshop`. Proměnná `shop` je subdoména obchodu na shopzi.cz. Obchod s vlastní doménou odpovídá
stejně i na ní, takže vygenerovanému klientovi můžete adresu nastavit rovnou, například
`https://muj-eshop.cz/api/v1`.

Přesnou adresu REST API obchodu ukazuje administrace v **Nastavení → API a MCP**,
v části **Přístup a klíče**, v kartě **Připojení klienta** pod nadpisem **REST API**. Je to doména,
na které má vlastník administraci otevřenou, s cestou `/api/v1`.

## Vygenerování klienta [#vygenerovani-klienta]

Dokument je běžné OpenAPI 3.1, takže poslouží kterýkoli generátor, který tuhle verzi zná. Typy pro
TypeScript:

```bash
npx openapi-typescript https://muj-eshop.cz/openapi-v1.json -o shopzi-api.d.ts
```

Klient pro Python, nebo pro jiný jazyk podle přepínače `-g`:

```bash
openapi-generator-cli generate \
  -i https://muj-eshop.cz/openapi-v1.json \
  -g python \
  -o shopzi-client
```

Dokument popisuje dvě rovnocenná schémata zabezpečení: `bearerAuth` (klíč v hlavičce
`Authorization: Bearer`) a `apiKeyHeader` (týž klíč v hlavičce `x-api-key`). Stačí jedno z nich;
vygenerovaný klient obvykle nabídne obě. Jak klíč získat, je v článku
[Autentizace a oprávnění](/dokumentace/vyvojari/autentizace-a-opravneni).

## Ověřování odpovědí [#overovani-odpovedi]

Každé schéma odpovědi je v `components.schemas` a jde podle něj ověřovat, třeba validátorem Ajv
v režimu JSON Schema 2020-12. Hodí se to hlavně v testech integrace: odpověď, která na schéma
nesedí, znamená chybu na jedné ze stran, a je lepší ji chytit u sebe než v účetnictví.

Schémata **pole navíc nezakazují**. Nové pole v odpovědi proto validaci neshodí, stejně jako
nerozbije vygenerovaného klienta, a přesně to říká slib o změnách níž. Kdo si validátor nastaví
přísněji (`additionalProperties: false`), vezme si tím na sebe každou budoucí změnu, kterou za
změnu verze nepovažujeme.

Dokument nese dvě vlastní rozšíření:

* `x-shopzi-scope` u každé operace říká, jaké oprávnění klíč potřebuje; `null` znamená libovolný
  platný klíč.
* `x-shopzi-sync-field` u výpisů říká, podle kterého času stránkuje `updated_since`: `updated_at`,
  nebo `created_at` u záznamů, které se po vzniku nemění.

V `components.headers` jsou popsané i hlavičky odpovědí: `X-RateLimit-Limit`,
`X-RateLimit-Remaining` a `X-RateLimit-Reset` u stropu volání, `Retry-After` u odpovědí 429 a 503,
`WWW-Authenticate` u 401 a `Content-Disposition` u PDF a ISDOC.

## Čas, peníze a výčty [#cas-penize-a-vycty]

* Čas je řetězec ve formátu `date-time`. V odpovědích přichází vždy v UTC se zónou `Z`
  a s mikrosekundami, například `2026-09-01T08:14:02.118204Z`. `datetime.fromisoformat` v Pythonu
  starším než 3.11 zónu `Z` nepřečte, tam ji nahraďte za `+00:00`. Datum bez času má tvar
  `RRRR-MM-DD`.
* Částky jsou celá čísla v haléřích a vedle nich stojí `currency_code`. Výjimkou jsou ceny
  položek katalogu dodavatelů (`/api/v1/catalog-items`), které jsou v setinách měny feedu, třeba
  v eurocentech; měnu říká `currency_code` téže položky. Sazba DPH je celé procento.
* Výčty (stavy objednávek, druhy dokladů a další) jsou v dokumentu vyjmenované. **Nová hodnota
  výčtu může přibýt bez nové verze**, takže klient s neznámou hodnotou nesmí spadnout.

## Co slibujeme o změnách [#co-slibujeme-o-zmenach]

Verze je v cestě i v názvu souboru: `/api/v1` a `/openapi-v1.json`.
Změna, která by rozbila existujícího klienta, tedy přejmenované nebo zmizelé pole, změněný typ,
zrušená cesta nebo nový povinný parametr, znamená **novou verzi cesty i nový soubor**, ne tichou
změnu téhle.

Za takovou změnu nepovažujeme nové pole v odpovědi, novou cestu ani novou hodnotu výčtu. Parser
proto musí neznámá pole a hodnoty přeskočit, ne na nich padat. Jak vypadají chyby a co s nimi
dělat, popisuje článek [Chybové odpovědi](/dokumentace/vyvojari/chybove-odpovedi).
