# Autentizace a oprávnění

> Jak se klíčem prokázat, kterou hlavičku poslat, co který rozsah otevírá a jak rozlišit neplatný klíč od chybějícího oprávnění.

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

---

Obě rozhraní, REST i MCP, se ověřují **týmž API klíčem**. Klíč vyrábí vlastník obchodu
v **Nastavení → API a MCP** (v levém sloupci Nastavení je to oddíl ve skupině
**Technické**) a zaškrtává u něj oprávnění. Tenhle článek popisuje, jak se klíčem prokázat a co která
kontrola odmítne; obchodnickou verzi postupu najdete v článku [API a MCP](/dokumentace/nastaveni/api-a-mcp).

## Nejdřív musí být plocha zapnutá [#nejdriv-musi-byt-plocha-zapnuta]

Externí přístup se nezapíná sám. Plochy jsou dvě a zapínají se **nezávisle**: `api` pro čtecí REST
a `mcp` pro server MCP, takže zapnuté REST API neznamená zapnuté MCP. Dokud vlastník obchodu plochu
nezapne, vrací **každá** cesta pod `/api/v1`, resp. `/api/mcp`, odpověď `403 external_access_not_enabled`,
a to **ještě než se ověří platnost klíče**: zavřená plocha schválně nerozlišuje platný klíč od
neplatného, aby se přes ni nedaly klíče uhodnout.

Plochu zapíná jen vlastník obchodu v **Nastavení → API a MCP**, v části
**Přístup a klíče**, přepínačem u řádku **REST API** nebo **Server MCP** v kartě **Externí přístup**:

1. Klikněte na přepínač. Nejdřív se ověří, že obchod plochu zapnout smí; když ji drží zavřenou tarif
   nebo zásah SHOPZI, věta pod řádkem to řekne a přepínač nepustí.
2. Při prvním zapnutí plochy se otevře dialog **Potvrzení odpovědnosti**. Zaškrtněte „Přečetl(a) jsem
   to a za klienty, kterým vydám klíč, odpovídám.“ a klikněte na **Potvrdit a pokračovat**. Znovu se
   potvrzení ptá jen po změně textu.
3. Krok potvrďte heslem do administrace, nebo šestimístným kódem z e-mailu, pokud se přihlašujete přes
   Google či Apple a heslo jste si nenastavili. Druhé ověření chce každé zapnutí.

Vypnutí je jedno kliknutí na tentýž přepínač, bez potvrzení a bez druhého ověření. Stav plochy se
čte při každém požadavku znovu, takže klienti dostanou odmítnutí hned při dalším volání. Manažer
a účet podpory SHOPZI kartu vidí, ale přepínače ne.

Zapnutá plocha ještě nestačí: **externí přístup má obchod s aktivním placeným tarifem, s jednorázovou
licencí, a také obchod ve zkušebním období, který má uloženou platební kartu** (kartu zadává obchodník
už při zakládání obchodu s placeným tarifem). Obchod na tarifu Free, se zrušeným předplatným nebo ve
zkušebním období BEZ karty dostane `403 plan_required`, i když má plochu zapnutou; jakmile obchodník
tarif zaplatí nebo kartu doplní, přístup se otevře sám a klíče fungují dál bez výměny. Když Stripe
zkouší neúspěšnou platbu znovu, přístup mezitím běží.

SHOPZI může externí přístup jednomu obchodu pozastavit (`403 external_access_suspended`), nebo
plochu dočasně vypnout všem obchodům naráz (`403 external_access_disabled`). Obojí plochu zavře, i když
ji má obchod zapnutou, a obojí se kontroluje dřív, než se ověří platnost klíče.

Pozastavený nebo neaktivní obchod neodpovídá vůbec, bez ohledu na klíč i na zapnutou plochu: ještě
před API ho odmítne ochranná vrstva odpovědí `503` s tělem
`{ "error": "Tento obchod je momentálně nedostupný." }`, tedy bez kódu chyby. Když týž stav
zachytí až API samo, odpoví `403 shop_unavailable`. Obchod, který ještě není spuštěný a jeho web je
schovaný za závěsem s PINem, na REST API i na serveru MCP odpovídá normálně: tam se prokazuje klíčem.

> **Ping nerozliší všechno** Ověřovací cesta odliší neplatný klíč od chybějícího oprávnění jen tehdy, když je plocha otevřená a klíč pro ni platí. Na zavřené ploše, na obchodě bez placeného tarifu, při pozastavení od SHOPZI i s klíčem pro druhou plochu neprojde ani správný klíč, takže z odmítnutí nepoznáte, jestli je klíč v pořádku.

## Pořadí kontrol [#poradi-kontrol]

Každý požadavek na `/api/v1` i `/api/mcp` projde branami v tomhle pořadí. O odpovědi rozhoduje první,
která neprojde, takže z kódu poznáte, kam až požadavek došel:

1. `403 origin_not_allowed`, jen u serveru MCP: požadavek nese hlavičku `Origin`, tedy přišel
   z webové stránky. Klient v terminálu ani v editoru ji neposílá.
2. `404 shop_not_found`: na doméně, na kterou požadavek přišel, žádný obchod neběží (typicky shopzi.cz
   místo domény obchodu).
3. `403 shop_unavailable`: obchod neobchoduje. Obvykle ho ale dřív odmítne ochranná vrstva odpovědí
   `503`, viz výš.
4. `403 external_access_disabled`: plocha je dočasně vypnutá všem obchodům.
5. `401 missing_api_key`: klíč v hlavičce chybí, nebo nezačíná prefixem `shopzi_sk_`.
6. `403 external_access_not_enabled`, `403 external_access_suspended` a `403 plan_required`, v tomhle
   pořadí: přepínač obchodu, pozastavení od SHOPZI a tarif.
7. `401 invalid_api_key`: klíč neznáme, je odvolaný, nebo mu vypršela platnost.
8. `403 key_surface_mismatch`: klíč platí jen pro druhou plochu.
9. `403 insufficient_scope`: klíči chybí oprávnění, které cesta REST API chce. Server MCP nástroj,
   na který klíč nedosáhne, rovnou nenabídne.
10. `429 rate_limited`, jen u REST API: klíč vyčerpal strop volání za minutu nebo za den.

## Klíč [#klic]

Klíč začíná prefixem `shopzi_sk_` a zobrazí se **jednou**, hned po vytvoření.
Ukládáme si jen jeho otisk, takže ho nepřečteme znovu ani my. Ztracený klíč se nedá obnovit, jen
nahradit novým.

Posílá se v hlavičce `authorization` nebo `x-api-key`. První tvar je běžný Bearer token
(`Authorization: Bearer shopzi_sk_…`), druhý nese holý klíč bez slova `Bearer`
(`x-api-key: shopzi_sk_…`) a existuje proto, že se v HTTP modulu Make a v uzlu HTTP Request v n8n
zadává o krok rychleji. Když přijdou obě, rozhoduje `Authorization` s `Bearer`.

```bash
curl -s https://muj-eshop.cz/api/v1/ping \
  -H "Authorization: Bearer $SHOPZI_API_KEY"
```

Klíč navíc nese **plochu**, na kterou smí: obě, jen REST API, nebo jen server MCP. Klíč omezený na
jednu plochu dostane na té druhé `403 key_surface_mismatch`, i když má obchod zapnuté obě. Plochu
volí vlastník při vytvoření klíče v poli **Kde klíč platí** (**REST API i server MCP**, **Jen REST
API**, **Jen server MCP**) a úpravou klíče se nemění. **Rychlá volba** ji předvyplní: **Vše**
a **Čtení katalogu** platí pro obě plochy, **Objednávky a sklad** a **Obsah a marketing** jen pro
server MCP, protože jejich zápisová oprávnění by REST API stejně neuplatnilo.

Volání REST API mají strop na každý klíč podle tarifu obchodu; čísla a hlavičky, podle kterých si
klient určí tempo, jsou v článku [Chybové odpovědi](/dokumentace/vyvojari/chybove-odpovedi).

> **Adresa je vždy doména obchodu** Obchod se rozpoznává z hostitele požadavku ještě předtím, než se klíč vůbec dohledá. Neexistuje tedy žádná centrální adresa, na kterou by šlo poslat identifikátor obchodu jako parametr, a klíč z jednoho obchodu na doméně jiného obchodu nefunguje: tam ho nikdo nezná.

## Vydání klíče krok za krokem [#vydani-klice-krok-za-krokem]

Klíč vydává jen vlastník obchodu v **Nastavení → API a MCP**, v části
**Přístup a klíče**:

1. V kartě **API klíče** klikněte na **Vytvořit klíč**. Otevře se dialog **Nový API klíč**.
2. Vyplňte **Název klíče**, podle kterého klíč poznáte v seznamu i v protokolu volání (nejvýš
   80 znaků, například „Claude na notebooku“).
3. V poli **Kde klíč platí** zvolte plochu.
4. Zvolte **Platnost** a **Měsíční strop kreditů**; co znamenají, popisuje oddíl
   **Jak oprávnění nastavit** níž.
5. Vyberte oprávnění. Dialog začíná rychlou volbou **Čtení katalogu** a oprávnění jsou rozdělená do
   skupin **Čtení** a **Zápis (jen server MCP)**.
6. Klikněte na **Vytvořit klíč** a krok potvrďte heslem nebo kódem z e-mailu.
7. Dialog **Klíč je vytvořený** ukáže celý klíč s tlačítkem **Kopírovat**, u klíče pro server MCP
   hotové nastavení klientů (**Připojení asistenta přes MCP**) a u klíče pro REST API ověřovací
   volání ping (**Ověření přes REST API**). Klíč si uložte do nastavení klienta nebo do správce
   hesel a dialog zavřete tlačítkem **Mám klíč uložený**. Znovu už ho neuvidíte.

## Kdo klíč vydává a kolik jich smí být [#kdo-klic-vydava-a-kolik-jich-smi-byt]

Klíč vytváří, upravuje a vyměňuje jen **vlastník obchodu**. Manažer a účet podpory SHOPZI klíče
vidí a smí je odvolat; vydat, upravit ani vyměnit je nemohou a místo tlačítka **Vytvořit klíč**
uvidí větu, že API klíče vydává jen vlastník obchodu.

Než se administrace zeptá na heslo nebo kód, ověří, že obchod klíč vydat smí: nárok na externí
přístup podle tarifu, žádné pozastavení od SHOPZI, aspoň jedna zapnutá plocha a volné místo pod
stropem klíčů. Potom zkontroluje vyplnění formuláře a teprve nakonec přijde druhé ověření, takže
heslo nezadáváte kvůli klíči, který by stejně nevznikl.

Druhé ověření je heslo do administrace, nebo šestimístný kód z e-mailu, pokud účet vznikl
přihlášením přes Google či Apple a heslo si nenastavil. Kód platí 10 minut, použít jde jednou, zadat
nejvýš pětkrát a poslat nejvýš třikrát za 15 minut; heslo zadané pětkrát špatně zamkne účet na
15 minut, stejně jako při přihlášení. Potvrzení samo platí 10 minut, takže druhý klíč hned po prvním
už znovu potvrzovat nemusíte. Platí ale jen pro tentýž druh úkonu: potvrzením práce s klíči se
nezapne plocha a neschválí změna z MCP, obojí se potvrzuje zvlášť.

Kolik **aktivních** klíčů obchod smí mít, určuje tarif: Basic 1, Standard 5, Business 20, Enterprise
a jednorázová licence 50. Odvolaný ani vypršelý klíč se do stropu nepočítá a klíč, který po
výměně dobíhá, také ne. Když obchod přejde na nižší tarif, který externí přístup pořád zahrnuje,
klíče, které už má, fungují dál; další vznikne až tehdy, když jich bude méně než strop nového
tarifu.

O každém vytvoření, úpravě, výměně i odvolání klíče dostanou všichni vlastníci obchodu e-mail
a upozornění v administraci. Klíč, který vydal nebo odvolal někdo jiný, tak nezůstane bez povšimnutí.

## Ověření klíče [#overeni-klice]

`/api/v1/ping` vrátí identitu klíče a seznam jeho oprávnění, žádná data obchodu. Stačí mu libovolný
platný klíč, který platí pro REST API, takže je to jediná cesta, na které se dá **neplatný klíč**
spolehlivě odlišit od **chybějícího oprávnění**: když ping projde a jiná cesta vrátí 403, klíč je
v pořádku a chybí mu rozsah. Ping patří k REST API, takže klíč jen pro server MCP na něm dostane
`403 key_surface_mismatch` a obchod, který má zapnutý jen server MCP, `403
external_access_not_enabled`. Klíč pro server MCP se ověřuje voláním `tools/list`, viz
[Připojení asistenta k obchodu](/dokumentace/vyvojari/pripojeni-asistenta).

```json
{
  "ok": true,
  "key_id": "9d2c1f7a-4b60-4f2e-9a11-8f0d2c3b5e64",
  "scopes": ["orders:read", "products:read"],
  "api_version": "v1"
}
```

## Oprávnění REST API [#opravneni-rest-api]

Zaškrtnutá oprávnění jsou to jediné, co klíč otevírá. Na co zaškrtnutá nejsou, na to odpověď zní
403 a v těle je vypsané, co klíči chybí a co má. REST API pracuje
s 5 oblastmi:

| Oprávnění | K čemu je | Otevírá |
| --- | --- | --- |
| `customers:read` | Pro CRM a e-mailový nástroj: kdo u vás nakupuje, jak ho zastihnout a jestli souhlasil s obchodními sděleními. Obsahuje osobní údaje. | `GET /api/v1/customers` `GET /api/v1/customers/{id}` |
| `documents:read` | Pro účetní software: co bylo vystaveno, komu, kdy a na kolik, i s rekapitulací DPH, PDF a ISDOC. | `GET /api/v1/documents` `GET /api/v1/documents/{id}` `GET /api/v1/documents/{id}/isdoc` `GET /api/v1/documents/{id}/pdf` |
| `orders:read` | Pro účetnictví, ERP a expedici: kdo co objednal, v jakém je to stavu, kolik to stálo, co se vrací a kde je zásilka. | `GET /api/v1/orders` `GET /api/v1/orders/{id}` `GET /api/v1/returns` `GET /api/v1/returns/{id}` `GET /api/v1/shipments` `GET /api/v1/supplier-orders` |
| `products:read` | Pro vlastní frontend, srovnávače a mobilní aplikaci: katalog s variantami, cenami, dostupností a stromem kategorií. | `GET /api/v1/catalog-items` `GET /api/v1/categories` `GET /api/v1/pricing-rules` `GET /api/v1/product-source-links` `GET /api/v1/products` `GET /api/v1/products/{id}` `GET /api/v1/supplier-approvals` `GET /api/v1/supplier-subscriptions` `GET /api/v1/supplier-sync-runs` |
| `stock:read` | Pro externí sklad nebo WMS: kolik kusů které varianty leží na skladě a který pohyb to změnil. | `GET /api/v1/stock` `GET /api/v1/stock/movements` |

Zápisová oprávnění se u klíče zaškrtávají také, ale **na REST API nemají žádný účinek**: tam se
data jen čtou. Uplatní se výhradně u nástrojů MCP, kde je u každého nástroje vidět v rejstříku
v článku [MCP server](/dokumentace/vyvojari/mcp-server).

## Jak oprávnění nastavit [#jak-opravneni-nastavit]

Klíč se dává dohromady v dialogu **Nový API klíč** v **Nastavení → API a MCP**
tak, aby uměl právě to, co po něm chcete, a nic navíc:

1. Napřed si sepište, které endpointy nebo nástroje napojení volá.
2. Podle tabulky výš (u MCP podle rejstříku nástrojů) k nim najděte oprávnění a zaškrtejte jen ta.
   U každého zaškrtávátka je napsané, co otevírá.
3. Zvolte **Platnost**: **30 dní**, **90 dní (doporučeno)**, **180 dní** nebo **1 rok**. Klíč po té
   době sám přestane fungovat a vlastníci obchodu dostanou e-mail a upozornění v administraci 14 a 3
   dny předem. Volba **Bez expirace** je pro napojení, které běží trvale: klíč pak platí, dokud ho
   neodvoláte, a formulář na to upozorní.
4. Nastavte **Měsíční strop kreditů**. Hlídá jen server MCP: kolik kreditů smí klíč za kalendářní
   měsíc utratit za placené akce, tedy generování obrázků a videí, hledání na webu a hromadnou AI
   úpravu produktů. Výchozí strop je 2 000, nula utrácení pro klíč vypne. Přes REST API se kredity
   neutrácejí.
5. Pro každé napojení zvlášť klíč. Pak jde odvolat právě to jedno, aniž by spadla ostatní.

Nad zaškrtávátky je v dialogu **Rychlá volba** (**Vše**, **Čtení katalogu**, **Objednávky a sklad**,
**Obsah a marketing**) a u každé sady plocha a odhad, kolik nástrojů z ní vznikne a kolik tisíc tokenů
za jejich popis zaplatí asistent při každém připojení. Pro REST API to nehraje roli, pro klienta MCP
je to ta nejviditelnější cena širokého klíče: `tools/list` je v revizi protokolu 2026-07-28 první
volání, takže se ten manifest platí při každém spojení znovu.

> **Oprávnění vydaného klíče jde upravit** Když má napojení dosáhnout dál, nebo naopak méně daleko, upraví vlastník klíč v Nastavení → API a MCP ikonou Upravit klíč: změní název, platnost, měsíční strop kreditů nebo oprávnění a tajemství zůstane, takže napojení běží dál. Úprava chce druhé ověření stejně jako vydání klíče a rychlou volbu nenabízí. Plochu úpravou nezměníte, na tu je potřeba nový klíč. Upravit jde jen aktivní klíč. Výměna klíče (níž) oprávnění nemění, přenese je beze změny.

## Výměna klíče [#vymena-klice]

Klíč, který se mohl dostat k někomu dalšímu, nebo jen dlouho běží, vymění vlastník obchodu
v **Nastavení → API a MCP** ikonou **Vyměnit klíč** v řádku klíče a v potvrzovacím
dialogu tlačítkem **Vyměnit klíč**; krok potvrdí heslem nebo kódem z e-mailu. Vznikne nový klíč se
stejným názvem, oprávněními, plochou i stropem kreditů a se stejně dlouhou platností, nejvýš rok
(klíč bez expirace zůstane bez expirace). Zobrazí se jednou v dialogu **Nový klíč po výměně**.

**Starý klíč funguje ještě 24 hodin** a v seznamu má mezitím stav **Vyměněný, dobíhá**. Za tu dobu
nový klíč vložíte do napojení bez výpadku; potom starý přestane platit sám a dostane 401 jako
kterýkoli neplatný klíč. Kdyby měl starý klíč vypršet dřív než za 24 hodin, dobíhá jen do svého
původního konce. Vyměněný klíč už znovu vyměnit ani upravit nejde: vyměňuje a upravuje se ten nový.

## Odvolání [#odvolani]

Klíč odvolá vlastník, manažer i účet podpory SHOPZI v **Nastavení → API a MCP**
ikonou **Odvolat klíč** v řádku klíče a v potvrzovacím dialogu tlačítkem **Odvolat klíč**, a to bez
druhého ověření: kdo zjistí, že klíč unikl, nemá čekat na kód z e-mailu. Odvolání zneplatní klíč
okamžitě a nevratně. Všechno, co ho používalo, dostane od té vteřiny 401, takže nový klíč si
připravte dřív, než starý odvoláte; když klíč jen nahrazujete, použijte místo toho **Vyměnit klíč**.
Odvolat jde i klíč, který po výměně dobíhá: pak skončí hned, ne až po 24 hodinách. Ve stejné chvíli
přestanou platit i odkazy ke stažení dokladů, které klíč vydal přes MCP: podpis odkazu nese klíč,
který si o něj řekl, a při stažení se ověřuje, že pořád platí.

Odvolejte klíč vždy, když se mohl dostat k někomu dalšímu, i kdyby jen omylem v chatu nebo
v protokolu. V seznamu klíčů je u každého ve sloupci **Naposledy** vidět, kdy byl naposledy použit,
takže klíč, který nikdo nepoužil několik měsíců, je nejlepší kandidát na odvolání.

Co se stane, když ověření neprojde, popisuje článek
[Chybové odpovědi](/dokumentace/vyvojari/chybove-odpovedi).

## Časté potíže [#caste-potize]

* **`401 missing_api_key`, přestože klíč posíláte.** Hlavička `Authorization` musí mít tvar
  `Bearer shopzi_sk_…`; hodnota bez slova `Bearer` se nepřečte, holý klíč patří do `x-api-key`.
  Zkontrolujte i uvozovky, které do hodnoty přidala šablona v Make nebo v n8n: klíč musí začínat
  přesně prefixem `shopzi_sk_`.
* **`401 invalid_api_key` s klíčem, který v administraci vidíte.** Klíč vypršel, byl odvolaný, nebo
  patří jinému obchodu: platí jen na doméně obchodu, pro který vznikl. Stav klíče ukazuje seznam
  klíčů (**Aktivní**, **Vyměněný, dobíhá**, **Vypršel**, **Odvolaný**).
* **`403 key_surface_mismatch`.** Klíč má v poli **Kde klíč platí** jen druhou plochu. Úprava plochu
  nezmění, vydejte nový klíč.
* **Tlačítko Vytvořit klíč chybí.** Jste přihlášení jako manažer nebo účtem podpory; klíče vydává
  jen vlastník obchodu.
* **Vytvoření odmítne, že by klíč nic neotevřel.** Ani jedna plocha není zapnutá. Nejdřív zapněte
  REST API nebo server MCP v kartě **Externí přístup**.
* **„Tarif obchodu dovoluje nejvýš …“** Obchod má plný strop aktivních klíčů. Odvolejte klíč, který už
  nepotřebujete, nebo přejděte na vyšší tarif.
* **Klíč nejde upravit ani vyměnit.** Upravit a vyměnit jde jen aktivní klíč. Vypršelý klíč nahraďte
  novým; u vyměněného upravte nebo vyměňte ten nový.
* **Druhé ověření nepustí.** Po pěti špatných heslech je účet 15 minut zamčený, i pro přihlášení. Kód
  z e-mailu jde poslat nejvýš třikrát za 15 minut a platí vždy jen ten poslední.
