# REST API: zásoby a skladové pohyby

> Referenční popis cest skladu, tedy zásob po variantách a knihy skladových pohybů: parametry, pole odpovědi, synchronizace, chyby a ukázka volání.

- Sekce: Pro vývojáře
- Stránka: https://shopzi.cz/dokumentace/vyvojari/rest-sklad
- Ověřeno: 2026-09-16

---

Pro externí sklad nebo WMS: kolik kusů které varianty leží na skladě a který pohyb to změnil.

Cesty odpovídají na `GET` na doméně vašeho obchodu, například `https://muj-eshop.cz/api/v1/…`, a klíč se posílá v hlavičce `Authorization: Bearer` nebo `x-api-key`. Parametry, pole i chyby na téhle stránce se generují ze smlouvy, podle které API odpovídá, takže platí pro build, na kterém stránka běží. Každá cesta může navíc vrátit chyby společné všem cestám: `invalid_api_key`, `missing_api_key`, `external_access_disabled`, `external_access_not_enabled`, `external_access_suspended`, `key_surface_mismatch`, `plan_required`, `shop_unavailable`, `shop_not_found`, `rate_limited` a `server_error`. Co znamenají, popisuje článek [Chybové odpovědi](/dokumentace/vyvojari/chybove-odpovedi), klíč a oprávnění [Autentizace a oprávnění](/dokumentace/vyvojari/autentizace-a-opravneni) a průchod výpisem [Stránkování a filtry](/dokumentace/vyvojari/strankovani-a-filtry).

## `GET /api/v1/stock` [#get-api-v1-stock]

Zásoby po variantě, sečtené přes sklady, i s názvem varianty z hodnot jejích voleb (například velikost a barva). Obchod s vypnutým modulem Sklad tenhle endpoint neotevírá.

* **Oprávnění:** `stock:read`, u klíče „Sklad, pohyby a nákup (čtení)“.
* **Odpověď:** stránka výpisu, záznamy jsou v `data` a jak otevřít další stránku, říká seznam Obálka odpovědi.
* **Synchronizace:** s `updated_since` se výpis řadí podle pole `updated_at` od nejstarší změny, bez něj od nejnovějšího záznamu. Pole `updated_at`: Poslední změna zásoby, varianty (například SKU) nebo názvu produktu.

```bash
curl -s "https://muj-eshop.cz/api/v1/stock?limit=100" \
  -H "Authorization: Bearer $SHOPZI_API_KEY"
```

**Parametry dotazu**

* `limit` (celé číslo od 1 do 100, výchozí `25`; nepovinný): Počet řádků na stránku, výchozí 25. Vyšší hodnota se ořízne na 100, nesmysl spadne na výchozí.
* `cursor` (text; nepovinný): Hodnota `next_cursor` z předchozí stránky, beze změny. Platí jen pro tentýž dotaz.
* `updated_since` (čas ISO 8601; nepovinný): ISO 8601 se zónou `Z` nebo s číselným posunem (`+02:00`). Vrátí záznamy změněné od té chvíle včetně, seřazené od nejstarší změny, a stránkuje stabilně: řádek změněný během průchodu se v něm neopakuje a přijde v příštím. Hodnota `next_updated_since` jde do adresy vložit bez kódování; `+` z nezakódované adresy se čte jako `+`.

**Obálka odpovědi**

* `data` (pole záznamů): Záznamy stránky, jejich pole popisuje seznam Pole záznamu.
* `next_cursor` (text nebo `null`): Kurzor další stránky, `null` = tohle je poslední stránka.
* `next_updated_since` (čas ISO 8601): Hodnota `updated_since` pro příští průchod: začátek tohoto průchodu mínus 5 minut. Na všech stránkách jednoho průchodu je stejná a do adresy jde vložit bez kódování.

**Pole záznamu**

* `variant_id` (UUID)
* `product_id` (UUID)
* `sku` (text nebo `null`)
* `title` (text): Název produktu. Kterou variantu řádek nese, říká `variant`.
* `variant` (text nebo `null`): Název varianty z hodnot jejích voleb v pořadí voleb produktu, oddělených lomítkem, například `Černá / 42`. `null`, když varianta žádné volby nemá (jednoduchý produkt).
* `on_hand` (číslo): Fyzicky na skladě, sečteno přes sklady.
* `available` (číslo): Kolik jde prodat. Dnes totéž co `on_hand`, obchod nerezervuje.
* `updated_at` (čas ISO 8601): Poslední změna zásoby, varianty (například SKU) nebo názvu produktu.
* `created_at` (čas ISO 8601)

**Chyby této cesty**

* **400** `invalid_query`: Parametr 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.
* **400** `invalid_cursor`: Kurzor 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.
* **403** `insufficient_scope`: Klíč je platný, ale nemá oprávnění, které cesta vyžaduje. Zpráva vypíše, co klíči chybí a co má.
* **403** `inventory_disabled`: Obchod má vypnutý modul Sklad, takže skladová data neotevírá nikomu.

## `GET /api/v1/stock/movements` [#get-api-v1-stock-movements]

Skladové pohyby jako neměnná kniha: varianta, sklad, změna množství, důvod a to, k čemu pohyb patří. Nákupní cena ani poznámka k pohybu ven nejdou a s vypnutým modulem Sklad je cesta zavřená.

* **Oprávnění:** `stock:read`, u klíče „Sklad, pohyby a nákup (čtení)“.
* **Odpověď:** stránka výpisu, záznamy jsou v `data` a jak otevřít další stránku, říká seznam Obálka odpovědi.
* **Synchronizace:** s `updated_since` se výpis řadí podle pole `created_at` od nejstarší změny, bez něj od nejnovějšího záznamu. Pole `created_at`: Kdy pohyb vznikl. Pohyb se nemění, takže podle něj stránkuje i `updated_since`.

```bash
curl -s "https://muj-eshop.cz/api/v1/stock/movements?limit=100" \
  -H "Authorization: Bearer $SHOPZI_API_KEY"
```

**Parametry dotazu**

* `limit` (celé číslo od 1 do 100, výchozí `25`; nepovinný): Počet řádků na stránku, výchozí 25. Vyšší hodnota se ořízne na 100, nesmysl spadne na výchozí.
* `cursor` (text; nepovinný): Hodnota `next_cursor` z předchozí stránky, beze změny. Platí jen pro tentýž dotaz.
* `updated_since` (čas ISO 8601; nepovinný): ISO 8601 se zónou `Z` nebo s číselným posunem (`+02:00`). Vrátí záznamy změněné od té chvíle včetně, seřazené od nejstarší změny, a stránkuje stabilně: řádek změněný během průchodu se v něm neopakuje a přijde v příštím. Hodnota `next_updated_since` jde do adresy vložit bez kódování; `+` z nezakódované adresy se čte jako `+`.
* `type` (jedna z hodnot `receipt`, `usage`, `writeoff`, `correction`, `return`, `transfer` a `stocktake_adjustment`; nepovinný): Druh pohybu.

**Obálka odpovědi**

* `data` (pole záznamů): Záznamy stránky, jejich pole popisuje seznam Pole záznamu.
* `next_cursor` (text nebo `null`): Kurzor další stránky, `null` = tohle je poslední stránka.
* `next_updated_since` (čas ISO 8601): Hodnota `updated_since` pro příští průchod: začátek tohoto průchodu mínus 5 minut. Na všech stránkách jednoho průchodu je stejná a do adresy jde vložit bez kódování.

**Pole záznamu**

* `id` (UUID)
* `variant_id` (UUID): Varianta, které se pohyb týká. SKU, produkt a název varianty čtěte z `/stock`: mění se, kdežto pohyb je neměnný a znovu by nepřišel.
* `location_id` (UUID nebo `null`): Sklad, `null` u pohybu na zrušeném skladě. Zrušení skladu pohyb znovu nepošle.
* `type` (jedna z hodnot `receipt`, `usage`, `writeoff`, `correction`, `return`, `transfer` a `stocktake_adjustment`)
* `quantity_change` (číslo): Změna množství: kladná přidává, záporná ubírá.
* `quantity_before` (číslo)
* `quantity_after` (číslo)
* `reason` (text nebo `null`): Důvod odpisu, jinak `null`.
* `reference` (objekt)
* `reference.type` (text nebo `null`): K čemu pohyb patří, například `order` nebo `purchase_order`.
* `reference.id` (UUID nebo `null`)
* `created_at` (čas ISO 8601): Kdy pohyb vznikl. Pohyb se nemění, takže podle něj stránkuje i `updated_since`.

**Chyby této cesty**

* **400** `invalid_query`: Parametr 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.
* **400** `invalid_cursor`: Kurzor 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.
* **403** `insufficient_scope`: Klíč je platný, ale nemá oprávnění, které cesta vyžaduje. Zpráva vypíše, co klíči chybí a co má.
* **403** `inventory_disabled`: Obchod má vypnutý modul Sklad, takže skladová data neotevírá nikomu.
