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
- Propojujete MyÚčto s e-shopem, CRM, Make, Zapierem nebo vlastním skriptem.
- Potřebujete stáhnout data do BI nebo reportingu.
- Hledáte dokumentaci endpointů a specifikaci OpenAPI.
- Token unikl nebo ho už nepoužíváte a chcete ho zrušit.
- Integrace dostává
403a potřebujete zjistit proč.
| Kdy | Co udělat | Kde |
|---|---|---|
| před spuštěním integrace | Vytvořit token s nejmenším potřebným rozsahem | Firma → API tokeny, § 103.3 |
| po vytvoření | Vyzkoušet volání | § 103.4 |
| u integrace z jednoho serveru | Omezit 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 úniku | Token zrušit | § 103.7 |
103.2 Než začnete
- Každý uživatel spravuje své vlastní tokeny; dostupné firmy a oprávnění se odvozují z jeho účtu.
- K vytvoření tokenu potřebujete passkey nebo TOTP (účet bez silného faktoru použije aktuální heslo). Samotné přihlášení nestačí.
- Mějte připravený password manager nebo secret úložiště, kam token uložíte.
- Dokumentace API je na třech variantách nad jednou specifikací OpenAPI:
| URL | Nástroj | Použití |
|---|---|---|
| /api/docs | Swagger UI | „Try it out": vložte API token (Authorize) a volejte endpointy přímo z prohlížeče |
| /api/reference | Redoc | Statická reference, 3-sloupcový layout, lepší typografie pro čtení |
| /api/scalar | Scalar | Moderní reference s vestavěným API klientem a fulltext vyhledáváním |
| /api/openapi.yaml | Raw OpenAPI 3.1 | Import do Postmana, Insomnie, Zapier Custom App, Make HTTP modulu |
103.3 Krok za krokem: vytvoření tokenu
- Otevřete
Firma → API tokenya klikněte na Nový token. - Vyplňte:
- Název - pojmenujte integraci (například „Make integrace").
- Dodavatel - má-li účet víc firem, vyberte firmu, do které token patří. Doporučeno: token vázaný na jednu firmu nemůže přistupovat k datům jiných firem.
- Rozsah -
read(GET a výslovně čtecí POSTy katalogu) neboread & write(plné API). - Evidence mzdových podání v Dokumentech - volitelné, výchozí vypnuto (viz § 103.9.2).
- Expirace - nezadáte-li datum, platí token 90 dní (nejvýše 730 dní). Volba Token bez expirace se nedoporučuje a token s právem zápisu bez expirace může vytvořit jen superadmin.
- 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.
- 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í.
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í
- Zavolejte endpoint, který vrací identitu tokenu:
curl -H "Authorization: Bearer mi_pat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
https://myucto.cz/api/v1/auth/api-me
- Zkontrolujte odpověď (
user,supplier,auth_method,token). - 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
- Otevřete
Firma → API tokenya u tokenu klikněte na Nastavit omezení podle IP adresy. - Do pole IP adresa nebo rozsah zadejte adresu (například
203.0.113.7nebo192.168.1.0/24), případně Poznámka, a klikněte na Přidat. - 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.
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í
- Otevřete
Firma → MCP servera sekci Log volání. - Filtrujte podle tokenu, metody, cesty, zdroje (jen MCP), případně jen chyby.
- 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
- Otevřete
Firma → API tokeny. - U tokenu klikněte na Zrušit a potvrďte dotaz. Přístup skončí okamžitě.
- 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.
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íte | Proč | Co udělat |
|---|---|---|
401 / invalid_token | Chybí, vypršel nebo byl zrušen token | Vytvořte nový token |
403 insufficient_scope | Token má rozsah read | Vytvořte token s read & write |
403 token_write_forbidden | Zápis do účetní a daňové vrstvy přes token nejde | Úkon proveďte v aplikaci (§ 103.9.7.1) |
403 token_endpoint_forbidden | Endpoint (například mzdy) je jen pro přihlášené v prohlížeči | Použijte aplikaci; veřejný kontrakt pro mzdy neexistuje |
403 session_required | Operaci dělá člověk v aplikaci | Použijte aplikaci |
403 token_ip_forbidden | Token není povolen z této IP | Přidejte IP v omezení tokenu |
429 Too Many Requests | Překročen limit 600 požadavků za minutu | Poč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 zdroj | Zdroj 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
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.
- Evidence mzdových podání v Dokumentech je volitelná schopnost, výchozí vypnutá. Dokumenty navázané na mzdová podání (doručenky datové schránky, protokoly ČSSZ, odpovědi zdravotních pojišťoven) jsou pro tokeny normálně neviditelné; výpis je přeskočí a detail vrátí
404. Zaškrtněte jen tehdy, když je integrace opravdu potřebuje, například archivační skript, který je zakládá a pak s nimi pracuje. Zdravotní údaje, exekuce, insolvenci ani výplatní pásky tím neodemknete, ty zůstávají jen pro přihlášení v prohlížeči. Schopnost jde nastavit jen při vytváření tokenu; existujícímu ji doplnit nelze, vyrobte nový. Jestli ji token má, poznáte podle štítku v přehledu tokenů a podleallow_payroll_submission_docsvapi-me. - Expirace. Bez zadaného data platí token 90 dní (nejvýše 730 dní). Token bez expirace se nedoporučuje.
- Čerstvé ověření. Passkey otevře systémový dialog zařízení; TOTP vyžaduje aktuální šestimístný kód. Ověření je jednorázové a vázané přímo na vytvoření tokenu.
- Plain-text token (
mi_pat_…) se zobrazí jen jednou, zpětně ho nelze získat.
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í
- Stabilní cesta:
/api/v1/... - Každá response vrací hlavičku
X-API-Version: 1. - Pokud přidáme nekompatibilní změnu, půjde do
/api/v2/...; v1 zůstane funkční.
103.9.5 Rate limity
- 600 requestů / minutu / token (defaultně, konfigurovatelně přes
cfg.rate_limits.api_per_min_per_token). - Při překročení vrátíme
429 Too Many Requests+Retry-After: <s>.
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
| Scope | Povolené metody |
|---|---|
read | GET, HEAD a čtecí dávkové POSTy katalogu |
read_write | vš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.
| Cesta | GET | zápis |
|---|---|---|
/api/v1/accounting/** mimo mzdové podcesty | ano | ne, 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-sheet | ne | ne |
/api/v1/reports/** | ano | ne |
/api/v1/tax/, /api/v1/tax-evidence/ | ano | ne |
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í:
| Operace | Cesta |
|---|---|
| založit koncept | POST /api/v1/accounting/other-items |
| upravit a smazat koncept | PUT, 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 konceptu | PUT /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:
| Operace | Cesta |
|---|---|
| založit analytiku | POST /api/v1/accounting/accounts |
| přejmenovat, deaktivovat nebo znovu aktivovat analytiku | PATCH /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:
- ruční zaúčtování přijaté faktury, tedy přechod na stav
booked(POST /api/v1/purchase-invoices/{id}/transitionstarget: "booked"), - změna druhu nákladu u zaúčtované přijaté faktury (
PUT /api/v1/purchase-invoices/{id}/expense-kinds), protože by se doklad přeúčtoval, - vynucená úprava (
force=1) vystavené faktury nebo přijaté faktury, která už není koncept, a vynucené smazání takového dokladu, - jakákoli úprava dokladu v uzavřeném účetním období přes
force=1.
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í.
- Prázdný seznam = bez omezení. Token funguje odkudkoliv. Tak se chovají všechny existující tokeny, dokud jim první pravidlo nepřidáte.
- Jakmile přidáte první pravidlo, projdou jen volání z uvedených adres. Ostatní dostanou
403 token_ip_forbidden- a zamítnutí se zapíše do logu volání (viz níže), takže je poznat, že někdo zkouší token odjinud. - Podporované zápisy: IPv4 i IPv6, samostatná adresa i CIDR rozsah.
| Zápis | Význam |
|---|---|
203.0.113.7 | jediná IPv4 adresa |
192.168.1.0/24 | celý rozsah IPv4 |
2001:db8::1 | jediná IPv6 adresa |
2001:db8::/32 | prefix 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.
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ód | Význam |
|---|---|
unauthenticated / invalid_token | Chybí nebo neplatný token |
insufficient_scope | Token nemá read_write |
token_endpoint_forbidden | Endpoint není přes token dostupný (jen z webu) |
token_write_forbidden | Zá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_required | Operaci dělá člověk v aplikaci; token na ni nestačí ani se read_write |
token_ip_forbidden | Token není povolen z této IP adresy |
validation_failed | Tělo neprošlo validací |
not_found | Zdroj neexistuje (nebo nepatří aktuálnímu supplier-ovi) |
rate_limited | Př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):
PUT /api/v1/settings/supplier- částečný update: fakturační údaje, defaulty, číslování dokladů (invoice_number_format,proforma_number_format,credit_note_number_format,purchase_invoice_number_format,invoice_number_period) a branding (email_branding_enabled,email_accent_color,pdf_logo_show_name,invoice_pdf_monochrome,display_name,tagline). Tato pole představují původní nastavení dodavatele, které se používá při vypnutých brandingových profilech. Logo se přes tento endpoint nastavit nedá. Poledefault_rounding_mode(auto,none,whole_czk) určuje režim zaokrouhlení, který dostane nová faktura založená bez polerounding_mode. Volbainvoice_pdf_show_issued_byzapne na PDF faktury řádek „Vystavil“. Kdo doklad vystavil, vrací detail faktury v políchissued_by(id uživatele) aissued_by_name(jméno v okamžiku vystavení). U konceptu, importovaného dokladu a dokladu vystaveného bez přihlášeného uživatele jsou obě polenull.
PUT /api/v1/settings/supplier/invoice-counter- nastaví counter číselné řady tak, aby příští vystavený doklad dostal zadané číslo. Hodí se při migraci z jiného fakturačního software (navázání na existující řadu):
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ří.
POST /api/v1/settings/supplier/logo- multipart upload loga (polefile; PNG / JPG / SVG / WebP, max 1 MiB). Logo se v e-mailech a PDF ukládá do původního nastavení dodavatele a zobrazuje při zapnutém brandingu.DELETEna stejné cestě logo odebere:
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
- hromadný export vystavených dokladů za měsíc (nebo
period=quarterly&year=YYYY&quarter=1..4). PDF ZIP, ISDOC, Pohoda, Stereo, Money S3 XML nebo CSV;date_by=taxzařazuje dle DUZP (shodně s výkazy DPH). Jde o stejnou logiku jako na obrazovce Export / Import → Export vystavených. GET /api/v1/invoices/{id}/isdoc- ISDOC XML jedné vystavené faktury (koncept nelze, 400). PDF je dostupné přesGET /api/v1/invoices/{id}/pdf.
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
- Ukládejte token jako secret (password manager, Make encrypted variable, GitHub Secrets…). Nepushujte do gitu.
- Vyhraď token jedné integraci - pokud aplikaci přestanete používat, zrušte jen tenhle token, ostatní zůstanou funkční.
- Read-only kde to jde - reporting do BI nepotřebuje
read_write. - Bound na supplier_id - minimalizuje radius pádu při kompromitaci.
- Sledujte
last_used_atv UI - token, který se 3 měsíce nepoužil, asi nepotřebujete. - Při ztrátě nebo podezření okamžitě klikněte v UI na Zrušit. Revokace je instantní (žádný cache).
- Zrušit, nebo Smazat? Zrušení je bezpečná volba: přístup skončí okamžitě, ale token zůstane v přehledu a v logu volání si drží celou historii - je pak vidět, co s ním kdo dělal. Mazání je navíc úklid: token z přehledu zmizí a jeho volání v logu ztratí přiřazení (zůstanou jako volání bez jména). Při podezření na zneužití proto nejdřív zrušte a mažte až po prošetření - jinak zahodíte právě ty stopy, které byste potřebovali. Kdo co smazal, zůstane v Aktivitě (
api_token.deletedvčetně jména a prefixu).
103.9.15 Co API nepokrývá
- Session-only a administrační endpointy mohou být v
openapi.yamlzdokumentované kvůli úplnému kontraktu SPA, ale bearer token je volat nesmí. Poznáte je podle popisu operace a případné chybytoken_endpoint_forbidden. Externí integraci stavte jen na operacích výslovně dostupných pro PAT; interní správu uživatelů, rolí, tokenů a podpisových profilů neautomatizujte. - Webhooks nejsou podporované - pokud potřebujete notifikaci o platbě, použijte polling
/api/v1/invoices?status=paid&from=<last_check>. - OAuth2 nepodporujeme - PAT je vědomé zjednodušení pro tenhle typ produktu.
- Idempotency-Key není podporován; pokud Make po retry vytváří duplicitní záznam, založte issue.
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.
| Endpoint | Povinné parametry | Obsah |
|---|---|---|
/accounting/reports/dimension-profit | type_id, from, to | Výnosy, náklady a zisk podle hodnot dimenze; volitelně value_id, responsible_user_id, accounts=1, companies=1 |
/accounting/reports/dimension-analytics | type_id, year | Měsíční vývoj, srovnání minulého roku a souhrny dimenzí a firem |
/accounting/reports/dimension-cash-flow | from, to | Manaž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.
| Operace | Endpoint | Co dělá |
|---|---|---|
| Seznam | GET /api/v1/stock/sets | Stránkovaný seznam sad s definicí; filtry q, sku, active, updated_since |
| Detail | GET /api/v1/stock/sets/{id} | Karta sady a její definice s row_version |
| Založení | POST /api/v1/stock/sets | Kartu sady i definici založí v jedné transakci |
| Úprava | PUT /api/v1/stock/sets/{id} | Nahradí definici; row_version musí odpovídat uložené verzi |
| Dávka | POST /api/v1/stock/sets/bulk | Až 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ěří:
- u každé položky platí základ + DPH = částka s DPH (na haléř) a DPH odpovídá sazbě (tolerance 1 Kč v měně dokladu pro zaokrouhlení daně za celý doklad);
- součty položek sedí na základ, DPH a celkovou částku dokladu, rozdíl celkové částky pokryje jen pole
rounding; - faktura má kladnou celkovou částku, dobropis zápornou (záporné množství na položkách, stejně jako dobropis vystavený v aplikaci);
- sazba DPH patří mezi tuzemské sazby firmy, doklad v cizí měně nese
exchange_rate.
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ší:
- úhradu - zaplacení zaevidujte potom přes
POST /api/v1/invoices/{id}/mark-paidneboPOST /api/v1/invoices/{id}/payments; - sklad - výdejka nevznikne, zásobu vede e-shop;
- OSS - položky se ukládají jako tuzemské, prodej v režimu OSS tudy nepřevezmete.
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
- MCP server
- Bezpečnost - passkeys, TOTP a role
- Licence a aktivace
- Řešení problémů