MyÚčto.cz Manuál
Stáhnout PDF Příručky Zpět na hlavní stránku

103. REST API (automatizace a integrace)

Návod pro správce a integrátory: jak vytvořit API token, vyzkoušet první volání, omezit token podle IP adresy, sledovat log volání a token zrušit. Na konci je referenční výklad práv, limitů a vybraných endpointů.

MyÚčto.cz nabízí veřejné REST API pro integraci s e-shopy, CRM, Make/Zapier a vlastními skripty. API používá Personal Access Tokens (PAT) v hlavičce Authorization.

103.1 Kdy to potřebujete

KdyCo udělatKde
před spuštěním integraceVytvořit token s nejmenším potřebným rozsahemFirma → API tokeny, § 103.3
po vytvořeníVyzkoušet volání§ 103.4
u integrace z jednoho serveruOmezit token podle IP§ 103.5
při ladění nebo podezřeníProjít log voláníFirma → MCP server, § 103.6
při ukončení integrace nebo únikuToken zrušit§ 103.7

103.2 Než začnete

URLNástrojPoužití
/api/docsSwagger UI„Try it out": vložte API token (Authorize) a volejte endpointy přímo z prohlížeče
/api/referenceRedocStatická reference, 3-sloupcový layout, lepší typografie pro čtení
/api/scalarScalarModerní reference s vestavěným API klientem a fulltext vyhledáváním
/api/openapi.yamlRaw OpenAPI 3.1Import do Postmana, Insomnie, Zapier Custom App, Make HTTP modulu

103.3 Krok za krokem: vytvoření tokenu

  1. Otevřete Firma → API tokeny a klikněte na Nový token.
  2. Vyplňte:
  1. Ověřte se: Ověřit přístupovým klíčem, nebo zadejte aktuální šestimístný kód TOTP; účet bez silného faktoru zadá aktuální heslo.
  2. Klikněte na Vytvořit. Zobrazí se plain-text token (mi_pat_...) jen jednou. Uložte ho do password manageru, zaškrtněte potvrzení a zavřete okno.

Jak poznáte, že je hotovo: Token je v přehledu se stavem Aktivní, prefixem a rozsahem. Přehled ukazuje i sloupce Naposledy, Expirace a IP omezení.

Upozornění

Token se po zavření okna už nezobrazí. Při ztrátě vytvořte nový a starý zrušte.

103.4 Krok za krokem: první volání

  1. Zavolejte endpoint, který vrací identitu tokenu:
   curl -H "Authorization: Bearer mi_pat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
        https://myucto.cz/api/v1/auth/api-me
  1. Zkontrolujte odpověď (user, supplier, auth_method, token).
  2. Pro seznam faktur za leden 2026 použijte:
   curl -H "Authorization: Bearer mi_pat_…" \
        "https://myucto.cz/api/v1/invoices?from=2026-01-01&to=2026-01-31"

Jak poznáte, že je hotovo: Volání vrátí 200 a v token je správný název, rozsah a firma. Další příklady (vytvoření klienta, označení faktury za zaplacenou) a vysvětlení polí jsou v § 103.9.3.

103.5 Krok za krokem: omezení tokenu podle IP adresy

  1. Otevřete Firma → API tokeny a u tokenu klikněte na Nastavit omezení podle IP adresy.
  2. Do pole IP adresa nebo rozsah zadejte adresu (například 203.0.113.7 nebo 192.168.1.0/24), případně Poznámka, a klikněte na Přidat.
  3. Pravidlo, které nechcete, odeberte tlačítkem Odebrat.

Dialog zobrazuje také vaši IP adresu podle aplikace. Jde o aktuální prohlížeč; integrace nebo MCP klient na jiném serveru může mít jinou adresu. U privátní, lokální nebo sdílené adresy se zobrazí upozornění a odkaz na nastavení předávání IP za proxy a v Dockeru. Před omezením tokenu ověřte, že aplikace vidí správnou adresu klienta.

Jak poznáte, že je hotovo: Ve sloupci IP omezení se místo „bez omezení" ukáže seznam. Volání odjinud dostane 403 token_ip_forbidden.

Tip

Jede-li integrace z jednoho serveru, omezte token na jeho adresu. Uniklý token je pak k ničemu komukoli mimo vaši síť.

103.6 Krok za krokem: kontrola logu volání

  1. Otevřete Firma → MCP server a sekci Log volání.
  2. Filtrujte podle tokenu, metody, cesty, zdroje (jen MCP), případně jen chyby.
  3. U záznamu zkontrolujte čas, token, metodu, cestu, návratový kód, dobu zpracování a zdrojovou IP. U volání z MCP serveru je navíc název nástroje.

Jak poznáte, že je hotovo: Vidíte volání svých tokenů včetně zamítnutých. Záznamy se drží 90 dní.

103.7 Krok za krokem: zrušení tokenu

  1. Otevřete Firma → API tokeny.
  2. U tokenu klikněte na Zrušit a potvrďte dotaz. Přístup skončí okamžitě.
  3. Chcete-li token z přehledu úplně odstranit, klikněte na Smazat až po prošetření.

Jak poznáte, že je hotovo: Token má stav Zrušen a integrace dostává 401.

Upozornění

Při podezření na zneužití token nejdřív zrušte a mažte až po prošetření. Smazáním přijdete o přiřazení jeho volání v logu.

103.8 Když něco nejde

Co vidítePročCo udělat
401 / invalid_tokenChybí, vypršel nebo byl zrušen tokenVytvořte nový token
403 insufficient_scopeToken má rozsah readVytvořte token s read & write
403 token_write_forbiddenZápis do účetní a daňové vrstvy přes token nejdeÚkon proveďte v aplikaci (§ 103.9.7.1)
403 token_endpoint_forbiddenEndpoint (například mzdy) je jen pro přihlášené v prohlížečiPoužijte aplikaci; veřejný kontrakt pro mzdy neexistuje
403 session_requiredOperaci dělá člověk v aplikaciPoužijte aplikaci
403 token_ip_forbiddenToken není povolen z této IPPřidejte IP v omezení tokenu
429 Too Many RequestsPřekročen limit 600 požadavků za minutuPočkejte podle Retry-After, zpomalte
Integrace nevidí doručenky a protokoly podáníToken nemá schopnost mzdových podáníVytvořte nový token se zaškrtnutou schopností (§ 103.9.3)
404 na zdrojZdroj neexistuje nebo nepatří aktuální firměZkontrolujte ID a firmu tokenu

Kompletní seznam chybových kódů je v § 103.9.10.

103.9 Podrobnosti a pravidla

103.9.1 Dokumentační rozhraní a rozsah specifikace

Tip

openapi.yaml pokrývá fakturaci a klienty i další dostupné agendy - účetnictví (tagy okolo podvojného účetnictví, účtové osnovy, období a deníku), sklad (skladové karty, pohyby, doklady, inventury), e-shop (katalog zboží, kategorie, číselníky) a klientský portál (agregovaný přehled hospodaření). Detailní chování jednotlivých endpointů popisují kapitoly k dané agendě - tady jde jen o to, že přes REST API se dá automatizovat i tahle část systému. Samotná přítomnost operace ve specifikaci však neznamená, že ji lze zavolat PAT tokenem: taková operace odpoví 403 session_required a v popisu to má uvedené. Popis konkrétní operace může uvádět session-only přístup, superadmina nebo zákaz zápisu přes bearer token.

103.9.2 Vytvoření tokenu (podrobnosti)

Postup je v § 103.3. Zde jsou pravidla.

Samotné přihlášení pomocí MFA nestačí: vytvoření PAT vždy vyžaduje nový účelový step-up, pokud má účet passkey nebo TOTP. Účet bez jakéhokoli silného faktoru se místo toho prokáže aktuálním heslem. Proof pro jinou operaci ani odemčení zamčené PWA token nevytvoří. PAT je bearer credential a serverový zámek browserové session se na něj nevztahuje; chraňte jej vlastní expirací, minimálním scopem a včasnou revokací.

103.9.3 Použití tokenu

curl -H "Authorization: Bearer mi_pat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
     https://myucto.cz/api/v1/auth/api-me

Response:

{
  "user":     { "id": 1, "email": "you@example.com", "name": "Petr", "role": "admin" },
  "supplier": { "id": 1, "company_name": "Acme s.r.o.", "display_name": "Acme" },
  "auth_method": "bearer",
  "token":    {
    "id": 42, "name": "Make integrace", "prefix": "mi_pat_abcd",
    "scope": "read_write", "allow_payroll_submission_docs": false, "expires_at": null
  }
}

allow_payroll_submission_docs říká, jestli token dostal volitelnou schopnost z vytvoření tokenu. Když integrace nevidí doručenky ani protokoly podání, podívejte se sem dřív, než začnete hledat chybu v datech - false znamená zavřený kanál, ne prázdný výsledek. Přepnout to u hotového tokenu nejde, vyrobte nový.

103.9.3.1 Příklady

Seznam faktur za leden 2026:

curl -H "Authorization: Bearer mi_pat_…" \
     "https://myucto.cz/api/v1/invoices?from=2026-01-01&to=2026-01-31"

Vytvoření klienta:

curl -X POST https://myucto.cz/api/v1/clients \
     -H "Authorization: Bearer mi_pat_…" \
     -H "Content-Type: application/json" \
     -d '{
       "company_name": "Nový klient s.r.o.",
       "ic": "12345678",
       "street": "Hlavní 1",
       "city": "Praha",
       "zip": "11000",
       "country_id": 1
     }'

Označení faktury jako zaplacené:

curl -X POST https://myucto.cz/api/v1/invoices/123/mark-paid \
     -H "Authorization: Bearer mi_pat_…" \
     -H "Content-Type: application/json" \
     -d '{"paid_at": "2026-05-10"}'

103.9.4 Verzování

103.9.5 Rate limity

Každá bearer-authed response vrací tyto headers, ať se můžete sami zbrzdit před tím, než narazíte na 429:

X-RateLimit-Limit:     600         (limit v aktuálním okně)
X-RateLimit-Remaining: 587         (kolik volání vám ještě zbývá)
X-RateLimit-Reset:     42          (sekundy do reset countru)

Doporučujeme klienta s retry-with-backoff (axios-retry, Retry-After-aware) + sledovat X-RateLimit-Remaining a brzdit, když klesá pod ~10 %.

103.9.6 Multi-supplier

Pokud má účet víc firem (dodavatelů), máte dvě možnosti:

Token bound na supplier_id (doporučeno)Token globální
Token operuje vždy v kontextu této firmy.Klient pošle hlavičku X-Supplier-Id: <id> u každého requestu.
Hlavička X-Supplier-Id se ignoruje.Bez hlavičky = výchozí firma.
Token nemůže „skočit“ do jiné firmy = bezpečnější.Flexibilnější pro power-user skripty.

103.9.7 Scopes

ScopePovolené metody
readGET, HEAD a čtecí dávkové POSTy katalogu
read_writevšechny (POST, PUT, PATCH, DELETE)

Volání s nedostatečným scopem vrátí 403 insufficient_scope. Čtecí POSTy katalogu jsou výjimka: pouze nesou strukturovaný výběr nebo projekci, data nemění, proto fungují i s rozsahem read.

103.9.7.1 Účetnictví a daně jen ke čtení

Nad rámec scopů platí tvrdé pravidlo: účetní a daňová vrstva je přes API token jednosměrná. Čtení funguje normálně, zápis odmítne i token se scope read_write - chybou 403 token_write_forbidden.

CestaGETzápis
/api/v1/accounting/** mimo mzdové podcestyanone, kromě konceptů ostatních pohledávek a závazků a analytických účtů osnovy (viz níže)
/api/v1/accounting/payroll/**, /api/v1/accounting/reports/payroll-sheetnene
/api/v1/reports/**anone
/api/v1/tax/, /api/v1/tax-evidence/anone

Zaúčtování dokladu, storno zápisu, uzavření období, zaevidování opravy podle § 46 / § 74b i odeslání podání na EPO jsou úkony s daňovou odpovědností, kde chyba znamená opravné podání. Dělají se proto výhradně z webového rozhraní, kde je vidět kontext a krok se potvrzuje. Integraci ani AI asistentovi to nebrání v tom podstatném - obratovku, rozvahu, výsledovku, saldo i odhad DPH si přes API přečtou.

Zápisové výjimky jsou dvě. První jsou koncepty ostatních pohledávek a závazků (nájem, půjčka, úvěr, leasing, kauce, pojistné). Token se scope read_write smí:

OperaceCesta
založit konceptPOST /api/v1/accounting/other-items
upravit a smazat konceptPUT, DELETE /api/v1/accounting/other-items/{id}
nastavit nebo zrušit splátkový kalendářPUT /api/v1/accounting/other-items/{item_id}/installments
založit opakováníPOST /api/v1/accounting/other-items/{item_id}/schedule
pozastavit nebo obnovit opakováníPUT /api/v1/accounting/other-items/schedules/{id}/status
nastavit dimenze hlavičky konceptuPUT /api/v1/accounting/dimensions/documents/other-items/{id}

Dimenze token zapíše jen ke konceptu, který nepatří do opakování s automatickým účtováním; jinak 403 token_write_forbidden. Smlouvu nebo jiný dokument k dokladu připojíte běžnou vazbou dokumentu POST /api/v1/documents/{id}/links s entity_type: other_item.

Do deníku se tím nic nezapisuje. Upravit a smazat jde jen koncept; potvrzený nebo zaúčtovaný doklad server odmítne chybou 409. Automatické účtování opakování token nezapne ani neobnoví a koncept z automaticky účtovaného opakování neupraví ani nesmaže, to skončí chybou 403 other_items.error.auto_post_session_only. Potvrzení a zaúčtování, storno, přeúčtování, párování úhrad i ruční generování opakování zůstávají jen ve webovém rozhraní (403 token_write_forbidden). Uživatel, kterému token patří, musí mít oprávnění zápisu k ostatním položkám.

Druhou výjimkou jsou analytické účty účtové osnovy, například 378.800 pro zápůjčku pod syntetickým účtem 378. Integrace nebo AI asistent je tak založí dřív, než na ně připraví koncept:

OperaceCesta
založit analytikuPOST /api/v1/accounting/accounts
přejmenovat, deaktivovat nebo znovu aktivovat analytikuPATCH /api/v1/accounting/accounts/{id}

Rodiče určíte číslem (parent_code, např. 378) nebo ID (parent_id). Analytika přebírá typ účtu i stranu po syntetice a číslo bez tečky se doplní (378800 → 378.800). Neexistující rodič vrátí 404, obsazené číslo 409 duplicate_account. Syntetické účty token jen čte (403 token_write_forbidden) a smazat účet lze jen ve webovém rozhraní. Uživatel, kterému token patří, musí mít oprávnění zápisu do účetnictví a firma musí vést podvojné účetnictví.

Stejné pravidlo platí i u akcí nad doklady, které jinak token používat smí. Chybou 403 token_write_forbidden skončí přes API token:

Běžný postup zůstává tokenu dostupný: koncept upraví, přijatou fakturu přijme nebo označí jako uhrazenou, druh nákladu doplní u nezaúčtovaného dokladu. Pokud má firma zapnuté automatické zaúčtování při vystavení faktury nebo přijetí přijaté faktury, proběhne i při volání přes token, stejně jako v aplikaci.

Mzdové endpointy jsou kvůli rodným číslům, adresám, mzdovým částkám a dalším personálním údajům dostupné pouze přihlášenému uživateli ve webové aplikaci. Bearer token na ně vrátí 403 token_endpoint_forbidden; veřejný mzdový API kontrakt zatím neexistuje.

103.9.8 Omezení tokenu podle IP adresy

U každého tokenu lze nastavit seznam povolených zdrojových adres. Ve výpisu tokenů k tomu slouží sloupec IP omezení.

ZápisVýznam
203.0.113.7jediná IPv4 adresa
192.168.1.0/24celý rozsah IPv4
2001:db8::1jediná IPv6 adresa
2001:db8::/32prefix IPv6

Neplatný zápis se neuloží. Kontroluje se i smysluplnost prefixu vůči rodině adresy, takže 192.168.1.0/64 skončí chybou - jinak by vzniklo pravidlo, které nikdy nic nepovolí, a token by tiše přestal fungovat.

Tip

Když jede integrace z jednoho serveru, omezte token na jeho adresu. Uniklý token je pak k ničemu komukoli mimo vaši síť.

103.9.9 Log volání API

Každé volání bearer tokenem se zaznamenává - včetně zamítnutých. Výpis najdete v Firma → MCP server, sekce Log volání; vidíte vždy jen volání svých vlastních tokenů.

U každého záznamu je čas, token, HTTP metoda, cesta, návratový kód, doba zpracování a zdrojová IP. U volání z MCP serveru navíc název nástroje, který volání vyvolal, takže je poznat záměr, ne jen holá cesta.

Filtrovat jde podle tokenu, metody, cesty, zdroje (jen MCP) a na samotné chyby. Záznamy se drží 90 dní, pak je uklidí údržbový cron. Nejde o auditní stopu podle § 33a - ta žije dál v Aktivitě uživatelů a nemaže se.

103.9.10 Chybové odpovědi

Všechny chyby v unifikovaném formátu:

{ "error": { "code": "validation_failed", "message": "Pole 'name' je povinné." } }
KódVýznam
unauthenticated / invalid_tokenChybí nebo neplatný token
insufficient_scopeToken nemá read_write
token_endpoint_forbiddenEndpoint není přes token dostupný (jen z webu)
token_write_forbiddenZápis do účetní / daňové vrstvy přes token nejde; výjimkou jsou jen koncepty ostatních pohledávek a závazků a analytické účty osnovy (§ 103.9.7.1)
session_requiredOperaci dělá člověk v aplikaci; token na ni nestačí ani se read_write
token_ip_forbiddenToken není povolen z této IP adresy
validation_failedTělo neprošlo validací
not_foundZdroj neexistuje (nebo nepatří aktuálnímu supplier-ovi)
rate_limitedPřekročen limit (viz Retry-After)

103.9.11 Nastavení dodavatele a číslování dokladů přes API

Veřejný subset nastavení dodavatele jde měnit tokenem se scope read_write (uživatel tokenu musí být admin):

curl -X PUT https://mojefirma.example/api/v1/settings/supplier/invoice-counter \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{ "type": "invoice", "next_number": 42 }'
# → { "type": "invoice", "next_number": 42, "counter": 41,
#     "period": "202607", "preview": "2607042",
#     "client_id": 0, "revenue_category_id": 0 }

Counter jde i snížit; pokud by nové číslo kolidovalo s už vystaveným dokladem, vystavení se samoopravně posune na první volné číslo - duplicitní číslo nikdy nevznikne. Volitelné date (YYYY-MM-DD) určuje období řady (při invoice_number_period = year/month), default je dnešek.

Řada nemusí patřit dodavateli: volitelné client_id, resp. revenue_category_id míří na vlastní řadu zákazníka, resp. kategorie tržby. Obě naráz nejdou a osa musí mít vlastní šablonu daného typu - u zděděné šablony je řada společná s dodavatelem a nastavuje se na něm. Zákazník nebo kategorie mimo vaši firmu vrací 400 invalid_reference. Odpověď v client_id / revenue_category_id vrací osu, na které counter vznikl.

Totéž pole nabízí i aplikace - v nastavení firmy, u zákazníka i u kategorie tržby, vždy pod tou šablonou, ke které řada patří.

curl -X POST https://mojefirma.example/api/v1/settings/supplier/logo \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@logo.png"
# → { "logo_path": "storage/supplier-logos/sup-1.png", "width": 480, "height": 160 }

103.9.12 Brandingový profil faktury

Po zapnutí modulu brandingových profilů vrací aktivní profily aktuálního dodavatele read-only endpoint:

curl -H "Authorization: Bearer $TOKEN" \
  https://mojefirma.example/api/v1/branding-profiles

Hodnotu id lze poslat při vytvoření konceptu faktury:

curl -X POST https://mojefirma.example/api/v1/invoices \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": 123,
    "branding_profile_id": 5,
    "issue_date": "2026-07-20",
    "due_date": "2026-08-03",
    "items": [{
      "description": "Konzultační služby",
      "quantity": 1,
      "unit": "h",
      "unit_price_without_vat": 2500,
      "vat_rate_id": 1
    }]
  }'

Profil musí být aktivní a patřit stejnému dodavateli jako klient. Jinak API vrátí HTTP 400 s kódem integrity_violation. Když branding_profile_id v těle chybí nebo je null, nový koncept převezme výchozí profil klienta a následně výchozí profil dodavatele. Není-li žádný nastaven, použije základní identitu.

Při vystavení se výsledná identita včetně cesty k verzi loga uloží do snapshotu faktury. Pozdější úprava profilu tedy již vystavený doklad nezmění.

103.9.13 Export faktur přes API

curl -H "Authorization: Bearer $TOKEN" -OJ \
  "https://mojefirma.example/api/v1/invoices/export?format=isdoc&month=2026-06"

103.9.14 Bezpečnost tokenů - best practices

103.9.15 Co API nepokrývá

103.9.16 Dávkové čtení katalogu

103.9.16.1 Navigace ve filtrovaném výběru

POST /api/v1/stock/items/{id}/neighbors přijímá filters stejného tvaru jako seznam karet a volitelná pole ids a excluded_ids, každé nejvýše 30 000 ID. Vrátí previous_id, next_id, position a total pro celý filtrovaný výběr. Prázdné ids znamená prázdný výběr, vynechané ids všechny vyhovující karty. Nedostupná karta má nulové sousedy a position: null, bez prozrazení cizí firmy. Endpoint je čtecí a povoluje token se scope read.

Pro synchronizaci e-shopu použijte čtecí POSTy POST /api/v1/catalog/products/batch a POST /api/v1/catalog/prices/batch. Jsou dostupné i tokenu se scope read: POST je zde jen způsob, jak předat větší strukturovaný dotaz, data nemění.

Oba endpointy přijmou nejvýš 500 unikátních ID. Výsledek obsahuje položku pro každé vstupní ID ve stejném pořadí. Karta, která neexistuje nebo nepatří aktuální firmě, vrátí shodně { "status": "unavailable", "data": null }; API tak neprozrazuje existenci cizích karet.

103.9.16.2 Produkty

POST /api/v1/catalog/products/batch očekává alespoň ids. Bez fields vrací sku, name, ean a is_active; každá dostupná karta má vždy také id a row_version. Pole fields slouží pro selektivní načtení dalších sekcí, například i18n, prices nebo availability. Překlady lze omezit polem locales (nejvýš 20 jazyků), ceny polem currencies (nejvýš 10 měn) a dostupnost polem warehouse_ids (nejvýš 50 skladů). Vynechané warehouse_ids zahrnou všechny sklady firmy.

Projekce costs obsahuje nákladové ocenění a vyžaduje oprávnění stock.items.write; token pouze pro čtení ji nedostane, i když samotný dávkový endpoint je čtecí.

{
  "ids": [41, 42],
  "fields": ["sku", "name", "i18n", "availability"],
  "locales": ["cs", "en"],
  "warehouse_ids": [3]
}

103.9.16.3 Efektivní ceny

POST /api/v1/catalog/prices/batch přijímá seznam items s id a volitelným qty. Množství je kladný desetinný řetězec s nejvýš 11 číslicemi před a třemi za desetinnou tečkou, aby integrace neztratila přesnost převodem na JavaScriptové číslo. Když qty vynecháte, API použije "1"; currency je výchozí CZK a on_date dnešní datum. Cena se vyhodnocuje zvlášť pro množství každé položky. Pokud pro kartu a měnu platná cena není, je cena null, nikdy náhradní nula.

{
  "currency": "EUR",
  "on_date": "2026-09-09",
  "items": [
    { "id": 41, "qty": "2.500" },
    { "id": 42 }
  ]
}

103.9.17 Asynchronní export katalogu

POST /api/v1/catalog/exports založí JSONL export a vrátí katalogovou úlohu se stavem queued nebo running. Jde o třetí čtecí POST katalogu, takže je dostupný i tokenu se scope read. Stav úlohy průběžně načítejte přes GET /api/v1/eshop/jobs/{id} a hotový soubor stáhněte z GET /api/v1/catalog/exports/{id}/download.

Tělo má selection a projection. Výběr je buď konkrétní seznam ids, nebo all_matching: true s filtry stejného tvaru jako seznam skladových karet a volitelným excluded_ids. Výběr konkrétních ID i vyloučení má strop 30 000 položek. Projekce přijímá stejná pole jako dávkové čtení produktů, kromě costs; náklady export vždy odmítne 403 forbidden_projection, bez ohledu na oprávnění tokenu. Výchozí pole jsou sku, name, ean, is_active, jazyky cs a měny CZK. locales, currencies a warehouse_ids mají stejné limity 20, 10 a 50 jako dávkové čtení.

{
  "selection": {
    "all_matching": true,
    "filters": { "active": true, "availability": "in_stock" },
    "excluded_ids": [42]
  },
  "projection": {
    "fields": ["sku", "name", "i18n", "prices", "availability"],
    "locales": ["cs", "en"],
    "currencies": ["CZK", "EUR"],
    "warehouse_ids": [3]
  }
}

Při založení exportu se zmrazí ID a row_version každé vybrané karty. Worker čte obsah po dávkách v konzistentním snapshotu a ke každé hotové kartě zapíše captured_at. Změní-li se karta mezi zařazením a jejím zachycením, výsledný řádek má status: "conflict" a error_code: "version_conflict"; export tak nemíchá starou identitu a nová data. Karta neexistující, cizí nebo nedostupná při čtení zůstává v souboru se status: "failed", error_code: "unavailable" a data: null.

Hotový soubor je application/x-ndjson a začíná jedním manifestem:

{"type":"manifest","format_version":1,"job_id":81,"total":2,"consistency":"selection_versions_with_per_batch_snapshot"}

Následuje jeden řádek pro každou požadovanou kartu ve zmrazeném pořadí. Každý má type: "product", ordinal, id, status, expected_version, error_code, captured_at a data. Dokud úloha není completed, download vrací 409 export_not_ready. ID cizí firmy, neexistující export a jiný typ úlohy vracejí shodně 404.

103.9.18 Dimenze a manažerské sestavy

GET /api/v1/accounting/dimensions vrací zapnutí dimenzí, typy, hodnoty a jejich hierarchii pro aktuální firmu. Kontext firmy určuje X-Supplier-Id a oprávnění tokenu. Dimenze jsou dostupné ke čtení s účetním oprávněním.

EndpointPovinné parametryObsah
/accounting/reports/dimension-profittype_id, from, toVýnosy, náklady a zisk podle hodnot dimenze; volitelně value_id, responsible_user_id, accounts=1, companies=1
/accounting/reports/dimension-analyticstype_id, yearMěsíční vývoj, srovnání minulého roku a souhrny dimenzí a firem
/accounting/reports/dimension-cash-flowfrom, toManažerský cash flow nepřímou metodou a kontrola proti skutečnému pohybu peněz

První a třetí sestava používají scope=group pro součet dostupných firem skupiny u globální dimenze. Statistiky používají supplier_id=all; jinak se vztahují na aktuální firmu. Pro cash flow skupiny je nutný dimension_value_id globální hodnoty. Token vázaný na firmu nemůže tento rozsah rozšířit. Práva k jednotlivým firmám se ověřují při každém dotazu.

Rozvaha, druhová i účelová výsledovka, výkazy po účtech, obratová předvaha, hlavní kniha a účetní deník podporují dimension_value_id. Parametr dimension_descendants=0 vybere jen zadanou hodnotu, jinak filtr zahrnuje také podřízené hodnoty. Rozvaha a výsledovka vyžadují period_id z aktuální firmy a mohou použít as_of; nelze do nich předat účetní období jiné firmy.

Seznamy faktur podporují filter[include_dimensions]=1, účetní deník include_dimensions=1 pro dimenzní štítky v odpovědi. Podrobná přiřazení jsou dostupná přes /accounting/dimensions/documents/{doc}/{id} a /accounting/dimensions/journal/{id}. Tyto operace data nemění.

Úplný kontrakt včetně schémat odpovědí je v OpenAPI. Pro AI asistenta stejné sestavy zpřístupňuje MCP server.

103.9.19 Sady (virtuální sety)

Sada je skladová karta bez vlastní zásoby se složením z jiných karet (Virtuální sety). ID sady je shodné s ID karty. Čtení stačí token se scope read a oprávnění eshop; zápis vyžaduje scope read_write a oprávnění eshop.write a stock.items.write.

OperaceEndpointCo dělá
SeznamGET /api/v1/stock/setsStránkovaný seznam sad s definicí; filtry q, sku, active, updated_since
DetailGET /api/v1/stock/sets/{id}Karta sady a její definice s row_version
ZaloženíPOST /api/v1/stock/setsKartu sady i definici založí v jedné transakci
ÚpravaPUT /api/v1/stock/sets/{id}Nahradí definici; row_version musí odpovídat uložené verzi
DávkaPOST /api/v1/stock/sets/bulkAž 200 sad, upsert podle sku, výsledek po položkách

Definice má pevné komponenty (components), skupiny voleb (groups) a cenotvorbu podle měny (prices). Komponentu lze určit přes item_id, nebo přes sku; obojí se hledá jen v aktuální firmě, cizí karta skončí chybou set_component_not_found. Validace je stejná jako v konfigurátoru: komponenty musí být aktivní, cyklus se odmítne a karta vedená skladem sadou být nemůže.

{
  "sku": "SADA-KAVA",
  "name": "Dárková sada kávy",
  "definition": {
    "components": [
      { "sku": "KAVA-250", "quantity": "2" },
      { "sku": "HRNEK-BILY", "quantity": "1" }
    ],
    "prices": { "CZK": { "mode": "discount", "discount_pct": "10" } }
  }
}

Při úpravě pošlete row_version z posledního čtení. Pokud sadu mezitím změnil někdo jiný, API vrátí 409 version_conflict a sadu je potřeba načíst znovu.

Dávka zpracuje každou položku ve vlastní transakci, takže chyba jedné položky ostatní neovlivní a odpověď je 200 i při částečném neúspěchu. Pole results má pro každou položku status (created, updated, unchanged, error) a u chyby error.code. Položka, jejíž uložená definice už odpovídá požadavku, vrátí unchanged a verzi nezvýší, proto lze dávku po výpadku bez obav poslat znovu. Sada může jako komponentu použít sadu založenou dříve v téže dávce. Název a další údaje existující karty dávka nemění, k tomu slouží PUT /api/v1/stock/items/{id}. Tisíce sad pošlete po dávkách nejvýš 200 sad postupně, ne souběžně. Firma může mít nejvýš 5 000 sad.

Seznam i detail skladové karty (/api/v1/stock/items) vracejí is_set a set_id, takže integrace pozná sadu i bez dalšího dotazu.

103.9.20 Převzetí faktur a dobropisů vystavených e-shopem

Když faktury a dobropisy vystavuje e-shop sám, převezme je POST /api/v1/invoices/import tak, jak je zákazník dostal: s původním číslem, položkami, daty, částkami i DPH. Doklad vznikne rovnou jako vystavený, MyÚčto mu nepřiděluje číslo z řady a částky nepřepočítává. Evidence DPH, přiznání i kontrolní hlášení pak čtou přesně ty částky, které poslal e-shop. Token potřebuje scope read_write, uživatel oprávnění k zakládání i vystavování faktur.

{
  "invoice_type": "invoice",
  "varsymbol": "2026000123",
  "client_id": 42,
  "issue_date": "2026-06-15",
  "tax_date": "2026-06-15",
  "due_date": "2026-06-29",
  "currency": "CZK",
  "prices_include_vat": true,
  "payment_method": "card",
  "total_without_vat": 199.99,
  "total_vat": 42.00,
  "total_with_vat": 241.99,
  "items": [
    { "description": "Zboží A", "quantity": 3, "unit": "ks", "unit_price_without_vat": 33.33,
      "vat_rate": 21, "total_without_vat": 99.99, "total_vat": 20.99, "total_with_vat": 120.98 },
    { "description": "Zboží B", "quantity": 1, "unit": "ks", "unit_price_without_vat": 100.00,
      "vat_rate": 21, "total_without_vat": 100.00, "total_vat": 21.01, "total_with_vat": 121.01 }
  ]
}

Co API před uložením ověří:

Import odmítne stejně jako vystavení doklad v uzavřeném účetním období, přenesenou povinnost bez DIČ odběratele a doklad s DPH v době, kdy firma nebyla plátcem. Odmítne i období, za které už je podané přiznání k DPH, kontrolní hlášení nebo OSS přiznání: převzatý doklad by do něj dodatečně přibyl a výkazy by nesouhlasily s tím, co je odevzdané.

Dobropis se k opravované faktuře naváže přes parent_invoice_id nebo parent_varsymbol (číslo faktury). Den doručení dobropisu (corrective_delivered_on) se uloží a určí zdaňovací období opravy (§ 42 odst. 3 ZDPH), stejně jako u dobropisu vystaveného v aplikaci.

Když doklad se stejným číslem už existuje, API vrátí 409 varsymbol_duplicate a v error.existing_invoice_id id uloženého dokladu. Opakovaný pokus e-shopu po výpadku tak doklad nezdvojí a integrace ví, ke kterému dokladu patří.

Import neřeší:

Chybějící členění plnění (vat_classification_code) se doplní stejně jako u faktury vytvořené v aplikaci. Číselná řada se po importu dorovná, takže faktura vystavená později přímo v MyÚčtu nedostane číslo, které už má převzatý doklad.

103.9.21 Účetní kontext k datu

GET /api/v1/accounting/catalog/context?date=2026-07-01 vyžaduje právo accounting ke čtení. Vrací účetní rámec, metodu evidence, role účtů a identifikátory jejich datovaných definic. date je povinné a nejdříve 1900-01-01. Token vázaný na firmu zůstává v jejím kontextu.

Výsledek používá současnou znalost evidence, nikoli tehdejší znalost. Parametr known_at není podporovaný a vrací 409 accounting_context_known_at_unsupported. Intervaly mají zahrnutý počátek effective_from a nezahrnutý konec effective_until; neomezená nebo neznámá hranice je null podle temporal_source.

complete a findings uvádějí historická omezení. Účet bez historie vrací platnou hodnotu s temporal_source=current_base, nikoli prázdnou osnovu; jeho historická jistota zůstává neúplná. Účet před doloženým založením se nevrací. Chybějící účet role má account_id=null. Revize metadat poskytuje pouze ID, číslo revize a otisk definice. Volné názvy účtů, podklady, autoři a interní JSON se nevracejí.

Systémové dimenze pro rámec 504 poskytují pouze současné identifikátory typů a významových hodnot. Jejich názvy a aktivita nejsou historicky doložené, proto mají historical_state_available=false a odpovídající finding. Kontext nevytváří chybějící účty ani dimenze a neprovádí právní či daňové posouzení. Všechna pole pocházejí z jednoho konzistentního databázového snapshotu.

role_profile výslovně uvádí aktuální katalog rolí vybraný datovaným rámcem. Resolver nečte právní profil ani příznaky modulu SVJ. Historické verze pravidel nejsou evidované; kontext neposuzuje právní způsobilost a complete nepotvrzuje tehdejší znění pravidel.

Čtení účetních případů služeb a financování vlastníků

Veřejné API nabízí pod /api/v1/property/catalog čtecí cesty service-lifecycles, service-lifecycles/{id}, service-lifecycles/reconciliation, funds/operations a funds/balances. Vyžadují právo čtení agendy SVJ. Zaúčtování, právní potvrzení, čerpání a storna se provádějí v potvrzovaném aplikačním toku.

Rekonciliace a zůstatky vyžadují date. Bez filtru jednotky či domu se zůstatky ověřují za celou firmu včetně nepropojených zápisů. Zachovejte matches, coverage, zjištění a identifikátory nepokrytých řádků. Neúplný výsledek nepotvrzuje finanční pozici. Částky v haléřích jsou přesné podepsané řetězce; neurčené částky zůstávají null.

Seznamy používají after_id a limit nejvýše 100. Další stránku načtěte z next_after_id při stejné firmě a filtrech. Lifecycle služeb a jeho rekonciliace čtou současnou znalost podkladů a nepodporují known_at; jeho zadání vrací 409. Zůstatky financování podporují doložený čas zaznamenání a zaúčtování podle known_at. Výstupy neobsahují soukromé důkazy, kontakty ani celé zdrojové snapshoty.

Potvrzené granty, dary, investiční zdroje a fondy

Účelové zdroje čte GET /api/v1/accounting/catalog/nonprofit-funding a jeho číselný detail /{id}. ID zdroje je ID jeho první potvrzené revize; current_revision_id a revision_no označují poslední zaznamenanou revizi. Katalog ověřuje návaznost a otisky revizí. Aktuální rozhodnutí o účelu, způsobilost a skutečné použití nejsou pokryté: purpose_decision=unknown, eligibility=not_assessed a usage_links=not_available. Hodnoty source_current, usage_count, used_cents, budget_remaining_cents a available_cents zůstávají null. Zaznamenaná metadata a ověřený řetězec nepotvrzují právní ani daňový závěr. Uživatelský klíč zdroje, právní podklady, účelové texty, autoři a osobní údaje se nevracejí. Poskytovatel je pouze provider_client_id dostupné firmy.

Ověřitelné podklady jednoho zdroje, například pro potvrzení o daru, čte GET /api/v1/accounting/catalog/nonprofit-funding/{id}/evidence s povinnými period_id, assessment_id a kind. Čtou se z potvrzeného posouzení J6 uloženého jako neměnný stránkovaný graf. kind=purpose vrací účetní řádek, datum a částku přijetí, druh činnosti, právní titul, volbu osvobození a zákonný kód zařazení. kind=usage vrací souhrn čerpání zdroje v posouzení a kind=uses jednotlivé čerpané nákladové řádky s částkou. Každá stránka ověří jeden blok grafu. Prázdná stránka s next_cursor neznamená konec; pokračujte s after_ordinal a offset z next_cursor, dokud není null. U kind=uses určuje limit (1 až 100) počet položek na stránce. Posouzení uložené jen ve starším formátu vrací 409 nonprofit_tax_legacy_history_requires_migration. Potvrzení ani dopis aplikace netvoří; podklady jsou určené externímu nástroji.

Investiční zdroje a fondy čte GET /api/v1/accounting/catalog/nonprofit-capital, detail /{id} a zaznamenaná použití a storna /{id}/events. Vazby na účetní řádky, majetek, odpisy a původní operaci jsou číselné identifikátory. Hodnoty ověřuje nativní evidence včetně přesného storna; katalog je nepřepočítává.

Všechny tyto cesty vyžadují accounting ke čtení a zůstávají pouze čtecí i pro token s právem zápisu. Kolekce přijímají after_id z next_cursor a limit od 1 do 100. Každý request má vlastní kanonickou owner transakci; stránky nejsou společný atomický snapshot. Neúplné zaznamenané zdroje se nevynechávají. Prázdná poslední stránka má next_cursor=null.

Částky jsou řetězce v haléřích. Zachovejte null, source_current, proof_status a coverage.findings. pending_coverage=not_assessed a complete=false výslovně znamenají, že čekající operace nejsou pokryté; prázdná stránka jejich absenci nedokládá. Účelové zdroje zpřístupňují pouze zaznamenaná metadata revizí. Částky ani proof status nejsou oprávnění k dalšímu čerpání.

Katalog vrací současnou znalost. Parametry date, as_of a known_at nepodporuje a odmítá kódem 409 nonprofit_catalog_time_unsupported.

103.10 Související kapitoly