Založte si e-shop zdarma a získejte 10 000 AI kreditů na start. Bez karty, bez závazku.E-shop zdarma + 10 000 AI kreditů na start

Začít zdarma
Přeskočit na obsah

Chybové odpovědi

Tvar chyby na REST API i na MCP, seznam kódů i s tím, kdy nastanou, a co má klient udělat s každým z nich. Kódy se generují z kódu, který je vrací.

Ověřeno 20. 10. 2026Markdown verze

Chyba REST API má vždycky stejný tvar a code je to, na co se má váš program rozhodovat. Text v message je pro člověka, který se dívá do protokolu, a smí se kdykoli změnit. MCP server mluví JSON-RPC, takže má tvar vlastní a je popsaný v samostatném oddíle níž.

{
  "error": {
    "code": "insufficient_scope",
    "message": "This key is missing the `orders:read` scope. It has: products:read."
  }
}

Většina zpráv je anglicky, brány přístupu českyTělo chyby čte stroj a vývojář, proto je text u neplatného klíče, chybějícího oprávnění nebo neexistujícího záznamu anglicky. Výjimkou jsou odmítnutí, jejichž nápravu dělá obchodník, ne váš kód: plocha není zapnutá, obchod nemá placený tarif, přístup je pozastavený nebo dočasně vypnutý, nebo klíč patří k jiné ploše. Ta jsou česky, abyste je mohli obchodníkovi rovnou přeposlat. Rozhodujte se vždy podle code, ne podle textu.

Kódy

StavKódKdy nastaneKde
401invalid_api_keyKlíč neznáme, byl odvolaný, nebo mu vypršela platnost. Která z těch tří možností to je, schválně neprozrazujeme.všechny cesty
401missing_api_keyHlavička s klíčem chybí, nebo hodnota nezačíná prefixem klíče.všechny cesty
403external_access_disabledSHOPZI tuhle plochu (REST API nebo server MCP) dočasně vypnulo pro všechny obchody. Na obchodu ani na klíči nic neměňte a zkuste to později.všechny cesty
403external_access_not_enabledVlastník obchodu plochu nezapnul. Zapíná ji v Nastavení → API a MCP přepínačem REST API nebo Server MCP.všechny cesty
403external_access_suspendedSHOPZI externí přístup k tomuto obchodu pozastavilo. Důvod sdělí vlastníkovi obchodu podpora SHOPZI.všechny cesty
403insufficient_scopeKlíč je platný, ale nemá oprávnění, které cesta vyžaduje. Zpráva vypíše, co klíči chybí a co má.všechny cesty
403key_surface_mismatchKlíč je vydaný jen pro druhou plochu (jen pro REST API, nebo jen pro MCP). Vlastník obchodu vydá klíč pro správnou plochu v Nastavení → API a MCP.všechny cesty
403plan_requiredREST API i server MCP patří k placeným tarifům a obchod teď aktivní placený tarif nemá. Po obnovení tarifu se přístup otevře sám.všechny cesty
403shop_unavailableObchod je deaktivovaný nebo pozastavený, takže požadavky přes API ani MCP neobsluhuje. Klíč s tím nic nezmůže; otevře ho až obnovení obchodu.všechny cesty
404not_foundZáznam s tímhle identifikátorem v obchodě není.všechny cesty
404shop_not_foundNa doméně, na kterou požadavek přišel, žádný obchod neběží. API se volá na doméně obchodu.všechny cesty
429rate_limitedKlíč vyčerpal strop volání za minutu nebo za den podle tarifu obchodu. Počkejte tolik sekund, kolik říká hlavička Retry-After, a pokračujte.všechny cesty
500server_errorChyba na naší straně. Opakujte s odstupem.všechny cesty
400invalid_cursorKurzor je poškozený, nebo patří k jinému dotazu (jiná cesta, jiný filtr nebo jiné updated_since). Začněte průchod znovu bez cursor.všechny výpisy
400invalid_queryParametr dotazu má neplatnou hodnotu: čas v updated_since bez časového posunu, nebo hodnota filtru, kterou výčet nezná. Zpráva jmenuje parametr, u filtru i povolené hodnoty.všechny výpisy
402plan_requiredTarif obchodu feedy dodavatelů nezahrnuje, takže katalog dodavatelů se neotevře. Otevře ho tarif Basic a vyšší; ostatní cesty feedů vracejí, co obchod už má uložené.GET /api/v1/catalog-items
403inventory_disabledObchod má vypnutý modul Sklad, takže skladová data neotevírá nikomu.GET /api/v1/stock GET /api/v1/stock/movements
422isdoc_invalidDoklad by neprošel pravidly ISDOC, typicky dobropis bez čísla opravovaného dokladu. Zpráva říká proč; opakování nepomůže, doklad je potřeba opravit v administraci.GET /api/v1/documents/{id}/isdoc
422unsupported_document_typeDoklad existuje, ale daňový není: objednávka, cenová nabídka ani účtenka nemají rozpis DPH, PDF faktury ani ISDOC.GET /api/v1/documents/{id} GET /api/v1/documents/{id}/isdoc GET /api/v1/documents/{id}/pdf
502pdf_unavailablePDF se teď nepodařilo vyrobit. Nic se nezměnilo, zkuste to s odstupem znovu.GET /api/v1/documents/{id}/pdf
503pdf_busyObchod právě vyrábí jiná PDF a další vykreslení by čekalo ve frontě. Počkejte tolik sekund, kolik říká hlavička Retry-After, a zkuste to znovu. Doklad, jehož PDF už existuje, tuhle odpověď nedostane.GET /api/v1/documents/{id}/pdf

Kódů sdílených všemi cestami je 13. V jakém pořadí se kontroly přístupu vyhodnocují, popisuje článek Autentizace a oprávnění.

Co s nimi dělat

  • 400 znamená, že cesta dotaz nepřečetla. invalid_query přijde u neplatné hodnoty parametru (čas bez časového posunu v updated_since, hodnota filtru mimo výčet) a zpráva jmenuje parametr. invalid_cursor přijde u kurzoru, který se cestou poškodil nebo patří k jinému dotazu, třeba s jiným filtrem. Stejný dotaz znovu neprojde; u invalid_cursor začněte průchod bez cursor.
  • 401 znamená, že klíč není platný nebo hlavička chybí. missing_api_key je požadavek úplně bez klíče (nebo s hodnotou, která nezačíná prefixem shopzi_sk_). Rozhoduje se o něm dřív než o přepínači plochy, takže přijde i na obchodě, který externí přístup zapnutý nemá; předběhne ho jen neexistující nebo pozastavený obchod a plocha dočasně vypnutá pro všechny obchody. invalid_api_key znamená klíč, který se nepodařilo ověřit. Neopakujte: znovu poslaný stejný klíč bude neplatný pořád. Odpověď nese hlavičku www-authenticate, takže na ni umí zareagovat i obecný HTTP klient.
  • 403 znamená, že klíč je v pořádku, ale nedosáhne tam, kam sáhl. Buď mu chybí oprávnění (pak ho vlastník obchodu klíči doplní v Nastavení → API a MCP ikonou Upravit klíč), nebo je vypnutá celá funkce obchodu, jako u inventory_disabled. Ani jedno neopravíte opakováním.
    • Čtyři kódy se týkají celé plochy, na kterou voláte, ne vašeho klíče. Přicházejí dřív, než se ověří platnost klíče, takže je dostanete i se správným klíčem a naopak z nich nepoznáte, jestli je klíč platný. Kontroluje se to v tomhle pořadí:
      • external_access_disabled: plocha je na SHOPZI dočasně vypnutá pro všechny obchody (údržba nebo zásah při incidentu). Zkuste to později.
      • external_access_not_enabled: obchodu tahle plocha není zapnutá. Obchodník ji zapíná v administraci, viz Autentizace a oprávnění.
      • external_access_suspended: SHOPZI externí přístup tomuto obchodu pozastavil. Obchodník se důvod dozví od podpory; opakování ani nový klíč nepomůže.
      • plan_required: obchod nemá na externí přístup nárok. Nemá tedy ani aktivní placený tarif, ani licenci, ani zkušební období s uloženou kartou (je třeba na tarifu Free, nebo ve zkušebním období bez karty). Po zaplacení tarifu nebo po doplnění karty se přístup otevře sám, bez nového klíče.
    • key_surface_mismatch: klíč je omezený na druhou plochu (jen REST API, nebo jen server MCP). Pro tuhle plochu je potřeba jiný klíč.
    • shop_unavailable znamená pozastavený nebo neaktivní obchod. Obvykle ho ale nedostanete: takový obchod odmítne dřív ochranná vrstva před API (viz oddíl Když odpověď nemá tvar chyby API níž).
  • 402 plan_required vrací jediná cesta, GET /api/v1/catalog-items: obchod externí přístup má, ale jeho tarif nezahrnuje feedy dodavatelů (počet odběrů feedů je v tarifu nula), takže katalog dodavatelů nevidí. Je to jiná situace než 403 plan_required výš, kdy obchod nemá nárok na celé API; rozlišujte je podle stavového kódu. Opakování nepomůže, katalog se otevře po přechodu na tarif s feedy dodavatelů. Ostatní cesty feedů dodavatelů tuhle chybu nevracejí, vydají to, co obchod má uložené (obchodu, který feedy nikdy neodebíral, prázdný výpis).
  • 404 u not_found znamená, že záznam v obchodě není; u dokladu i to, že je stornovaný, protože stornovaný dobropis se přes API nevydává. U shop_not_found znamená, že na doméně, na kterou jste volali, žádný obchod neběží: nejčastěji je to shopzi.cz místo domény obchodu. Podívejte se na hostitele v adrese, ne na klíč.
  • 422 vracejí cesty dokladu. unsupported_document_type znamená, že doklad existuje, ale daňový není (objednávka, cenová nabídka, účtenka), a nemá proto detail, PDF ani ISDOC. isdoc_invalid znamená, že by ISDOC neprošel pravidly formátu, typicky u dobropisu bez čísla opravovaného dokladu; zpráva říká proč. Ani jedno neopraví opakování.
  • 429 rate_limited znamená, že klíč vyčerpal strop volání REST API za minutu nebo za den (oddíl Objem požadavků níž). Počkejte tolik sekund, kolik říká hlavička Retry-After, a pak pokračujte tam, kde jste skončili. Opakovat dřív nemá smysl: minutové okno je pevné a končí s celou minutou, takže každý další pokus před jejím koncem dostane znovu 429.
  • 500 server_error je chyba na naší straně. Tady opakování smysl má, ale s odstupem, který se prodlužuje.
  • 502 pdf_unavailable znamená, že se PDF dokladu teď nepodařilo vyrobit. Nic se nezměnilo; opakujte s odstupem.
  • 503 pdf_busy přijde, když se PDF dokladu ještě nevyrábělo a server už vyrábí nejvíc souběžných PDF, kolik smí. Počkejte tolik sekund, kolik říká hlavička Retry-After, a zkuste to znovu. Stahujte PDF po jednom nebo po dvou, ne celou dávku naráz; doklad, jehož PDF už jednou vzniklo, přijde hned a tuhle odpověď nedostane.

Neplatný klíč, odvolaný klíč a vypršelý klíč vracejí totéžVšechny tři jsou 401 invalid_api_key se stejným textem. Rozlišovat je by znamenalo prozradit tomu, kdo klíče zkouší, že jeden z nich existoval. Který stav klíč má, je vidět v administraci v seznamu klíčů. Chybějící hlavička a hodnota bez prefixu mají jiný kód, missing_api_key: o těch se rozhoduje bez databáze.

Chyby přes MCP

MCP server má vlastní tvar, protože mluví JSON-RPC, a je užitečné rozlišit tři vrstvy.

Nepustila brána. Všechno, co se rozhodne na vstupu, přijde jako obyčejná HTTP odpověď v tvaru chyby REST API výš, ne jako odmítnutí nástroje: 403 origin_not_allowed u požadavku s hlavičkou Origin (prohlížečového klienta nepodporujeme, takže se odmítne každý původ), 401 u chybějícího nebo neplatného klíče, 403 u zavřené plochy, chybějícího tarifu, pozastavení a klíče pro druhou plochu, 404 shop_not_found na doméně bez obchodu a 405 method_not_allowed s hlavičkou Allow: POST na GET a DELETE.

Nástroj odmítl. Přijde běžný úspěšný JSON-RPC výsledek s isError: true, českou větou v content a strojovým kódem v _meta pod klíčem cz.shopzi/errorCode. structuredContent v takové odpovědi nikdy není: výstupní schéma nástroje popisuje úspěch, takže chybový objekt by na něm spadl a důvod odmítnutí by se k modelu vůbec nedostal. Kódy jsou forbidden, not_found, conflict, invalid_input, suspended, plan_required, confirmation_required, confirmation_declined, approval_required, approval_pending, credit_cap_exceeded, plan_change_limited, quote_changed, payment_declined a internal_error.

  • confirmation_required a confirmation_declined znamenají „zeptej se člověka a zavolej znovu“, ne „na tohle nemáš právo“, a hostitel, který by je nerozlišil, by uživateli tvrdil, že mu chybí oprávnění, které mu nechybí. confirmation_required přijde i tehdy, když schválení mezitím vypršelo nebo už bylo jednou použité: zavolejte nástroj znovu a vznikne nové.
  • approval_required znamená, že akci musí schválit člověk v administraci obchodu. Odkaz na stránku schválení je v _meta["cz.shopzi/approvalUrl"]. Předejte ho uživateli a po schválení zavolejte nástroj znovu se stejnými argumenty.
  • approval_pending znamená, že se na schválení pořád čeká. Odkaz je tentýž, nové schválení nevzniklo; neopakujte volání ve smyčce, počkejte na člověka. Jeden klíč má na schválení nejvýš 20 čekajících žádostí a za hodinu jich založí nejvýš 30, ať skončily jakkoli; obojí je odmítnutí conflict s větou, na co počkat. Zamítnutá žádost vrátí confirmation_declined.
  • credit_cap_exceeded znamená, že by akce překročila měsíční strop kreditů přístupového klíče (nový klíč má 2 000 kreditů měsíčně, pokud mu vlastník nenastaví jiný), nebo strop teď nejde ověřit. Nestrhlo se nic. Opakování pomůže až prvního dne dalšího měsíce, kdy se strop obnoví, nebo když vlastník obchodu strop klíče upraví v Nastavení → API a MCP ikonou Upravit klíč. Když je strop klíče nastavený na nulu, je utrácení pro ten klíč vypnuté a nový měsíc nepomůže. Když strop jen nešel ověřit, zkuste volání za chvíli znovu.
  • plan_required znamená, že akci neumožňuje tarif obchodu. Vyčerpaný počet vlastních domén to není: ten mají všechny tarify stejný, takže přijde conflict s větou, že je potřeba nejdřív odebrat stávající doménu.
  • plan_change_limited znamená, že se tarif obchodu přes MCP za posledních 24 hodin už měnil (nebo se právě mění). Nestrhlo se nic. Od kdy půjde další změna, je v _meta["cz.shopzi/retryAt"]; v administraci jde tarif změnit hned.
  • quote_changed znamená, že potvrzená částka navýšení tarifu už neplatí: Stripe teď spočítal jinou, nabídka je starší než 90 minut, nebo patří k jiné periodě platby. Nestrhlo se nic. Zavolejte upgrade znovu bez quote a nechte potvrdit novou částku, starou nabídku neopakujte.
  • payment_declined znamená, že karta uložená u SHOPZI platbu za navýšení tarifu odmítla. Tarif zůstal a nic se nestrhlo. Se stejnou kartou opakování nepomůže; kartu obchodník vymění v administraci v Nastavení → Předplatné tlačítkem Spravovat platby, a tahle věta je i ve zprávě odmítnutí.
  • suspended je pojistka pro obchod, který se pozastavil během volání. Pozastavený obchod jinak neodpovídá už na vstupu (viz oddíl níž).
  • internal_error je nečekaná chyba na naší straně. Věta je obecná schválně: podrobnosti zůstávají v našem protokolu, aby se ven nedostaly názvy tabulek ani cizí data. Zkuste to znovu s odstupem.

Selhal protokol. Pak je to opravdová JSON-RPC chyba s číselným kódem: -32601 na neznámou metodu (a na subscriptions/listen, které nevedeme, s HTTP 404), -32602 na neplatné parametry (sem spadá i podvržený nebo pozměněný requestState z potvrzovacího kola), -32600 s HTTP 400 na dávku, ve které je completion/complete nebo subscriptions/listen, -32021 na chybějící schopnost klienta, -32022 na nepodporovanou verzi protokolu a -32020, když si hlavičky a tělo požadavku odporují.

Chyba z databáze se ven nedostane nikdy v surové podobě: přeloží se na českou větu bez jmen tabulek a omezení, a surový text zůstane v našem protokolu.

Když odpověď nemá tvar chyby API

Dva případy, kdy odpověď nevypadá jako chyby výš:

  • 503 s tělem { "error": "Tento obchod je momentálně nedostupný." } posílá ochranná vrstva ještě před API. Znamená pozastavený nebo neaktivní obchod, nebo subdoménu shopzi.cz, na které žádný obchod neběží. Nemá pole code a nemá smysl ji parsovat jako chybu API.
  • Odpověď, která není JSON, přišla od něčeho před aplikací: od ochranné vrstvy sítě, od proxy, nebo je to stránka obchodu, protože požadavek netrefil cestu /api/v1. Zkontrolujte adresu a hlavičky.

Kde chybu dohledat

Volání, které dojde až k obchodu, si obchod zapíše do protokolu bez obsahu: čas, klíč, plochu, operaci, výsledek s kódem chyby, stavový kód HTTP, dobu zpracování, kredity, IP adresu a klienta. Vlastník nebo manažer obchodu ho najde v Nastavení → API a MCP v části Protokol volání:

  1. Nahoře zvolte období a filtry Plocha, Výsledek a Klíč. Volání, u kterých se klíč ověřit nepodařilo, mají v řádku klíče „Bez platného klíče“.
  2. Ve sloupci Výsledek je, jak volání dopadlo (Úspěch, Chyba, Odmítnuto, Neověřený klíč, Bez oprávnění, Strop kreditů, Nad limit, Čeká na potvrzení, Čeká na schválení), a pod ním strojový kód chyby, tentýž, jaký dostal klient.

Protokol ukazuje nejvýš posledních 30 dní. Neúspěšných volání zapíše jen omezený počet (bez platného klíče 60 za hodinu na obchod, s platným klíčem 1 000 za den na klíč a plochu); kolik jich za období opravdu přišlo, ukazuje část Využití, kde se denní součty drží 90 dní. Odmítnutí hlavičkou Origin a požadavky na doménu bez obchodu se nezapisují nikam, protože k nim žádný obchod nepatří.

Objem požadavků

REST API /api/v1 počítá volání na každý klíč zvlášť, v minutovém a v denním okně. Strop se řídí tarifem obchodu:

TarifVolání za minutuVolání za den
Basic6020 000
Standard12050 000
Business240100 000
Enterprise a jednorázová licence300200 000

Obě okna jsou pevná, ne klouzavá. Minutové začíná a končí s celou minutou, denní je kalendářní den v českém čase a obnoví se o půlnoci v Praze. Dva klíče téhož obchodu se počítají odděleně, takže rozběhnutá integrace nevyčerpá strop té druhé.

Počítají se jen volání, která prošla ověřením klíče, oprávnění, plochy a tarifu: tato odmítnutí 401 a 403 ze stropu neubírají (inventory_disabled ano, tu vrací až cesta sama). Každé započítané volání jde do minutového okna, i to, které skončí 429; do denního jen ta, která minutový strop pustil, takže klient, který chvíli nečekal, si tím nespálí zbytek dne.

Odpověď na volání, které prošlo všemi branami, tedy klíčem, plochou, tarifem i oprávněním, nese hlavičky, podle kterých si klient sám určí tempo; nese je i odmítnutí 429:

  • X-RateLimit-Limit: strop okna, které je právě těsnější (minutové, nebo denní);
  • X-RateLimit-Remaining: kolik volání v tom okně ještě zbývá;
  • X-RateLimit-Reset: kdy se to okno obnoví, jako Unix čas v sekundách.

Chybí jen ve výjimečné chvíli, kdy počítadlo nejde zapsat: volání pak projde bez omezení a hlavičky by neměly z čeho vzniknout.

Nad strop přijde 429 s kódem rate_limited a navíc hlavičkou Retry-After v sekundách. Když je vyčerpaný celý den, Retry-After míří až na půlnoc, ne na konec minuty.

Příliš hustý provoz z jedné IP adresy může navíc odmítnout ochranná vrstva sítě ještě před aplikací; takové odmítnutí nemá tvar chyby API (viz oddíl výš). Držte se proto rozumné kadence a synchronizujte přírůstkově podle článku Stránkování a filtry, místo abyste stahovali celý katalog v každém běhu.

Volání nástrojů přes MCP mají strop také, ale jiný: každé volání nástroje se počítá klíči, kterým přišlo, v okně celé hodiny a kalendářního dne v českém čase, a strop se řídí tarifem obchodu:

TarifVolání nástrojů za hodinuVolání nástrojů za den
Basic6005 000
Standard1 20010 000
Business2 00020 000
Enterprise a jednorázová licence3 00030 000

Do téhož stropu se počítá každé kolo, i to, které se jen ptá na potvrzení, a také našeptávání hodnot (completion/complete); našeptávání nad strop neodmítne, jen vrátí prázdnou nabídku. Vedle toho má obchod vlastní strop AI generování, do kterého se počítá i práce Agenta v administraci, a když je vyčerpaný, odmítne i volání přes MCP. Odmítnutí je v obou případech odmítnutí nástroje s kódem conflict a věta v něm říká, který ze dvou stropů narazil, aby šlo poznat rozběhnutou integraci od vytíženého obchodu. Samo to pomine, takže tady opakování s odstupem smysl má.