# Poštárna > Poštárna je česká platforma pro e-mail marketing: hromadné rozesílky, automatizace a statistiky, které ukážou, co každý e-mail vydělal. Pro firmy i e-shopy v Česku a na Slovensku, aplikace i podpora česky a slovensky. Provozovatel deriverge s.r.o., IČ 19456361. - Magic Editor: Bloky přetáhnete myší, na telefonu je vložíte klepnutím. Editor ukládá sám. - Automatizace: Scénář poskládáte na plátně a před spuštěním ho vyzkoušíte nanečisto. Nic přitom neodejde. - Uvidíte, co každý e-mail vydělal. Doručení, otevření, kliky i objednávky u každé kampaně a každého e-mailu automatizace. - Pro e-shopy: Produkty z feedu, Opuštěný košík, Objednávky ve statistikách, Kupte si znovu, CZ a SK v jedné kampani. - Přechod ze SmartEmailingu: Stačí API klíč. Poštárna ze SmartEmailingu jen čte a nic v něm nemění. - Ceník: Platíte podle počtu kontaktů. Bez závazků, měsíčně nebo ročně. Ceny jsou bez DPH. Automatizace, feedy, kupóny, formuláře, landing pages, statistiky i podpora v každém tarifu. Aktuální ceník (JSON): https://www.postarna.cz/api/v1/public/price-list - API: API v1 (`/api/v1/tenants/{tenant}/...`) je úplné API, které používá i webová aplikace; API v3 (`/api/v3/...`) je kompatibilní se SmartEmailingem; server MCP (`/mcp`) slouží AI asistentům. Přihlášení API klíčem: `Authorization: Bearer pst_...`. - Celý strojově čitelný popis API: https://www.postarna.cz/api/openapi.json (OpenAPI 3.1). Jen jedna skupina: `?tag=Automations` (názvy skupin v poli `tags`). - Před odesláním skutečným příjemcům (schválení kampaně, zapnutí automatizace) vždy nejdřív spočítejte příjemce a ověřte nastavení: kampaň `POST /campaigns/audience`, automatizace `POST /automations/validate` a `POST /automations/{id}/test`. ## Produkt - [Poštárna](https://www.postarna.cz/): Hromadné rozesílky, automatizace a podrobné statistiky pro firmy všech velikostí. Magic Editor, segmenty, unikátní slevové kódy, svátky a narozeniny, napojení na e-shop i přechod ze SmartEmailingu. Česky a slovensky. - [Funkce](https://www.postarna.cz/#features): Napište e-mail, který vypadá skvěle. Pošlete ho přesně těm, koho se týká. A uvidíte, co vám vydělal. - [Automatizace](https://www.postarna.cz/#automation): Scénář poskládáte na plátně a před spuštěním ho vyzkoušíte nanečisto. Nic přitom neodejde. - [Přechod ze SmartEmailingu](https://www.postarna.cz/#switch): Stačí API klíč. Poštárna ze SmartEmailingu jen čte a nic v něm nemění. - [Ceník](https://www.postarna.cz/#pricing): Platíte podle počtu kontaktů. Bez závazků, měsíčně nebo ročně. Ceny jsou bez DPH. - [Aktuální ceník (JSON)](https://www.postarna.cz/api/v1/public/price-list): tarify podle počtu kontaktů s měsíční cenou bez DPH, roční sleva, zkušební doba a limity bezplatného tarifu, přímo z ceníku aplikace - [Časté otázky](https://www.postarna.cz/#faq): odpovědi na otázky: Kdo Poštárnu provozuje? Hodí se Poštárna pro moji firmu? Z jaké adresy se e-maily odesílají? Jak přejdu ze SmartEmailingu? Jak Poštárna nakládá s osobními údaji? Kde najdu pomoc? ## Návody a zdroje - [Ceník Poštárny](https://www.postarna.cz/cenik): Aktuální ceník Poštárny: tarify podle počtu kontaktů, měsíční cena bez DPH, roční sleva a zkušební doba. Všechny funkce v každém tarifu. - [Návody pro e-mail marketing](https://www.postarna.cz/navody): Praktické návody krok za krokem: první newsletter, opuštěný košík, e-maily ke svátku, win-back, formulář s double opt-in, přechod ze SmartEmailingu, SPF, DKIM a DMARC a segmentace zákazníků. - [Jak poslat první newsletter](https://www.postarna.cz/navody/prvni-newsletter): Od ověření domény přes import kontaktů a šablonu v editoru po testovací e-mail a odeslání kampaně. První newsletter v Poštárně krok za krokem. - [Opuštěný košík krok za krokem](https://www.postarna.cz/navody/opusteny-kosik): Jak napojit e-shop na Shoptetu jedním řádkem v patičce a poslat zákazníkovi připomenutí košíku dvě hodiny po poslední změně, jen když neobjednal. - [E-maily ke svátku a narozeninám](https://www.postarna.cz/navody/svatky-a-narozeniny): Automatické přání ke svátku nebo narozeninám se správným oslovením v 5. pádě a jednorázovým slevovým kódem. Český i slovenský kalendář jmen. - [Win-back kampaň pro neaktivní zákazníky](https://www.postarna.cz/navody/win-back): Jak automaticky oslovit zákazníky, kteří dlouho nenakoupili: připomenutí, druhý e-mail s výhodou a konec série pro ty, kdo mezitím nakoupí. - [Formulář s potvrzením odběru (double opt-in)](https://www.postarna.cz/navody/formular-double-opt-in): Přihlašovací formulář na web nebo jako pop-up, s potvrzením odběru e-mailem a doloženým souhlasem podle GDPR. Postup v Poštárně. - [Přechod ze SmartEmailingu do Poštárny](https://www.postarna.cz/navody/prechod-ze-smartemailingu): Jak sami přenést kontakty, seznamy, odhlášení, souhlasy, šablony a automatizace ze SmartEmailingu do Poštárny. Stačí API klíč, ve SmartEmailingu se nic nezmění. - [Lepší doručitelnost se SPF, DKIM a DMARC](https://www.postarna.cz/navody/spf-dkim-dmarc): Proč e-maily padají do spamu a jak to opravit: ověření domény přes DKIM, záznam SPF a DMARC, postupné zvyšování objemu a čistá databáze. Návod pro Poštárnu. - [Segmentace zákazníků v e-mailingu](https://www.postarna.cz/navody/segmentace-zakazniku): Jak rozdělit kontakty podle nákupů, aktivity a souhlasů a posílat každé skupině to, co ji zajímá. Příklady segmentů pro e-shopy a postup v Poštárně. - [Slovník pojmů e-mail marketingu](https://www.postarna.cz/slovnik): Co znamená double opt-in, míra otevření, CTR, soft a hard bounce, SPF, DKIM, DMARC, segment, opuštěný košík nebo win-back. Krátké definice a jak to řeší Poštárna. - [Integrace Poštárny](https://www.postarna.cz/integrace): Napojení Poštárny na Shoptet, produktové feedy Google Merchant, Heureka a Zboží.cz, RSS, import CSV, webhooky, API, API kompatibilní se SmartEmailingem a MCP pro AI asistenty. ## API dokumentace: Začínáme - [API dokumentace Poštárny](https://www.postarna.cz/docs/api): Co API Poštárny umí, jak je dokumentace uspořádaná a kde začít. - [Začínáme](https://www.postarna.cz/docs/api/getting-started): API klíč, ID firmy a první volání API za pět minut. - [Pravidla API](https://www.postarna.cz/docs/api/conventions): Formáty dat, stránkování, řazení, chyby, limity požadavků, opakování a souběžné úpravy. ## API dokumentace: Koncepty - [Firma a e-shopy](https://www.postarna.cz/docs/api/tenants-and-shops): Firma (tenant), její e-shopy s měnou a jazykem, časová zóna a izolace dat. - [Kontakty a souhlasy](https://www.postarna.cz/docs/api/contacts-and-consent): Kontakt a jeho stavy, souhlasy a účely zpracování, potlačení a blacklist, komu Poštárna smí psát. - [Seznamy a segmenty](https://www.postarna.cz/docs/api/lists-and-segments): Kdy použít seznam a kdy segment, stavy členství, jazyk podmínek segmentů a živý náhled počtu. - [Šablony a personalizace](https://www.postarna.cz/docs/api/templates-and-personalization): Šablony e-mailů, obsah a verze, kontrola obsahu, zástupné značky, skripty Twig, kupóny a data objednávek. - [Kampaně](https://www.postarna.cz/docs/api/campaigns): Životní cyklus kampaně, publikum a jeho výpočet, schválení s počtem příjemců, plánování, pauza a zrušení. - [Automatizace](https://www.postarna.cz/docs/api/automations): Model grafu, uzly a výstupy, spouštěče, jazyk podmínek, čekání, validace, zapnutí, uložení běžícího scénáře, verze a testování. - [Reference automatizací](https://www.postarna.cz/docs/api/automation-reference): Přesná schémata všech uzlů automatizace, událostí, podmínek, pravidel segmentů a časových údajů s ověřenými příklady. - [Objednávky, feedy a kupóny](https://www.postarna.cz/docs/api/orders-feeds-coupons): Zápis objednávek a mapa stavů, produktové, zákaznické a objednávkové feedy, zásobníky slevových kupónů a konverze. ## API dokumentace: Recepty - [Recept: opuštěný košík](https://www.postarna.cz/docs/api/recipe-abandoned-cart): Automatizace, která za 2 hodiny připomene neodeslaný košík, s událostmi košíku posílanými z e-shopu. - [Recept: série po nákupu](https://www.postarna.cz/docs/api/recipe-post-purchase): Poděkování a prosba o hodnocení 3 dny po dokončené objednávce, tip na přípravu těm, kdo neklikli. - [Recept: svátky se slevou](https://www.postarna.cz/docs/api/recipe-name-days): Každý den v 8:00 popřát kontaktům, které mají svátek, a dát jim jednorázový slevový kód. - [Recept: návrat neaktivních zákazníků](https://www.postarna.cz/docs/api/recipe-win-back): Zákazníkům 120 dní bez nákupu poslat připomenutí a po týdnu druhé, pokud mezitím nenakoupí. - [Recept: přihlašovací formulář s potvrzením](https://www.postarna.cz/docs/api/recipe-double-opt-in): Formulář s double opt-in na web, seznam odběratelů, souhlas s účelem a uvítací e-mail po potvrzení. - [Recept: import kontaktů z CSV](https://www.postarna.cz/docs/api/recipe-import-contacts): Nahrání CSV, náhled mapování a problémů, spuštění importu s doloženým souhlasem a sledování průběhu. - [Recept: odeslání kampaně](https://www.postarna.cz/docs/api/recipe-send-campaign): Koncept kampaně, obsah, kontrola obsahu, počet příjemců, testovací e-mail, schválení s plánovaným časem a zrušení. - [Recept: příjem webhooků](https://www.postarna.cz/docs/api/recipe-webhook-consumer): Registrace účtových webhooků, ověření Basic, idempotentní zpracování a ukázkový příjemce v Pythonu a Node.js. ## API dokumentace: Integrace - [Webhooky](https://www.postarna.cz/docs/api/webhooks): Účtové webhooky (nový kontakt, odhlášení, doručení, otevření, klik), tvar dat, doručování a opakování, zabezpečení a webhook v automatizaci. - [MCP pro AI asistenty](https://www.postarna.cz/docs/api/mcp): Připojení ChatGPT, Claude a dalších klientů k serveru MCP Poštárny, rozsahy přístupu, nástroje a povinné potvrzení před odesláním. - [Kompatibilita se SmartEmailingem](https://www.postarna.cz/docs/api/smartemailing): API v3 a CSV statistiky se stejnými cestami, obálkami a chybami jako SmartEmailing, přihlášení, limity a rozdíly. ## API dokumentace: Reference API - [Přehled operací](https://www.postarna.cz/docs/api/reference): Všechny operace API po skupinách s odkazy na podrobnou referenci a strojově čitelný dokument OpenAPI. - [Chyby a limity](https://www.postarna.cz/docs/api/errors-and-limits): Každý kód chyby s významem a nápravou, HTTP stavy, limity požadavků a limity jednotlivých akcí. - [Contacts](https://www.postarna.cz/docs/api/reference-contacts): Contacts of the company: profile fields, consent state, suppressions, custom fields, purposes of processing (consents), activities and GDPR export and erasure. - [Lists](https://www.postarna.cz/docs/api/reference-lists): Contact lists with explicit membership (manual and form lists) and the lists bound to an e-shop (read only membership). - [Segments](https://www.postarna.cz/docs/api/reference-segments): Rule based groups of contacts of one e-shop: an AND / OR tree of conditions, evaluated live (daily) or as a snapshot (static). - [Campaigns](https://www.postarna.cz/docs/api/reference-campaigns): One-off e-mail campaigns (newsletters): draft, audience, content, test, approve (send now or schedule), pause, resume, cancel, language variants. - [Templates and content](https://www.postarna.cz/docs/api/reference-templates): E-mail templates (HTML or the visual MJML editor), content versions, lint and spam check, footers, unsubscribe pages, saved editor elements, script templates (Twig), SMS templates, landing pages, surveys and the file manager. - [Automations](https://www.postarna.cz/docs/api/reference-automations): Automation scenarios: a graph of triggers, conditions, waits and actions; validation, versions, activation, test and trace, run history, statistics, and the contact events API that feeds event triggers (custom events, carts, page visits). - [Forms](https://www.postarna.cz/docs/api/reference-forms): Sign-up forms (double opt-in): builder settings, embed code, history. - [Imports and exports](https://www.postarna.cz/docs/api/reference-imports-and-exports): CSV import of contacts (upload, preview, run) and CSV exports. - [Orders, feeds and coupons](https://www.postarna.cz/docs/api/reference-orders-and-feeds): Orders of the e-shops (they drive purchase triggers and conditions), order states, product and customer feeds, coupon stacks. - [Statistics](https://www.postarna.cz/docs/api/reference-statistics): E-mail statistics of campaigns and automations, dashboard, conversions. - [Sending and deliverability](https://www.postarna.cz/docs/api/reference-sending): Senders, sending domains (SPF, DKIM, DMARC), DMARC reports, sending mode. - [Account and settings](https://www.postarna.cz/docs/api/reference-account): Shops (e-shops) of the company, company data, consent settings, notifications, labels, web tracking, billing (read), SmartEmailing migration state. - [SmartEmailing compatible API v3](https://www.postarna.cz/docs/api/reference-smartemailing-v3): The same paths, envelopes and errors as SmartEmailing REST API v3 (read operations and account webhooks). HTTP Basic: member e-mail + API key. - [SmartEmailing compatible CSV statistics](https://www.postarna.cz/docs/api/reference-smartemailing-csv): Semicolon separated CSV as SmartEmailing /api/csv: e-mail statistic ids, per-contact event details, list members. - [MCP server for AI assistants](https://www.postarna.cz/docs/api/reference-mcp): Model Context Protocol over Streamable HTTP (JSON-RPC 2.0). Tools map to API v1 routes; sending, deleting and other irreversible actions need a preview and a confirm token. - [OAuth 2.1 for AI assistants](https://www.postarna.cz/docs/api/reference-oauth): Dynamic client registration, authorization code with PKCE, tokens and revocation, server metadata. Used by MCP clients; integrations use API keys instead. - [This document](https://www.postarna.cz/docs/api/reference-meta): The OpenAPI document itself. - [Historie změn](https://www.postarna.cz/docs/api/changelog): Změny API a dokumentace. ## OpenAPI - [openapi.json](https://www.postarna.cz/api/openapi.json): OpenAPI 3.1, všechny operace a schémata ## Optional - [llms-full.txt](https://www.postarna.cz/llms-full.txt): tento přehled, popis produktu a všechny návody API dokumentace v jednom souboru Markdown - [Obchodní podmínky služby Poštárna](https://www.postarna.cz/terms): Verze 1.1, účinná od 12. 10. 2026, provozovatel deriverge s.r.o. - [Reklamační řád a podpora služby Poštárna](https://www.postarna.cz/claims): Verze 1.0, účinná od 12. 10. 2026, provozovatel deriverge s.r.o. - [Smlouva o zpracování osobních údajů](https://www.postarna.cz/dpa): Verze 1.0, účinná od 12. 10. 2026, provozovatel deriverge s.r.o. - [Zásady používání a pravidla rozesílání](https://www.postarna.cz/acceptable-use): Verze 1.0, účinná od 12. 10. 2026, provozovatel deriverge s.r.o. - [Zásady ochrany osobních údajů služby Poštárna](https://www.postarna.cz/privacy): Verze 1.0, účinná od 12. 10. 2026, provozovatel deriverge s.r.o. - [Zásady používání cookies](https://www.postarna.cz/cookies): Verze 1.0, účinná od 12. 10. 2026, provozovatel deriverge s.r.o. --- # Poštárna: Platforma pro e-mail marketing Hromadné rozesílky, automatizace a statistiky, ze kterých hned poznáte, co funguje. Pro každou firmu. Česká aplikace od deriverge s.r.o., podpora česky i slovensky. ## Magic Editor: Poskládejte e-mail jako stavebnici Bloky přetáhnete myší, na telefonu je vložíte klepnutím. Editor ukládá sám. - Bloky a sekce: Text, obrázky, tlačítka a sloupce. Obrázky oříznete přímo v editoru. - Produkty z feedu: Vyberete produkt a editor doplní obrázek, cenu i odkaz. - Kód pro každého: Každý příjemce dostane vlastní slevový kód ze zásobníku. - Telefon i tmavý režim: Náhled na telefonu i v tmavém režimu ještě před odesláním. - Kontrola před odesláním: Testovací e-mail a antispamová kontrola, která každý nález vysvětlí a poradí, jak ho opravit. ## Uvidíte, co každý e-mail vydělal Doručení, otevření, kliky i objednávky u každé kampaně a každého e-mailu automatizace. - Přímé i asistované objednávky: Objednávka do 24 hodin od kliknutí je přímá, do 5 dnů od kliknutí nebo do 24 hodin od otevření asistovaná. - Koruny a eura zvlášť: Tržby v různých měnách se nikdy nesčítají. ## Automatizace, které pracují i v noci Scénář poskládáte na plátně a před spuštěním ho vyzkoušíte nanečisto. Nic přitom neodejde. Spouštěče scénářů: Hned teď, V plánovaný čas, Opakovaně, Nový odběratel, Nová objednávka, Změna v košíku, Vyplnění formuláře, Klik na odkaz, Svátek, narozeniny, výročí, Kupte si znovu. - Výsledky u každého e-mailu: Odesláno, otevřeno i objednávky krok po kroku. - Stopa jednoho kontaktu: Uvidíte, kudy kontakt scénářem prošel a proč, i kudy by šel nanečisto. - Webhooky a upozornění: Scénář zavolá webhook nebo upozorní kolegy. ## Máte e-shop? Poštárna umí ještě víc. - Produkty z feedu: Feed Google Merchant, třeba ze Shoptetu. Obrázek i cena se doplní samy. - Opuštěný košík: Jeden řádek v patičce e-shopu a automatizace ví, co zůstalo v košíku. - Objednávky ve statistikách: Objednávky se spojí s kliky v e-mailech. - Kupte si znovu: Připomenutí dalšího nákupu ve správnou chvíli. - CZ a SK v jedné kampani: Každá verze s produkty a cenami svého e-shopu. ## Všechno, co e-mailing potřebuje - Segmenty: Přepočítávají se samy. - Formuláře a pop-upy: S dvojitým potvrzením. - Landing pages: Včetně dotazníků. - Doručitelnost: Kontrola SPF, DKIM a DMARC. - Souhlasy a odhlášení: Odhlášenému už nic nepřijde. - Svátky a narozeniny: Oslovení v 5. pádě. - Česky i slovensky: Aplikace, podpora i kalendář svátků. - API a webhooky: I pro AI asistenty přes MCP. ## Ze SmartEmailingu přejdete sami Stačí API klíč. Poštárna ze SmartEmailingu jen čte a nic v něm nemění. 1. Připojení: Zadáte e-mail a API klíč. Ukážeme vám, kde ho najdete. 2. Co přenést: Seznamy, souhlasy, šablony a názvy automatizací jako koncepty. 3. Přenos: Odhlášení jdou první, aby nikdo nedostal e-mail navíc. 4. Kontrola počtů: Na konci porovnáte počty v obou systémech. ## Ceník: Jeden tarif. Všechny funkce. Platíte podle počtu kontaktů. Bez závazků, měsíčně nebo ročně. Ceny jsou bez DPH. Automatizace, feedy, kupóny, formuláře, landing pages, statistiky i podpora v každém tarifu. Aktuální ceník (JSON): https://www.postarna.cz/api/v1/public/price-list (tarify podle počtu kontaktů s měsíční cenou bez DPH, roční sleva, zkušební doba a limity bezplatného tarifu, přímo z ceníku aplikace). ## Na co se nás ptáte ### Kdo Poštárnu provozuje? Poštárnu provozuje česká společnost deriverge s.r.o., IČ 19456361. Od ní dostanete fakturu i podporu. ### Hodí se Poštárna pro moji firmu? Ano. Poštárnu využije každá firma, která posílá newslettery, oznámení nebo automatické e-maily svým zákazníkům a chce vidět jejich výsledky. E-shopům navíc čte produktové feedy ve formátu Google Merchant, spojuje objednávky s kliky v e-mailech a přes webtracking hlídá košíky. Jeden účet zvládne více značek či e-shopů v korunách i v eurech. ### Z jaké adresy se e-maily odesílají? Z vaší vlastní domény. Doménu zadáte v nastavení, záznamy DNS pro ni připravíme a průvodce pak sám zkontroluje, že jsou v pořádku. Ostré odesílání nového účtu schvalujeme, obvykle do jednoho pracovního dne. Do té doby si posíláte testovací e-maily. ### Jak přejdu ze SmartEmailingu? V nastavení zadáte API klíč svého účtu ve SmartEmailingu a vyberete, co přenést. Poštárna přenese kontakty, seznamy, odhlášení, souhlasy, šablony a názvy automatizací jako koncepty a na konci porovná počty. Ze SmartEmailingu jen čte. ### Jak Poštárna nakládá s osobními údaji? Údaje vašich kontaktů zpracováváme jako zpracovatel podle smlouvy o zpracování osobních údajů. Evidujeme účely a souhlasy a odhlášenému kontaktu už nic nepošleme. ### Kde najdu pomoc? Napište na podpora@postarna.cz nebo zavolejte na +420 777 849 095. Odpovídáme česky i slovensky. --- # Návody pro e-mail marketing Postupy pro marketéry a majitele e-shopů, kteří chtějí posílat e-maily, které se čtou a vydělávají. Každý návod vysvětlí, proč to dělat, a pak krok za krokem ukáže, jak to nastavit v Poštárně. Neznámé pojmy najdete ve [slovníku](https://www.postarna.cz/slovnik), napojení na e-shop a další systémy v přehledu [integrací](https://www.postarna.cz/integrace). Vývojáři najdou stejné postupy přes API jako [recepty v API dokumentaci](https://www.postarna.cz/docs/api#jak-je-dokumentace-usporadana). --- # Jak poslat první newsletter Newsletter je nejjednodušší způsob, jak pravidelně připomínat značku a přivádět zákazníky zpět. Aby dorazil do doručené pošty a ne do spamu, potřebuje tři věci: ověřenou doménu odesílatele, kontakty se souhlasem a e-mail, který se dobře zobrazí na telefonu i v počítači. ## Než začnete • **Doména:** e-maily odchází z vaší domény (například novinky@vasefirma.cz), ne z Gmailu nebo Seznamu. Budete potřebovat přístup k nastavení DNS. • **Kontakty se souhlasem:** posílejte jen lidem, kteří se k odběru přihlásili, nebo zákazníkům v rámci [zákaznické výjimky](https://www.postarna.cz/slovnik#soft-opt-in-zakaznicka-vyjimka). • **Ostré odesílání:** nový účet posílá nejdřív jen testovací e-maily na testovací adresy firmy. Ostré odesílání zapne provozovatel Poštárny po schválení účtu. ## Postup krok za krokem {#postup} 1. **Ověřte doménu**: v Nastavení › Odesílání › DNS záznamy přes Nová doména projdete čtyři kroky (Doména, Záznamy v DNS, Kontrola, Adresy odesílatele). Podrobně v návodu [SPF, DKIM a DMARC](https://www.postarna.cz/navody/spf-dkim-dmarc). 2. **Nahrajte kontakty**: v Kontakty a seznamy › Importy nahrajete soubor CSV nebo export ze Shoptetu, přiřadíte sloupce a vyberete seznam. Neplatné adresy import přeskočí a odhlášené adresy zůstanou odhlášené. 3. **Připravte e-mail**: v Obsah a vzhled › Šablony e-mailů založíte šablonu a v Magic Editoru ji poskládáte z bloků (text, obrázky, tlačítka, produkty z feedu). Náhled ukáže e-mail na telefonu i v tmavém režimu. 4. **Pošlete si test**: tlačítko Testovací e-mail pošle náhled na testovací adresy firmy (nastavíte je v Nastavení › Odesílání). Antispamová kontrola vysvětlí každý nález a poradí, jak ho opravit. 5. **Založte kampaň**: v Kampaně › E-mailové kampaně spustíte průvodce. Vyplníte název, e-shop, odesílatele, předmět a [preheader](https://www.postarna.cz/slovnik#preheader), vyberete seznam nebo segment a průvodce hned spočítá příjemce i vynechané kontakty. 6. **Odešlete nebo naplánujte**: zvolíte Ihned, Naplánovat (datum a čas) nebo Vyřešit později (kampaň zůstane konceptem). Odeslání potvrdíte s počtem příjemců a časem. 7. **Sledujte výsledky**: ve statistikách kampaně uvidíte doručení, otevření, prokliky, odhlášení a objednávky po prokliku zvlášť v korunách a v eurech. ## Tipy pro lepší výsledky • Předmět pište krátce a konkrétně, preheader ho má doplnit, ne opakovat. • Neaktivní kontakty (angažovanost E) průvodce kampaní ve výchozím nastavení vynechá. Zlepšuje to doručitelnost. • Oslovte jménem: značka `{{df_salution}}` vloží české oslovení v 5. pádě (Petře, Lucie). • Posílejte pravidelně a ve stejném rytmu, ať odběratelé vědí, co čekat. Co znamenají čísla ve statistikách, vysvětluje [slovník](https://www.postarna.cz/slovnik#mira-otevreni-open-rate). Postup přes API je v receptu [Odeslání kampaně](https://www.postarna.cz/docs/api/recipe-send-campaign). --- # Opuštěný košík krok za krokem Zákazník vloží zboží do košíku, odbíhá a objednávku nedokončí. Připomenutí košíku je jeden z automatických e-mailů, které se e-shopům vyplácí nejvíc: přijde ve chvíli, kdy zákazník o nákupu ještě přemýšlí, a vede ho rovnou zpět. ## Jak to v Poštárně funguje • **Webtracking**: jeden řádek v patičce e-shopu posílá do Poštárny košík návštěvníka, kterého e-shop zná: přihlášeného zákazníka, nebo toho, kdo v pokladně vyplnil e-mail. Skript nepoužívá cookies ani otisk prohlížeče a když má e-shop lištu cookies, posílá košík až poté, co návštěvník přijme personalizační cookies. • Košík se uloží jen u adresy, která už je kontaktem e-shopu, a jen dokud v e-shopu běží scénář se spouštěčem Každá změna v košíku. • Každá změna košíku je událost. Když zákazník košík změní znovu, čekání začne od začátku, takže připomenutí přijde jedno, až po poslední změně. ## Postup krok za krokem {#postup} 1. **Zapněte webtracking**: v Nastavení › Datové zdroje › Webtracking zkontrolujte, že je zapnuté Používat, a zkopírujte kód pro váš e-shop. 2. **Vložte kód do patičky e-shopu**: v administraci Shoptetu otevřete Vzhled a obsah › Editor › HTML kód › Zápatí, vložte řádek a uložte. 3. **Připravte e-mail**: v Obsah a vzhled › Šablony e-mailů vytvořte šablonu připomenutí s tlačítkem zpět do košíku. Krátký text a jedna jasná výzva fungují nejlépe. 4. **Založte automatizaci**: v Automatizace › Nová automatizace zadejte název, vyberte e-shop a otevřete plátno. 5. **Nastavte spouštěč**: uzel Při události s událostí Každá změna v košíku a opakovaným vstupem Restartovat s každou další událostí. 6. **Počkejte a ověřte košík**: za spouštěč dejte Čekání (například 2 hodiny) a Podmínku: Počet položek v nákupním košíku je větší než 0 a Objednávka od vstupu do scénáře nenastala. 7. **Odešlete e-mail**: do větve ano dejte uzel Odeslat e-mail se šablonou připomenutí. Větev ne scénář ukončí. 8. **Otestujte a zapněte**: scénář otestujte bez odeslání, zapněte ho a na e-shopu se přihlaste testovacím zákaznickým účtem. Po vložení zboží do košíku ho uvidíte v přehledu Webtracking. ## Tipy • Nečekejte příliš dlouho, ale ani ne pár minut: zákazník může být jen v pokladně. Dvě hodiny jsou rozumný začátek. • Druhé připomenutí přidáte dalším Čekáním a Podmínkou. Slevu dávejte opatrně a raději [jednorázovým kódem](https://www.postarna.cz/slovnik#unikatni-slevovy-kod). • Kolik objednávek scénář přivedl, uvidíte ve statistikách automatizace jako [konverze](https://www.postarna.cz/slovnik#konverze-z-e-mailu). Vývojáři mohou košíky posílat i přes API, viz recept [Opuštěný košík](https://www.postarna.cz/docs/api/recipe-abandoned-cart). --- # E-maily ke svátku a narozeninám Přání ke svátku je v Česku a na Slovensku zvyk, který zákazníci znají a mají rádi. Automatický e-mail s osobním oslovením a malým dárkem připomene značku bez pocitu reklamy a často vede k nákupu. ## Jak Poštárna pozná svátek • Když má kontakt vyplněné pole Svátek, slaví v ten den. • Jinak se svátek hledá podle křestního jména v kalendáři jazyka kontaktu: slovenský pro slovenské kontakty, jinak český. Kontakt bez jména svátek nemá. • Narozeniny se berou z pole Narozeniny u kontaktu. ## Postup krok za krokem {#postup} 1. **Nahrajte slevové kódy**: v Nastavení › Datové zdroje › Slevové kupóny založte zásobník a vložte jednorázové kódy vytvořené v e-shopu, jeden na řádek. 2. **Napište přání**: v Obsah a vzhled › Šablony e-mailů vytvořte šablonu. Oslovení vložte značkou `{{df_salution}}` (Petře, Lucie) a kód v Magic Editoru prvkem Kupón (lišta Nový prvek), ve kterém vyberete zásobník, text nad kódem a tlačítko. V HTML editoru vložíte kód značkou kupónu (skupina Slevové kupóny v nabídce značek). Každý příjemce dostane vlastní kód. 3. **Založte automatizaci**: v Automatizace › Nová automatizace zadejte název a e-shop. 4. **Nastavte spouštěč**: uzel Svátek, narozeniny, výročí s volbou Dnes má svátek (nebo Dnes má narozeniny) a časem odeslání, například 8:00. 5. **Přidejte e-mail**: za spouštěč dejte uzel Odeslat e-mail se šablonou přání. 6. **Otestujte a zapněte**: scénář otestujte bez odeslání a zapněte. Poštárna pak každý den projde kontakty, které slaví, a pošle jim přání. ## Tipy • Hlídejte, kolik kódů v zásobníku zbývá. Když kódy dojdou, e-mail s kódem neodejde. • Přání pište krátce a osobně, sleva má být dárek, ne hlavní sdělení. • Spouštěč umí i výročí prvního nákupu nebo datum z vlastního pole, třeba konec předplatného. Postup přes API: recept [Svátky se slevou](https://www.postarna.cz/docs/api/recipe-name-days). Pojmy: [oslovení v 5. pádě](https://www.postarna.cz/slovnik#osloveni-v-5-pade), [unikátní slevový kód](https://www.postarna.cz/slovnik#unikatni-slevovy-kod). --- # Win-back kampaň pro neaktivní zákazníky Získat nového zákazníka stojí víc než přivést zpět toho, kdo už jednou nakoupil. Win-back série osloví zákazníky, kteří dlouho nenakoupili: nejdřív jim připomene značku, a když nereagují, nabídne důvod se vrátit. ## Kdy je zákazník neaktivní Záleží na sortimentu. U zboží, které se kupuje pravidelně (káva, kosmetika, krmivo), může být neaktivní zákazník už po dvou nebo třech měsících, u dražšího zboží po roce. Začněte s hranicí, která odpovídá běžnému odstupu mezi nákupy ve vašem e-shopu, například 120 dní. ## Postup krok za krokem {#postup} 1. **Připravte dva e-maily**: v Obsah a vzhled › Šablony e-mailů vytvořte připomenutí (novinky, oblíbené produkty) a druhý e-mail s výhodou, ideálně s [jednorázovým slevovým kódem](https://www.postarna.cz/slovnik#unikatni-slevovy-kod). 2. **Založte automatizaci**: v Automatizace › Nová automatizace zadejte název a e-shop. 3. **Nastavte spouštěč**: uzel Opakovat, který každý den projde kontakty e-shopu. Ve filtru zvolte pravidlo Poslední objednávka starší než 120 dní a opakovaný vstup Jen jednou provždy, aby každý zákazník prošel sérií jen jednou. 4. **Pošlete první e-mail**: za spouštěč dejte Odeslat e-mail s připomenutím a pak Čekání 7 dní. 5. **Rozdělte podle nákupu**: přidejte Podmínku Objednávka od vstupu do scénáře. Kdo nakoupil, scénář končí; ostatním pošlete druhý e-mail s výhodou. 6. **Přidejte cíl**: uzel Cíl scénáře s objednávkou zajistí, že kdo nakoupí kdykoli během série, scénář hned opustí. 7. **Otestujte a zapněte**: scénář otestujte bez odeslání a zapněte. Výsledky sledujte ve statistikách automatizace. ## Tipy • Win-back funguje i pro odběratele, kteří nenakupují, ale přestali otevírat: použijte pravidlo podle [angažovanosti](https://www.postarna.cz/slovnik#angazovanost-kontaktu). • Kdo nereaguje ani na druhý e-mail, tomu posílejte méně. Neaktivní kontakty zhoršují [doručitelnost](https://www.postarna.cz/slovnik#dorucitelnost). • Podobný, ale jemnější je spouštěč Kupte si znovu: připomene další nákup podle toho, jak často zákazník obvykle nakupuje. Postup přes API: recept [Návrat neaktivních zákazníků](https://www.postarna.cz/docs/api/recipe-win-back). --- # Formulář s potvrzením odběru (double opt-in) Přihlašovací formulář je hlavní zdroj nových odběratelů. S potvrzením odběru ([double opt-in](https://www.postarna.cz/slovnik#double-opt-in)) se do databáze nedostanou překlepy, cizí ani falešné adresy a o každém odběrateli máte záznam, kdy a s jakým textem souhlasil. ## Co se stane po odeslání formuláře 1. Kontakt čeká na potvrzení a k přihlášce se uloží IP adresa, prohlížeč, stránka a přesné znění souhlasu. 2. Odejde potvrzovací e-mail bez reklamy. Odkaz v něm platí 7 dní a na jednu adresu odejdou nejvýš 3 potvrzení za den. 3. Po kliknutí je kontakt přihlášený, zařadí se do seznamů formuláře a zapíše se souhlas s účelem zpracování. Formulář odpovídá vždy stejně, takže neprozradí, kdo už v databázi je. Odhlášený kontakt se tak může znovu přihlásit, nedoručitelná adresa nebo adresa se stížností nedostane nic. ## Postup krok za krokem {#postup} 1. **Připravte seznam**: v Kontakty a seznamy › Seznamy kontaktů založte seznam pro odběratele, například Newsletter. 2. **Zkontrolujte účel zpracování**: v Kontakty a seznamy › Účely zpracování os. údajů je účel, ke kterému se souhlas zapíše, například zasílání obchodních sdělení. 3. **Vytvořte formulář**: v Obsah a vzhled › Webové formuláře založte formulář, vyberte seznam, účel a text souhlasu a přidejte pole (například jméno). 4. **Nastavte potvrzení**: potvrzení odběru je zapnuté ve výchozím nastavení. Můžete upravit potvrzovací e-mail a stránky po odeslání a po potvrzení. 5. **Vložte formulář na web**: zkopírujte kód formuláře do stránky, nebo ho zobrazte jako pop-up či vyjíždějící okno. U pop-upu nastavíte, kdy se ukáže (po načtení, po čase, po odscrollování) a jak často. 6. **Přivítejte nové odběratele**: v automatizaci se spouštěčem Při události a událostí Nový odběratel pošlete uvítací e-mail. ## Tipy • Na telefonu se pop-up ukáže, jen když to zapnete, a to jako spodní panel s velkým tlačítkem pro zavření, ne přes celou obrazovku. • Pop-up jde skrýt přihlášeným zákazníkům e-shopu na Shoptetu a těm, kdo přišli z vašeho e-mailu, pokud odkazy v e-mailech nesou parametr Poštárny. • Slibujte jen to, co budete posílat, a jak často. Odběratel, který ví, co čekat, se méně odhlašuje. Postup přes API: recept [Formulář s potvrzením](https://www.postarna.cz/docs/api/recipe-double-opt-in). --- # Přechod ze SmartEmailingu do Poštárny Přechod zvládnete sami během pár minut. Poštárna se ke SmartEmailingu připojí vaším API klíčem, data jen čte a nic v něm nemění. Nejdřív přenese odhlášení a blacklist, aby nikdo nedostal e-mail navíc, a na konci porovná počty v obou systémech. ## Co se přenese • **Vždy**: kontakty se všemi vlastními poli, seznamy a členství, odhlášení, blacklist a nedoručitelné adresy. • **Podle volby**: účely zpracování a souhlasy kontaktů s datem platnosti, e-maily z knihovny jako šablony (obrázky se přenesou do správce souborů) a automatizace jako koncepty. SmartEmailing předá jen názvy automatizací, kroky doplníte v editoru a samy se nespustí. • Kontakt, který už v Poštárně máte, se nezdvojí: údaje se sloučí a ruční úpravy zůstanou. ## Postup krok za krokem {#postup} 1. **Vytvořte API klíč ve SmartEmailingu**: v Nastavení › Datové zdroje › API klíče klikněte na Vytvořit nový klíč a klíč hned zkopírujte, SmartEmailing ho ukáže jen jednou. 2. **Připojte SmartEmailing**: v Poštárně otevřete Nastavení › Datové zdroje › Přechod ze SmartEmailingu (spouští ho Správce účtu), vložte přihlašovací e-mail do SmartEmailingu a klíč a klikněte na Ověřit a připojit. 3. **Vyberte, co přenést**: u každého seznamu zvolte, co znamená: přihlášení k odběru (souhlas), zákazníci bez potvrzeného souhlasu, odhlášení (nikdy neposílat), nebo nepřenášet. Návrh je připravený podle názvu seznamu, zkontrolujte ho. 4. **Spusťte přenos**: přenos běží na pozadí, stránku můžete zavřít. Když se přeruší, spustíte ho znovu a naváže tam, kde skončil. 5. **Zkontrolujte počty**: tabulka porovná kontakty, blacklist, nedoručitelné adresy, odhlášení, pole, souhlasy, šablony a automatizace v obou systémech. Posílat z Poštárny je bezpečné, až když jsou v ní všechna odhlášení. 6. **Zapněte souběh, pokud ho potřebujete**: dokud ještě posíláte i ze SmartEmailingu, může Poštárna každou hodinu načíst nové kontakty, odhlášení a blacklist. Až SmartEmailing přestanete používat, synchronizaci vypněte. ## Integrace a API Vlastní napojení postavené na REST API v3 SmartEmailingu funguje s Poštárnou po změně adresy, uživatelského jména a klíče: Poštárna má API v3 se stejnými cestami, obálkami a chybami pro čtení kontaktů, seznamů a polí, webhooky a vybrané CSV statistiky. Kontakty a seznamy přes API v3 zatím nezapisujete, k tomu slouží API v1. Podrobnosti a rozdíly jsou v [API dokumentaci](https://www.postarna.cz/docs/api/smartemailing). ## Po přechodu • Ověřte doménu odesílatele v Nastavení › Odesílání, viz [SPF, DKIM a DMARC](https://www.postarna.cz/navody/spf-dkim-dmarc). • Doplňte kroky automatizací přenesených jako koncepty a před zapnutím je otestujte. • Nahraďte kód formulářů a webtrackingu na webu kódy z Poštárny. --- # Lepší doručitelnost se SPF, DKIM a DMARC Gmail, Seznam, Outlook i další poštovní služby dnes od hromadných odesílatelů vyžadují ověřenou doménu. E-mail bez podpisu DKIM a bez záznamů SPF a DMARC častěji skončí ve spamu nebo ho služba odmítne. Nastavení zabere pár minut a dělá se jednou. ## Tři záznamy v DNS • **[DKIM](https://www.postarna.cz/slovnik#dkim)** podepisuje každý e-mail. Poštovní služba podle veřejného klíče ve vaší doméně ověří, že e-mail přišel od vás. • **[SPF](https://www.postarna.cz/slovnik#spf)** vyjmenuje servery, které smí za doménu odesílat. • **[DMARC](https://www.postarna.cz/slovnik#dmarc)** říká, co dělat s e-mailem, který kontrolou neprojde, a kam posílat souhrnné zprávy. ## Postup krok za krokem {#postup} 1. **Zadejte doménu**: v Nastavení › Odesílání › DNS záznamy klikněte na Nová doména a zadejte doménu, ze které chcete posílat, například vasefirma.cz. Domény bezplatných schránek (gmail.com, seznam.cz a podobné) odesílat nemohou. 2. **Přidejte záznamy do DNS**: krok Záznamy v DNS vypíše přesné záznamy: záznamy DKIM (CNAME) jsou povinné, SPF a DMARC (TXT) doporučené. Přidáte je u správce domény, nebo je pošlete tomu, kdo vám doménu spravuje. Když záznamy u nové domény ještě nevidíte, dokončujeme její nastavení na naší straně a objeví se tu samy. 3. **Spusťte kontrolu**: krok Kontrola ověří každý záznam a ukáže, který je v pořádku, který chybí a který je chybný. Změny v DNS se mohou projevit až za několik hodin. 4. **Přidejte adresy odesílatele**: v kroku Adresy odesílatele založíte adresy, ze kterých budou chodit kampaně, například novinky@vasefirma.cz, a adresu pro odpovědi. 5. **Nastavte testovací adresy**: v Nastavení › Odesílání uložte adresy, na které smí odcházet testovací e-maily, a pošlete si test. ## Co dalšího pomáhá • **Postupný náběh**: nový účet posílá první dny jen část denního limitu a limit roste po krocích, plného objemu dosáhne za 4 týdny. Poštovní služby tak odesílatele poznají postupně. • **Tempo podle poštovních služeb**: e-maily odchází v dávkách a s limity za minutu pro jednotlivé služby. • **Hlídání kampaní**: kampaň se ve výchozím nastavení sama pozastaví, když podíl odhlášení, nedoručitelných adres nebo stížností překročí bezpečnou mez. • **Čistá databáze**: nedoručitelné adresy a stížnosti se potlačí samy a kampaně ve výchozím nastavení vynechají neaktivní kontakty. • **Zprávy DMARC**: souhrnné zprávy DMARC ukazují, kolik e-mailů z vašich domén prošlo kontrolou SPF, DKIM a DMARC a odkud odcházely. Jejich načítání do Statistik › DMARC zatím zapínáme na požádání, napište nám. • **Kontrola obsahu**: antispamová kontrola v editoru upozorní na rizikové fráze, zkracovače odkazů, chybějící odhlášení a další nálezy a u každého poradí, jak ho opravit. Pojmy z návodu: [doručitelnost](https://www.postarna.cz/slovnik#dorucitelnost), [warm-up](https://www.postarna.cz/slovnik#warm-up-zahrivani-odesilani), [soft a hard bounce](https://www.postarna.cz/slovnik#hard-bounce). --- # Segmentace zákazníků v e-mailingu Jeden e-mail pro všechny je nejjednodušší, ale málokdy nejlepší. Kdo nakoupil včera, nepotřebuje stejnou nabídku jako ten, kdo nenakoupil rok. [Segment](https://www.postarna.cz/slovnik#segment) vybere kontakty podle pravidel a přepočítává se sám, takže kampaň vždy dostanou ti správní. ## Příklady segmentů pro e-shop • **Noví zákazníci**: právě jedna objednávka, a to v posledních 30 dnech. Hodí se pro sérii po prvním nákupu. • **Věrní zákazníci**: tři a více objednávek. Dostanou novinky jako první. • **Zákazníci, kteří přestávají nakupovat**: poslední objednávka před více než 120 dny. Kandidáti na [win-back](https://www.postarna.cz/navody/win-back). • **Kupující značky nebo kategorie**: objednali produkt dané značky nebo kategorie, pokud objednávky tyto údaje obsahují (značku má export objednávek ze Shoptetu, kategorii zapíšete přes API). • **Aktivní odběratelé**: angažovanost A nebo B. Vhodní pro častější rozesílky. • **Firmy**: kontakty s vyplněným IČO. Poštárna má připravené výchozí segmenty, například kupující v posledních 12 měsících, kupující před 13 až 24 měsíci, firemní zákazníky a kontakty aktivní v posledních 90 dnech. ## Postup krok za krokem {#postup} 1. **Otevřete segmenty**: v Kontakty a seznamy › Segmenty založte nový segment a vyberte e-shop. 2. **Přidejte pravidla**: zvolte typ pravidla, například Poslední objednávka, počet nebo hodnota objednávek, objednaný produkt, angažovanost, seznam, souhlas s účelem zpracování, reakce na kampaň nebo pole kontaktu. 3. **Spojte pravidla**: pravidla spojíte přes A (musí platit všechna) nebo NEBO (stačí jedno) a můžete je vnořovat do skupin. 4. **Zkontrolujte počet**: segment ukáže, kolik kontaktů do něj patří. Upravujte pravidla, dokud skupina neodpovídá tomu, co chcete. 5. **Použijte segment**: v průvodci kampaní vyberte segment jako příjemce. Stejná pravidla použijete i ve filtru spouštěče automatizace. ## Tipy • Hodnota objednávek se počítá zvlášť v korunách a v eurech, nikdy se nesčítá. • Segment nahradí ruční seznamy, které by někdo musel udržovat. Ruční seznam používejte pro lidi, kteří se k něčemu sami přihlásili. • Začněte dvěma nebo třemi segmenty a sledujte, jak se liší míra prokliku a objednávky. Teprve pak přidávejte další. Pro vývojáře: [Seznamy a segmenty v API dokumentaci](https://www.postarna.cz/docs/api/lists-and-segments). --- # Slovník pojmů e-mail marketingu Krátké a přesné vysvětlení pojmů, na které narazíte při rozesílání newsletterů a automatických e-mailů. U pojmů, které Poštárna přímo řeší, najdete i to, jak to v aplikaci funguje. Postupy krok za krokem jsou v [návodech](https://www.postarna.cz/navody). ## A/B test A/B test rozdělí příjemce do dvou nebo více skupin a každé pošle jinou verzi e-mailu, například s jiným předmětem nebo nabídkou. Podle výsledků (otevření, kliky, objednávky) pak víte, která verze funguje lépe. Aby byl výsledek spolehlivý, má mít každá skupina dost příjemců a verze se mají lišit jen v jedné věci. **V Poštárně:** v automatizaci rozdělí uzel A/B test kontakty podle zadaných procent až do 10 větví. Každý e-mail ve větvi má vlastní statistiky, takže větve porovnáte vedle sebe. ## Angažovanost kontaktu Angažovanost říká, jak kontakt na e-maily reaguje: jestli je otevírá, kliká a nakupuje. Pomáhá posílat více těm, kdo o e-maily stojí, a šetřit neaktivní kontakty, které zhoršují doručitelnost. **V Poštárně:** každý kontakt má angažovanost A až E (od Velmi aktivní po Neaktivní) nebo N (Bez dat). Počítá se jednou týdně z reakcí za posledních 180 dní a kontakt s objednávkou za posledních 30 dní je vždy ve skupině A. Podle angažovanosti můžete stavět segmenty a kampaň umí neaktivní kontakty vynechat. ## Automatizace Automatizace (scénář) posílá e-maily sama, když nastane určitá událost nebo přijde určitý den: přihlášení k odběru, objednávka, opuštěný košík, svátek nebo narozeniny. Jednou ji nastavíte a pak běží pro každý kontakt zvlášť, ve správný okamžik. **V Poštárně:** scénář skládáte na plátně z uzlů: spouštěč (například Při události, V plánovaný čas, Svátek, narozeniny, výročí, Kupte si znovu), Čekání, Podmínka, Odeslat e-mail, Změna v seznamu, Webhook a další. Před zapnutím jde scénář otestovat bez odeslání. ## BIMI BIMI (Brand Indicators for Message Identification) je standard, podle kterého mohou některé poštovní služby ukázat u e-mailu logo odesílatele. Předpokladem je doména zabezpečená přes DMARC s přísnou politikou (quarantine nebo reject) a záznam BIMI v DNS s logem ve formátu SVG; část služeb vyžaduje i ověřený certifikát loga. ## Blacklist Blacklist je seznam adres, na které se nikdy nic neposílá, bez ohledu na seznamy a segmenty. Patří na něj adresy, které si o to výslovně řekly, nebo adresy, na které psát nechcete. **V Poštárně:** adresu přidáte na blacklist u kontaktu nebo importem souboru blacklistu. Blacklist je součástí potlačení (suppression), takže na adresu neodejde ani kampaň, ani automatický e-mail. ## CTOR CTOR (click-to-open rate) je podíl otevřených e-mailů, ve kterých příjemce klikl. Říká, jak dobře obsah e-mailu přesvědčil ty, kdo ho otevřeli, nezávisle na předmětu. **V Poštárně:** CTOR = unikátní prokliky / unikátní otevření, ve statistikách každé kampaně a každého e-mailu automatizace. ## DKIM DKIM (DomainKeys Identified Mail) je elektronický podpis e-mailu. Odesílací server e-mail podepíše a příjemce podle veřejného klíče v DNS vaší domény ověří, že e-mail opravdu přišel od vás a cestou se nezměnil. **V Poštárně:** průvodce v Nastavení › Odesílání vypíše záznamy DKIM (CNAME), které přidáte do DNS domény, a v kroku Kontrola ověří, že jsou správně. Bez ověřené domény z ní Poštárna neodesílá. ## DMARC DMARC (Domain-based Message Authentication, Reporting and Conformance) je pravidlo v DNS domény, které poštovním službám říká, co dělat s e-mailem, který neprojde kontrolou SPF nebo DKIM: doručit (p=none), dát do spamu (p=quarantine) nebo odmítnout (p=reject). Zároveň určuje, kam posílat souhrnné zprávy o tom, kdo z vaší domény odesílá. **V Poštárně:** průvodce odesíláním doporučí výchozí záznam DMARC a ověří ho. Načítání souhrnných zpráv DMARC do Statistik › DMARC zatím zapínáme na požádání. ## Doručitelnost Doručitelnost (deliverability) vyjadřuje, kolik e-mailů dorazí do doručené pošty, a ne do spamu nebo nikam. Ovlivňuje ji ověření domény (SPF, DKIM, DMARC), reputace odesílatele, kvalita databáze, množství stížností a obsah e-mailu. **V Poštárně:** průvodce nastavením odesílání ověří doménu, nový účet zvyšuje denní objem postupně, e-maily odchází v tempu přizpůsobeném jednotlivým poštovním službám a kampaň se sama zastaví, když roste podíl stížností, odhlášení nebo nedoručitelných adres. ## Double opt-in Double opt-in je přihlášení k odběru ve dvou krocích: člověk vyplní formulář a pak potvrdí odběr kliknutím na odkaz v e-mailu. Tím je jisté, že adresa existuje a patří tomu, kdo se přihlásil, a máte doložený souhlas. **V Poštárně:** formuláře používají double opt-in ve výchozím nastavení. Kontakt čeká na potvrzení, odkaz platí 7 dní a k přihlášce se uloží IP adresa, prohlížeč, stránka a přesné znění souhlasu. Odhlášený kontakt se může znovu přihlásit jen přes potvrzení. Postup je v návodu [Formulář s potvrzením odběru](https://www.postarna.cz/navody/formular-double-opt-in). ## Hard bounce Hard bounce je trvalá nedoručitelnost: schránka neexistuje, doména neexistuje nebo server adresu odmítá natrvalo. Na takovou adresu už se nemá posílat. **V Poštárně:** adresa s hard bounce se hned potlačí a žádný další e-mail na ni neodejde. Kampaň se ve výchozím nastavení sama pozastaví, když podíl nedoručitelných adres překročí 1 % (po prvních 200 odeslaných). ## Konverze z e-mailu Konverze je objednávka, kterou e-mail přivedl. Obvykle se počítá objednávka po prokliku z e-mailu v určité době (atribuční okno), aby bylo vidět, kolik kampaň nebo automatizace vydělala. **V Poštárně:** objednávka do 24 hodin od prokliku je přímá konverze, od 24 hodin do 5 dnů od prokliku nebo do 24 hodin od otevření asistovaná; počítá se poslední proklik. Tržby se ukazují zvlášť v korunách a v eurech a zrušené objednávky se nepočítají. ## List hygiene (čištění databáze) List hygiene je pravidelné čištění seznamu kontaktů: odstranění nedoručitelných adres, adres se stížností a dlouhodobě neaktivních kontaktů. Čistá databáze znamená méně nedoručitelných e-mailů, méně stížností a lepší doručitelnost. **V Poštárně:** nedoručitelné adresy a stížnosti se potlačí samy. Kampaň ve výchozím nastavení vynechá neaktivní kontakty (angažovanost E) a import přeskočí neplatné adresy. ## Míra otevření (open rate) Míra otevření je podíl doručených e-mailů, které příjemci otevřeli. Měří se obrázkovým pixelem, proto ji zkreslují služby, které obrázky stahují samy (například ochrana soukromí v Apple Mail), a příjemci s vypnutými obrázky. **V Poštárně:** míra otevření = unikátní otevření / doručené e-maily. Strojová otevření se do ní nepočítají a proklik se počítá i jako otevření. ## Míra prokliku (CTR) Míra prokliku (click-through rate) je podíl e-mailů, ve kterých příjemce klikl na odkaz. Spolehlivěji než otevření ukazuje skutečný zájem o obsah. **V Poštárně:** CTR = unikátní prokliky / odeslané e-maily. Strojové kliky (bezpečnostní skenery odkazů) se nepočítají. ## Newsletter Newsletter je e-mail, který posíláte pravidelně odběratelům: novinky, nabídky, články nebo tipy. Na rozdíl od automatického e-mailu ho odesíláte ručně jako kampaň a dostanou ho všichni ve vybraném seznamu nebo segmentu. **V Poštárně:** newsletter je e-mailová kampaň. Návod na první rozesílku je v článku [Jak poslat první newsletter](https://www.postarna.cz/navody/prvni-newsletter). ## Odhlášení z odběru Každý obchodní e-mail musí obsahovat snadný způsob, jak se odhlásit. Velké poštovní služby navíc vyžadují odhlášení jedním kliknutím přímo v aplikaci pošty (hlavička List-Unsubscribe podle RFC 8058). **V Poštárně:** každý e-mail kampaně a automatizace má odkaz na odhlášení i hlavičku pro odhlášení jedním kliknutím. Odhlašovací stránka se může zeptat na důvod a ukázat nastavení odběru. Odhlášenému kontaktu Poštárna už nic nepošle. ## Opuštěný košík Opuštěný košík je situace, kdy zákazník vloží zboží do košíku a objednávku nedokončí. Automatický e-mail mu po nějaké době košík připomene a často přivede zpět část objednávek, které by jinak propadly. **V Poštárně:** jeden řádek v patičce e-shopu (Webtracking) posílá do Poštárny košíky zákazníků, které e-shop zná, a spouštěč Každá změna v košíku spustí scénář. Návod: [Opuštěný košík krok za krokem](https://www.postarna.cz/navody/opusteny-kosik). ## Oslovení v 5. pádě V češtině se v oslovení používá 5. pád (vokativ): Petře, Lucie, pane Nováku. Správné oslovení působí osobně, chybné (Dobrý den, Petr) naopak neprofesionálně. **V Poštárně:** značka `{{df_salution}}` vloží oslovení v 5. pádě podle českých pravidel a výjimek. Hodnota vyplněná u kontaktu má přednost a slovenská jména se nesklonují. ## Personalizace Personalizace přizpůsobí obsah e-mailu konkrétnímu příjemci: oslovení jménem, produkty podle jeho nákupů, jeho slevový kód nebo obsah podle jazyka. Personalizované e-maily bývají relevantnější než jeden text pro všechny. **V Poštárně:** šablony umí proměnné kontaktu, podmínky a cykly, produkty z feedu, objednávky kontaktu a jednorázové slevové kódy. ## Preheader Preheader je krátký text, který poštovní aplikace ukáže v přehledu zpráv hned za předmětem. Doplňuje předmět a má vliv na to, jestli příjemce e-mail otevře. **V Poštárně:** preheader zadáte v průvodci kampaní hned pod předmět, nejvýš 200 znaků. ## RFM analýza RFM rozdělí zákazníky podle tří údajů: jak nedávno nakoupili (recency), jak často nakupují (frequency) a kolik utratili (monetary). Z kombinace vzniknou skupiny, například věrní zákazníci, noví zákazníci nebo zákazníci, kteří přestávají nakupovat, a každé můžete psát jinak. ## Segment Segment je skupina kontaktů vybraná podle pravidel, například zákazníci, kteří nakoupili v posledních 12 měsících, nebo odběratelé, kteří otevřeli poslední kampaň. Na rozdíl od ručního seznamu se segment počítá z dat. **V Poštárně:** pravidla segmentu mohou být podle polí kontaktu, seznamů, počtu a hodnoty objednávek, poslední objednávky, objednaných produktů, angažovanosti, souhlasů a reakcí na kampaně, spojená přes A a NEBO. Návod: [Segmentace zákazníků](https://www.postarna.cz/navody/segmentace-zakazniku). ## Soft bounce Soft bounce je dočasná nedoručitelnost, například plná schránka nebo krátkodobý výpadek serveru. Jednotlivý soft bounce není důvod adresu mazat, opakovaný ale ukazuje na problém. **V Poštárně:** adresa se ve výchozím nastavení potlačí po 3 soft bounce za sebou. Úspěšné doručení počítadlo vynuluje. ## Soft opt-in (zákaznická výjimka) Soft opt-in je zákonná výjimka, podle které smí e-shop posílat obchodní sdělení o podobných produktech svým zákazníkům i bez výslovného souhlasu, pokud jim to při nákupu oznámil a dal možnost odmítnout. Každý e-mail pak musí nabídnout odhlášení. **V Poštárně:** výjimka se nastavuje po e-shopech. Slovenský e-shop má ze zákona limit 12 měsíců od poslední dokončené objednávky, u ostatních e-shopů lhůta neplatí, dokud ji firma nenastaví (1 až 120 měsíců). Kontaktu, kterému lhůta vypršela, kampaně ani automatizace nic nepošlou. ## Souhlas se zpracováním (GDPR) Pro posílání obchodních sdělení potřebujete souhlas nebo jiný právní důvod a musíte umět doložit, kdy a jak jste ho získali. Podle GDPR má člověk právo souhlas odvolat, požádat o výpis svých údajů i o jejich výmaz. **V Poštárně:** souhlasy se evidují podle účelů zpracování a každá změna se zapíše do historie s časem, IP adresou a zněním souhlasu. U kontaktu jde stáhnout všechna data nebo provést výmaz na žádost. ## Spam filtr Spam filtr rozhoduje, jestli e-mail dorazí do doručené pošty, nebo do spamu. Hodnotí ověření domény, reputaci odesílatele, reakce příjemců i obsah: podezřelé fráze, poměr textu a obrázků, zkracovače odkazů nebo chybějící odhlášení. **V Poštárně:** kontrola obsahu před odesláním spočítá skóre podle vlastních pravidel (slova v předmětu, fráze v češtině, slovenštině a angličtině, velká písmena, obrázky, odkazy, skrytý text, velikost a odkaz na odhlášení) a ukáže, co opravit. ## SPF SPF (Sender Policy Framework) je záznam v DNS domény, který vyjmenuje servery oprávněné posílat e-maily za tuto doménu. Poštovní služba podle něj pozná podvržený e-mail. **V Poštárně:** průvodce v Nastavení › Odesílání doporučí záznam SPF pro vaši doménu a v kroku Kontrola ověří, zda je v DNS. ## Stížnost na spam Stížnost vznikne, když příjemce označí e-mail tlačítkem Spam. Poštovní služby stížnosti přísně sledují: už podíl kolem 0,1 % zhoršuje doručitelnost. **V Poštárně:** adresa se stížností se hned potlačí a kampaň se ve výchozím nastavení sama pozastaví, když podíl stížností překročí 0,1 %. ## Strojová otevření Strojové otevření je otevření nebo klik, který neudělal člověk: obrázky stáhne poštovní služba sama, bezpečnostní skener projde odkazy nebo se e-mail načte v proxy. Zkresluje míru otevření i prokliku. **V Poštárně:** strojová otevření a kliky se ukládají zvlášť a do statistik ani do angažovanosti se nepočítají. Statistika ukáže, u kolika e-mailů proběhlo jen strojové otevření. ## Transakční e-mail Transakční e-mail posílá e-shop nebo aplikace jako přímou reakci na úkon zákazníka: potvrzení objednávky, faktura, obnova hesla nebo informace o doručení. Na rozdíl od obchodního sdělení se posílá i bez marketingového souhlasu, ale nemá obsahovat reklamu. ## Unikátní slevový kód Unikátní slevový kód je jednorázový kód, který dostane jen jeden příjemce. Na rozdíl od jednoho kódu pro všechny se nedá sdílet a víte, kdo ho použil. **V Poštárně:** kódy z e-shopu nahrajete do zásobníku kupónů a každý e-mail vezme nový volný kód, který se kontaktu přiřadí. Hodí se pro svátky, narozeniny a návrat zákazníků. ## Warm-up (zahřívání odesílání) Warm-up je postupné zvyšování počtu odeslaných e-mailů z nové domény nebo IP adresy. Poštovní služby nedůvěřují odesílateli, který z ničeho začne posílat tisíce e-mailů denně, proto se objem zvyšuje v řádu týdnů. **V Poštárně:** nový účet posílá první dny jen část denního limitu a limit roste po krocích, plného objemu dosáhne za 4 týdny od prvního ostrého odeslání. ## Webhook Webhook je adresa vašeho systému, na kterou jiná aplikace sama pošle zprávu, když se něco stane, například nový kontakt, odhlášení nebo proklik. Nemusíte se tak pořád dotazovat přes API. **V Poštárně:** účtové webhooky nastavíte v Nastavení › Datové zdroje › Webhooky nebo přes API a posílají události nový a změněný kontakt, odhlášení, odeslaný e-mail, stav doručení, otevření a proklik. V automatizaci je navíc uzel Webhook. Podrobnosti jsou v [API dokumentaci](https://www.postarna.cz/docs/api/webhooks). ## Win-back (návrat zákazníků) Win-back je série e-mailů pro zákazníky, kteří dlouho nenakoupili, nebo odběratele, kteří přestali reagovat. Připomene značku, nabídne důvod se vrátit a u těch, kdo nereagují, pomůže rozhodnout, zda je dál oslovovat. **V Poštárně:** win-back postavíte jako automatizaci se spouštěčem Opakovat a podmínkou na poslední objednávku. Návod: [Win-back kampaň pro neaktivní zákazníky](https://www.postarna.cz/navody/win-back). --- # Integrace Poštárny Poštárna se napojí na e-shop a další systémy bez programování tam, kde to jde, a přes otevřené API tam, kde potřebujete vlastní řešení. Všechna napojení najdete v aplikaci v Nastavení › Datové zdroje. ## Shoptet E-shop na Shoptetu napojíte bez programování: • **Import zákazníků a odběratelů**: export zákazníků nebo odběratelů newsletteru ze Shoptetu nahrajete v Kontakty a seznamy › Importy. U exportu zákazníků rozhoduje o každém řádku sloupec souhlasu s newsletterem: kdo souhlas nemá, je zákazník bez marketingového souhlasu a e-maily nedostává. • **Feed objednávek**: adresu exportu objednávek (orders.csv) zadáte jako feed objednávek. Poštárna ho stahuje každou hodinu a u exportu orders.csv ze Shoptetu načítá objednávky posledních 3 dnů každých 10 minut. Objednávky pohání automatizace po nákupu, segmenty podle nákupů a tržby ve statistikách. První stažení historie automatizace nespouští. • **Feed zákazníků**: export zákaznických účtů jako feed načte zákazníky e-shopu do Poštárny a s objednávkami doplní data zákazníků: v Nastavení › E-shopy tlačítkem Doplnit údaje vyplníte prázdná pole kontaktů (jméno, telefon, firmu, adresu, jazyk, svátek a oslovení), nejdřív uvidíte náhled. Zákazník tím nevzniká jako odběratel a nezískává souhlas. • **Webtracking košíku**: jeden řádek v patičce e-shopu posílá košíky známých zákazníků pro [opuštěný košík](https://www.postarna.cz/navody/opusteny-kosik). • **Pop-up formuláře**: pop-up umí skrýt přihlášené zákazníky a zákazníky na stránce po objednávce. ## Produktové feedy Produktový feed ve formátu Google Merchant, Heureka.cz nebo Zboží.cz (XML) zadáte adresou. Produkty z feedu pak vkládáte do e-mailů v Magic Editoru (obrázek, název, cena a odkaz se doplní samy) a páruje se s nimi položky objednávek. U feedu můžete zapnout automatické stahování jednou denně; limit je 20 MB a 50 000 položek. ## Články z blogu (RSS a Atom) Článkový feed ve formátu RSS 2.0 nebo Atom, například blog e-shopu, nabídne v editoru výběr článků do newsletteru. ## Import CSV Kontakty z jiného systému nahrajete jako CSV (oddělovač středník, čárka nebo tabulátor, kódování UTF-8 nebo Windows-1250). Poštárna navrhne přiřazení sloupců podle záhlaví v češtině, slovenštině i angličtině, neplatné adresy přeskočí a odhlášené adresy nikdy znovu nepřihlásí. Import umí kontakty přidat nebo aktualizovat, jen aktualizovat, odhlásit z vybraných seznamů, z vybraných seznamů odebrat, nebo adresy přidat na blacklist. Postup přes API: [Import kontaktů](https://www.postarna.cz/docs/api/recipe-import-contacts). ## Přechod ze SmartEmailingu Kontakty, seznamy, odhlášení, blacklist, souhlasy, šablony a názvy automatizací jako koncepty přenesete sami pomocí API klíče, ve SmartEmailingu se nic nezmění. Volitelně běží hodinová synchronizace, dokud posíláte z obou systémů. Návod: [Přechod ze SmartEmailingu](https://www.postarna.cz/navody/prechod-ze-smartemailingu). ## API kompatibilní se SmartEmailingem Integrace napsaná pro REST API v3 SmartEmailingu funguje s Poštárnou po změně adresy, uživatelského jména a klíče: stejné cesty, obálky, chyby a stránkování pro čtení kontaktů, seznamů a vlastních polí, účtové webhooky a vybrané CSV statistiky. Kontakty a seznamy přes API v3 zatím nezapisujete, k tomu slouží API v1. Podrobnosti: [kompatibilita se SmartEmailingem](https://www.postarna.cz/docs/api/smartemailing). ## API v1 Úplné REST API, stejné, jaké používá webová aplikace: kontakty a souhlasy, seznamy a segmenty, šablony, kampaně, automatizace, objednávky, feedy a slevové kupóny. Přihlášení API klíčem z Nastavení › Datové zdroje › API klíče, popis v OpenAPI 3.1. Objednávky z jiného e-shopu nebo pokladny zapíšete přes API, viz [Objednávky, feedy a kupóny](https://www.postarna.cz/docs/api/orders-feeds-coupons). Začněte [API dokumentací](https://www.postarna.cz/docs/api). ## Webhooky Účtové webhooky nastavíte v Nastavení › Datové zdroje › Webhooky (i s tlačítkem Otestovat) nebo přes API a pošlou na vaši adresu událost, když vznikne nebo se změní kontakt, kontakt se odhlásí, e-mail odejde, změní se stav doručení, nebo příjemce e-mail otevře či klikne. Strojová otevření a kliky webhook neposílá. V automatizaci je navíc uzel Webhook. Podrobnosti: [webhooky](https://www.postarna.cz/docs/api/webhooks). ## MCP pro AI asistenty Server MCP (Model Context Protocol) propojí Poštárnu s AI asistenty, jako jsou ChatGPT, Claude nebo Cursor. Asistent se přihlásí přes OAuth nebo API klíčem a umí pracovat s kontakty, seznamy, segmenty, šablonami, kampaněmi, automatizacemi, formuláři, importy a statistikami. Odeslání skutečným lidem a mazání vždy vyžaduje náhled a potvrzení. Podrobnosti: [MCP pro AI asistenty](https://www.postarna.cz/docs/api/mcp). --- # API dokumentace Poštárny Poštárna je platforma pro e-mail marketing se statistikami pro firmy i e-shopy v Česku a na Slovensku. Přes API uděláte totéž co v aplikaci: spravujete kontakty a souhlasy, seznamy a segmenty, píšete šablony, posíláte kampaně, stavíte automatizace, přijímáte objednávky, feedy a kupóny a necháte si posílat webhooky. Dokumentace je psaná tak, aby podle ní člověk i AI agent napsal funkční integraci napoprvé, bez zkoušení naslepo. ## Tři rozhraní | Rozhraní | Adresa | K čemu | |---|---|---| | **API v1** | `https://www.postarna.cz/api/v1/tenants/{tenant}/...` | Celé API Poštárny, stejné, jaké používá webová aplikace. JSON, přihlášení API klíčem. | | **API v3 kompatibilní se SmartEmailingem** | `https://www.postarna.cz/api/v3/...` a `/api/csv/...` | Stejné cesty, obálky a chyby jako REST API v3 SmartEmailingu. Čtení kontaktů, seznamů a polí, účtové webhooky, CSV statistiky. | | **Server MCP** | `https://www.postarna.cz/mcp` | Model Context Protocol pro AI asistenty (ChatGPT, Claude, Cursor a další). | Stejné API odpovídá i na `https://www.postarna.sk`. ## Nejdůležitější pravidla na jednom místě • **Přihlášení**: API klíč `pst_...` v hlavičce `Authorization: Bearer pst_...` (nebo HTTP Basic: e-mail člena firmy a klíč). Klíč vytvoříte v aplikaci v Nastavení › Datové zdroje › API klíče. Podrobně v [Začínáme](https://www.postarna.cz/docs/api/getting-started). • **Firma v cestě**: `{tenant}` je veřejné ID firmy (UUID). Zjistíte ho voláním `GET /api/v3/account-info` (pole `data.guid`) nebo na stránce API klíčů. • **JSON**: ID jsou řetězce, časy ISO 8601 v UTC, peníze desetinný řetězec vedle měny. **CZK a EUR se nikdy nesčítají ani nepřevádějí.** Viz [Pravidla API](https://www.postarna.cz/docs/api/conventions). • **Chyby**: `{"error": {"code", "message", "params"}}`, `code` je stálý strojový kód, `message` jmenuje pole. Každý kód s významem a nápravou je v [Chyby a limity](https://www.postarna.cz/docs/api/errors-and-limits). • **Limity**: na firmu zásobník 2 500 požadavků doplňovaný 4 za sekundu a 100 000 za den; hlavičky `X-RateLimit-*`, po překročení 429 s `Retry-After`. • **Bezpečnost odesílání**: odhlášenému, vrácenému nebo potlačenému kontaktu Poštárna nikdy nic nepošle. Než pošlete skutečným příjemcům, spočítejte je (`POST .../campaigns/audience`) a automatizaci otestujte (`POST .../automations/{id}/test`). ## Pro AI agenty • [`/llms.txt`](https://www.postarna.cz/llms.txt): stručný rozcestník celé dokumentace v Markdownu. • [`/llms-full.txt`](https://www.postarna.cz/llms-full.txt): všechny návody, koncepty a recepty v jednom souboru a seznam všech operací. • [`/api/openapi.json`](https://www.postarna.cz/api/openapi.json): OpenAPI 3.1 se všemi operacemi a schématy. Jen jednu skupinu načtete parametrem `?tag=`, například `?tag=Automations` nebo `?tag=Contacts,Lists`. • Graf automatizace, podmínky a časové údaje mají přesná schémata v [Referenci automatizací](https://www.postarna.cz/docs/api/automation-reference); stejná pravidla používá validátor serveru. • Postup „nejdřív náhled, potom akce“: `POST /automations/validate`, `POST /automations/{id}/test`, `POST /campaigns/audience`. U trasy s `x-mcp-confirm` v OpenAPI vždy počítejte s tím, že posílá skutečným lidem nebo maže data. ## Jak je dokumentace uspořádaná • **Začínáme**: [první volání](https://www.postarna.cz/docs/api/getting-started) a [pravidla API](https://www.postarna.cz/docs/api/conventions). • **Koncepty**: [firma a e-shopy](https://www.postarna.cz/docs/api/tenants-and-shops), [kontakty a souhlasy](https://www.postarna.cz/docs/api/contacts-and-consent), [seznamy a segmenty](https://www.postarna.cz/docs/api/lists-and-segments), [šablony a personalizace](https://www.postarna.cz/docs/api/templates-and-personalization), [kampaně](https://www.postarna.cz/docs/api/campaigns), [automatizace](https://www.postarna.cz/docs/api/automations) a jejich [reference](https://www.postarna.cz/docs/api/automation-reference), [objednávky, feedy a kupóny](https://www.postarna.cz/docs/api/orders-feeds-coupons). • **Recepty**: hotové postupy s ověřenými požadavky a odpověďmi: [opuštěný košík](https://www.postarna.cz/docs/api/recipe-abandoned-cart), [série po nákupu](https://www.postarna.cz/docs/api/recipe-post-purchase), [svátky](https://www.postarna.cz/docs/api/recipe-name-days), [návrat neaktivních zákazníků](https://www.postarna.cz/docs/api/recipe-win-back), [formulář s potvrzením](https://www.postarna.cz/docs/api/recipe-double-opt-in), [import kontaktů](https://www.postarna.cz/docs/api/recipe-import-contacts), [odeslání kampaně](https://www.postarna.cz/docs/api/recipe-send-campaign), [příjem webhooků](https://www.postarna.cz/docs/api/recipe-webhook-consumer). • **Integrace**: [webhooky](https://www.postarna.cz/docs/api/webhooks), [MCP pro AI asistenty](https://www.postarna.cz/docs/api/mcp), [kompatibilita se SmartEmailingem](https://www.postarna.cz/docs/api/smartemailing). • **Reference API**: [přehled všech operací](https://www.postarna.cz/docs/api/reference), [chyby a limity](https://www.postarna.cz/docs/api/errors-and-limits), stránka pro každou skupinu operací a [historie změn](https://www.postarna.cz/docs/api/changelog). > **Ověřené příklady:** každý požadavek a odpověď v receptech se při testech Poštárny pouští proti skutečnému serveru. Když se API změní, test selže a příklad se opraví dřív, než změna odejde. --- # Začínáme Za pět minut budete mít klíč, ID firmy a první odpověď API. ## 1. Vytvořte API klíč V aplikaci Poštárna otevřete **Nastavení › Datové zdroje › API klíče** a zvolte **Nový API klíč**. • **Název**: k čemu klíč slouží, například „CRM synchronizace“. • **Platnost**: poslední den platnosti (nejdéle 730 dní dopředu), nebo bez omezení. Klíč, který se 180 dní nepoužije, sám přestane fungovat. • **Role**: co klíč smí. Klíč nikdy nedostane víc práv než člověk, který ho vytváří, a přestane fungovat, když jeho autor z firmy odejde. • **Přístup**: **plný** (čtení i změny) nebo **jen čtení** (jen trasy, které nic nemění). Klíč má tvar `pst_` a 43 znaků. **Zobrazí se jen jednou**, Poštárna si ukládá jen jeho otisk. Uložte ho do správce hesel nebo proměnné prostředí, nikdy do kódu v repozitáři. Firma může mít nejvýš 20 platných klíčů. ### Jakou roli klíči dát Role určují úroveň v jednotlivých modulech (`none`, `read`, `full`). Každá operace v [referenci](https://www.postarna.cz/docs/api/reference) uvádí modul a úroveň, kterou potřebuje. | Role | contacts | campaigns | content | settings | billing | |---|---|---|---|---|---| | `account_admin` (správce účtu) | full | full | full | full | full | | `marketing_manager` (marketing) | full | full | full | read | none | | `content_manager` (obsah) | none | read | full | none | none | | `data_analyst` (analytik) | read | read | read | none | none | | `developer` (vývojář) | none | read | none | read | none | | `finance` (finance) | none | none | none | none | full | • Pro běžnou integraci (kontakty, objednávky, kampaně, automatizace) stačí `marketing_manager`. • Účtové webhooky, feedy, kupóny, stavy objednávek a odesílací domény potřebují `settings` na úrovni `full`, tedy roli `account_admin`. • Role `developer` **nevidí kontakty**; pro integraci s kontakty ji nepoužívejte samotnou. • Moduly `users` a `api_keys` (členové, pozvánky, API klíče, připojené aplikace) klíč nikdy nedostane, ani s plným přístupem. Tyto trasy vrátí 403 `forbidden` / `api_key`. ## 2. Připravte proměnné prostředí ```bash title="Terminál" export POSTARNA_API_KEY="pst_váš_klíč_zde" # klíč z kroku 1 export POSTARNA_USER="vas.email@example.cz" # e-mail člena firmy (jen pro HTTP Basic) ``` Všechny příklady v dokumentaci čtou klíč z `POSTARNA_API_KEY` a ID firmy z `TENANT`. ## 3. Zjistěte ID firmy {#3-zjistete-id-firmy} Cesty API v1 obsahují veřejné ID firmy: `/api/v1/tenants/{tenant}/...`. Zjistíte ho z API kompatibilního se SmartEmailingem, které ID firmy nepotřebuje: ```bash title="Požadavek: GET /api/v3/account-info" curl -sS -X GET "https://www.postarna.cz/api/v3/account-info" \ -u "$POSTARNA_USER:$POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "status": "ok", "meta": [], "data": { "account_id": 4, "guid": "3f6c2a1e-8b7d-4c5e-9f10-2a3b4c5d6e7f", "username": "admin@example.cz", "firstname": null, "surname": null, "company": "Example s.r.o.", "phone": null } } ``` Hodnota `data.guid` je vaše `{tenant}`. Stejné ID ukazuje aplikace na stránce API klíčů. ```bash title="Terminál" export TENANT="3f6c2a1e-8b7d-4c5e-9f10-2a3b4c5d6e7f" # data.guid z odpovědi ``` ## 4. První volání API v1 E-shopy firmy (každý má svou měnu a jazyk; ID e-shopu budete potřebovat skoro všude): ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/shops" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/shops" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "items": [ { "id": "7", "code": "cz", "displayName": "Example.cz", "domain": "example.cz", "currency": "CZK", "language": "cs", "active": true }, { "id": "8", "code": "sk", "displayName": "Example.sk", "domain": "example.sk", "currency": "EUR", "language": "sk", "active": true } ] } ``` Kontakty, dva na stránku: ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/contacts" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts?pageSize=2" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "items": [], "total": 0, "page": 1, "pageSize": 2 } ``` ## 5. Dvě možnosti přihlášení • **Bearer** (doporučeno): `Authorization: Bearer pst_...`. • **HTTP Basic**: uživatelské jméno je e-mail aktivního člena firmy, heslo je API klíč. Funguje na API v1 i v3 (tak se přihlašuje i SmartEmailing). Seznam použitelných e-mailů je na stránce API klíčů. Cookie ani CSRF hlavičku API klíč nepotřebuje; ty používá jen webová aplikace. ## 6. Když něco nejde Bez klíče (nebo s neplatným, propadlým či zrušeným klíčem) server odpoví 401: ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/shops" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/shops" ``` ```json title="Odpověď: 401 Unauthorized" { "error": { "code": "unauthorized", "message": "" } } ``` Neplatný parametr vrátí 400 `validation` a v `message` název parametru: ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/contacts" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts?pageSize=500" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 400 Bad Request" { "error": { "code": "validation", "message": "pageSize" } } ``` Všechny kódy chyb s významem a nápravou: [Chyby a limity](https://www.postarna.cz/docs/api/errors-and-limits). ## Co dál • [Pravidla API](https://www.postarna.cz/docs/api/conventions): formáty, stránkování, limity, opakování požadavků. • [Kontakty a souhlasy](https://www.postarna.cz/docs/api/contacts-and-consent): komu Poštárna smí psát. • Recepty: [opuštěný košík](https://www.postarna.cz/docs/api/recipe-abandoned-cart), [odeslání kampaně](https://www.postarna.cz/docs/api/recipe-send-campaign), [import kontaktů](https://www.postarna.cz/docs/api/recipe-import-contacts). --- # Pravidla API Platí pro API v1 (`/api/v1/...`). API v3 kompatibilní se SmartEmailingem má vlastní obálky a formáty, popsané v [Kompatibilitě se SmartEmailingem](https://www.postarna.cz/docs/api/smartemailing). ## Adresa a formát • Základ: `https://www.postarna.cz/api/v1`. Operace firmy: `/api/v1/tenants/{tenant}/...`, kde `{tenant}` je veřejné ID firmy (UUID). • Tělo požadavků POST, PUT a PATCH je JSON (`Content-Type: application/json`, UTF-8). Jiný typ obsahu = 415 `validation` / `contentType`, tělo, které není objekt JSON, = 400 `validation` / `body`. Výjimky: nahrání CSV a souborů přijímá i `multipart/form-data`. • Odpovědi jsou JSON v UTF-8 (diakritika není escapovaná). Exporty a statistiky umí i CSV (`format=csv`). • Jedno tělo požadavku má nejvýš 5 MB (větší = 413 `validation` / `size`); CSV soubor importu nahraný jako `multipart/form-data` až 64 MB. ## Datové typy | Údaj | Formát | Příklad | |---|---|---| | ID objektu | řetězec číslic | `"1201"` | | ID firmy | UUID | `"3f6c2a1e-8b7d-4c5e-9f10-2a3b4c5d6e7f"` | | Čas | ISO 8601 v UTC s milisekundami | `"2026-10-01T08:00:00.000Z"` | | Kalendářní den firmy | `YYYY-MM-DD` v časové zóně firmy | `"2026-10-31"` | | Místní čas v automatizacích | `YYYY-MM-DDTHH:MM`, `HH:MM` | `"2026-12-01T09:00"`, `"08:00"` | | Peníze | desetinný řetězec vedle `currency` | `"1290.00"` a `"CZK"` | | Svátek kontaktu | `MM-DD` | `"10-31"` | • Časy zapisované do API (`sendAt`, `createdAt` objednávky) posílejte s časovou zónou (`Z` nebo `+02:00`). • Dny v segmentech a podmínkách („za posledních 30 dní“) jsou kalendářní dny v časové zóně firmy (Europe/Prague, Europe/Bratislava). • **Měny se nikdy nesčítají ani nepřevádějí.** Každý e-shop má jednu měnu; objednávka v jiné měně, než má její e-shop, je chyba 400. Součty (obraty, konverze) jsou vždy po měnách. ## Stránkování, hledání a řazení • Seznamy objektů mají `page` (od 1) a `pageSize` (1 až 100, výchozí 25). Odpověď je `{"items": [...], "total": 240, "page": 1, "pageSize": 25}`. • Projděte všechny stránky, dokud `page * pageSize < total`. • `q` hledá v názvu nebo adrese bez ohledu na velikost písmen a diakritiku (nejvýš 200 znaků). U automatizací `q=#123` najde automatizaci podle ID. • `shop` omezí přehled na jeden e-shop (ID e-shopu). • `sort` u přehledů, které ho mají: pole oddělená čárkou, `-` na začátku = sestupně, nejvýš 3 pole (`sort=name,-createdAt`). Výchozí řazení je od nejnovějšího. Neznámé pole = 400 `validation` / `sort`. ## Chyby Každá chyba má stejný tvar a vhodný HTTP stav: ```json title="Tělo chyby" {"error": {"code": "conflict", "message": "version", "params": {"current": 4}}} ``` • `code`: stálý strojový kód (`validation`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `unavailable` a další). Podle něj se rozhodujte. • `message`: technický údaj, obvykle název pole (`email`, `definition.1.0.listId`, `graph`) nebo důvod (`version`, `status`). Není to text pro lidi a může být prázdný. • `params`: podrobnosti, například `issues` u grafu automatizace, `expected` a `actual` u počtu příjemců, `reason`. • API neposílá texty pro lidi; texty v češtině a slovenštině si skládá aplikace. Úplný seznam kódů s významem a nápravou: [Chyby a limity](https://www.postarna.cz/docs/api/errors-and-limits). ## Limity požadavků • Na firmu (všechny klíče dohromady): zásobník **2 500 požadavků**, který se doplňuje **4 požadavky za sekundu**, a **100 000 požadavků za den** (doplňuje se průběžně, žádný reset o půlnoci). • Každá odpověď na požadavek s klíčem nese `X-RateLimit-Limit`, `X-RateLimit-Remaining` a `X-RateLimit-Reset` (unixový čas, kdy bude zásobník zase plný) zásobníku, kterému zbývá méně. • Po překročení přijde 429 `rate_limited` s hlavičkou `Retry-After` (za kolik sekund). Odmítnuté požadavky se nepočítají. • Některé akce mají vlastní limity (testovací e-maily, události kontaktu, MCP); jsou v [Chybách a limitech](https://www.postarna.cz/docs/api/errors-and-limits#limity-akci). ## Opakování požadavků a idempotence {#opakovani-pozadavku-a-idempotence} API nepoužívá hlavičku `Idempotency-Key`. Po výpadku sítě nebo chybě 5xx proto opakujte jen to, co je bezpečné opakovat: • **GET** opakujte vždy. • **PUT** nahrazuje celý objekt (obsah šablony, graf automatizace, stavy objednávek): opakování se stejnými daty nic nepokazí; u obsahu a grafu ale hlídá verzi (viz níže). • **DELETE** opakujte; druhé volání vrátí 404, což znamená „už smazáno“. • **POST /orders** je upsert podle dvojice (`shopId`, `id` objednávky): opakování se stejnými daty vrátí `change: "unchanged"`. • **POST /lists/{id}/members** je idempotentní: kontakt, který už je členem, se počítá do `alreadyMember`. • **POST /contacts**: druhé založení stejné adresy vrátí 409 `conflict` / `email`. Před opakováním kontakt vyhledejte (`GET /contacts?q=adresa`) a případně upravte přes `PATCH`. • **POST /contact-events** idempotentní není: každá událost se zapíše znovu. Po časovém limitu raději jednu událost ztraťte, než ji pošlete dvakrát. • **POST /campaigns/{id}/approve** chrání stav kampaně: druhé schválení vrátí 409 `conflict` / `status`. • Při 429 počkejte `Retry-After`; při 5xx opakujte s rostoucí prodlevou (1, 2, 4, 8 s) a nejvýš pětkrát. ## Souběžné úpravy (verze) Obsah šablon a kampaní, patičky a grafy automatizací mají číslo verze. Ukládání posílá `baseVersion` = verzi, kterou jste naposledy načetli. Když mezitím uložil někdo jiný, server vrátí 409 `conflict` / `version` s `params.current`; načtěte objekt znovu, sloučte změny a uložte s novou verzí. ## Oprávnění • Každá operace patří do modulu (`contacts`, `campaigns`, `content`, `settings`, `billing`) a potřebuje úroveň `read` nebo `full`. Reference to u každé operace uvádí. • Klíč s přístupem jen pro čtení dosáhne jen na operace s úrovní `read` (i POST, který jen počítá, například náhled segmentu). Jinak 403 `forbidden` / `scope`. • Klíč v cizí firmě: 403 `forbidden` / `tenant`. Chybějící role: 403 `forbidden` s názvem modulu v `message`. Objekt jiné firmy se tváří jako neexistující (404). • Bez přihlášené osoby (tedy ani klíčem) nejde: správa členů, pozvánek, API klíčů a připojených aplikací, hlavní vypínač odesílání a změny tarifu. ## Neznámá pole Posílejte jen zdokumentovaná pole. Většina tras neznámá pole ignoruje, některé je odmítnou s názvem pole v `message` (například `POST /orders`), nastavení uzlů automatizace se při uložení zahodí. Nová pole v odpovědích mohou přibývat, klient je má ignorovat. --- # Firma a e-shopy ## Firma (tenant) Účet v Poštárně patří **firmě**. V API se jí říká tenant a její veřejné ID (UUID) je v cestě každé operace: `/api/v1/tenants/{tenant}/...`. • Data firem jsou od sebe oddělená na úrovni databáze. Klíč jedné firmy na cestě jiné firmy dostane 403 `forbidden` / `tenant`, objekt jiné firmy se tváří jako neexistující (404). • Firma má členy s rolemi (správce účtu, marketing, obsah, analytik, vývojář, finance). API klíč patří firmě, pracuje s rolemi, které mu jeho autor dal, a nikdy nespravuje členy ani klíče. • ID firmy zjistíte z `GET /api/v3/account-info` (`data.guid`), viz [Začínáme](https://www.postarna.cz/docs/api/getting-started#3-zjistete-id-firmy). ## E-shopy Firma má jeden nebo víc **e-shopů** (například CZ v korunách a SK v eurech). E-shop určuje: • **měnu** (`CZK` nebo `EUR`): objednávky, košíky, kupóny a podmínky o tržbách jsou vždy v měně e-shopu, • **jazyk** (`cs` nebo `sk`): výchozí jazyk kontaktů a stránek pro příjemce, • **odesílatele** (ověřené adresy, `GET /senders`) a patičku s identitou firmy, • **odkazovou doménu**, na které běží odhlášení, nastavení odběru a formuláře. ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/shops" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/shops" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "items": [ { "id": "7", "code": "cz", "displayName": "Example.cz", "domain": "example.cz", "currency": "CZK", "language": "cs", "active": true }, { "id": "8", "code": "sk", "displayName": "Example.sk", "domain": "example.sk", "currency": "EUR", "language": "sk", "active": true } ] } ``` Ke kterému e-shopu co patří: | Objekt | Vazba na e-shop | |---|---| | Kontakt | hlavní e-shop (`shopId`); zakládá se vždy s e-shopem | | Seznam | e-shop, nebo celá firma (`shopId: null`) | | Segment | vždy jeden e-shop; vyhodnocuje se nad kontakty s tímto hlavním e-shopem | | Kampaň | jeden e-shop (odesílatel, patička, měna) | | Automatizace | jeden e-shop; e-shop se po založení nemění | | Objednávka, košík, kupóny, feed | jeden e-shop | Vypnutý e-shop (`POST /shops/{id}/disable`) nic nového neposílá: jeho automatizace nejde zapnout a nové kampaně neodejdou. ## Zákaznická výjimka (soft opt-in) Zákazníkovi, který u e-shopu nakoupil, smí e-shop za zákonných podmínek posílat obchodní sdělení bez výslovného souhlasu. Poštárna to hlídá po e-shopech: • Slovenský e-shop má ze zákona limit 12 měsíců od poslední dokončené objednávky (zákon č. 452/2021 Z. z., § 116 ods. 16), i bez nastavení. • Jiný e-shop má výjimku vypnutou, dokud si ji firma nenastaví. • Čtení a změna: `GET /consent-settings`, `PATCH /consent-settings/{shopId}` s tělem `{"months": 12}` (0 = vypnuto, 1 až 120 měsíců). • Kontaktu, kterému výjimka vypršela, kampaně ani automatizace nepošlou nic (v počtu příjemců jako `exception_expired`). ## Časová zóna Firma má časovou zónu (Europe/Prague nebo Europe/Bratislava). V ní se počítají kalendářní dny segmentů a podmínek, místní časy automatizací (`"08:00"`, `"2026-12-01T09:00"`) a dny v CSV statistikách. Časy v JSON jsou vždy v UTC. --- # Kontakty a souhlasy ## Kontakt Kontakt je jedna e-mailová adresa ve firmě (adresa je ve firmě jedinečná, bez ohledu na velikost písmen). Má hlavní e-shop (`shopId`), profilová pole a stav. Profilová pole (názvy v API): `firstName`, `lastName`, `titleBefore`, `titleAfter`, `salutation`, `salutationFormal`, `vocativeFirstName` (oslovení v 5. pádě, například „Petře“), `vocativeLastName`, `gender` (`f`, `m`, `null`), `language` (`cs`, `sk` ...), `company`, `companyId` (IČO), `phone`, `mobile`, `street`, `city`, `postalCode`, `country` (dvě písmena), `birthday` (`YYYY-MM-DD`), `nameDay` (`MM-DD`), `note`, `affiliateId` a vlastní pole `customFields` (`{"": hodnota}`, ID polí z `GET /custom-fields`). ### Stav kontaktu (`status`) | Stav | Význam | Dostává e-maily | |---|---|---| | `subscribed` | přihlášený | ano (pokud není potlačený a nemá slabý souhlas) | | `pending` | čeká na potvrzení odběru (double opt-in) | ne | | `unsubscribed` | odhlášený | ne, nikdy znovu bez nového potvrzení | | `bounced` | adresa je nedoručitelná | ne | | `complained` | označil e-mail jako spam | ne | | `customer` | zákazník bez marketingového souhlasu (vznikl z objednávky) | ne (jen v rámci zákaznické výjimky e-shopu) | **Poštárna nikdy znovu neobešle odhlášený, vrácený nebo potlačený kontakt.** Odhlášený kontakt se znovu přihlásí jen novým potvrzením odběru (double opt-in), nikdy voláním API. ### Původ souhlasu (`consentBasis`) `double_opt_in` (potvrdil odběr), `imported` (doložený souhlas zadaný ručně nebo importem), `soft_opt_in_customer` (zákaznická výjimka), `none`. Pole `consentWeak` = slabý souhlas; takovým kontaktům kampaně ani automatizace nepíšou. ## Účely zpracování a souhlasy Účel zpracování (`purpose`) je druh souhlasu, například „Zasílání obchodních sdělení (newsletter)“. Každá firma má výchozí účel; seznam vrátí `GET /purposes`. • Souhlas kontaktu s účelem: `GET /contacts/{id}/purposes`, zápis `POST /contacts/{id}/purposes`, odvolání `POST /contacts/{id}/purposes/{consentId}/withdraw`. • Kampaň může vzít jen kontakty s platným souhlasem (`onlyWithPurpose`), segmenty a podmínky automatizací umí pravidlo `purpose` / `contact_purpose`. ## Založení kontaktu Kontakt přes API založíte jen tehdy, když máte **doložený souhlas** (například z vlastního formuláře nebo smlouvy). Tělo musí obsahovat `purposeId` (účel, ke kterému se souhlas vztahuje) a `consentConfirmed: true` (potvrzujete, že souhlas máte doložený). ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/contacts" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "email": "jana.novakova@example.cz", "shopId": "3", "purposeId": "2", "consentConfirmed": true, "firstName": "Jana", "lastName": "Nováková", "city": "Brno" } JSON ``` ```json title="Odpověď: 201 Created" { "id": "1202", "email": "jana.novakova@example.cz", "firstName": "Jana", "lastName": "Nováková", "status": "subscribed", "engagement": "N", "excluded": false, "shopId": "3", "suppressionReason": null, "blacklisted": false, "blacklistedAt": null, "state": null, "createdAt": "2026-10-01T08:00:00.000Z", "phone": "", "mobile": "", "titleBefore": "", "titleAfter": "", "salutation": "", "salutationFormal": "", "vocativeFirstName": "", "vocativeLastName": "", "gender": null, "language": "cs", "company": "", "companyId": "", "street": "", "city": "Brno", "postalCode": "", "note": "", "affiliateId": "", "country": null, "birthday": null, "nameDay": null, "source": "manual", "consentBasis": "imported", "statusAt": "2026-10-01T08:00:00.000Z", "consentAt": "2026-10-01T08:00:00.000Z", "consentWeak": false, "softBounces": 0, "lastSentAt": null, "lastOpenAt": null, "lastClickAt": null, "suppressedAt": null, "engagementAt": null, "suppressionNote": null, "customFields": {}, "updatedAt": "2026-10-01T08:00:00.000Z", "stats90d": { "received": 0, "opened": 0, "clicked": 0, "bestHour": null }, "lists": [], "recentActivities": [ { "id": "consent-2", "type": "status_change", "at": "2026-10-01T08:00:00.000Z", "title": "purpose_assigned" } ], "orders": [], "orderTotals": [], "editedFields": [], "sources": [] } ``` • Nový kontakt dostane `source: "manual"`, `consentBasis: "imported"` a jazyk e-shopu, pokud nepošlete vlastní. • Adresa, která je potlačená (odhlášená, vrácená, stížnost), vznikne s odpovídajícím stavem a potlačení zůstává. • `listIds` rovnou přidá kontakt do ručních nebo formulářových seznamů. • Adresa, která už je kontaktem, vrátí 409: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/contacts" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "email": "jana.novakova@example.cz", "shopId": "3", "purposeId": "2", "consentConfirmed": true } JSON ``` ```json title="Odpověď: 409 Conflict" { "error": { "code": "conflict", "message": "email" } } ``` Když souhlas doložený nemáte, použijte **formulář s potvrzením** (double opt-in), viz [recept](https://www.postarna.cz/docs/api/recipe-double-opt-in). Kupující z objednávek ([`POST /orders`](https://www.postarna.cz/docs/api/orders-feeds-coupons)) dostanou stav `customer` a e-maily nedostávají. ## Hledání a úpravy ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/contacts" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts?q=jana.novakova%40example.cz" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "items": [ { "id": "1202", "email": "jana.novakova@example.cz", "firstName": "Jana", "lastName": "Nováková", "status": "subscribed", "engagement": "N", "excluded": false, "shopId": "3", "suppressionReason": null, "blacklisted": false, "blacklistedAt": null, "state": "active", "createdAt": "2026-10-01T08:00:00.000Z" } ], "total": 1, "page": 1, "pageSize": 25 } ``` `PATCH /contacts/{id}` mění profilová pole a vlastní pole, nikdy adresu, stav ani souhlas (400 `email`). Pole, která upravil člověk v aplikaci, importy a synchronizace nepřepíšou. ```bash title="Požadavek: PATCH /api/v1/tenants/{tenant}/contacts/1202" curl -sS -X PATCH "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts/1202" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "phone": "+420 600 000 000", "customFields": {} } JSON ``` ```json title="Odpověď: 200 OK" { "id": "1202", "email": "jana.novakova@example.cz", "firstName": "Jana", "lastName": "Nováková", "status": "subscribed", "engagement": "N", "excluded": false, "shopId": "3", "suppressionReason": null, "blacklisted": false, "blacklistedAt": null, "state": null, "createdAt": "2026-10-01T08:00:00.000Z", "phone": "+420 600 000 000", "mobile": "", "titleBefore": "", "titleAfter": "", "salutation": "", "salutationFormal": "", "vocativeFirstName": "", "vocativeLastName": "", "gender": null, "language": "cs", "company": "", "companyId": "", "street": "", "city": "Brno", "postalCode": "", "note": "", "affiliateId": "", "country": null, "birthday": null, "nameDay": null, "source": "manual", "consentBasis": "imported", "statusAt": "2026-10-01T08:00:00.000Z", "consentAt": "2026-10-01T08:00:00.000Z", "consentWeak": false, "softBounces": 0, "lastSentAt": null, "lastOpenAt": null, "lastClickAt": null, "suppressedAt": null, "engagementAt": null, "suppressionNote": null, "customFields": {}, "updatedAt": "2026-10-01T08:00:00.000Z", "stats90d": { "received": 0, "opened": 0, "clicked": 0, "bestHour": null }, "lists": [], "recentActivities": [ { "id": "consent-2", "type": "status_change", "at": "2026-10-01T08:00:00.000Z", "title": "purpose_assigned" } ], "orders": [], "orderTotals": [], "editedFields": [], "sources": [] } ``` Další filtry seznamu kontaktů: `status`, `list` (ID seznamu), `shop`, `engagement` (A až E, N), `source`, `createdFrom`, `createdTo`, `tab` a záporné varianty `stateOp=neq`, `listOp=neq` a další (viz [reference kontaktů](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-list)). ## Odhlášení, potlačení a blacklist • `POST /contacts/{id}/unsubscribe` odhlásí kontakt ze všeho, jako by klikl na odkaz v e-mailu: stav `unsubscribed`, adresa se potlačí, e-maily ve frontě se přeskočí, zápis do historie souhlasů. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/contacts/1202/unsubscribe" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts/1202/unsubscribe" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "note": "Požádala telefonicky" } JSON ``` ```json title="Odpověď: 200 OK" { "id": "1202", "email": "jana.novakova@example.cz", "firstName": "Jana", "lastName": "Nováková", "status": "unsubscribed", "engagement": "N", "excluded": false, "shopId": "3", "suppressionReason": "unsubscribed", "blacklisted": false, "blacklistedAt": null, "state": null, "createdAt": "2026-10-01T08:00:00.000Z", "phone": "+420 600 000 000", "mobile": "", "titleBefore": "", "titleAfter": "", "salutation": "", "salutationFormal": "", "vocativeFirstName": "", "vocativeLastName": "", "gender": null, "language": "cs", "company": "", "companyId": "", "street": "", "city": "Brno", "postalCode": "", "note": "", "affiliateId": "", "country": null, "birthday": null, "nameDay": null, "source": "manual", "consentBasis": "imported", "statusAt": "2026-10-01T08:00:00.000Z", "consentAt": "2026-10-01T08:00:00.000Z", "consentWeak": false, "softBounces": 0, "lastSentAt": null, "lastOpenAt": null, "lastClickAt": null, "suppressedAt": "2026-10-01T08:00:00.000Z", "engagementAt": null, "suppressionNote": null, "customFields": {}, "updatedAt": "2026-10-01T08:00:00.000Z", "stats90d": { "received": 0, "opened": 0, "clicked": 0, "bestHour": null }, "lists": [ { "listId": "41", "name": "VIP zákazníci", "state": "confirmed", "changedAt": "2026-10-01T08:00:00.000Z", "listSize": 1 } ], "recentActivities": [ { "id": "consent-4", "type": "unsubscribed", "at": "2026-10-01T08:00:00.000Z", "title": "admin" }, { "id": "consent-3", "type": "status_change", "at": "2026-10-01T08:00:00.000Z", "title": "suppressed" }, { "id": "consent-2", "type": "status_change", "at": "2026-10-01T08:00:00.000Z", "title": "purpose_assigned" } ], "orders": [], "orderTotals": [], "editedFields": [], "sources": [] } ``` • **Potlačení** (`suppressions`) je seznam adres, na které se nesmí psát: odhlášení, nedoručitelné, stížnosti a ruční blacklist. `GET /suppressions`, ruční přidání `POST /suppressions` s `{"email", "detail"}`. ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/suppressions" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/suppressions" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "items": [ { "email": "jana.novakova@example.cz", "reason": "unsubscribed", "source": "admin", "detail": "", "blacklisted": false, "createdAt": "2026-10-01T08:00:00.000Z" } ], "total": 1, "page": 1, "pageSize": 25 } ``` • Potlačení se maže **jen po jednom** (`DELETE /suppressions/{email}`), hromadné mazání databáze odmítne. Blacklist kontaktu: `POST` a `DELETE /contacts/{id}/blacklist`; adresa potlačená z jiného důvodu vrátí 409 `suppression_locked`. ## Osobní údaje (GDPR) • `GET /contacts/{id}/export`: všechna data kontaktu (profil, souhlasy, seznamy, aktivity, objednávky). • `POST /contacts/{id}/erase` s tělem `{"confirm": true}`: nevratný výmaz na žádost člověka. Kontakt, jeho souhlasy, členství a historie zmizí, adresa se odstraní i z odeslaných e-mailů, objednávek a záznamu souhlasů. Zůstane jen otisk adresy (ne adresa), aby ji import ani synchronizace znovu nezaložily, a řádek potlačení, pokud se adresa odhlásila nebo byla nedoručitelná (pravidlo „nikdy znovu nepsat“). • `DELETE /contacts/{id}`: smaže kontakt s jeho členstvími, souhlasy a aktivitami; odeslané e-maily a záznamy zůstanou s adresou a potlačení se nemění. Pro žádost o výmaz používejte `erase`. ## Shrnutí: komu e-mail odejde E-mail kampaně nebo automatizace odejde jen kontaktu, který je současně: 1. ve stavu `subscribed`, 2. bez potlačení (odhlášení, nedoručitelnost, stížnost, blacklist), 3. bez slabého souhlasu, 4. u zákaznické výjimky ještě v její lhůtě, 5. a u kampaně splňuje její publikum (seznamy, segmenty, vyloučení, účel). Kontroluje se při výběru příjemců i těsně před odesláním každého e-mailu. --- # Seznamy a segmenty | | Seznam | Segment | |---|---|---| | Členství | výslovné: kontakty do něj přidáte (ručně, formulářem, importem, automatizací) | podle podmínek: kontakt je členem, dokud podmínky splňuje | | E-shop | jeden e-shop, nebo celá firma | vždy jeden e-shop | | Typické použití | odběr newsletteru, VIP klub, kontakty z akce | „utratili přes 3 000 Kč za rok“, „neotevřeli 90 dní“ | | Kampaň | ano | ano | | Podmínka v automatizaci | `contact_in_list` | pravidla segmentu přímo v podmínce | ## Seznamy • `GET /lists`, `POST /lists`, `PATCH /lists/{id}`, `DELETE /lists/{id}`. • **Ruční seznamy** (`manualMembers: true`): členy přidáváte a odebíráte sami. • **Seznamy napojené na e-shop** (`systemKind` `shop_contacts`, `shop_newsletter`, `shop_unsubscribed`) plní synchronizace e-shopu; přidat nebo odebrat člena = 409 `conflict` / `locked`. • **Formulářové seznamy** plní formuláře, členy jde přidávat i ručně. • `publicName` je název seznamu, který kontakt uvidí na stránce nastavení odběru. Stavy členství: `confirmed` (potvrzený), `unconfirmed` (čeká na potvrzení odběru), `unsubscribed` (odhlásil se z tohoto seznamu), `removed` (odebraný). ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/lists" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/lists" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "VIP zákazníci", "publicName": "Novinky pro VIP", "shopId": null, "notifyOnUnsubscribe": false, "notifyOnAdd": false, "note": "" } JSON ``` ```json title="Odpověď: 201 Created" { "id": "41", "name": "VIP zákazníci", "publicName": "Novinky pro VIP", "shopId": null, "systemKind": null, "locked": false, "manualMembers": true, "tags": [], "counts": { "total": 0, "byBucket": { "active": 0, "unconfirmed": 0, "unsubscribed": 0, "bounced": 0, "complained": 0, "blacklisted": 0 } }, "createdAt": "2026-10-01T08:00:00.000Z", "notifyOnUnsubscribe": false, "notifyOnAdd": false, "note": "" } ``` ### Přidání a odebrání členů `POST /lists/{id}/members` s `{"contactIds": [...]}` (1 až 1 000 ID): • už člen = `alreadyMember`, • kontakt odhlášený z tohoto seznamu, odhlášený celkově, nedoručitelný nebo potlačený = `skipped` (nikdy ho znovu nepřihlásí), • ostatní = `added` (kontakt čekající na potvrzení se přidá jako `unconfirmed`). ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/lists/41/members" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/lists/41/members" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "contactIds": [ "1202" ] } JSON ``` ```json title="Odpověď: 200 OK" { "added": 1, "alreadyMember": 0, "skipped": 0 } ``` • `POST /lists/{id}/members/remove` člena odebere (stav `removed`), `POST /lists/{id}/members/unsubscribe` ho z tohoto seznamu odhlásí. • Přidání do seznamu může spustit zapnutou automatizaci se spouštěčem `list_added`. ## Segmenty {#segmenty} Segment patří jednomu e-shopu a vyhodnocuje se nad kontakty s tímto hlavním e-shopem. Definice je strom skupin A (`all`) / NEBO (`any`) a pravidel: ```json title="Definice segmentu" {"type": "group", "match": "all", "rules": [ {"type": "list", "operator": "in", "listId": "43"}, {"type": "group", "match": "any", "rules": [ {"type": "order_value", "operator": "gte", "amount": "3000", "currency": "CZK", "shopId": "15", "days": "365"}, {"type": "field", "field": "lastClickAt", "operator": "in_last_days", "value": "30"}]}]} ``` • Nejvýš 8 úrovní skupin a 50 pravidel. Prázdná podskupina je chyba; prázdný kořen odpovídá všem kontaktům e-shopu (uložit ale jde jen segment s aspoň jedním pravidlem). • **Hodnoty pravidel jsou řetězce**: počet dní `"30"` (1 až 3 650), částka `"1500.50"`, datum `"2026-09-30"`. • Dny jsou kalendářní dny v časové zóně firmy: „za posledních 30 dní“ = od dneška minus 30 dní včetně dneška; „ne za posledních N dní“ platí i pro prázdné datum (nikdy neotevřel). • Objednávky se počítají jen dokončené; `order_value` sčítá jen jednu měnu (`currency` je povinná). • `refresh`: `daily` (vyhodnocuje se živě) nebo `static` (snímek členů při každém uložení). Typy pravidel: `field` (pole kontaktu), `list` (členství), `order_count`, `order_value`, `last_order`, `order_attribute` (kód, kategorie nebo značka v objednávce), `engagement` (A až E, N), `purpose` (platný souhlas), `custom_field`, `campaign` (doručeno, otevřeno, kliknuto), `segment` (člen jiného segmentu). Všechna pole a operátory: [Reference automatizací › Pravidla segmentů](https://www.postarna.cz/docs/api/automation-reference#pravidla-segmentu). ### Živý náhled počtu `POST /segments/preview` spočítá kontakty bez uložení: `matched` (splní podmínky), `mailable` (z nich těch, kterým lze psát), `total` (všechny kontakty e-shopu). ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/segments/preview" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/segments/preview" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "shopId": "15", "definition": { "type": "group", "match": "all", "rules": [ { "type": "list", "operator": "in", "listId": "43" }, { "type": "group", "match": "any", "rules": [ { "type": "order_value", "operator": "gte", "amount": "3000", "currency": "CZK", "shopId": "15", "days": "365" }, { "type": "field", "field": "lastClickAt", "operator": "in_last_days", "value": "30" } ] } ] } } JSON ``` ```json title="Odpověď: 200 OK" { "matched": 0, "mailable": 0, "total": 0 } ``` ### Uložení ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/segments" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/segments" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Aktivní a utrácející", "shopId": "15", "refresh": "daily", "definition": { "type": "group", "match": "all", "rules": [ { "type": "list", "operator": "in", "listId": "43" }, { "type": "group", "match": "any", "rules": [ { "type": "order_value", "operator": "gte", "amount": "3000", "currency": "CZK", "shopId": "15", "days": "365" }, { "type": "field", "field": "lastClickAt", "operator": "in_last_days", "value": "30" } ] } ] } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "31", "name": "Aktivní a utrácející", "publicName": "", "shopId": "15", "refresh": "daily", "matched": 0, "mailable": 0, "computedAt": "2026-10-01T08:00:00.000Z", "ruleCount": 3, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "definition": { "type": "group", "match": "all", "rules": [ { "type": "list", "listId": "43", "operator": "in" }, { "type": "group", "match": "any", "rules": [ { "days": "365", "type": "order_value", "amount": "3000", "shopId": "15", "currency": "CZK", "operator": "gte" }, { "type": "field", "field": "lastClickAt", "value": "30", "operator": "in_last_days" } ] } ] }, "signatureHtml": "" } ``` Chybné pravidlo vrátí 400 s cestou k poli: `definition..`. Tady měna nepatří e-shopu: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/segments" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/segments" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Chybný", "shopId": "15", "refresh": "daily", "definition": { "type": "group", "match": "all", "rules": [ { "type": "order_value", "operator": "gte", "amount": "3000", "currency": "EUR", "shopId": "15" } ] } } JSON ``` ```json title="Odpověď: 400 Bad Request" { "error": { "code": "validation", "message": "definition.0.currency" } } ``` • Odkazy mezi segmenty (`segment`) smí vést jen na segment stejného e-shopu, nesmí vytvořit cyklus ani řetězec delší než 5 (`definition.segmentCycle`, `definition.segmentDepth`). • E-shop uloženého segmentu se nemění (400 `shop`). Název je ve firmě jedinečný (409 `name`). --- # Šablony a personalizace ## Šablona a její obsah Šablona (`template`) má název, předmět, preheader a obsah. Obsah je `{editor, html, design, version}`: • `editor: "html"`: obsah je HTML, `design` je `null`. Pro API nejjednodušší. • `editor: "visual"`: obsah vizuálního editoru (MJML) v `design` (`{"format": "mjml-1", "mjml", "styles"}`) a z něj vykreslené `html`. Založení se zkopírovaným obsahem jedním voláním: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/templates" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/templates" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Opuštěný košík", "subject": "{{df_name|default('Dobrý den', true)}}, něco jste nechali v košíku", "preheader": "Váš košík na vás počká ještě pár dní", "content": { "editor": "html", "design": null, "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

ve vašem košíku zůstalo {{ metadata.event.attributes.itemCount }} ks zboží za {{ metadata.event.attributes.total }} {{ metadata.event.attributes.currency }}.

Dokončit objednávku

{{cl_company}}, {{cl_address}}. Odhlásit odběr

" } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "301", "name": "Opuštěný košík", "subject": "{{df_name|default('Dobrý den', true)}}, něco jste nechali v košíku", "preheader": "Váš košík na vás počká ještě pár dní", "editor": "html", "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "tags": [], "size": 465, "archived": false, "archivedAt": null, "readOnly": false, "usage": { "campaigns": 0, "automations": 0 }, "lastUsedAt": null, "check": { "errors": [], "warnings": [ "subject_long" ], "checkedAt": "2026-10-01T08:00:00.000Z" }, "content": { "editor": "html", "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

ve vašem košíku zůstalo {{ metadata.event.attributes.itemCount }} ks zboží za {{ metadata.event.attributes.total }} {{ metadata.event.attributes.currency }}.

Dokončit objednávku

{{cl_company}}, {{cl_address}}. Odhlásit odběr

", "design": null, "version": 1, "updatedAt": "2026-10-01T08:00:00.000Z" }, "settings": { "linkParams": [], "headers": [], "unsubscribePageId": null, "footerId": null }, "draft": { "pending": false, "savedAt": null, "publishedAt": null }, "activeUses": { "automations": 0, "emails": 0, "campaigns": 0 }, "publicUrl": "https://links.example.cz/template/1/72cf576a-85b2-474e-86e2-bfdbd1f4d38f" } ``` Úprava obsahu: `PUT /templates/{id}/content` s `{editor, html, design, baseVersion}`; `baseVersion` je verze, kterou jste načetli (u nové šablony 1). Jiná verze na serveru = 409 `conflict` / `version` s `params.current`. Každé uložení se zapíše do historie (`GET /templates/{id}/versions`). • HTML server před uložením vyčistí: žádné skripty, rámy, atributy `on*`, odkazy `javascript:` ani nebezpečné CSS. Čistý vstup zůstane beze změny. • HTML nad 102 000 bajtů hlásí kontrola obsahu jako chybu a takový e-mail neodejde (Gmail delší e-mail ořízne). • Kampaň má **vlastní kopii** obsahu (`PUT /campaigns/{id}/content`); pozdější úprava šablony kampaň nezmění. ### Šablona, kterou posílá zapnutá automatizace Aby se omylem nezměnil e-mail, který právě chodí zákazníkům, uloží se změna obsahu takové šablony do **konceptu**. E-maily posílají dál publikovanou podobu, dokud koncept nepublikujete: • `POST /templates/{id}/publish` s `{"confirm": ""}` (klíčem API; přihlášený člověk posílá heslo). • `DELETE /templates/{id}/draft` koncept zahodí. • Smazat šablonu, kterou posílá zapnutá automatizace, nejde (409 `conflict` / `in_use`). ## Kontrola obsahu `POST /content/lint` s `{html, subject, preheader}` vrátí `issues` s kódy (chyby první). Stejná kontrola běží při schválení kampaně a zapnutí automatizace: **chyba** odeslání zastaví, **upozornění** ne. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/content/lint" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/content/lint" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "html": "

Dobrý den, {{df_jmeno}}

", "subject": "Podzimní novinky", "preheader": "" } JSON ``` ```json title="Odpověď: 200 OK" { "issues": [ { "code": "unknown_tag", "severity": "error", "params": { "tags": "{{df_jmeno}}" } }, { "code": "no_unsubscribe", "severity": "warning", "params": {} } ] } ``` | Kód | Závažnost | Kdy | |---|---|---| | `subject_missing` | chyba | prázdný předmět | | `subject_too_long` | chyba | předmět nad 200 znaků | | `content_empty` | chyba | žádný text ani obrázek | | `unknown_tag` | chyba | neznámá zástupná značka (`params.tags`) | | `foreign_tag` | chyba | značky jiných nástrojů (`*\|X\|*`, `%%x%%`, `{$x}`) | | `script_error` | chyba | skript Twig nejde spustit (`params.line`, `params.detail`) | | `unsupported_filter` | chyba | nepodporovaný filtr (například `\|raw`) | | `bad_fallback` | chyba | neplatná náhrada `default(...)` | | `emoji` | chyba | emoji, když je firma zakázala | | `forbidden_word` | podle pravidla | zakázané slovo podle pravidel firmy | | `image_placeholder`, `image_data_uri` | chyba | nenahrazený zástupný obrázek, obrázek vložený jako `data:` | | `banned_host` | chyba | odkaz nebo obrázek na zakázaném hostiteli | | `html_too_large` | chyba | HTML nad 102 000 B | | `no_unsubscribe` | upozornění | chybí `{{unsubscribe}}`; Poštárna doplní standardní patičku | | `footer_incomplete` | upozornění | odhlášení není odkaz nebo chybí jméno odesílatele; doplní se patička | | `subject_long`, `img_without_alt`, `insecure_image`, `image_foreign_host`, `text_image_ratio` | upozornění | doporučení | > **Odhlašovací odkaz:** každý obchodní e-mail musí obsahovat odkaz na odhlášení. Když v obsahu `{{unsubscribe}}` chybí, Poštárna doplní standardní patičku s odkazem a identitou odesílatele sama. ## Zástupné značky | Značka | Hodnota | |---|---| | `{{df_name}}`, `{{df_surname}}` | křestní jméno, příjmení | | `{{df_salution}}` | oslovení v 5. pádě („Petře“) | | `{{df_emailaddress}}` | e-mail příjemce | | `{{df_titlesbefore}}`, `{{df_titlesafter}}`, `{{df_gender}}`, `{{df_birthday}}`, `{{df_nameday}}`, `{{df_language}}`, `{{df_company}}`, `{{df_street}}`, `{{df_town}}`, `{{df_postalcode}}`, `{{df_country}}`, `{{df_phone}}`, `{{df_cellphone}}`, `{{df_notes}}` | další pole kontaktu | | `{{df_id}}`, `{{df_created}}`, `{{df_updated}}`, `{{df_domain}}` | ID kontaktu, založení, poslední změna, doména adresy | | `{{cf_}}` | vlastní pole podle ID (víc hodnot oddělených čárkou) | | `{{cl_sendername}}`, `{{cl_senderemail}}` | jméno a e-mail odesílatele | | `{{cl_company}}`, `{{cl_address}}` | firma a adresa odesílajícího e-shopu | | `{{unsubscribe}}` (`{{unsubscribelink}}`) | odkaz na odhlášení jedním kliknutím | | `{{preferences}}` (`{{confirmlink}}`) | odkaz na nastavení odběru | | `{{webversion}}` (`{{webversionlink}}`, `{{forwardLink}}`) | webová verze e-mailu | | `{{coupon_}}` | nový kód ze zásobníku kupónů s tímto klíčem | **Náhrada prázdné hodnoty**: `{{df_name|default('zákazníku', true)}}`. Text náhrady má 1 až 40 znaků a nesmí obsahovat `' " \ { } < > | % &`. V testovacím e-mailu se dosadí jméno „Test“ a odkazy na odhlášení vedou na ukázkovou stránku, takže test nikoho neodhlásí. ## Skripty (Twig) Obsah smí obsahovat bezpečnou podmnožinu jazyka Twig, stejně jako SmartEmailing: `{% if %}`, `{% elseif %}`, `{% else %}`, `{% for %}` (i `loop`), `{% set %}`, komentáře `{# #}`, operátory `and`, `or`, `not`, `in`, `~`, `??`, `? :`, testy (`is defined`, `empty`, `null`, `even`, `odd`, `divisible by`), filtry (`abs`, `capitalize`, `date`, `default`, `first`, `join`, `json_encode`, `keys`, `last`, `length`, `lower`, `merge`, `number_format`, `replace`, `reverse`, `round`, `slice`, `sort`, `split`, `striptags`, `title`, `trim`, `upper`, `url_encode`) a funkce `date()`, `min()`, `max()`. Každá vypsaná hodnota se escapuje, filtr `raw` není. Data pro skripty: | Výraz | Co vrátí | |---|---| | `data.orders(filtr, řazení, limit)` | objednávky kontaktu v e-shopu e-mailu (nejvýš 200 nejnovějších); položky `items[]` | | `data.products({'item_id': kód}, řazení, limit)` | produkty produktových feedů e-shopu | | `data.articles(filtr, řazení, limit)` | články článkových feedů (nejvýš 25) | | `data.lists(filtr)` | seznamy kontaktu a jejich stavy | | `data.promoCode('')` | nový kód kupónu ze zásobníku s tímto **názvem** pro každý e-mail | | `data.promo.assigned('', od, do)` | kódy, které kontakt už dostal | | `data.terminate('')` | e-mail tomuto kontaktu neodešle (přeskočí se) | | `metadata.order` | objednávka, která spustila běh automatizace (jen v e-mailu automatizace) | | `metadata.event.attributes` | data události, která běh spustila (košík: `itemCount`, `total`, `currency`, `shopId`; vlastní událost: `name` a `data`; návštěva: `url`, `visitType`, `attributes`) | ```twig title="Ukázka skriptu v obsahu" {% set o = metadata.order %} {% if o %}

Děkujeme za objednávku {{ o.eshop_code }}.

    {% for item in o.items %}
  • {{ item.name }}
  • {% endfor %}
{% endif %}

Váš kód: {{ data.promoCode('Svátek') }}

``` • Kupón: `{{ data.promoCode('Svátek') }}` bere **název** zásobníku, `{{coupon_svatek}}` jeho **klíč** (`mergeKey`). Když zásobník dojde, e-mail neodejde a automatizace zaznamená selhání `customizationDataboxOutOfPromocodes`. • Skript, který nejde spustit, zastaví e-mail (`failed`); kontrola obsahu ho najde dřív jako `script_error`. • **Nepodporováno**: seznam položek košíku v e-mailu (v datech košíku je jen počet kusů a součet), obecné feedy (`data.generic.items` vrací prázdný seznam). ## Testovací e-mail • Jde jen na testovací adresy firmy (`GET /test-recipients`); jiná adresa = 400 `validation` / `to`. • `POST /campaigns/{id}/test` s `{"to"}`, `POST /templates/{id}/test` s `{"shopId", "to"}`. Předmět dostane předponu `[TEST] `, nic se neměří. • Nejvýš 10 testů jedné kampaně nebo šablony za 24 hodin (429 `rate_limited` / `test`). ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/campaigns/151/test" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/151/test" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "to": "test@example.cz" } JSON ``` ```json title="Odpověď: 200 OK" { "to": "test@example.cz", "sentAt": "2026-10-01T08:00:00.000Z" } ``` ## Patičky, odhlašovací stránky a další obsah • Patičky (`/footers`) a odhlašovací stránky (`/unsubscribe-pages`) mají výchozí položku firmy; šablona a uzel automatizace mohou mít vlastní. • Šablony skriptů (`/script-templates`), uložené prvky editoru (`/editor-elements`), správce souborů (`/files`, `/file-folders`), landing pages, dotazníky a šablony SMS mají vlastní skupiny v [referenci](https://www.postarna.cz/docs/api/reference-templates). --- # Kampaně Kampaň je jednorázová rozesílka (newsletter) jednoho e-shopu. **Nic neodejde z konceptu**: odeslání spustí jen schválení s potvrzeným počtem příjemců. ## Stavy | Akce | Ze stavu | Do stavu | |---|---|---| | `POST /campaigns/{id}/approve` se `sendAt` | `draft` | `scheduled` | | `POST /campaigns/{id}/approve` se `sendAt: null` | `draft` | `sending` | | nastal čas odeslání | `scheduled` | `sending` (nebo `paused` s `recipient_drift`, když se počet příjemců změnil o víc než 5 %) | | automatická pauza | `sending` | `paused` (`bounce_rate`, `complaint_rate`, `unsubscribe_rate`, `template_error`) | | `POST /campaigns/{id}/pause` | `scheduled`, `sending` | `paused` (`manual`) | | `POST /campaigns/{id}/resume` | `paused` | `sending`, nebo `scheduled`, když ještě nezačala | | `POST /campaigns/{id}/cancel` | `draft`, `scheduled`, `sending`, `paused` | `cancelled` | | odešel poslední e-mail | `sending` | `completed` | Jiný přechod = 409 `conflict` / `status`. Upravovat (`PATCH`, obsah) jde jen koncept. ## Koncept `POST /campaigns` založí koncept; povinné jsou jen `name` a `shopId`, zbytek doplníte později. • `senderId`: ověřený odesílatel e-shopu kampaně (`GET /senders`). • `fromName`, `subject` (do 200 znaků), `preheader`. • `audience`: komu kampaň jde (viz níže). • `trackOpens`, `trackClicks` (výchozí `true`), `utm` (`{source, medium, campaign, term?, content?}` nebo `null`), `linkParams`, `headers` (vlastní hlavičky `X-...`). • `templateId` je jen informace, odkud se obsah zkopíroval. Obsah kampaně uložíte přes `PUT /campaigns/{id}/content` (`{editor, html, design, baseVersion}`, u nové kampaně `baseVersion: 0`). ## Publikum ```json title="audience" {"listIds": ["42"], "segmentIds": [], "excludeListIds": [], "excludeInactive": true, "excludeEmails": [], "onlyWithPurpose": false, "purposeIds": []} ``` • `listIds`, `segmentIds`: seznamy e-shopu kampaně nebo celé firmy a segmenty e-shopu kampaně (nejvýš 100 ID v každém poli). • `excludeListIds`, `excludeEmails` (nejvýš 1 000 adres): vyloučení. • `excludeInactive`: vynechá kontakty s angažovaností E. • `onlyWithPurpose` a `purposeIds`: jen kontakty s platným souhlasem pro některý z účelů. `POST /campaigns/audience` spočítá příjemce a důvody vyloučení (každý kontakt má jeden důvod): `not_mailable` (odhlášený, nedoručitelný, stížnost, potlačený), `unconfirmed`, `weak_consent`, `exception_expired`, `no_purpose`, `excluded_list`, `excluded_manual`, `inactive`. Platí `recipients + součet excluded = matched`. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/campaigns/audience" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/audience" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "shopId": "17", "audience": { "listIds": [ "44" ], "segmentIds": [], "excludeListIds": [], "excludeInactive": true, "excludeEmails": [], "onlyWithPurpose": false, "purposeIds": [] } } JSON ``` ```json title="Odpověď: 200 OK" { "matched": 1, "recipients": 1, "excluded": { "not_mailable": 0, "unconfirmed": 0, "weak_consent": 0, "exception_expired": 0, "no_purpose": 0, "excluded_list": 0, "excluded_manual": 0, "inactive": 0 } } ``` ## Schválení (odeslání) `POST /campaigns/{id}/approve` s `{"sendAt", "expectedRecipients"}`: • `sendAt`: `null` = odeslat hned, jinak čas 5 minut až 365 dní dopředu (ISO 8601 se zónou). • `expectedRecipients`: počet příjemců, který jste právě spočítali a uživatel potvrdil. Když se skutečný počet liší o víc než 5 %, server vrátí 409 `conflict` / `recipients` s `params.expected` a `params.actual` a kampaň zůstane konceptem: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/campaigns/151/approve" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/151/approve" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "sendAt": "2026-10-02T07:00:00.000Z", "expectedRecipients": 250 } JSON ``` ```json title="Odpověď: 409 Conflict" { "error": { "code": "conflict", "message": "recipients", "params": { "expected": 250, "actual": 1 } } } ``` Kontroly v tomto pořadí: stav `draft`, `subject`, `fromName`, `senderId` (ověřený odesílatel téhož e-shopu), `content` (bez obsahu nejde odeslat), `lint` (chyba kontroly obsahu, `params.codes`), `audience` (aspoň jeden seznam nebo segment a aspoň jeden příjemce), `sendAt`, `expectedRecipients`. > **Pozor:** schválení posílá e-maily skutečným lidem a nejde vrátit. Integrace i AI agent mají před schválením ukázat člověku předmět, odesílatele, čas a počet příjemců a nechat si ho potvrdit. ## Co musí být nastavené, aby e-maily odešly • Ověřený odesílatel e-shopu (doména s SPF, DKIM a DMARC, Nastavení › Odesílání; přes API `/sending/...`). • Zapnuté odesílání firmy: `GET /sending-mode` vrací `sendingEnabled` (hlavní vypínač firmy, zapíná ho jen přihlášený člověk) a `sendingState` (schválení ostrého odesílání platformou). Dokud je vypnuté, naplánované kampaně čekají a automatizace nikoho nepustí; testovací e-maily chodí. • Denní limity a zahřívání nové domény rozloží velké rozesílky v čase. ## Statistiky {#statistiky} `GET /campaigns/{id}` vrací `stats` (`sent`, `delivered`, `opened`, `clicked`, `bounced`, `complained`, `unsubscribed`; unikátní kontakty, `delivered + bounced = sent`). Podrobně: `GET /stats/campaigns/{id}`, `/activity`, `/conversions`, `/recipients` (i CSV), `/heatmap` ve skupině [Statistiky](https://www.postarna.cz/docs/api/reference-statistics). Strojová otevření a kliky (skenery odkazů) se nepočítají. ## Jazykové varianty Kampaň může mít jazykové varianty pro kontakty s jiným jazykem (`/campaigns/{id}/variants`): náhled rozdělení (`/variants/preview`), schválení (`/variants/approve`), pauza, obnovení a zrušení celé skupiny. API klíčem jdou volat; AI asistent přes MCP skupinu variant neschválí (posílá ji jen člověk v aplikaci). --- # Automatizace Automatizace (scénář) je **graf**: uzly (spouštěče, operátory, akce) spojené hranami. Kontakt do scénáře vstoupí spouštěčem, prochází uzly po hranách a scénář opustí na uzlu Konec, na výstupu bez hrany nebo splněním cíle. Každý průchod jednoho kontaktu je **běh** (`run`). Přesná schémata všech uzlů, událostí, podmínek a časových údajů: [Reference automatizací](https://www.postarna.cz/docs/api/automation-reference). Hotové scénáře: [recepty](https://www.postarna.cz/docs/api/recipe-abandoned-cart). ## Graf ```json title="AutomationGraph" { "nodes": [ {"id": "kosik", "type": "trigger_event", "name": "Změna košíku", "config": {"event": "cart_updated", "reentry": "restart"}}, {"id": "pockat", "type": "wait", "config": {"mode": "duration", "value": 2, "unit": "hours"}}, {"id": "stale-v-kosiku", "type": "condition", "config": {"definition": {"type": "group", "match": "all", "rules": [ {"type": "cart_items_count", "operator": "gt", "value": 0}, {"type": "ordered_since_entry", "operator": "no"}]}}}, {"id": "email", "type": "send_email", "config": {"templateId": "301"}} ], "edges": [ {"source": "kosik", "target": "pockat", "branch": "next"}, {"source": "pockat", "target": "stale-v-kosiku", "branch": "next"}, {"source": "stale-v-kosiku", "target": "email", "branch": "yes"} ] } ``` • `id` uzlu je **klíč**, který si zvolíte: písmena, číslice, `-` a `_`, nejvýš 40 znaků, v grafu jedinečný. Při dalších uloženích ho nechte stejný: běhy, historie a e-maily se na uzel odkazují klíčem. • `type` vybírá druh uzlu, `config` jeho nastavení. Neznámé klíče v `config` server při uložení zahodí. Volitelně `name` (do 100 znaků), `note` (do 1 000) a `position` `{x, y}` pro plátno v aplikaci. • Hrana vede z **výstupu** (`branch`) zdroje do cíle: `next` (jediný výstup), `yes` / `no` (podmínka), `v1` až `v10` (A/B test). Každý výstup má nejvýš jednu hranu; výstup bez hrany = kontakt scénář opustí. • Graf nesmí mít cyklus (ani přes uzel `goto`), do spouštěče a cíle nevede hrana. Scénář smí mít **víc spouštěčů**. Nejvýš 300 uzlů a 600 hran. • Automatizace patří jednomu e-shopu (odesílatel, patička, objednávky spouštěčů); e-shop se po založení nemění. ## Druhy uzlů | Skupina | Typy | |---|---| | Spouštěče | `trigger_event` (událost), `trigger_date` (svátek, narozeniny, datum, svátky v roce, první objednávka), `trigger_reorder` (kupte si znovu), `trigger_repeat` (opakovaně), `trigger_scheduled` (jednou v čase), `trigger_now` (jednou při zapnutí) | | Operátory | `condition` (ano / ne), `wait` (čekání), `ab_test`, `holding` (odkladiště), `goal` (cíl scénáře) | | Akce | `send_email`, `list_change`, `set_field`, `webhook`, `fire_event`, `notify`, `reset`, `goto`, `end` | | Zatím nedostupné | `send_sms`, `send_viber`, `whatsapp`, `fb_audience`, `sklik_retargeting`, `motionlab_adina` (uložit nejdou, chyba `unavailable`) | ### Spouštěč při události (`trigger_event`) `config.event` vybírá událost; některé mají vlastní nastavení: | Událost | Kdy | Nastavení | |---|---|---| | `order_created` | nová objednávka | `shopId` | | `order_completed` | objednávka dokončena (zaplacena, odeslána, doručena) | `shopId` | | `order_changed` | objednávka změnila stav | `shopId`, `state` | | `cart_updated` | změna košíku (`POST /contact-events` typ `cart`) | `shopId` | | `page_visit` | návštěva stránky (`POST /contact-events` typ `visit`) | `shopId`, `url`, `urlOperator`, `visitType` | | `custom` | vlastní událost (`POST /contact-events` typ `custom`, nebo uzel `fire_event` jiného scénáře) | `customEvent` | | `subscribed` | kontakt se přihlásil k odběru | `sources` | | `contact_created` | nový kontakt | | | `contact_updated` | změna pole kontaktu | `fieldFilter` | | `list_added` | přidání do seznamu | `listId` | | `list_status_changed` | změna stavu v seznamu | `listId`, `status` | | `form_submitted` | odeslaný a potvrzený formulář | `formId` | | `email_sent`, `link_clicked` | e-mail nebo klik z uzlu **jiného** scénáře | `emailNode`, `link`, `compareParams` | | `engagement_changed` | změna angažovanosti | | | `blacklisted` | kontakt na blacklistu | | | `action_failed` | selhala akce automatizace | `failureType`, `failureNode` | | `manual` | ručně přidané kontakty (`POST /automations/{id}/contacts`) | | Počítají se jen události **po zapnutí** automatizace. Co zapsal hromadný zápis (import, synchronizace e-shopu), automatizace nespustí, pokud import výslovně nepovolí `runAutomations: true`. Objednávka zapsaná přes `POST /orders` spouštěče objednávek spouští. ### Opakovaný vstup (`reentry`) Každý spouštěč má `reentry`: • `parallel`: kontakt smí mít ve scénáři víc běhů současně (nejvýš 10); výchozí pro nové spouštěče. • `restart`: nový vstup ukončí rozběhnutý běh (typicky košík). • `skip`: dokud běh kontaktu trvá, znovu nevstoupí. • `once`: jednou provždy. ## Jazyk podmínek Uzel `condition`, cíl (`goal`) a filtr časových spouštěčů (`filter`) mají **definici**: stejný strom jako [segment](https://www.postarna.cz/docs/api/lists-and-segments#segmenty), jehož pravidla smí být i podmínky automatizace. ```json title="definition" {"type": "group", "match": "all", "rules": [ {"type": "contact_in_list", "listId": "41", "state": "confirmed"}, {"type": "orders_total_value", "operator": "gte", "value": "3000", "currency": "CZK", "period": {"from": {"variant": "interval", "sign": "-", "value": 1, "unit": "years"}, "to": null}}, {"type": "email_activity", "operator": "opened", "nodeId": "email-1", "negate": true} ]} ``` • `match`: `all` (a zároveň) nebo `any` (nebo). Skupiny lze vnořovat (nejvýš 8 úrovní, 50 pravidel). • Každé pravidlo smí mít `"negate": true` (neplatí, že). • Pravidla s obdobím mají `period` `{from, to}`; strany jsou [časové údaje](https://www.postarna.cz/docs/api/automation-reference#casove-udaje) relativní k teď, `null` = bez omezení. • Podmínky automatizací (37 podle SmartEmailingu a vlastní): kontakt v seznamu, v automatizaci, pole kontaktu, výročí (narozeniny, svátek), odeslané a otevřené e-maily, počet a hodnota objednávek, objednaný produkt nebo atribut, košík, den v měsíci a týdnu, hodina, kupón, skript, kliky, návštěvy, feed, vítěz A/B testu, angažovanost. • Pravidla, která čtou běh (`email_activity`, `passed_node`, `ordered_since_entry`, `event_attribute`, `script`), nejde použít ve filtru spouštěče (běh tam ještě není). • Hodnoty podmínek automatizací smí být čísla (`"value": 0`) i řetězce číslic; pravidla segmentu mají hodnoty jako řetězce. Přesná pole každého pravidla: [Reference automatizací](https://www.postarna.cz/docs/api/automation-reference#podminky-automatizaci). ### Podmínka s čekáním na splnění `condition.config.waitUntilMet` `{"value": 3, "unit": "days"}`: kontakt v uzlu čeká, dokud podmínka neplatí (pak výstup `yes`), nejdéle po zadanou dobu (pak `no`). Kontrola běží každých 20 minut až jednou denně podle délky čekání. ## Čekání a čas Uzel `wait` má `mode`: | `mode` | Čeká | |---|---| | `duration` | `value` jednotek `unit` (minuty až roky) | | `time_of_day` | na nejbližší `time` (`"09:00"`) | | `weekday` | na nejbližší den z `weekdays` (1 = pondělí) v čase `time` | | `date` | na místní datum a čas `date` (`"2026-12-24T09:00"`) | | `time` | na časový údaj `spec` (`countFrom` `node` = od příchodu do uzlu, `scenario` = od vstupu do scénáře) | | `preferred` | na obvyklou dobu, kdy kontakt otevírá e-maily (bez historie nečeká) | | `spread` | rozloží kontakty rovnoměrně do období `spread` | Nejdelší čekání je 10 let. Časové údaje (`spec`, `period`) mají tři varianty: `calendar` (konkrétní den), `interval` (posun o jednotky), `event` (pojmenovaný den: zítra, příští pondělí, příští pracovní den, poslední den měsíce). Náhled přesného okamžiku: `POST /automations/resolve-time`. ## Životní cyklus | Stav | Význam | |---|---| | `draft` | koncept, nikdy nespuštěný | | `active` | běží | | `paused` | zastavený po běhu (ručně, nebo automaticky při vysokém podílu nedoručitelných, stížností či odhlášení, nebo při chybě šablony; `pausedReason`) | • `POST /automations` založí koncept (verze 1); graf můžete poslat rovnou, nebo později přes `PUT /automations/{id}/graph`. • `POST /automations/{id}/activate` zapne: `draft` nebo `paused` → `active`. Když něco chybí, vrátí 400 `validation` / `graph` s `params.issues` (viz níže). Zapnutí posílá e-maily skutečným lidem. • `POST /automations/{id}/pause` zastaví; čekající kontakty zůstanou na místě a po dalším zapnutí pokračují. • `DELETE /automations/{id}` smaže jen scénář, do kterého nikdo nevstoupil (jinak 409 `runs`). • `POST /automations/{id}/copy` vytvoří koncept „ - kopie“ (bez hesel webhooků). ## Validace a problémy grafu {#validace-a-problemy-grafu} Problémy mají tvar `{"node": "" | null, "field": "", "code": ""}` a dvě úrovně: • **Chyby** (`errors`): graf nejde uložit (400 `validation` / `graph` s `params.issues`). Kódy: `invalid`, `unavailable` (typ uzlu), `duplicate`, `node` (hrana k neexistujícímu uzlu), `cycle`, `self_trigger` (scénář by spouštěl sám sebe). • **Neúplné nastavení** (`incomplete`): graf se uloží, ale nejde zapnout ani otestovat. Kódy: `required`, `invalid`, `unavailable` (událost nebo podmínka), `not_found`, `locked` (seznam napojený na e-shop), `empty` (šablona bez obsahu), `lint` (chyba kontroly obsahu šablony), `unverified` (neověřený odesílatel), `unreachable` (uzel, kam žádný spouštěč nedojde), `too_short`, `too_long`, `not_whitelisted`, `reserved`. Bez spouštěče: `{"node": null, "field": "trigger", "code": "required"}`. `POST /automations/validate` s `{shopId, graph}` zkontroluje graf bez uložení: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/validate" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/validate" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "shopId": "1", "graph": { "nodes": [ { "id": "kosik", "type": "trigger_event", "config": { "event": "cart_updated", "shopId": "1", "reentry": "restart" } }, { "id": "pockat", "type": "wait", "config": { "mode": "duration", "value": 2, "unit": "hours" } }, { "id": "email", "type": "send_email", "config": {} } ], "edges": [ { "source": "kosik", "target": "pockat" }, { "source": "pockat", "target": "email" } ] } } JSON ``` ```json title="Odpověď: 200 OK" { "errors": [], "incomplete": [ { "node": "email", "field": "templateId", "code": "required" } ] } ``` Detail automatizace (`GET /automations/{id}`) vrací v `issues` vše, co brání zapnutí. ## Uložení grafu a verze `PUT /automations/{id}/graph` s `{"baseVersion", "graph"}` vrátí detail s verzí + 1. • Jiná verze na serveru = 409 `conflict` / `version` s `params.current`. • **Běžící scénář** (`active`) se uloží jen s `"confirmRunning": true` a jen bez jakéhokoli problému; jinak 409 `conflict` / `confirm`. Změny platí pro další krok každého kontaktu. • Odstranit nebo změnit typ uzlu, ve kterém kontakty čekají, nejde: 409 `conflict` / `waiting` s `params.nodes` (nejdřív je uvolněte: `POST /automations/{id}/nodes/{klíč}/release`). • Změna spouštěče začne jeho plán znovu; nová hrana z odkladiště pustí čekající kontakty dál. • Každé uložení je verze: `GET /automations/{id}/versions`, `GET /automations/{id}/versions/{verze}`. ```bash title="Požadavek: PUT /api/v1/tenants/{tenant}/automations/81/graph" curl -sS -X PUT "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/81/graph" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "baseVersion": 1, "graph": { "nodes": [], "edges": [] } } JSON ``` ```json title="Odpověď: 409 Conflict" { "error": { "code": "conflict", "message": "confirm" } } ``` ## Testování a sledování • `POST /automations/{id}/test`: zkušební průchod nad dnešními daty, **nic se neuloží ani neodešle**. Vrátí, kolik kontaktů by vstoupilo a kolik by došlo do každého uzlu a výstupu. Volitelně `graph` (neuložený graf z editoru) a `days` (1 až 90, okno přehrání událostí). • `POST /automations/{id}/trace` s `{"contactId" | "email"}`: průchod jednoho kontaktu krok za krokem s důvody (smí vstoupit, kudy půjde, kde skončí). Nic se neodešle. • `GET /automations/{id}/counts`: živé počty po uzlech a výstupech včetně čekajících. • `GET /automations/{id}/runs?contactId=`: historie běhů kontaktu. • `GET /automations/{id}/nodes/{klíč}/passes`: kdo prošel uzlem. • `GET /automations/{id}/report?from=&to=` (i `format=csv`): statistiky e-mailových uzlů a volání webhooků. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/83/test" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/83/test" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' {} JSON ``` ```json title="Odpověď: 200 OK" { "scope": "today", "days": null, "since": null, "entered": 0, "waiting": 0, "left": 0, "nodes": { "svatek": { "reached": 0, "waiting": 0, "left": 0, "outputs": { "next": 0 } }, "prani": { "reached": 0, "waiting": 0, "left": 0, "outputs": { "next": 0 } } }, "testedAt": "2026-10-01T08:00:00.000Z" } ``` ## Kdo vstoupí a kdy odejde e-mail • Vstupují jen kontakty, kterým lze psát (přihlášené, bez potlačení a slabého souhlasu, v lhůtě zákaznické výjimky) z e-shopu automatizace. • E-mail uzlu odejde jednomu kontaktu nejvýš jednou za 24 hodin (nastavení firmy) a jen se zapnutým odesíláním firmy, v denním limitu. Před odesláním se stav kontaktu kontroluje znovu; e-mail starší 48 hodin ve frontě neodejde. • Scénář, který by spouštěl sám sebe, nejde uložit (`self_trigger`); řetěz scénářů (událost jednoho spouští druhý) končí po 3 krocích. • Běh spuštěný objednávkou skončí, když se objednávka zruší, vrátí nebo smaže. ## Události z vašeho systému `POST /contact-events` zapíše událost existujícího kontaktu (podle `contactId` nebo `email`; nikdy kontakt nezaloží): • `{"type": "custom", "name": "vip-dosazeno", "data": {...}}`: vlastní událost pro spouštěč `custom` (název a-z, 0-9 a `-`, nejvýš 50 znaků, ne `se-`). • `{"type": "cart", "shopId", "items": [{code, name, quantity, price, url}], "currency", "total"}`: aktuální stav košíku (prázdné `items` = košík vyprázdněn) pro `cart_updated` a podmínku `cart_items_count`. • `{"type": "visit", "shopId", "url", "visitType", "attributes"}`: návštěva stránky pro `page_visit`. Nejvýš 60 událostí jednoho kontaktu za 10 minut (429 `rate_limited`). Ukázka v [receptu opuštěného košíku](https://www.postarna.cz/docs/api/recipe-abandoned-cart). ## Transakční automatizace (smluvní e-maily) Pro e-maily k uzavřené smlouvě, například upomínky splatnosti faktur. Režim zapnete polem `"transactional": true` při `POST /automations` nebo `PATCH /automations/{id}` (stejné oprávnění jako úprava automatizací); přepnout jde jen scénář, který neběží (jinak 409 `conflict` / `status`). • Spouštěč smí být jen vlastní událost (`trigger_event` s `event: "custom"`) a uzly jen `send_email`, `wait`, `condition` a `end`. Jiný graf vrátí 400 `validation` / `transactional` (při přepnutí) nebo `graph` (při uložení) s `params.issues` a kódy `transactional_node`, `transactional_trigger`. • E-mail dostane každý existující kontakt bez ohledu na souhlas s newsletterem nebo odhlášení z něj. Tvrdý odraz, stížnost, neplatná adresa, limit měkkých odrazů a blacklist ho zastaví vždy, při vstupu i těsně před odesláním. • E-mail nemá odkaz na odhlášení, hlavičku `List-Unsubscribe` ani patičku newsletteru. Šablona proto nepotřebuje `{{unsubscribe}}` a nesmí ho mít (ani `{{gf_footer}}`, odkaz na nastavení odběru nebo kupón; kód problému `transactional_content`). Otevření a prokliky se měří jako obvykle. • Scénář patří e-shopu události: `shopId` u `POST /contact-events` určuje, která automatizace se spustí (bez něj se použije hlavní e-shop kontaktu). Limit jednoho e-mailu uzlu za 24 hodin neplatí (dvě faktury jedné firmy se stejnou splatností dostanou dva e-maily); opakování hlídá váš systém. • Předmět e-mailu je prostý text bez skriptů: data události v něm čtou značky `{{metadata.event.attributes.data.}}` (jen jednoduché hodnoty), například `Faktura {{metadata.event.attributes.data.invoiceNumber}}`. • Platební QR kód: značka `{{payment_qr}}` vloží obrázek QR platby z `data.spayd` události (řetězec SPAYD 1.0 s účtem `ACC`), například `{% set d = metadata.event.attributes.data %}{% if d.spayd %}{{payment_qr}}{% endif %}`. Obrázek je podepsaný odkaz `/m/r/.png` na doméně odkazů, takže ho ukáže i Gmail a Outlook; bez platného řetězce se nevloží nic. • Právní poznámka (není právní stanovisko): upomínka k vystavené faktuře není obchodní sdělení (zákon 480/2004 Sb., na Slovensku zákon 452/2021 Z. z.), právním základem je plnění smlouvy. E-mail proto nesmí obsahovat marketing (nabídky zboží, kupóny, bannery). --- # Reference automatizací Vše na této stránce se generuje z kódu validátoru Poštárny a testy ověřují, že každý příklad validátor přijme, že bez povinného pole automatizace nejde zapnout a že výčtové hodnoty odpovídají validátoru. Stejná schémata jsou v [OpenAPI](https://www.postarna.cz/api/openapi.json?tag=Automations) jako `AutomationNode_`, `ConditionRule_`, `SegmentRule_` a `TimeSpec`. Technické popisy polí jsou anglicky, stejně jako v OpenAPI. ## Uzly Každý uzel: `{"id": "", "type": "", "name"?, "note"?, "position"?, "config": {...}}`. Pole se sloupcem „Povinné“ = ano musí být vyplněná, jinak automatizace nejde zapnout ani otestovat (graf se ale uloží, viz [validace](https://www.postarna.cz/docs/api/automations#validace-a-problemy-grafu)). Další pole bývají povinná jen u některých hodnot (například `listId` u události `list_added`); popis to uvádí. ### Spouštěče #### `trigger_now` {#node-trigger-now} Starts once, right at the activation, with the contacts of the shop matching the filter (SmartEmailing "Hned teď"). **Výstupy:** `next` · SmartEmailing: `run` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `filter` | `ConditionGroup` or null | ne | Who may enter: a condition tree (segment rules and automation conditions except the run only ones). null or left out = every mailable contact of the shop. | | `reentry` | one of: `parallel`, `restart`, `skip`, `once` | ne | What happens when a contact meets the trigger again: parallel (one more run, at most the company's limit of parallel runs; default for new triggers), restart (the new entry ends the running one), skip (nobody enters while their run is active; default of triggers saved without the setting), once (one run per contact for ever). | ```json { "id": "trigger-now-1", "type": "trigger_now", "config": { "reentry": "once" } } ``` #### `trigger_scheduled` {#node-trigger-scheduled} Starts once at a local date and time (SmartEmailing "V plánovaný čas"). **Výstupy:** `next` · **Povinné pro zapnutí:** `at` · SmartEmailing: `scheduled-time` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `at` | string | ano | YYYY-MM-DDTHH:MM, local time of the company. pattern `^[0-9]{4}-[0-9]{2}-[0-9]{2}T([01][0-9]\|2[0-3]):[0-5][0-9]$` | | `filter` | `ConditionGroup` or null | ne | Who may enter: a condition tree (segment rules and automation conditions except the run only ones). null or left out = every mailable contact of the shop. | | `reentry` | one of: `parallel`, `restart`, `skip`, `once` | ne | What happens when a contact meets the trigger again: parallel (one more run, at most the company's limit of parallel runs; default for new triggers), restart (the new entry ends the running one), skip (nobody enters while their run is active; default of triggers saved without the setting), once (one run per contact for ever). | ```json { "id": "trigger-scheduled-1", "type": "trigger_scheduled", "config": { "at": "2026-12-01T09:00", "reentry": "once" } } ``` #### `trigger_repeat` {#node-trigger-repeat} Starts repeatedly every `every` from startAt (default the activation) until stopAt, with the contacts matching the filter (SmartEmailing "Opakovat"). **Výstupy:** `next` · **Povinné pro zapnutí:** `every` · SmartEmailing: `repeat` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `every` | object | ano | Interval, at least 15 minutes, at most 10 years. | | `startAt` | string | ne | YYYY-MM-DDTHH:MM (local). pattern `^[0-9]{4}-[0-9]{2}-[0-9]{2}T([01][0-9]\|2[0-3]):[0-5][0-9]$` | | `stopAt` | string | ne | YYYY-MM-DDTHH:MM (local), after startAt. pattern `^[0-9]{4}-[0-9]{2}-[0-9]{2}T([01][0-9]\|2[0-3]):[0-5][0-9]$` | | `filter` | `ConditionGroup` or null | ne | Who may enter: a condition tree (segment rules and automation conditions except the run only ones). null or left out = every mailable contact of the shop. | | `reentry` | one of: `parallel`, `restart`, `skip`, `once` | ne | What happens when a contact meets the trigger again: parallel (one more run, at most the company's limit of parallel runs; default for new triggers), restart (the new entry ends the running one), skip (nobody enters while their run is active; default of triggers saved without the setting), once (one run per contact for ever). | ```json { "id": "trigger-repeat-1", "type": "trigger_repeat", "config": { "every": { "value": 1, "unit": "days" }, "startAt": "2026-11-01T08:00", "reentry": "parallel", "filter": { "type": "group", "match": "all", "rules": [ { "type": "contact_anniversary", "field": "nameDay", "relation": "now" } ] } } } ``` #### `trigger_event` {#node-trigger-event} Starts when an event happens to a contact (SmartEmailing "Při události"). Only events after the activation count. Event specific settings: `cart_updated`: The contact's cart changed (POST /contact-events type cart). shopId narrows the shop. `contact_created`: A new contact of the automation's shop. `order_created`: A new order (shopId: shop of the order, default the automation's shop). `order_changed`: An order changed state (state narrows to one state). `list_added`: The contact was added to listId. `contact_updated`: A profile field changed (fieldFilter narrows to one field and its values before / after). `action_failed`: An action of an automation failed (failureType, failureNode narrow it). `list_status_changed`: The contact's state in listId changed to status. `email_sent`: An e-mail of emailNode (a send_email node of ANOTHER automation) was sent. `page_visit`: A web tracking visit (POST /contact-events type visit): url, urlOperator, visitType. `link_clicked`: The contact clicked a link (link, compareParams) in an e-mail of emailNode (another automation). `engagement_changed`: The contact's engagement level changed. `custom`: A custom event named customEvent (POST /contact-events type custom, or a fire_event node of another automation). `form_submitted`: A form was submitted and confirmed (formId narrows to one form). `blacklisted`: The contact was blacklisted. `order_completed`: An order was completed (paid, shipped or delivered). `subscribed`: The contact subscribed (sources narrows the source; imports only when listed). `manual`: Contacts added by hand: POST /automations/{id}/contacts. **Výstupy:** `next` · **Povinné pro zapnutí:** `event` · SmartEmailing: `on-event` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `event` | one of: `cart_updated`, `contact_created`, `order_created`, `order_changed`, `list_added`, `contact_updated`, `score_changed`, `action_failed`, `list_status_changed`, `automation_saved`, `email_sent`, `sms_sent`, `page_visit`, `motionlab_rendered`, `link_clicked`, `engagement_changed`, `custom`, `form_submitted`, `blacklisted`, `order_completed`, `subscribed`, `manual` | ano | The event. Not available yet: score_changed (scoring), automation_saved (unverified), sms_sent (sms), motionlab_rendered (motionlab). | | `shopId` | string | ne | Orders, carts, visits: shop (default the automation's). | | `listId` | string | ne | list_added, list_status_changed: list id. | | `sources` | array of one of: `erp_order`, `signup_form`, `import`, `api`, `manual`, `shoptet`, `smartemailing` | ne | subscribed: sources (default erp_order, signup_form, api, manual). min 1 items | | `state` | one of: `new`, `unpaid`, `paid`, `processing`, `shipped`, `pickup`, `delivered`, `cancelled`, `returned`, `other` | ne | order_changed: the new order state. | | `status` | one of: `confirmed`, `unsubscribed`, `removed` | ne | list_status_changed: the new state. | | `fieldFilter` | object | ne | contact_updated: one field and optionally its values before and after. Operators by field kind: text: any, eq, empty, filled, contains, starts; date: any, on_day, newer, until, older, from, filled, empty; number: any, gt, gte, lt, lte, filled, empty; choice: any, eq_option, filled, empty; multi: any, has_option, filled, empty; checkbox: any, checked, unchecked. Fields: affiliateId, language, firstName, mobile, city, birthday, vocativeFirstName, salutation, salutationFormal, vocativeLastName, gender, note, lastName, postalCode, company, nameDay, phone, titleBefore, titleAfter, street, country or cf:. | | `failureType` | one of: `customizationDataboxTerminate`, `customizationDataboxOutOfPromocodes`, `customizationSyntaxError`, `contactSetFieldFail`, `smsRateLimitReached`, `sklikError`, `other` | ne | action_failed: type. | | `failureNode` | object | ne | action_failed: the node (automationId null = this graph). | | `emailNode` | object | ne | An e-mail node: automationId null (or left out) = a send_email node of this graph, else the id of another automation of the company and its node key. | | `link` | string | ne | link_clicked: the URL (at most 2 000); empty = any link. | | `compareParams` | boolean | ne | link_clicked: compare query parameters, default true. | | `url` | string | ne | page_visit: URL (at most 2 000). | | `urlOperator` | one of: `eq`, `starts` | ne | page_visit: eq (default) or starts. | | `visitType` | one of: `home`, `article`, `cart`, `product`, `category`, `search`, `order_done`, `other` | ne | page_visit: type of page. | | `customEvent` | string | ne | custom: event name, a-z, 0-9 and - (1 to 50), not starting with se-. pattern `^[a-z0-9-]{1,50}$` | | `formId` | string | ne | form_submitted: form id (empty = any form). | | `reentry` | one of: `parallel`, `restart`, `skip`, `once` | ne | What happens when a contact meets the trigger again: parallel (one more run, at most the company's limit of parallel runs; default for new triggers), restart (the new entry ends the running one), skip (nobody enters while their run is active; default of triggers saved without the setting), once (one run per contact for ever). | ```json { "id": "trigger-event-1", "type": "trigger_event", "config": { "event": "cart_updated", "shopId": "1", "reentry": "restart" } } ``` #### `trigger_date` {#node-trigger-date} Starts once a day at `at` for contacts whose date is today: name day, birthday, a date custom field (shifted by offsetDays), fixed holidays (every contact of the shop), or the first completed order exactly `days` ago. **Výstupy:** `next` · **Povinné pro zapnutí:** `kind`, `at` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `kind` | one of: `name_day`, `birthday`, `first_order`, `custom_date`, `holiday` | ano | Kind of date. | | `days` | integer | ne | first_order: days after the first order, 1 to 3 650. min 1, max 3650 | | `field` | string | ne | custom_date: cf: of a date custom field. | | `dates` | array of string | ne | holiday: days of the year MM-DD (at most 366, unique). min 1 items, max 366 items | | `offsetDays` | integer | ne | name_day, birthday, custom_date: shift -365 to 365 (e.g. -3 = three days before). min -365, max 365 | | `at` | string | ano | HH:MM local time of the daily pass. pattern `^([01][0-9]\|2[0-3]):[0-5][0-9]$` | | `reentry` | one of: `parallel`, `restart`, `skip`, `once` | ne | What happens when a contact meets the trigger again: parallel (one more run, at most the company's limit of parallel runs; default for new triggers), restart (the new entry ends the running one), skip (nobody enters while their run is active; default of triggers saved without the setting), once (one run per contact for ever). | ```json { "id": "trigger-date-1", "type": "trigger_date", "config": { "kind": "name_day", "at": "08:00", "reentry": "parallel" } } ``` #### `trigger_reorder` {#node-trigger-reorder} Starts once a day at `at` for customers whose last completed order is older than their usual interval between orders ("buy again"): the average gap of their order days, defaultDays with one order day, clamped to minDays..maxDays, plus graceDays. **Výstupy:** `next` · **Povinné pro zapnutí:** `at` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `at` | string | ano | HH:MM. pattern `^([01][0-9]\|2[0-3]):[0-5][0-9]$` | | `defaultDays` | integer | ne | 1 to 365, default 30. default `30`, min 1, max 365 | | `minDays` | integer | ne | 1 to 365, default 14. default `14`, min 1, max 365 | | `maxDays` | integer | ne | 1 to 365 and >= minDays, default 120. default `120`, min 1, max 365 | | `graceDays` | integer | ne | 0 to 365, default 0. default `0`, min 0, max 365 | | `reentry` | one of: `parallel`, `restart`, `skip`, `once` | ne | What happens when a contact meets the trigger again: parallel (one more run, at most the company's limit of parallel runs; default for new triggers), restart (the new entry ends the running one), skip (nobody enters while their run is active; default of triggers saved without the setting), once (one run per contact for ever). | ```json { "id": "trigger-reorder-1", "type": "trigger_reorder", "config": { "at": "10:00", "defaultDays": 30, "minDays": 14, "maxDays": 120, "graceDays": 3, "reentry": "parallel" } } ``` ### Operátory #### `condition` {#node-condition} Splits the run: output yes when the definition holds, else no. With waitUntilMet the contact waits until it holds (then yes) or the time runs out (then no); checked every 20 minutes to once a day. **Výstupy:** `yes`, `no` · **Povinné pro zapnutí:** `definition` · SmartEmailing: `condition` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `definition` | `ConditionGroup` | ano | | | `waitUntilMet` | object | ne | Wait for the definition up to this long (15 minutes to 10 years). | | `waitUpTo` | object | ne | Older form of waitUntilMet (hours or days, at most 30 days). | ```json { "id": "condition-1", "type": "condition", "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "email_activity", "operator": "opened", "nodeId": null } ] } } } ``` #### `wait` {#node-wait} Waits. mode time: until the time spec (relative to the arrival at the node, or to the entry with countFrom scenario); preferred: until the contact's usual reading time (most frequent quarter hour of opens, else no wait); spread: releases the contacts evenly over the period; duration: value units; time_of_day: the next HH:MM; weekday: the next listed weekday at time; date: a local date and time. At most 10 years. **Výstupy:** `next` · **Povinné pro zapnutí:** `mode` · SmartEmailing: `wait` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `mode` | one of: `time`, `preferred`, `spread`, `duration`, `time_of_day`, `weekday`, `date` | ano | Mode. | | `spec` | `TimeSpec` | ne | | | `countFrom` | one of: `node`, `scenario` | ne | time: node (default) or scenario. | | `spread` | object | ne | spread: period over which contacts are released. | | `value` | integer | ne | duration: 1 to 100 000. min 1, max 100000 | | `unit` | one of: `minutes`, `hours`, `days`, `weeks`, `months`, `years` | ne | duration: unit. | | `time` | string | ne | time_of_day, weekday: HH:MM. pattern `^([01][0-9]\|2[0-3]):[0-5][0-9]$` | | `weekdays` | array of integer | ne | weekday: 1 (Monday) to 7, unique. min 1 items | | `date` | string | ne | date: YYYY-MM-DDTHH:MM local. pattern `^[0-9]{4}-[0-9]{2}-[0-9]{2}T([01][0-9]\|2[0-3]):[0-5][0-9]$` | ```json { "id": "wait-1", "type": "wait", "config": { "mode": "duration", "value": 2, "unit": "days" } } ``` #### `ab_test` {#node-ab-test} Splits contacts randomly (stable per run) into 2 to 10 variants; outputs v1..vN. **Výstupy:** `v1`, `...`, `v10` · **Povinné pro zapnutí:** `variants` · SmartEmailing: `ab` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `variants` | array of object | ano | 2 to 10 variants {key: "v1".."vN" in order, share 1..99}, shares sum to 100. min 2 items, max 10 items | ```json { "id": "ab-test-1", "type": "ab_test", "config": { "variants": [ { "key": "v1", "share": 50 }, { "key": "v2", "share": 50 } ] } } ``` #### `holding` {#node-holding} Storage (Odkladiště): contacts wait here until an edge out of the node is added (then they continue) or 90 days pass. **Výstupy:** `next` · SmartEmailing: `storage` Bez nastavení. ```json { "id": "holding-1", "type": "holding", "config": {} } ``` #### `goal` {#node-goal} Goal of the scenario: before every step the goals are checked; a contact who meets one leaves the scenario wherever it is. No edges in or out. **Výstupy:** - · **Povinné pro zapnutí:** `definition` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `definition` | `ConditionGroup` | ano | | ```json { "id": "goal-1", "type": "goal", "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "operator": "yes", "shopId": null } ] } } } ``` ### Akce #### `send_email` {#node-send-email} Sends an e-mail from a template (once per node and contact within the company's window). Only to mailable contacts, rechecked right before sending. **Výstupy:** `next` · **Povinné pro zapnutí:** `templateId` · SmartEmailing: `send-email` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `templateId` | string | ano | Template with content (GET /templates). Required. | | `templateRef` | string | ne | Information only (definition files). | | `subject` | string | ne | Subject, at most 200 characters; default the template's. | | `preheader` | string | ne | Preheader, at most 300; default the template's. | | `senderId` | string | ne | Sender of the automation's shop (GET /senders); default the shop's default sender. Must be verified to activate. | | `senderName` | string | ne | Sender name, at most 100. | | `replyTo` | string | ne | Reply-To e-mail address. | | `trackOpens` | boolean | ne | Default true. | | `trackClicks` | boolean | ne | Default true. | | `trackingParams` | object | ne | UTM parameters added to links. | | `headers` | object | ne | Own e-mail headers. | | `unsubscribePageId` | string | ne | Own unsubscribe page of this node (GET /unsubscribe-pages). | | `controlAddress` | string | ne | Send every e-mail of this node only to this test address of the company (GET /test-recipients) instead of the contact; for checking a live scenario. | ```json { "id": "send-email-1", "type": "send_email", "config": { "templateId": "301", "subject": "Zapomněli jste něco v košíku", "trackOpens": true, "trackClicks": true } } ``` #### `list_change` {#node-list-change} Sets the contact's state in manual lists (confirmed adds, unsubscribed and removed take out). Lists bound to an e-shop cannot be changed. **Výstupy:** `next` · **Povinné pro zapnutí:** `status`, `listIds` · SmartEmailing: `add-to-list` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `status` | one of: `confirmed`, `unsubscribed`, `removed` | ano | New state. | | `action` | one of: `add`, `remove` | ne | Older form: add = confirmed, remove = removed. | | `listIds` | array of string | ano | 1 to 20 manual or form list ids, unique. min 1 items, max 20 items | | `listRefs` | array of string | ne | Information only. | ```json { "id": "list-change-1", "type": "list_change", "config": { "status": "confirmed", "listIds": [ "101" ] } } ``` #### `webhook` {#node-webhook} Calls a URL (queued, retried 5 times 5 minutes apart on a non-2xx answer, then an action failure "other"). Merge tags work in url (percent-encoded), body (JSON-escaped when the Content-Type is JSON; POST defaults to application/json) and header values. Only public addresses, no redirects. **Výstupy:** `next` · **Povinné pro zapnutí:** `url` · SmartEmailing: `send-webhook` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `url` | string | ano | http(s) URL or one starting with a merge tag, at most 2 000. | | `method` | one of: `GET`, `POST` | ne | Default POST. default `POST` | | `body` | string | ne | POST body, at most 10 000 characters (merge tags allowed). | | `headers` | array of object | ne | At most 20 {name, value}. max 20 items | | `basicAuth` | object | ne | HTTP Basic of the call. password is write only: answers show passwordSet. | ```json { "id": "webhook-1", "type": "webhook", "config": { "url": "https://crm.example.cz/hooks/postarna", "method": "POST", "body": "{\"email\": \"{{df_emailaddress}}\", \"event\": \"cart\"}", "headers": [ { "name": "X-Source", "value": "postarna" } ] } } ``` #### `set_field` {#node-set-field} Sets or clears a contact field. valueKind fixed (a value of the field's type), relative (dates: a time spec from now) or template (text fields: merge tags). **Výstupy:** `next` · **Povinné pro zapnutí:** `field`, `action` · SmartEmailing: `set-field` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `field` | string | ano | System field (firstName, lastName, titleBefore, titleAfter, company, companyId, phone, mobile, street, city, postalCode, note, affiliateId, salutation, salutationFormal, vocativeFirstName, vocativeLastName, gender, language, country, birthday, nameDay) or cf:. | | `action` | one of: `set`, `clear` | ano | Action. | | `valueKind` | one of: `fixed`, `relative`, `template` | ne | Default fixed. default `fixed` | | `value` | any | ne | set only: by field kind: text (at most 200), textarea (1 000), gender f / m, language xx, country XX, date YYYY-MM-DD, name day MM-DD, number as string, checkbox true / false, select / radio an option, multi_checkbox a list of options. | ```json { "id": "set-field-1", "type": "set_field", "config": { "field": "cf:62", "action": "set", "valueKind": "fixed", "value": "VIP" } } ``` #### `reset` {#node-reset} Ends the contact's other active runs of this scenario that wait in nodes after this one (SmartEmailing Reset). **Výstupy:** `next` · SmartEmailing: `reset` Bez nastavení. ```json { "id": "reset-1", "type": "reset", "config": {} } ``` #### `fire_event` {#node-fire-event} Fires a custom event of the contact that event triggers (custom) of OTHER automations listen to. **Výstupy:** `next` · **Povinné pro zapnutí:** `name` · SmartEmailing: `fire-event` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `name` | string | ano | a-z, 0-9 and - (1 to 50), not starting with se-. pattern `^[a-z0-9-]{1,50}$` | | `data` | object | ne | Event data, at most 2 000 characters as JSON. | ```json { "id": "fire-event-1", "type": "fire_event", "config": { "name": "vip-reached", "data": { "level": "gold" } } } ``` #### `notify` {#node-notify} Notifies the team in the app (notification centre). **Výstupy:** `next` · **Povinné pro zapnutí:** `message` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `message` | string | ano | 1 to 500 characters. | | `important` | boolean | ne | Mark as important, default false. | ```json { "id": "notify-1", "type": "notify", "config": { "message": "Zákazník dosáhl VIP úrovně", "important": false } } ``` #### `goto` {#node-goto} Jumps to another node of this graph (not a trigger or goal; the jump counts as an edge for cycles, so only forward). **Výstupy:** - · **Povinné pro zapnutí:** `target` | Pole | Typ | Povinné | Popis | |---|---|---|---| | `target` | string | ano | Key of the target node. | #### `end` {#node-end} Ends the run (the contact leaves). **Výstupy:** - Bez nastavení. ```json { "id": "end-1", "type": "end", "config": {} } ``` ### Zatím nedostupné | Typ | Chybí | |---|---| | `send_sms` | sms | | `send_viber` | viber | | `fb_audience` | meta | | `sklik_retargeting` | sklik | | `motionlab_adina` | motionlab | | `whatsapp` | whatsapp | ## Podmínky automatizací {#podminky-automatizaci} Pravidla uzlu `condition`, cíle a filtru spouštěčů (spolu s pravidly segmentů níže). Každé smí mít `negate`. #### `ab_test_significant` {#cond-ab-test-significant} The difference between nodes A and B is significant (95 %, two-proportion z-test). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `ab_test_significant` | ano | | | `metric` | one of: `open_rate`, `click_rate` | ano | Metric. | | `nodeA` | string | ano | send_email node key. | | `nodeB` | string | ano | Another send_email node key. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | #### `ab_test_winner` {#cond-ab-test-winner} Node A beats node B (two send_email nodes of this graph) in open or click rate. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `ab_test_winner` | ano | | | `metric` | one of: `open_rate`, `click_rate` | ano | Metric. | | `nodeA` | string | ano | send_email node key. | | `nodeB` | string | ano | Another send_email node key. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | #### `cart_items` {#cond-cart-items} Old name of cart_items_count (still accepted). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `cart_items` | ano | | | `operator` | one of: `eq`, `lt`, `lte`, `gt`, `gte` | ano | Operator. | | `value` | any | ano | Whole number. | | `shopId` | string or null | ne | | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "cart_items", "operator": "gt", "value": 0 } ``` #### `cart_items_count` {#cond-cart-items-count} Items in the contact's cart (a cart not changed since an order counts as empty). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `cart_items_count` | ano | | | `operator` | one of: `eq`, `lt`, `lte`, `gt`, `gte` | ano | Operator. | | `value` | any | ano | Whole number. | | `shopId` | string or null | ne | Shop, null = any cart. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "cart_items_count", "operator": "gt", "value": 0, "shopId": "1" } ``` #### `contact_anniversary` {#cond-contact-anniversary} Today is (or is offset from) the contact's birthday, name day or a date custom field. nameDay: the contact's own name day, else the calendar of the first name (calendar auto = Slovak for language sk, else by the shop's language). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `contact_anniversary` | ano | | | `field` | string | ano | birthday, nameDay or cf: of a date field. | | `calendar` | one of: `auto`, `cz`, `sk` | ne | nameDay only. | | `relation` | one of: `now`, `offset` | ne | now = today; offset = shifted. default `now` | | `offset` | object | ne | With relation offset, at least 15 minutes. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "contact_anniversary", "field": "nameDay", "calendar": "auto", "relation": "now" } ``` #### `contact_field` {#cond-contact-field} A contact field (system field or cf:) compared with a value. Text: eq, filled, empty, gt, gte, lt, lte, starts, contains; dates: date_eq, date_filled, date_empty, date_after, date_from, date_before, date_until with a time spec value; numbers: eq, gt, gte, lt, lte, filled, empty; gender: eq (f / m); checkbox: checked, unchecked; choice: eq_option; multi: has_option. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `contact_field` | ano | | | `field` | string | ano | System field (affiliateId, domain, email, language, firstName, mobile, city, birthday, vocativeFirstName, salutation, salutationFormal, vocativeLastName, gender, note, lastName, postalCode, company, nameDay, phone, titleBefore, titleAfter, street, createdAt, country, companyId) or cf:. | | `operator` | string | ano | Operator for the field kind. | | `value` | any | ne | Text, number, f / m, an option, or a time spec for dates. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "contact_field", "field": "city", "operator": "eq", "value": "Brno" } ``` #### `contact_in_any_list` {#cond-contact-in-any-list} Contact is in any list in a state. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `contact_in_any_list` | ano | | | `state` | one of: `confirmed`, `unsubscribed` | ne | State, default confirmed. default `confirmed` | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | ```json { "type": "contact_in_any_list" } ``` #### `contact_in_automation` {#cond-contact-in-automation} Contact is in an automation (another active run of it). automationId null = this automation (not allowed in a trigger filter). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `contact_in_automation` | ano | | | `automationId` | string or null | ne | | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "contact_in_automation", "automationId": "201" } ``` #### `contact_in_list` {#cond-contact-in-list} Contact is in a list in a state. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `contact_in_list` | ano | | | `listId` | string | ano | List id. | | `state` | one of: `confirmed`, `unsubscribed` | ne | State, default confirmed. default `confirmed` | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | ```json { "type": "contact_in_list", "listId": "101", "state": "confirmed" } ``` #### `contact_in_list_label` {#cond-contact-in-list-label} Contact is in a list with this label. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `contact_in_list_label` | ano | | | `label` | string | ano | Label, at most 40. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | ```json { "type": "contact_in_list_label", "label": "newsletter" } ``` #### `contact_origin` {#cond-contact-origin} Contact came from a source. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `contact_origin` | ano | | | `origin` | one of: `erp_order`, `signup_form`, `import`, `api`, `manual`, `shoptet`, `smartemailing` | ano | Source. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "contact_origin", "origin": "signup_form" } ``` #### `contact_purpose` {#cond-contact-purpose} Contact has a valid consent with a purpose. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `contact_purpose` | ano | | | `purposeId` | string | ano | Purpose id. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | ```json { "type": "contact_purpose", "purposeId": "51" } ``` #### `day_of_month` {#cond-day-of-month} Today is one of these days of the month. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `day_of_month` | ano | | | `days` | array of integer | ano | Days 1 to 31. min 1 items | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "day_of_month", "days": [ 1, 15 ] } ``` #### `day_of_week` {#cond-day-of-week} Today is one of these weekdays (1 = Monday). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `day_of_week` | ano | | | `weekdays` | array of integer | ano | 1 to 7. min 1 items | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "day_of_week", "weekdays": [ 6, 7 ] } ``` #### `email_activity` {#cond-email-activity} The contact opened / clicked an e-mail of this run (nodeId null = any). Run only. (not allowed in trigger filters (needs a run)) | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `email_activity` | ano | | | `operator` | one of: `opened`, `not_opened`, `clicked`, `not_clicked` | ano | Operator. | | `nodeId` | string or null | ne | send_email node key. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "email_activity", "operator": "opened", "nodeId": null } ``` #### `engagement_score` {#cond-engagement-score} Engagement level of the contact. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `engagement_score` | ano | | | `levels` | array of one of: `N`, `A`, `B`, `C`, `D`, `E` | ano | Levels. min 1 items | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "engagement_score", "levels": [ "A", "B" ] } ``` #### `event_attribute` {#cond-event-attribute} A value of the data of the custom event that started the run (data of POST /contact-events type custom, or of a fire_event node of another automation). Other triggers have no such data. Run only. (not allowed in trigger filters (needs a run)) | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `event_attribute` | ano | | | `attribute` | string | ano | Name. | | `operator` | one of: `eq`, `contains`, `starts`, `gt`, `gte`, `lt`, `lte`, `filled`, `empty` | ano | Operator. | | `value` | string | ne | Text. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "event_attribute", "attribute": "plan", "operator": "eq", "value": "gold" } ``` #### `feed_item_count` {#cond-feed-item-count} Number of items of a feed. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `feed_item_count` | ano | | | `feedId` | string | ano | Feed id. | | `operator` | one of: `eq`, `lt`, `lte`, `gt`, `gte` | ano | Operator. | | `value` | any | ano | Whole number. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "feed_item_count", "feedId": "71", "operator": "gt", "value": 0 } ``` #### `hour_of_day` {#cond-hour-of-day} The current hour (local) is one of these. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `hour_of_day` | ano | | | `hours` | array of integer | ano | 0 to 23. min 1 items | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "hour_of_day", "hours": [ 8, 9, 10 ] } ``` #### `opened_email` {#cond-opened-email} The contact opened an e-mail of a node. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `opened_email` | ano | | | `emailNode` | object | ano | An e-mail node: automationId null (or left out) = a send_email node of this graph, else the id of another automation of the company and its node key. | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "opened_email", "emailNode": { "automationId": "201", "nodeKey": "email-1" } } ``` #### `opened_emails_count` {#cond-opened-emails-count} Number of e-mails the contact opened. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `opened_emails_count` | ano | | | `operator` | one of: `eq`, `lt`, `lte`, `gt`, `gte` | ano | Operator. | | `value` | any | ano | Whole number. | | `kinds` | array of one of: `automation`, `campaign`, `transactional` | ne | Kinds. | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "opened_emails_count", "operator": "eq", "value": 0 } ``` #### `ordered_attribute` {#cond-ordered-attribute} A value of an order: code, state, status, sourceStatus, currency, companyId, totalWithVat, totalWithoutVat, or any delivery data field. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `ordered_attribute` | ano | | | `attribute` | string | ano | Attribute name: letters, digits and _ . : - (at most 60). | | `attributeType` | one of: `text`, `date`, `number` | ne | How to compare. default `text` | | `operator` | one of: `eq`, `filled`, `gt`, `gte`, `lt`, `lte`, `starts` | ano | Operator. | | `value` | any | ne | Text, a number, or a time spec for attributeType date. | | `limitToTriggerEvent` | boolean | ne | Only the order of the run's own trigger event (order triggers). | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "ordered_attribute", "attribute": "currency", "operator": "eq", "value": "CZK" } ``` #### `ordered_product` {#cond-ordered-product} The contact ordered a product by id (product code) or name. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `ordered_product` | ano | | | `productField` | one of: `id`, `name` | ne | Field, default id. default `id` | | `operator` | one of: `eq`, `starts`, `contains` | ano | Operator. | | `value` | string | ano | Text. | | `limitToTriggerEvent` | boolean | ne | Only the order of the run's own trigger event (order triggers). | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "ordered_product", "productField": "id", "operator": "eq", "value": "SKU-001" } ``` #### `ordered_product_by_attribute` {#cond-ordered-product-by-attribute} The contact ordered a product with a feed attribute. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `ordered_product_by_attribute` | ano | | | `attribute` | string | ano | Attribute name: letters, digits and _ . : - (at most 60). | | `attributeType` | one of: `text`, `date`, `number` | ne | How to compare. default `text` | | `operator` | one of: `eq`, `filled`, `gt`, `gte`, `lt`, `lte`, `starts` | ano | Operator. | | `value` | any | ne | Text, a number, or a time spec for attributeType date. | | `limitToTriggerEvent` | boolean | ne | Only the order of the run's own trigger event (order triggers). | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "ordered_product_by_attribute", "attribute": "brand", "operator": "eq", "value": "Example" } ``` #### `ordered_since_entry` {#cond-ordered-since-entry} The contact ordered since the run entered. Run only. (not allowed in trigger filters (needs a run)) | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `ordered_since_entry` | ano | | | `operator` | one of: `yes`, `no` | ano | Operator. | | `shopId` | string or null | ne | | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "ordered_since_entry", "operator": "yes", "shopId": null } ``` #### `orders_count` {#cond-orders-count} Number of orders. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `orders_count` | ano | | | `operator` | one of: `eq`, `lt`, `lte`, `gt`, `gte` | ano | Operator. | | `value` | any | ano | Whole number. | | `paid` | one of: `any`, `yes`, `no` | ne | Paid filter, default any. default `any` | | `states` | array of one of: `received`, `processing`, `shipped`, `cancelled`, `unknown` | ne | Order states (SmartEmailing names). | | `shopId` | string or null | ne | | | `limitToTriggerEvent` | boolean | ne | Only the order of the run's own trigger event (order triggers). | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "orders_count", "operator": "eq", "value": 1, "paid": "any" } ``` #### `orders_total_value` {#cond-orders-total-value} Sum (or avg, min, max) of the contact's orders with VAT in one currency. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `orders_total_value` | ano | | | `operator` | one of: `eq`, `lt`, `lte`, `gt`, `gte` | ano | Operator. | | `value` | any | ano | Number. | | `aggregate` | one of: `sum`, `avg`, `min`, `max` | ne | Aggregate, default sum. default `sum` | | `currency` | string | ano | Currency of a shop of the company (CZK, EUR). | | `shopId` | string or null | ne | | | `limitToTriggerEvent` | boolean | ne | Only the order of the run's own trigger event (order triggers). | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "orders_total_value", "operator": "gte", "value": "3000", "currency": "CZK" } ``` #### `passed_node` {#cond-passed-node} This run went (or did not go) through a node. Run only. (not allowed in trigger filters (needs a run)) | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `passed_node` | ano | | | `operator` | one of: `passed`, `not_passed` | ano | Operator. | | `nodeId` | string | ano | Node key. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | #### `promo_code` {#cond-promo-code} The contact got (assigned) or used a coupon of a stack. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `promo_code` | ano | | | `state` | one of: `assigned`, `used` | ano | State. | | `stackId` | string | ano | Coupon stack id. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "promo_code", "state": "used", "stackId": "81" } ``` #### `script` {#cond-script} A Twig script; true when it prints {{ result.returnTrue() }}. Not allowed in trigger filters. (not allowed in trigger filters (needs a run)) | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `script` | ano | | | `script` | string | ano | Twig source, at most 20 000 characters. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "script", "script": "{% if contact.city == 'Brno' %}{{ result.returnTrue() }}{% endif %}" } ``` #### `sent_email` {#cond-sent-email} An e-mail was sent to the contact: of one node (mode node) or of an automation (mode automation, automationId null = any). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `sent_email` | ano | | | `mode` | one of: `node`, `automation` | ano | Mode. | | `emailNode` | object | ne | An e-mail node: automationId null (or left out) = a send_email node of this graph, else the id of another automation of the company and its node key. | | `automationId` | string or null | ne | | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "sent_email", "mode": "node", "emailNode": { "automationId": "201", "nodeKey": "email-1" } } ``` #### `sent_emails_count` {#cond-sent-emails-count} Number of e-mails sent to the contact. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `sent_emails_count` | ano | | | `operator` | one of: `eq`, `lt`, `lte`, `gt`, `gte` | ano | Operator. | | `value` | any | ano | Whole number 0 to 10 000 000. | | `kinds` | array of one of: `automation`, `campaign`, `transactional` | ne | Kinds, default automation and campaign. | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "sent_emails_count", "operator": "gte", "value": 3 } ``` #### `tracking_url_clicked` {#cond-tracking-url-clicked} The contact clicked a link in an e-mail of a node. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `tracking_url_clicked` | ano | | | `emailNode` | object | ano | An e-mail node: automationId null (or left out) = a send_email node of this graph, else the id of another automation of the company and its node key. | | `link` | string | ano | URL (at most 2 000). | | `compareParams` | boolean | ne | Compare query parameters too, default true. default `true` | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "tracking_url_clicked", "emailNode": { "automationId": "201", "nodeKey": "email-1" }, "link": "https://www.example.cz/akce" } ``` #### `tracking_url_clicked_any` {#cond-tracking-url-clicked-any} The contact clicked any link of a node (emailNode null = any e-mail node of this automation). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `tracking_url_clicked_any` | ano | | | `emailNode` | object or null | ne | | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "tracking_url_clicked_any", "emailNode": null } ``` #### `visited_attribute` {#cond-visited-attribute} A web tracking visit with an attribute. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `visited_attribute` | ano | | | `url` | string | ne | URL. | | `urlOperator` | one of: `eq`, `starts` | ne | Default eq. default `eq` | | `visitType` | one of: `home`, `article`, `cart`, `product`, `category`, `search`, `order_done`, `other` | ne | Visit type. | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `attribute` | string | ano | Attribute name: letters, digits and _ . : - (at most 60). | | `attributeType` | one of: `text`, `date`, `number` | ne | How to compare. default `text` | | `value` | any | ne | Text, a number, or a time spec for attributeType date. | | `operator` | one of: `starts`, `gt`, `gte`, `lt`, `lte`, `eq` | ano | Operator. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "visited_attribute", "attribute": "category", "operator": "eq", "value": "Káva" } ``` #### `visited_url` {#cond-visited-url} A web tracking visit of a URL. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `visited_url` | ano | | | `url` | string | ne | URL. | | `urlOperator` | one of: `eq`, `starts`, `contains` | ne | Default eq. default `eq` | | `visitType` | one of: `home`, `article`, `cart`, `product`, `category`, `search`, `order_done`, `other` | ne | Visit type. | | `period` | object | ne | Time window of the rule: from and to are time specs relative to now (null = unbounded). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "visited_url", "url": "https://www.example.cz/kosik", "urlOperator": "starts" } ``` #### Zatím nedostupné podmínky | Typ | Chybí | |---|---| | `contact_preference` | preferences | | `contact_viber_state` | viber | | `delivered_viber` | viber | | `score` | scoring | | `seen_viber` | viber | | `sent_sms` | sms | ## Pravidla segmentů {#pravidla-segmentu} Pravidla segmentů (a podmínek automatizací). Hodnoty jsou řetězce. #### `campaign` {#rule-campaign} Delivered / opened / clicked a campaign (not_* also matches contacts that never got it); linkUrl narrows clicks to one link. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `campaign` | ano | | | `operator` | one of: `received`, `not_received`, `opened`, `not_opened`, `clicked`, `not_clicked` | ano | Operator. | | `campaignId` | string or null | ano | Campaign id; null only with received = an e-mail of any campaign. | | `linkUrl` | string | ne | clicked / not_clicked only. | | `days` | string or null | ne | Last N days or null. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "campaign", "operator": "opened", "campaignId": "121", "days": null } ``` #### `custom_field` {#rule-custom-field} A custom field. kind must match the field type: text and textarea -> text, number -> number, date -> date, checkbox -> bool, select and radio -> choice, multi_checkbox -> multi_choice (400 definition..kind otherwise). Operators: text like the text fields, number gte/lte/eq/is_empty/is_not_empty, date like the date fields, bool is_true/is_false, choice is/is_not, multi_choice contains_any/contains_all/not_contains_any. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `custom_field` | ano | | | `fieldId` | string | ano | Custom field id (without cf:). | | `kind` | one of: `bool`, `choice`, `date`, `multi_choice`, `number`, `text` | ano | Kind of the field type (see above). | | `operator` | string | ano | Operator for the kind. | | `value` | string | ne | Value (string). | | `values` | array of string | ne | Options (multi_choice). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "custom_field", "fieldId": "62", "kind": "text", "operator": "equals", "value": "VIP" } ``` #### `engagement` {#rule-engagement} Engagement level A (best) to E, N = new. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `engagement` | ano | | | `operator` | one of: `in`, `not_in` | ano | Operator. | | `values` | array of one of: `A`, `B`, `C`, `D`, `E`, `N` | ano | Levels. min 1 items | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "engagement", "operator": "in", "values": [ "A", "B" ] } ``` #### `field` {#rule-field} A contact field compared with a value. Text operators ignore case and diacritics; date operators count calendar days of the company. Text fields: email, firstName, lastName, city, company, companyId, phone, mobile, street, postalCode, note, country. Enum fields: status (pending/subscribed/unsubscribed/bounced/complained/customer), gender (f/m), language (cs/sk), source (erp_order/signup_form/import/api/manual/shoptet/smartemailing), consentBasis (soft_opt_in_customer/double_opt_in/imported/none). Date fields: createdAt, lastOpenAt, lastClickAt, lastSentAt, statusAt, consentAt. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `field` | ano | | | `field` | one of: `email`, `firstName`, `lastName`, `city`, `company`, `companyId`, `phone`, `mobile`, `street`, `postalCode`, `note`, `country`, `status`, `gender`, `language`, `source`, `consentBasis`, `createdAt`, `lastOpenAt`, `lastClickAt`, `lastSentAt`, `statusAt`, `consentAt` | ano | Contact field. | | `operator` | one of: `contains`, `not_contains`, `equals`, `not_equals`, `starts_with`, `ends_with`, `is_empty`, `is_not_empty`, `is`, `is_not`, `in_last_days`, `not_in_last_days`, `before`, `after`, `until`, `since` | ano | Text: contains, not_contains, equals, not_equals, starts_with, ends_with, is_empty, is_not_empty; enum: is, is_not; date: in_last_days, not_in_last_days, before, after, until, since, is_empty, is_not_empty. | | `value` | string | ano | Always a string: the text, the enum value, a number of days ("30") for in_last_days / not_in_last_days, or a date YYYY-MM-DD for before / after; "" for is_empty / is_not_empty. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "field", "field": "lastOpenAt", "operator": "in_last_days", "value": "60" } ``` #### `last_order` {#rule-last-order} The last completed order: within / older than N days, or before / after a date. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `last_order` | ano | | | `operator` | one of: `in_last_days`, `older_than_days`, `before`, `after` | ano | Operator. | | `value` | string | ano | Days "1" to "3650" or a date YYYY-MM-DD. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | | `shopId` | string or null | ne | Only orders of this shop (null = any). | | `currency` | string or null | ne | Only orders in this currency (CZK or EUR; it must be the currency of shopId when both are set). | ```json { "type": "last_order", "operator": "older_than_days", "value": "180" } ``` #### `list` {#rule-list} Membership in a list. in / not_in = confirmed or unconfirmed member; status_is compares the exact state; added_before / added_after compare the day the contact was added; longer_than_days / shorter_than_days: in the list longer / shorter than N days. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `list` | ano | | | `operator` | one of: `in`, `not_in`, `added_before`, `added_after`, `status_is`, `longer_than_days`, `shorter_than_days` | ano | Operator. | | `listId` | string | ano | List id. | | `value` | string | ne | status_is: confirmed, unconfirmed, unsubscribed, removed; added_*: YYYY-MM-DD; *_than_days: days "1" to "3650". | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "list", "operator": "in", "listId": "101" } ``` #### `list_label` {#rule-list-label} Confirmed or unconfirmed member of any list with this label. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `list_label` | ano | | | `operator` | one of: `in` | ano | Operator. | | `label` | string | ano | Label, 1 to 40. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "list_label", "operator": "in", "label": "vip" } ``` #### `opens` {#rule-opens} Number of the contact's e-mails (campaigns and automations) with an open. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `opens` | ano | | | `operator` | one of: `eq`, `gt`, `lt`, `gte`, `lte` | ano | Operator. | | `value` | string | ano | Count "0" to "100000". | | `days` | string or null | ne | Only the last N days, "1" to "3650" (null = any time). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "opens", "operator": "gte", "value": "3", "days": "90" } ``` #### `order_attribute` {#rule-order-attribute} A completed order has an item whose product code, category, brand or another item attribute (as stored on the order item) equals the value; with scope order an attribute of the order itself. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `order_attribute` | ano | | | `operator` | one of: `is` | ano | Operator. | | `scope` | one of: `item`, `order` | ne | item (default) or order. default `item` | | `attribute` | string | ano | item: productCode, category, brand or any attribute name; order: status, companyId, deliveryCity, deliveryCountry, deliveryZip, deliveryCompany. | | `value` | string | ano | Exact value, at most 200 characters. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | | `shopId` | string or null | ne | Only orders of this shop (null = any). | | `currency` | string or null | ne | Only orders in this currency (CZK or EUR; it must be the currency of shopId when both are set). | | `days` | string or null | ne | Only the last N days, "1" to "3650" (null = any time). | ```json { "type": "order_attribute", "operator": "is", "attribute": "brand", "value": "Example" } ``` #### `order_count` {#rule-order-count} Number of completed orders. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `order_count` | ano | | | `operator` | one of: `gte`, `lte`, `eq` | ano | Operator. | | `value` | string | ano | Count "0" to "100000". | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | | `shopId` | string or null | ne | Only orders of this shop (null = any). | | `currency` | string or null | ne | Only orders in this currency (CZK or EUR; it must be the currency of shopId when both are set). | | `days` | string or null | ne | Only the last N days, "1" to "3650" (null = any time). | ```json { "type": "order_count", "operator": "gte", "value": "2", "shopId": null, "currency": null, "days": "365" } ``` #### `order_value` {#rule-order-value} Sum of completed orders with VAT in one currency (CZK and EUR are never added up). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `order_value` | ano | | | `operator` | one of: `gte`, `lte` | ano | Operator. | | `amount` | string | ano | Amount, at most 2 decimals, e.g. "1500.50". | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | | `shopId` | string or null | ne | Only orders of this shop (null = any). | | `currency` | string or null | ano | Only orders in this currency (CZK or EUR; it must be the currency of shopId when both are set). | | `days` | string or null | ne | Only the last N days, "1" to "3650" (null = any time). | ```json { "type": "order_value", "operator": "gte", "amount": "2000", "currency": "CZK", "shopId": "1", "days": "365" } ``` #### `product_bought` {#rule-product-bought} A completed order has an item whose name contains the text or whose product code equals it (case and diacritics ignored). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `product_bought` | ano | | | `operator` | one of: `is` | ano | Operator. | | `value` | string | ano | Part of the name or the code, at most 200. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | | `shopId` | string or null | ne | Only orders of this shop (null = any). | | `currency` | string or null | ne | Only orders in this currency (CZK or EUR; it must be the currency of shopId when both are set). | | `days` | string or null | ne | Only the last N days, "1" to "3650" (null = any time). | ```json { "type": "product_bought", "operator": "is", "value": "Espresso", "days": "30" } ``` #### `purpose` {#rule-purpose} A valid (not withdrawn, within its validity) consent with a purpose of processing. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `purpose` | ano | | | `operator` | one of: `has`, `not_has` | ano | Operator. | | `purposeId` | string | ano | Purpose id. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "purpose", "operator": "has", "purposeId": "51" } ``` #### `segment` {#rule-segment} Member of another segment of the same shop (never itself; chains at most 5 deep, no cycles). | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `segment` | ano | | | `operator` | one of: `in`, `not_in`, `added_before`, `added_after` | ano | Operator. | | `segmentId` | string | ano | Segment id. | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "segment", "operator": "not_in", "segmentId": "91" } ``` #### `web_attribute` {#rule-web-attribute} A page visit whose attribute matches: visitType = the page type, other names = the visit's own attributes; gt to lte compare numbers. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `web_attribute` | ano | | | `attribute` | string | ano | Attribute name. | | `operator` | one of: `is`, `starts_with`, `gt`, `gte`, `lt`, `lte` | ano | Operator. | | `value` | string | ano | At most 200 (a number for gt to lte). | | `days` | string or null | ne | Only the last N days, "1" to "3650" (null = any time). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "web_attribute", "attribute": "visitType", "operator": "is", "value": "product" } ``` #### `web_visit` {#rule-web-visit} A page visit recorded by the shop's script or the API; any = any page. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `type` | `web_visit` | ano | | | `operator` | one of: `any`, `is`, `starts_with`, `contains` | ano | Operator. | | `url` | string | ne | Not with any; at most 2 000. | | `days` | string or null | ne | Only the last N days, "1" to "3650" (null = any time). | | `negate` | boolean | ne | true = the rule must NOT hold (SmartEmailing "Neplatí, že"). | ```json { "type": "web_visit", "operator": "contains", "url": "/kava/", "days": "30" } ``` ## Časové údaje {#casove-udaje} A moment relative to a base moment (SmartEmailing's "Varianta výběru času"). The base is the moment the contact arrived at the node (or entered the scenario, countFrom scenario), or now in conditions. Days and longer keep the local wall time; months are calendar months. In waits only calendar, interval with sign "+" and event without the words yesterday and previous are allowed. Preview any spec with POST /automations/resolve-time. #### `calendar` A local calendar date and time. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `variant` | `calendar` | ano | | | `date` | string | ano | YYYY-MM-DD (local). pattern `^[0-9]{4}-[0-9]{2}-[0-9]{2}$` | | `time` | string | ne | HH:MM (local), default 00:00. pattern `^([01][0-9]\|2[0-3]):[0-5][0-9]$` | #### `interval` Base plus or minus a number of units. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `variant` | `interval` | ano | | | `sign` | one of: `+`, `-` | ano | "+" later, "-" earlier (conditions only). | | `value` | integer | ano | 1 to 100 000. min 1, max 100000 | | `unit` | one of: `minutes`, `hours`, `days`, `weeks`, `months`, `years` | ano | Unit. | | `time` | string or null | ne | Optional HH:MM set after the shift (days and longer). pattern `^([01][0-9]\|2[0-3]):[0-5][0-9]$` | #### `event` A named day: today, tomorrow, this/next/previous weekday, working day, week, month or year, or the last day of this or next month. | Pole | Typ | Povinné | Popis | |---|---|---|---| | `variant` | `event` | ano | | | `word` | one of: `yesterday`, `previous`, `today`, `this`, `tomorrow`, `next`, `last_day_of` | ano | Which day. | | `unit` | one of: `monday`, `tuesday`, `wednesday`, `thursday`, `friday`, `saturday`, `sunday`, `workday`, `day`, `week`, `month`, `year` | ne | With previous, this and next: a weekday, workday, day, week, month or year; with last_day_of: month. | | `scope` | one of: `this`, `next` | ne | With last_day_of: this or next month. | | `time` | string | ano | HH:MM (local), required. pattern `^([01][0-9]\|2[0-3]):[0-5][0-9]$` | ```json [ { "variant": "interval", "sign": "+", "value": 2, "unit": "days", "time": "09:00" }, { "variant": "event", "word": "next", "unit": "monday", "time": "08:00" }, { "variant": "calendar", "date": "2026-12-24", "time": "09:00" } ] ``` --- # Objednávky, feedy a kupóny ## Objednávky {#objednavky} Objednávky pohánějí spouštěče (`order_created`, `order_completed`, `order_changed`), podmínky (počet a hodnota objednávek, objednaný produkt), segmenty a konverze kampaní. Do Poštárny se dostanou třemi cestami: konektorem e-shopu, feedem objednávek (`kind: shop_orders`) nebo API. ### `POST /orders`: založení nebo úprava Objednávka se ukládá podle dvojice **(`shopId`, `id`)**, kde `id` je číslo objednávky ve vašem e-shopu. První zápis vrátí 201 a `change: "created"`, další 200 a `updated` nebo `unchanged`. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/orders" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/orders" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "id": "2026001234", "shopId": "13", "createdAt": "2026-10-01T09:30:00+02:00", "paidAt": "2026-10-01T09:31:00+02:00", "email": "karel.vesely@example.cz", "status": "Zaplaceno", "eshopCode": "2026001234", "orderUrl": "https://www.example.cz/objednavka/2026001234", "currency": "CZK", "totalWithVat": "1290.00", "totalWithoutVat": "1066.12", "items": [ { "id": "KAVA-1KG", "name": "Káva Kolumbie 1 kg", "quantity": 1, "unit": "ks", "price": { "withVat": "1290.00", "withoutVat": "1066.12", "currency": "CZK" }, "url": "https://www.example.cz/kava-kolumbie", "attributes": { "Category": "Káva", "Brand": "Example" } } ] } JSON ``` ```json title="Odpověď: 201 Created" { "change": "created", "order": { "id": "5001", "externalId": "2026001234", "eshopCode": "2026001234", "eshopName": "Example.cz", "shopId": "13", "createdAt": "2026-10-01T07:30:00.000Z", "paidAt": "2026-10-01T07:31:00.000Z", "email": "karel.vesely@example.cz", "contactId": "1205", "state": "paid", "status": "completed", "sourceStatus": "Zaplaceno", "orderUrl": "https://www.example.cz/objednavka/2026001234", "currency": "CZK", "totalWithVat": "1290.00", "totalWithoutVat": "1066.12", "itemCount": 1, "items": [ { "id": "1", "productCode": "KAVA-1KG", "name": "Káva Kolumbie 1 kg", "description": "", "price": { "withVat": "1290.00", "withoutVat": "1066.12", "currency": "CZK" }, "quantity": 1, "unit": "ks", "url": "https://www.example.cz/kava-kolumbie", "imageUrl": "", "attributes": { "Brand": "Example", "Category": "Káva" }, "paired": false } ], "conversion": null, "deleted": false, "receivedAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "seller": {}, "orderDelivery": {} } } ``` • `createdAt` (povinné) a `paidAt`: ISO 8601 s časovou zónou. • `email` nebo `contactId`: kupující. Kupující bez kontaktu dostane nový kontakt ve stavu `customer` (bez marketingového souhlasu, e-maily nedostává). • `status`: **název stavu ve vašem e-shopu** (například „Zaplaceno“). Na kanonický stav ho převede mapa stavů (níže). • `currency`: smí být jen měna e-shopu; jiná = 400. Částky jako desetinné řetězce. • `items`: položky s `id` (kód produktu), `name` (povinné), `quantity`, `unit`, `price {withVat, withoutVat, currency}`, `url`, `imageUrl`, `attributes` (atributy z feedu, například `Category`, `Brand`; podle nich pracuje pravidlo `order_attribute` a podmínky na produkty). • `deleted: true` = objednávka byla smazána (běh po nákupu se ukončí). • Neznámé pole = 400 s jeho názvem. > **Pozor:** každý zápis **nahrazuje celou objednávku**. Pole, které při úpravě nepošlete, se vyprázdní. Při změně stavu posílejte vždy celou objednávku. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/orders" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/orders" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "id": "2026001234", "shopId": "13", "createdAt": "2026-10-01T09:30:00+02:00", "paidAt": "2026-10-01T09:31:00+02:00", "email": "karel.vesely@example.cz", "status": "Předáno zákazníkovi", "eshopCode": "2026001234", "currency": "CZK", "totalWithVat": "1290.00", "items": [ { "id": "KAVA-1KG", "name": "Káva Kolumbie 1 kg", "quantity": 1, "price": { "withVat": "1290.00", "currency": "CZK" } } ] } JSON ``` ```json title="Odpověď: 200 OK" { "change": "updated", "order": { "id": "5001", "externalId": "2026001234", "eshopCode": "2026001234", "eshopName": "Example.cz", "shopId": "13", "createdAt": "2026-10-01T07:30:00.000Z", "paidAt": "2026-10-01T07:31:00.000Z", "email": "karel.vesely@example.cz", "contactId": "1205", "state": "paid", "status": "completed", "sourceStatus": "Předáno zákazníkovi", "orderUrl": "", "currency": "CZK", "totalWithVat": "1290.00", "totalWithoutVat": null, "itemCount": 1, "items": [ { "id": "2", "productCode": "KAVA-1KG", "name": "Káva Kolumbie 1 kg", "description": "", "price": { "withVat": "1290.00", "withoutVat": null, "currency": "CZK" }, "quantity": 1, "unit": "", "url": "", "imageUrl": "", "attributes": {}, "paired": false } ], "conversion": null, "deleted": false, "receivedAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "seller": {}, "orderDelivery": {} } } ``` ### Mapa stavů {#mapa-stavu} | Kanonický stav (`state`) | Skupina (`status`) | |---|---| | `new`, `unpaid`, `processing` | `pending` | | `paid`, `shipped`, `delivered` | `completed` (nákup) | | `cancelled`, `returned` | `cancelled` | | `other` | `other` | `GET /order-states` ukáže pravidla mapy a v `seen` názvy stavů, které přišly v objednávkách, s jejich výsledným stavem; `PUT /order-states` pravidla nahradí: `{"items": [{"sourceStatus": "Zaplaceno", "match": "exact", "state": "paid"}]}` (`match` `exact` nebo `prefix`, nejvýš 500 pravidel). Přemapování se projeví i na uložených objednávkách. Název bez mapování je `other` a nikdy se nepočítá jako nákup. ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/order-states" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/order-states" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "states": [ "new", "unpaid", "paid", "processing", "shipped", "delivered", "cancelled", "returned", "other" ], "items": [], "seen": [] } ``` ### Kdy objednávka spustí automatizaci • `order_created`: nová objednávka; `order_completed`: objednávka se poprvé dostala do skupiny `completed`; `order_changed`: změna stavu (volitelně jen do jednoho stavu). • Objednávky z prvního importu feedu objednávek (historie) a objednávky starší než 2 dny ve feedu automatizace nespouštějí. Objednávka zapsaná přes `POST /orders` je spouští. • Běh spuštěný objednávkou skončí, když se objednávka zruší, vrátí nebo smaže. • Každý e-shop má mít jediný zdroj objednávek (konektor, feed, nebo API); dva zdroje by uložily objednávky dvakrát. ## Feedy | `kind` | Co je | Limit | |---|---|---| | `google_products` | produktový feed Google Merchant (XML): produkty pro šablony (`data.products`), párování položek objednávek, podmínky | 20 MB, 50 000 položek | | `shop_customers` | export zákazníků e-shopu (CSV nebo XML); zákazník není odběratel, nevzniká kontakt ani souhlas | 100 MB, 500 000 záznamů | | `shop_orders` | export objednávek e-shopu (CSV), jeden na e-shop; stahuje se každou hodinu, poslední 3 dny každých 10 minut | 200 MB | | `articles` | článkový feed (RSS 2.0 nebo Atom), například blog e-shopu, pro `data.articles` | | Produktový feed má `format` `google`, `heureka` nebo `zbozi` (zvolí se při založení). • `POST /feeds` s `{kind, name, shopId, url, autoRefresh}`, `POST /feeds/{id}/refresh` stáhne hned, `GET /feeds/{id}/items` položky, `GET /feeds/{id}/preview` náhled. • Tajná část adresy (`hash`, `token`, `key`) se v odpovědích maskuje. • Feedy patří do modulu `settings` (klíč s rolí správce účtu). ## Slevové kupóny Zásobník (`coupon stack`) je sada jednorázových kódů jednoho e-shopu: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/coupon-stacks" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/coupon-stacks" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Svátek", "shopId": "11", "mergeKey": "svatek", "note": "Sleva 15 % k svátku" } JSON ``` ```json title="Odpověď: 201 Created" { "id": "11", "name": "Svátek", "shopId": "11", "mergeKey": "svatek", "tag": "{{coupon_svatek}}", "note": "Sleva 15 % k svátku", "counts": { "total": 0, "free": 0, "assigned": 0, "used": 0 }, "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z" } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/coupon-stacks/11/codes" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/coupon-stacks/11/codes" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "text": "SVATEK-7Q2K\nSVATEK-9P4M\nSVATEK-3X8D\n" } JSON ``` ```json title="Odpověď: 200 OK" { "counts": { "added": 3, "duplicate": 0, "invalid": 0, "total": 3 }, "stack": { "id": "11", "name": "Svátek", "shopId": "11", "mergeKey": "svatek", "tag": "{{coupon_svatek}}", "note": "Sleva 15 % k svátku", "counts": { "total": 3, "free": 3, "assigned": 0, "used": 0 }, "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z" } } ``` • V šabloně: `{{coupon_}}` nebo `{{ data.promoCode('') }}`. Každý e-mail dostane nový volný kód a kód se kontaktu přiřadí. • `POST /coupon-stacks/{id}/assign` přiřadí kód kontaktu ručně, `POST /coupon-stacks/{id}/used` označí kódy jako použité, `GET /contacts/{id}/coupons` kódy kontaktu. • Podmínka `promo_code` (dostal nebo použil kód zásobníku). • Došlé kódy zastaví e-mail (`customizationDataboxOutOfPromocodes`); hlídejte `counts.free`. ## Konverze Objednávka po prokliku z e-mailu se přičte kampani nebo automatizaci jako konverze: `GET /conversions` (souhrn po druzích a měnách), `GET /stats/campaigns/{id}/conversions`, `GET /stats/automations/{id}/conversions`. Tržby jsou vždy po měnách. --- # Recept: opuštěný košík **Cíl:** zákazníkovi, který si něco vložil do košíku a do 2 hodin neobjednal, poslat připomenutí. Když košík mezitím vyprázdní nebo objedná, e-mail neodejde. **Potřebujete:** klíč s rolí `marketing_manager` nebo `account_admin` (moduly `content` a `campaigns` plný přístup, `contacts` pro kontakty), ověřeného odesílatele e-shopu, ID e-shopu (`GET /shops`). ## Jak to funguje ```text title="Graf" [kosik] trigger_event cart_updated (reentry restart) └─ next → [pockat] wait 2 hours └─ next → [stale-v-kosiku] condition: košík není prázdný A neobjednal od vstupu ├─ yes → [email] send_email (šablona Opuštěný košík) └─ no → (konec, kontakt scénář opustí) ``` • Každá změna košíku (`POST /contact-events` typ `cart`) je událost `cart_updated`. Díky `reentry: "restart"` další změna košíku ukončí rozběhnutý běh a čekání začne znovu, takže zákazník dostane jedno připomenutí až 2 hodiny po poslední změně. • Podmínka `cart_items_count` čte poslední stav košíku: prázdný košík (nebo košík, který se od objednávky nezměnil) má 0 položek. • `ordered_since_entry: no` vyloučí kontakty, které od vstupu do scénáře objednaly. ## 1. Šablona e-mailu V e-mailu automatizace jsou data události, která běh spustila, v `metadata.event.attributes` (u košíku `itemCount`, `total`, `currency`, `shopId`): ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/templates" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/templates" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Opuštěný košík", "subject": "{{df_name|default('Dobrý den', true)}}, něco jste nechali v košíku", "preheader": "Váš košík na vás počká ještě pár dní", "content": { "editor": "html", "design": null, "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

ve vašem košíku zůstalo {{ metadata.event.attributes.itemCount }} ks zboží za {{ metadata.event.attributes.total }} {{ metadata.event.attributes.currency }}.

Dokončit objednávku

{{cl_company}}, {{cl_address}}. Odhlásit odběr

" } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "301", "name": "Opuštěný košík", "subject": "{{df_name|default('Dobrý den', true)}}, něco jste nechali v košíku", "preheader": "Váš košík na vás počká ještě pár dní", "editor": "html", "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "tags": [], "size": 465, "archived": false, "archivedAt": null, "readOnly": false, "usage": { "campaigns": 0, "automations": 0 }, "lastUsedAt": null, "check": { "errors": [], "warnings": [ "subject_long" ], "checkedAt": "2026-10-01T08:00:00.000Z" }, "content": { "editor": "html", "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

ve vašem košíku zůstalo {{ metadata.event.attributes.itemCount }} ks zboží za {{ metadata.event.attributes.total }} {{ metadata.event.attributes.currency }}.

Dokončit objednávku

{{cl_company}}, {{cl_address}}. Odhlásit odběr

", "design": null, "version": 1, "updatedAt": "2026-10-01T08:00:00.000Z" }, "settings": { "linkParams": [], "headers": [], "unsubscribePageId": null, "footerId": null }, "draft": { "pending": false, "savedAt": null, "publishedAt": null }, "activeUses": { "automations": 0, "emails": 0, "campaigns": 0 }, "publicUrl": "https://links.example.cz/template/1/72cf576a-85b2-474e-86e2-bfdbd1f4d38f" } ``` > **Nepodporováno:** seznam položek košíku v e-mailu. Data košíku nesou jen počet kusů a součet; odkaz vede do košíku na e-shopu. ## 2. Kontrola grafu bez uložení `POST /automations/validate` ukáže chyby (`errors`, graf nejde uložit) a neúplná nastavení (`incomplete`, nejde zapnout). Tady chybí šablona e-mailu: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/validate" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/validate" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "shopId": "1", "graph": { "nodes": [ { "id": "kosik", "type": "trigger_event", "config": { "event": "cart_updated", "shopId": "1", "reentry": "restart" } }, { "id": "pockat", "type": "wait", "config": { "mode": "duration", "value": 2, "unit": "hours" } }, { "id": "email", "type": "send_email", "config": {} } ], "edges": [ { "source": "kosik", "target": "pockat" }, { "source": "pockat", "target": "email" } ] } } JSON ``` ```json title="Odpověď: 200 OK" { "errors": [], "incomplete": [ { "node": "email", "field": "templateId", "code": "required" } ] } ``` ## 3. Založení automatizace ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Opuštěný košík", "shopId": "1", "description": "Připomenutí košíku po 2 hodinách", "tags": [ "e-shop" ], "graph": { "nodes": [ { "id": "kosik", "type": "trigger_event", "name": "Změna košíku", "position": { "x": 0, "y": 0 }, "config": { "event": "cart_updated", "shopId": "1", "reentry": "restart" } }, { "id": "pockat", "type": "wait", "name": "Počkat 2 hodiny", "position": { "x": 0, "y": 150 }, "config": { "mode": "duration", "value": 2, "unit": "hours" } }, { "id": "stale-v-kosiku", "type": "condition", "name": "Košík stále plný a bez objednávky", "position": { "x": 0, "y": 300 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "cart_items_count", "operator": "gt", "value": 0, "shopId": "1" }, { "type": "ordered_since_entry", "operator": "no", "shopId": "1" } ] } } }, { "id": "email", "type": "send_email", "name": "Připomenutí", "position": { "x": 0, "y": 450 }, "config": { "templateId": "301", "trackOpens": true, "trackClicks": true } } ], "edges": [ { "source": "kosik", "target": "pockat", "branch": "next" }, { "source": "pockat", "target": "stale-v-kosiku", "branch": "next" }, { "source": "stale-v-kosiku", "target": "email", "branch": "yes" } ] } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "81", "name": "Opuštěný košík", "shopId": "1", "status": "draft", "version": 1, "activeSince": null, "firstActivatedAt": null, "pausedReason": null, "tags": [ "e-shop" ], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "Připomenutí košíku po 2 hodinách", "graph": { "nodes": [ { "id": "kosik", "type": "trigger_event", "name": "Změna košíku", "note": "", "position": { "x": 0, "y": 0 }, "config": { "event": "cart_updated", "shopId": "1", "reentry": "restart" } }, { "id": "pockat", "type": "wait", "name": "Počkat 2 hodiny", "note": "", "position": { "x": 0, "y": 150 }, "config": { "mode": "duration", "unit": "hours", "value": 2 } }, { "id": "stale-v-kosiku", "type": "condition", "name": "Košík stále plný a bez objednávky", "note": "", "position": { "x": 0, "y": 300 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "cart_items_count", "value": 0, "shopId": "1", "operator": "gt" }, { "type": "ordered_since_entry", "shopId": "1", "operator": "no" } ] } } }, { "id": "email", "type": "send_email", "name": "Připomenutí", "note": "", "position": { "x": 0, "y": 450 }, "config": { "templateId": "301", "trackOpens": true, "trackClicks": true } } ], "edges": [ { "source": "kosik", "target": "pockat", "branch": "next" }, { "source": "pockat", "target": "stale-v-kosiku", "branch": "next" }, { "source": "stale-v-kosiku", "target": "email", "branch": "yes" } ] }, "issues": [], "triggers": {} } ``` Automatizace vznikne jako koncept (`status: "draft"`, verze 1). Odpověď má v `issues` vše, co brání zapnutí; tady je prázdné. ## 4. Zapnutí > **Pozor:** zapnutí posílá e-maily skutečným lidem. Než automatizaci zapnete, ukažte člověku spouštěč, e-maily a odesílatele. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/81/activate" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/81/activate" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "81", "name": "Opuštěný košík", "shopId": "1", "status": "active", "version": 1, "activeSince": "2026-10-01T08:00:00.000Z", "firstActivatedAt": "2026-10-01T08:00:00.000Z", "pausedReason": null, "tags": [ "e-shop" ], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "Připomenutí košíku po 2 hodinách", "graph": { "nodes": [ { "id": "kosik", "type": "trigger_event", "name": "Změna košíku", "note": "", "position": { "x": 0, "y": 0 }, "config": { "event": "cart_updated", "shopId": "1", "reentry": "restart" } }, { "id": "pockat", "type": "wait", "name": "Počkat 2 hodiny", "note": "", "position": { "x": 0, "y": 150 }, "config": { "mode": "duration", "unit": "hours", "value": 2 } }, { "id": "stale-v-kosiku", "type": "condition", "name": "Košík stále plný a bez objednávky", "note": "", "position": { "x": 0, "y": 300 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "cart_items_count", "value": 0, "shopId": "1", "operator": "gt" }, { "type": "ordered_since_entry", "shopId": "1", "operator": "no" } ] } } }, { "id": "email", "type": "send_email", "name": "Připomenutí", "note": "", "position": { "x": 0, "y": 450 }, "config": { "templateId": "301", "trackOpens": true, "trackClicks": true } } ], "edges": [ { "source": "kosik", "target": "pockat", "branch": "next" }, { "source": "pockat", "target": "stale-v-kosiku", "branch": "next" }, { "source": "stale-v-kosiku", "target": "email", "branch": "yes" } ] }, "issues": [], "triggers": {} } ``` Když něco chybí (neověřený odesílatel, chyba v obsahu šablony, neúplný uzel), server vrátí 400 `validation` / `graph` s `params.issues`. ## 5. Události košíku z e-shopu Při každé změně košíku přihlášeného zákazníka pošlete aktuální obsah. Kontakt najde Poštárna podle `email` nebo `contactId`; událost nikdy nezaloží nový kontakt (neznámý kontakt = 404). ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/contacts" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "email": "lucie.mala@example.cz", "shopId": "1", "purposeId": "1", "consentConfirmed": true, "firstName": "Lucie", "vocativeFirstName": "Lucie" } JSON ``` ```json title="Odpověď: 201 Created" { "id": "1201", "email": "lucie.mala@example.cz", "firstName": "Lucie", "lastName": "", "status": "subscribed", "engagement": "N", "excluded": false, "shopId": "1", "suppressionReason": null, "blacklisted": false, "blacklistedAt": null, "state": null, "createdAt": "2026-10-01T08:00:00.000Z", "phone": "", "mobile": "", "titleBefore": "", "titleAfter": "", "salutation": "", "salutationFormal": "", "vocativeFirstName": "Lucie", "vocativeLastName": "", "gender": null, "language": "cs", "company": "", "companyId": "", "street": "", "city": "", "postalCode": "", "note": "", "affiliateId": "", "country": null, "birthday": null, "nameDay": null, "source": "manual", "consentBasis": "imported", "statusAt": "2026-10-01T08:00:00.000Z", "consentAt": "2026-10-01T08:00:00.000Z", "consentWeak": false, "softBounces": 0, "lastSentAt": null, "lastOpenAt": null, "lastClickAt": null, "suppressedAt": null, "engagementAt": null, "suppressionNote": null, "customFields": {}, "updatedAt": "2026-10-01T08:00:00.000Z", "stats90d": { "received": 0, "opened": 0, "clicked": 0, "bestHour": null }, "lists": [], "recentActivities": [ { "id": "consent-1", "type": "status_change", "at": "2026-10-01T08:00:00.000Z", "title": "purpose_assigned" } ], "orders": [], "orderTotals": [], "editedFields": [], "sources": [] } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/contact-events" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/contact-events" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "type": "cart", "email": "lucie.mala@example.cz", "shopId": "1", "currency": "CZK", "total": "589.00", "items": [ { "code": "KAVA-250", "name": "Káva Brazílie 250 g", "quantity": 2, "price": "249.00", "url": "https://www.example.cz/kava-brazilie" }, { "code": "FILTR-02", "name": "Papírové filtry", "quantity": 1, "price": "91.00" } ] } JSON ``` ```json title="Odpověď: 201 Created" { "id": "9004" } ``` Vyprázdněný košík (nebo dokončená objednávka) pošlete jako prázdné `items`: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/contact-events" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/contact-events" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "type": "cart", "contactId": "1201", "shopId": "1", "items": [] } JSON ``` ```json title="Odpověď: 201 Created" { "id": "9005" } ``` • Nejvýš 60 událostí jednoho kontaktu za 10 minut (429 `rate_limited`). Posílejte stav košíku po změně, ne při každém zobrazení stránky. • Objednávku zapište přes [`POST /orders`](https://www.postarna.cz/docs/api/orders-feeds-coupons#objednavky); podmínka `ordered_since_entry` ji uvidí. ## 6. Sledování Počty po uzlech (`waiting` = kontakty, které právě čekají): ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/automations/81/counts" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/81/counts" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "nodes": {}, "runs": { "active": 0, "completed": 0, "exited": 0 } } ``` Historie jednoho kontaktu: `GET /automations/{id}/runs?contactId=1201`. Průchod kontaktu bez odeslání: `POST /automations/{id}/trace` s `{"contactId": "1201"}`. ## 7. Úprava běžící automatizace Běžící scénář jde uložit jen s `"confirmRunning": true`, jinak 409 `confirm`: ```bash title="Požadavek: PUT /api/v1/tenants/{tenant}/automations/81/graph" curl -sS -X PUT "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/81/graph" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "baseVersion": 1, "graph": { "nodes": [], "edges": [] } } JSON ``` ```json title="Odpověď: 409 Conflict" { "error": { "code": "conflict", "message": "confirm" } } ``` ## Varianty • **Dvě připomenutí:** za e-mail přidejte `wait` (1 den), znovu stejnou podmínku a druhý `send_email`, třeba se slevou (`{{ data.promoCode('Košík') }}`). • **Jen stálí zákazníci:** do podmínky přidejte pravidlo segmentu `order_count` (`"operator": "gte", "value": "1"`), nebo filtr na vlastní pole kontaktu. • **Cíl scénáře:** uzel `goal` s pravidlem `ordered_since_entry: yes` ukončí běh, jakmile zákazník objedná, ať je kdekoli. --- # Recept: série po nákupu **Cíl:** 3 dny po dokončení objednávky v 9:00 poslat poděkování s odkazem na hodnocení; kdo za 7 dní neklikne, dostane tip na použití produktu. **Potřebujete:** klíč s rolí `marketing_manager` (objednávky jsou v modulu `contacts`, automatizace v `campaigns`), mapu stavů objednávek (role `account_admin` pro `PUT /order-states`). ## Graf ```text title="Graf" [objednavka] trigger_event order_completed (reentry parallel) → [3-dny] wait 3 days → [rano] wait time_of_day 09:00 → [jak-chutna] send_email → [7-dni] wait 7 days → [klikl] condition email_activity clicked (jak-chutna) ├─ yes → konec └─ no → [tip] send_email ``` • `order_completed` nastane, když se objednávka poprvé dostane do skupiny `completed` (zaplacena, odeslána, doručena). • `reentry: "parallel"`: zákazník s druhou objednávkou dostane sérii znovu, i když ta první ještě běží. • Když se objednávka zruší, vrátí nebo smaže, běh skončí a další e-maily neodejdou. ## 1. Mapa stavů objednávek Poštárna potřebuje vědět, které vaše stavy znamenají nákup. Podívejte se, co už zná: ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/order-states" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/order-states" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "states": [ "new", "unpaid", "paid", "processing", "shipped", "delivered", "cancelled", "returned", "other" ], "items": [], "seen": [] } ``` Chybějící stavy doplníte přes `PUT /order-states` (viz [mapa stavů](https://www.postarna.cz/docs/api/orders-feeds-coupons#mapa-stavu)). ## 2. Šablony Data objednávky, která běh spustila, jsou v e-mailu v `metadata.order` (položky v `metadata.order.items`): ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/templates" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/templates" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Po nákupu: jak chutná", "subject": "Jak vám chutná?", "preheader": "Dejte nám vědět, jak jste spokojeni", "content": { "editor": "html", "design": null, "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

{% set o = metadata.order %}{% if o %}

děkujeme za objednávku {{ o.eshop_code }}.

    {% for item in o.items %}
  • {{ item.name }}
  • {% endfor %}
{% endif %}

Napsat hodnocení

{{cl_company}}, {{cl_address}}. Odhlásit odběr

" } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "304", "name": "Po nákupu: jak chutná", "subject": "Jak vám chutná?", "preheader": "Dejte nám vědět, jak jste spokojeni", "editor": "html", "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "tags": [], "size": 462, "archived": false, "archivedAt": null, "readOnly": false, "usage": { "campaigns": 0, "automations": 0 }, "lastUsedAt": null, "check": { "errors": [], "warnings": [], "checkedAt": "2026-10-01T08:00:00.000Z" }, "content": { "editor": "html", "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

{% set o = metadata.order %}{% if o %}

děkujeme za objednávku {{ o.eshop_code }}.

    {% for item in o.items %}
  • {{ item.name }}
  • {% endfor %}
{% endif %}

Napsat hodnocení

{{cl_company}}, {{cl_address}}. Odhlásit odběr

", "design": null, "version": 1, "updatedAt": "2026-10-01T08:00:00.000Z" }, "settings": { "linkParams": [], "headers": [], "unsubscribePageId": null, "footerId": null }, "draft": { "pending": false, "savedAt": null, "publishedAt": null }, "activeUses": { "automations": 0, "emails": 0, "campaigns": 0 }, "publicUrl": "https://links.example.cz/template/7/558d86a4-2556-4849-b817-02b81558d85f" } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/templates" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/templates" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Po nákupu: tip na přípravu", "subject": "Tip, jak připravit kávu doma", "preheader": "Tři kroky k lepší kávě", "content": { "editor": "html", "design": null, "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

tady jsou tři tipy, jak si doma připravit lepší kávu.

{{cl_company}}, {{cl_address}}. Odhlásit odběr

" } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "305", "name": "Po nákupu: tip na přípravu", "subject": "Tip, jak připravit kávu doma", "preheader": "Tři kroky k lepší kávě", "editor": "html", "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "tags": [], "size": 288, "archived": false, "archivedAt": null, "readOnly": false, "usage": { "campaigns": 0, "automations": 0 }, "lastUsedAt": null, "check": { "errors": [], "warnings": [], "checkedAt": "2026-10-01T08:00:00.000Z" }, "content": { "editor": "html", "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

tady jsou tři tipy, jak si doma připravit lepší kávu.

{{cl_company}}, {{cl_address}}. Odhlásit odběr

", "design": null, "version": 1, "updatedAt": "2026-10-01T08:00:00.000Z" }, "settings": { "linkParams": [], "headers": [], "unsubscribePageId": null, "footerId": null }, "draft": { "pending": false, "savedAt": null, "publishedAt": null }, "activeUses": { "automations": 0, "emails": 0, "campaigns": 0 }, "publicUrl": "https://links.example.cz/template/7/eafe9af1-437a-4904-be51-713bcd0113d9" } ``` ## 3. Automatizace ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Po nákupu", "shopId": "13", "graph": { "nodes": [ { "id": "objednavka", "type": "trigger_event", "config": { "event": "order_completed", "reentry": "parallel" } }, { "id": "3-dny", "type": "wait", "config": { "mode": "duration", "value": 3, "unit": "days" } }, { "id": "rano", "type": "wait", "config": { "mode": "time_of_day", "time": "09:00" } }, { "id": "jak-chutna", "type": "send_email", "config": { "templateId": "304" } }, { "id": "7-dni", "type": "wait", "config": { "mode": "duration", "value": 7, "unit": "days" } }, { "id": "klikl", "type": "condition", "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "email_activity", "operator": "clicked", "nodeId": "jak-chutna" } ] } } }, { "id": "tip", "type": "send_email", "config": { "templateId": "305" } } ], "edges": [ { "source": "objednavka", "target": "3-dny" }, { "source": "3-dny", "target": "rano" }, { "source": "rano", "target": "jak-chutna" }, { "source": "jak-chutna", "target": "7-dni" }, { "source": "7-dni", "target": "klikl" }, { "source": "klikl", "target": "tip", "branch": "no" } ] } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "84", "name": "Po nákupu", "shopId": "13", "status": "draft", "version": 1, "activeSince": null, "firstActivatedAt": null, "pausedReason": null, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "objednavka", "type": "trigger_event", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "event": "order_completed", "reentry": "parallel" } }, { "id": "3-dny", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "duration", "unit": "days", "value": 3 } }, { "id": "rano", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "time_of_day", "time": "09:00" } }, { "id": "jak-chutna", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "304" } }, { "id": "7-dni", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "duration", "unit": "days", "value": 7 } }, { "id": "klikl", "type": "condition", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "email_activity", "nodeId": "jak-chutna", "operator": "clicked" } ] } } }, { "id": "tip", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "305" } } ], "edges": [ { "source": "objednavka", "target": "3-dny", "branch": "next" }, { "source": "3-dny", "target": "rano", "branch": "next" }, { "source": "rano", "target": "jak-chutna", "branch": "next" }, { "source": "jak-chutna", "target": "7-dni", "branch": "next" }, { "source": "7-dni", "target": "klikl", "branch": "next" }, { "source": "klikl", "target": "tip", "branch": "no" } ] }, "issues": [], "triggers": {} } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/84/activate" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/84/activate" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "84", "name": "Po nákupu", "shopId": "13", "status": "active", "version": 1, "activeSince": "2026-10-01T08:00:00.000Z", "firstActivatedAt": "2026-10-01T08:00:00.000Z", "pausedReason": null, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "objednavka", "type": "trigger_event", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "event": "order_completed", "reentry": "parallel" } }, { "id": "3-dny", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "duration", "unit": "days", "value": 3 } }, { "id": "rano", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "time_of_day", "time": "09:00" } }, { "id": "jak-chutna", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "304" } }, { "id": "7-dni", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "duration", "unit": "days", "value": 7 } }, { "id": "klikl", "type": "condition", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "email_activity", "nodeId": "jak-chutna", "operator": "clicked" } ] } } }, { "id": "tip", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "305" } } ], "edges": [ { "source": "objednavka", "target": "3-dny", "branch": "next" }, { "source": "3-dny", "target": "rano", "branch": "next" }, { "source": "rano", "target": "jak-chutna", "branch": "next" }, { "source": "jak-chutna", "target": "7-dni", "branch": "next" }, { "source": "7-dni", "target": "klikl", "branch": "next" }, { "source": "klikl", "target": "tip", "branch": "no" } ] }, "issues": [], "triggers": {} } ``` ## 4. Objednávky z e-shopu Při vytvoření objednávky a při každé změně stavu pošlete celou objednávku. Kupující bez kontaktu dostane kontakt ve stavu `customer`, který e-maily nedostává; série tedy přijde jen zákazníkům s marketingovým souhlasem. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/orders" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/orders" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "id": "2026001234", "shopId": "13", "createdAt": "2026-10-01T09:30:00+02:00", "paidAt": "2026-10-01T09:31:00+02:00", "email": "karel.vesely@example.cz", "status": "Zaplaceno", "eshopCode": "2026001234", "orderUrl": "https://www.example.cz/objednavka/2026001234", "currency": "CZK", "totalWithVat": "1290.00", "totalWithoutVat": "1066.12", "items": [ { "id": "KAVA-1KG", "name": "Káva Kolumbie 1 kg", "quantity": 1, "unit": "ks", "price": { "withVat": "1290.00", "withoutVat": "1066.12", "currency": "CZK" }, "url": "https://www.example.cz/kava-kolumbie", "attributes": { "Category": "Káva", "Brand": "Example" } } ] } JSON ``` ```json title="Odpověď: 201 Created" { "change": "created", "order": { "id": "5001", "externalId": "2026001234", "eshopCode": "2026001234", "eshopName": "Example.cz", "shopId": "13", "createdAt": "2026-10-01T07:30:00.000Z", "paidAt": "2026-10-01T07:31:00.000Z", "email": "karel.vesely@example.cz", "contactId": "1205", "state": "paid", "status": "completed", "sourceStatus": "Zaplaceno", "orderUrl": "https://www.example.cz/objednavka/2026001234", "currency": "CZK", "totalWithVat": "1290.00", "totalWithoutVat": "1066.12", "itemCount": 1, "items": [ { "id": "1", "productCode": "KAVA-1KG", "name": "Káva Kolumbie 1 kg", "description": "", "price": { "withVat": "1290.00", "withoutVat": "1066.12", "currency": "CZK" }, "quantity": 1, "unit": "ks", "url": "https://www.example.cz/kava-kolumbie", "imageUrl": "", "attributes": { "Brand": "Example", "Category": "Káva" }, "paired": false } ], "conversion": null, "deleted": false, "receivedAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "seller": {}, "orderDelivery": {} } } ``` Změna stavu (pozor, zápis nahrazuje celou objednávku, posílejte všechna pole): ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/orders" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/orders" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "id": "2026001234", "shopId": "13", "createdAt": "2026-10-01T09:30:00+02:00", "paidAt": "2026-10-01T09:31:00+02:00", "email": "karel.vesely@example.cz", "status": "Předáno zákazníkovi", "eshopCode": "2026001234", "currency": "CZK", "totalWithVat": "1290.00", "items": [ { "id": "KAVA-1KG", "name": "Káva Kolumbie 1 kg", "quantity": 1, "price": { "withVat": "1290.00", "currency": "CZK" } } ] } JSON ``` ```json title="Odpověď: 200 OK" { "change": "updated", "order": { "id": "5001", "externalId": "2026001234", "eshopCode": "2026001234", "eshopName": "Example.cz", "shopId": "13", "createdAt": "2026-10-01T07:30:00.000Z", "paidAt": "2026-10-01T07:31:00.000Z", "email": "karel.vesely@example.cz", "contactId": "1205", "state": "paid", "status": "completed", "sourceStatus": "Předáno zákazníkovi", "orderUrl": "", "currency": "CZK", "totalWithVat": "1290.00", "totalWithoutVat": null, "itemCount": 1, "items": [ { "id": "2", "productCode": "KAVA-1KG", "name": "Káva Kolumbie 1 kg", "description": "", "price": { "withVat": "1290.00", "withoutVat": null, "currency": "CZK" }, "quantity": 1, "unit": "", "url": "", "imageUrl": "", "attributes": {}, "paired": false } ], "conversion": null, "deleted": false, "receivedAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "seller": {}, "orderDelivery": {} } } ``` ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/orders/5001" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/orders/5001" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "5001", "externalId": "2026001234", "eshopCode": "2026001234", "eshopName": "Example.cz", "shopId": "13", "createdAt": "2026-10-01T07:30:00.000Z", "paidAt": "2026-10-01T07:31:00.000Z", "email": "karel.vesely@example.cz", "contactId": "1205", "state": "paid", "status": "completed", "sourceStatus": "Předáno zákazníkovi", "orderUrl": "", "currency": "CZK", "totalWithVat": "1290.00", "totalWithoutVat": null, "itemCount": 1, "items": [ { "id": "2", "productCode": "KAVA-1KG", "name": "Káva Kolumbie 1 kg", "description": "", "price": { "withVat": "1290.00", "withoutVat": null, "currency": "CZK" }, "quantity": 1, "unit": "", "url": "", "imageUrl": "", "attributes": {}, "paired": false } ], "conversion": null, "deleted": false, "receivedAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "seller": {}, "orderDelivery": {} } ``` ## Varianty • **Jen první nákup:** do série přidejte za spouštěč podmínku `orders_count` (`"operator": "eq", "value": 1`). • **Podle kategorie:** podmínka `ordered_product_by_attribute` s `"limitToTriggerEvent": true` a `"attribute": "Category"` vybere jen objednávky s produktem dané kategorie. • **Kupte si znovu:** samostatná automatizace se spouštěčem `trigger_reorder` pošle připomenutí, když zákazníkovi dochází obvyklý interval mezi nákupy. --- # Recept: svátky se slevou **Cíl:** každý den v 8:00 poslat kontaktům, které mají svátek, přání s jednorázovým slevovým kódem. **Potřebujete:** klíč s rolí `account_admin` (zásobník kupónů je v modulu `settings`), slevové kódy z e-shopu. ## Jak Poštárna pozná svátek • Kontakt s vyplněným polem `nameDay` (`MM-DD`) slaví v ten den. • Kontakt bez něj slaví podle prvního slova křestního jména (bez ohledu na velká písmena a diakritiku) v kalendáři svého jazyka: slovenský pro jazyk `sk`, kontakt bez jazyka podle jazyka e-shopu, jinak český. Kontakt bez jména svátek nemá. • Spouštěč `trigger_date` s `kind: "name_day"` projde kontakty e-shopu jednou denně v čase `at` (místní čas firmy). `offsetDays` posune den (například `-1` = den předem). ## 1. Zásobník kupónů a kódy ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/coupon-stacks" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/coupon-stacks" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Svátek", "shopId": "11", "mergeKey": "svatek", "note": "Sleva 15 % k svátku" } JSON ``` ```json title="Odpověď: 201 Created" { "id": "11", "name": "Svátek", "shopId": "11", "mergeKey": "svatek", "tag": "{{coupon_svatek}}", "note": "Sleva 15 % k svátku", "counts": { "total": 0, "free": 0, "assigned": 0, "used": 0 }, "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z" } ``` Kódy vložte jako text, jeden na řádek (duplicitní a neplatné se přeskočí): ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/coupon-stacks/11/codes" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/coupon-stacks/11/codes" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "text": "SVATEK-7Q2K\nSVATEK-9P4M\nSVATEK-3X8D\n" } JSON ``` ```json title="Odpověď: 200 OK" { "counts": { "added": 3, "duplicate": 0, "invalid": 0, "total": 3 }, "stack": { "id": "11", "name": "Svátek", "shopId": "11", "mergeKey": "svatek", "tag": "{{coupon_svatek}}", "note": "Sleva 15 % k svátku", "counts": { "total": 3, "free": 3, "assigned": 0, "used": 0 }, "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z" } } ``` ## 2. Šablona s kódem `{{ data.promoCode('Svátek') }}` vezme pro každý e-mail nový volný kód ze zásobníku s **názvem** „Svátek“ (totéž dělá značka `{{coupon_svatek}}` podle klíče). `{{df_salution}}` je oslovení v 5. pádě. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/templates" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/templates" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Svátek", "subject": "Všechno nejlepší k svátku, {{df_salution|default('milý zákazníku', true)}}", "preheader": "Dárek k svátku: 15 % sleva", "content": { "editor": "html", "design": null, "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

k dnešnímu svátku vám přejeme vše nejlepší. Dárkem je sleva 15 % s kódem {{ data.promoCode('Svátek') }}.

Nakoupit se slevou

{{cl_company}}, {{cl_address}}. Odhlásit odběr

" } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "303", "name": "Svátek", "subject": "Všechno nejlepší k svátku, {{df_salution|default('milý zákazníku', true)}}", "preheader": "Dárek k svátku: 15 % sleva", "editor": "html", "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "tags": [], "size": 425, "archived": false, "archivedAt": null, "readOnly": false, "usage": { "campaigns": 0, "automations": 0 }, "lastUsedAt": null, "check": { "errors": [], "warnings": [ "subject_long" ], "checkedAt": "2026-10-01T08:00:00.000Z" }, "content": { "editor": "html", "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

k dnešnímu svátku vám přejeme vše nejlepší. Dárkem je sleva 15 % s kódem {{ data.promoCode('Svátek') }}.

Nakoupit se slevou

{{cl_company}}, {{cl_address}}. Odhlásit odběr

", "design": null, "version": 1, "updatedAt": "2026-10-01T08:00:00.000Z" }, "settings": { "linkParams": [], "headers": [], "unsubscribePageId": null, "footerId": null }, "draft": { "pending": false, "savedAt": null, "publishedAt": null }, "activeUses": { "automations": 0, "emails": 0, "campaigns": 0 }, "publicUrl": "https://links.example.cz/template/6/2dbee2ba-4435-418f-a8f4-da1f961a9d1a" } ``` > **Pozor:** když kódy dojdou, e-mail kontaktu neodejde (selhání `customizationDataboxOutOfPromocodes`). Hlídejte `counts.free` zásobníku. ## 3. Automatizace ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Svátek", "shopId": "11", "graph": { "nodes": [ { "id": "svatek", "type": "trigger_date", "config": { "kind": "name_day", "at": "08:00", "reentry": "parallel" } }, { "id": "prani", "type": "send_email", "config": { "templateId": "303" } } ], "edges": [ { "source": "svatek", "target": "prani" } ] } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "83", "name": "Svátek", "shopId": "11", "status": "draft", "version": 1, "activeSince": null, "firstActivatedAt": null, "pausedReason": null, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "svatek", "type": "trigger_date", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "at": "08:00", "kind": "name_day", "reentry": "parallel" } }, { "id": "prani", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "303" } } ], "edges": [ { "source": "svatek", "target": "prani", "branch": "next" } ] }, "issues": [], "triggers": {} } ``` ## 4. Test bez odeslání `POST /automations/{id}/test` ukáže, kolik kontaktů by spouštěč vzal dnes (`scope: "today"`) a kolik by jich došlo do každého uzlu. Nic se neuloží ani neodešle: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/83/test" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/83/test" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' {} JSON ``` ```json title="Odpověď: 200 OK" { "scope": "today", "days": null, "since": null, "entered": 0, "waiting": 0, "left": 0, "nodes": { "svatek": { "reached": 0, "waiting": 0, "left": 0, "outputs": { "next": 0 } }, "prani": { "reached": 0, "waiting": 0, "left": 0, "outputs": { "next": 0 } } }, "testedAt": "2026-10-01T08:00:00.000Z" } ``` ## 5. Zapnutí a stav kódů ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/83/activate" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/83/activate" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "83", "name": "Svátek", "shopId": "11", "status": "active", "version": 1, "activeSince": "2026-10-01T08:00:00.000Z", "firstActivatedAt": "2026-10-01T08:00:00.000Z", "pausedReason": null, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "svatek", "type": "trigger_date", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "at": "08:00", "kind": "name_day", "reentry": "parallel" } }, { "id": "prani", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "303" } } ], "edges": [ { "source": "svatek", "target": "prani", "branch": "next" } ] }, "issues": [], "triggers": {} } ``` ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/coupon-stacks/11" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/coupon-stacks/11" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "11", "name": "Svátek", "shopId": "11", "mergeKey": "svatek", "tag": "{{coupon_svatek}}", "note": "Sleva 15 % k svátku", "counts": { "total": 3, "free": 3, "assigned": 0, "used": 0 }, "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z" } ``` ## Varianty • **Narozeniny:** `kind: "birthday"` (pole `birthday`); 29. února se v jiných letech slaví 28. února. • **Výročí z vlastního pole:** `kind: "custom_date"`, `field: "cf:"` datového vlastního pole. • **Svátky v kalendáři firmy (Vánoce, Den matek):** `kind: "holiday"`, `dates: ["12-24"]`; projde všechny kontakty e-shopu. • **Výročí prvního nákupu:** `kind: "first_order"`, `days: 365`. --- # Recept: návrat neaktivních zákazníků **Cíl:** zákazník, který nenakoupil 120 dní, dostane připomenutí; když do týdne nenakoupí, druhý e-mail s výhodou. Každý zákazník projde sérií jen jednou. ## Graf ```text title="Graf" [kazdy-den] trigger_repeat every 1 day, filter: poslední objednávka starší než 120 dní A aspoň 1 objednávka, reentry once → [email-1] send_email → [tyden] wait 7 days → [nakoupil] condition ordered_since_entry ├─ yes → konec └─ no → [email-2] send_email [cil] goal: ordered_since_entry (kdo nakoupí, opouští scénář kdekoli) ``` • `trigger_repeat` projde každý den (od `startAt`) kontakty e-shopu, které splní `filter`. Filtr je strom pravidel segmentu a podmínek, které nepotřebují běh. • `reentry: "once"`: kontakt vstoupí jednou provždy, i když filtr splňuje každý den. • Uzel `goal` nemá hrany; před každým krokem se kontroluje, a kdo cíl splní, scénář opouští. ## 1. Šablony ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/templates" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/templates" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Win-back 1", "subject": "Chybíte nám", "preheader": "Podívejte se, co je u nás nového", "content": { "editor": "html", "design": null, "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

dlouho jste u nás nenakoupili. Podívejte se na novinky.

Novinky

{{cl_company}}, {{cl_address}}. Odhlásit odběr

" } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "306", "name": "Win-back 1", "subject": "Chybíte nám", "preheader": "Podívejte se, co je u nás nového", "editor": "html", "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "tags": [], "size": 346, "archived": false, "archivedAt": null, "readOnly": false, "usage": { "campaigns": 0, "automations": 0 }, "lastUsedAt": null, "check": { "errors": [], "warnings": [], "checkedAt": "2026-10-01T08:00:00.000Z" }, "content": { "editor": "html", "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

dlouho jste u nás nenakoupili. Podívejte se na novinky.

Novinky

{{cl_company}}, {{cl_address}}. Odhlásit odběr

", "design": null, "version": 1, "updatedAt": "2026-10-01T08:00:00.000Z" }, "settings": { "linkParams": [], "headers": [], "unsubscribePageId": null, "footerId": null }, "draft": { "pending": false, "savedAt": null, "publishedAt": null }, "activeUses": { "automations": 0, "emails": 0, "campaigns": 0 }, "publicUrl": "https://links.example.cz/template/11/1e8cfd05-8113-4e6b-9676-ad3dee1e849c" } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/templates" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/templates" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Win-back 2", "subject": "Poslední připomenutí", "preheader": "Doprava zdarma jen tento týden", "content": { "editor": "html", "design": null, "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

tento týden pro vás máme dopravu zdarma.

{{cl_company}}, {{cl_address}}. Odhlásit odběr

" } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "307", "name": "Win-back 2", "subject": "Poslední připomenutí", "preheader": "Doprava zdarma jen tento týden", "editor": "html", "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "tags": [], "size": 273, "archived": false, "archivedAt": null, "readOnly": false, "usage": { "campaigns": 0, "automations": 0 }, "lastUsedAt": null, "check": { "errors": [], "warnings": [], "checkedAt": "2026-10-01T08:00:00.000Z" }, "content": { "editor": "html", "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

tento týden pro vás máme dopravu zdarma.

{{cl_company}}, {{cl_address}}. Odhlásit odběr

", "design": null, "version": 1, "updatedAt": "2026-10-01T08:00:00.000Z" }, "settings": { "linkParams": [], "headers": [], "unsubscribePageId": null, "footerId": null }, "draft": { "pending": false, "savedAt": null, "publishedAt": null }, "activeUses": { "automations": 0, "emails": 0, "campaigns": 0 }, "publicUrl": "https://links.example.cz/template/11/8857a9fd-878f-4149-9ad1-55f5c0ae4115" } ``` ## 2. Automatizace ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Win-back po 120 dnech", "shopId": "21", "graph": { "nodes": [ { "id": "kazdy-den", "type": "trigger_repeat", "config": { "every": { "value": 1, "unit": "days" }, "startAt": "2026-10-02T10:00", "reentry": "once", "filter": { "type": "group", "match": "all", "rules": [ { "type": "last_order", "operator": "older_than_days", "value": "120", "shopId": "21" }, { "type": "order_count", "operator": "gte", "value": "1", "shopId": "21" } ] } } }, { "id": "email-1", "type": "send_email", "config": { "templateId": "306" } }, { "id": "tyden", "type": "wait", "config": { "mode": "duration", "value": 7, "unit": "days" } }, { "id": "nakoupil", "type": "condition", "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "operator": "yes", "shopId": "21" } ] } } }, { "id": "email-2", "type": "send_email", "config": { "templateId": "307" } }, { "id": "cil", "type": "goal", "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "operator": "yes", "shopId": "21" } ] } } } ], "edges": [ { "source": "kazdy-den", "target": "email-1" }, { "source": "email-1", "target": "tyden" }, { "source": "tyden", "target": "nakoupil" }, { "source": "nakoupil", "target": "email-2", "branch": "no" } ] } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "85", "name": "Win-back po 120 dnech", "shopId": "21", "status": "draft", "version": 1, "activeSince": null, "firstActivatedAt": null, "pausedReason": null, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "kazdy-den", "type": "trigger_repeat", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "every": { "unit": "days", "value": 1 }, "filter": { "type": "group", "match": "all", "rules": [ { "type": "last_order", "value": "120", "shopId": "21", "operator": "older_than_days" }, { "type": "order_count", "value": "1", "shopId": "21", "operator": "gte" } ] }, "reentry": "once", "startAt": "2026-10-02T10:00" } }, { "id": "email-1", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "306" } }, { "id": "tyden", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "duration", "unit": "days", "value": 7 } }, { "id": "nakoupil", "type": "condition", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "shopId": "21", "operator": "yes" } ] } } }, { "id": "email-2", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "307" } }, { "id": "cil", "type": "goal", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "shopId": "21", "operator": "yes" } ] } } } ], "edges": [ { "source": "kazdy-den", "target": "email-1", "branch": "next" }, { "source": "email-1", "target": "tyden", "branch": "next" }, { "source": "tyden", "target": "nakoupil", "branch": "next" }, { "source": "nakoupil", "target": "email-2", "branch": "no" } ] }, "issues": [], "triggers": {} } ``` Detail ukazuje graf, jak ho server uložil (s výchozími hodnotami) a `issues` (prázdné = jde zapnout): ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/automations/85" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/85" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "85", "name": "Win-back po 120 dnech", "shopId": "21", "status": "draft", "version": 1, "activeSince": null, "firstActivatedAt": null, "pausedReason": null, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "kazdy-den", "type": "trigger_repeat", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "every": { "unit": "days", "value": 1 }, "filter": { "type": "group", "match": "all", "rules": [ { "type": "last_order", "value": "120", "shopId": "21", "operator": "older_than_days" }, { "type": "order_count", "value": "1", "shopId": "21", "operator": "gte" } ] }, "reentry": "once", "startAt": "2026-10-02T10:00" } }, { "id": "email-1", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "306" } }, { "id": "tyden", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "duration", "unit": "days", "value": 7 } }, { "id": "nakoupil", "type": "condition", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "shopId": "21", "operator": "yes" } ] } } }, { "id": "email-2", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "307" } }, { "id": "cil", "type": "goal", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "shopId": "21", "operator": "yes" } ] } } } ], "edges": [ { "source": "kazdy-den", "target": "email-1", "branch": "next" }, { "source": "email-1", "target": "tyden", "branch": "next" }, { "source": "tyden", "target": "nakoupil", "branch": "next" }, { "source": "nakoupil", "target": "email-2", "branch": "no" } ] }, "issues": [], "triggers": {} } ``` ## 3. Zapnutí, pozastavení a verze ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/85/activate" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/85/activate" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "85", "name": "Win-back po 120 dnech", "shopId": "21", "status": "active", "version": 1, "activeSince": "2026-10-01T08:00:00.000Z", "firstActivatedAt": "2026-10-01T08:00:00.000Z", "pausedReason": null, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "kazdy-den", "type": "trigger_repeat", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "every": { "unit": "days", "value": 1 }, "filter": { "type": "group", "match": "all", "rules": [ { "type": "last_order", "value": "120", "shopId": "21", "operator": "older_than_days" }, { "type": "order_count", "value": "1", "shopId": "21", "operator": "gte" } ] }, "reentry": "once", "startAt": "2026-10-02T10:00" } }, { "id": "email-1", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "306" } }, { "id": "tyden", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "duration", "unit": "days", "value": 7 } }, { "id": "nakoupil", "type": "condition", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "shopId": "21", "operator": "yes" } ] } } }, { "id": "email-2", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "307" } }, { "id": "cil", "type": "goal", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "shopId": "21", "operator": "yes" } ] } } } ], "edges": [ { "source": "kazdy-den", "target": "email-1", "branch": "next" }, { "source": "email-1", "target": "tyden", "branch": "next" }, { "source": "tyden", "target": "nakoupil", "branch": "next" }, { "source": "nakoupil", "target": "email-2", "branch": "no" } ] }, "issues": [], "triggers": {} } ``` Pozastavení nechá čekající kontakty na místě; po dalším zapnutí pokračují: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/85/pause" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/85/pause" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "85", "name": "Win-back po 120 dnech", "shopId": "21", "status": "paused", "version": 1, "activeSince": null, "firstActivatedAt": "2026-10-01T08:00:00.000Z", "pausedReason": "manual", "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "kazdy-den", "type": "trigger_repeat", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "every": { "unit": "days", "value": 1 }, "filter": { "type": "group", "match": "all", "rules": [ { "type": "last_order", "value": "120", "shopId": "21", "operator": "older_than_days" }, { "type": "order_count", "value": "1", "shopId": "21", "operator": "gte" } ] }, "reentry": "once", "startAt": "2026-10-02T10:00" } }, { "id": "email-1", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "306" } }, { "id": "tyden", "type": "wait", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "mode": "duration", "unit": "days", "value": 7 } }, { "id": "nakoupil", "type": "condition", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "shopId": "21", "operator": "yes" } ] } } }, { "id": "email-2", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "307" } }, { "id": "cil", "type": "goal", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "definition": { "type": "group", "match": "all", "rules": [ { "type": "ordered_since_entry", "shopId": "21", "operator": "yes" } ] } } } ], "edges": [ { "source": "kazdy-den", "target": "email-1", "branch": "next" }, { "source": "email-1", "target": "tyden", "branch": "next" }, { "source": "tyden", "target": "nakoupil", "branch": "next" }, { "source": "nakoupil", "target": "email-2", "branch": "no" } ] }, "issues": [], "triggers": {} } ``` ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/automations/85/versions" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/85/versions" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "items": [ { "version": 1, "status": "draft", "savedAt": "2026-10-01T08:00:00.000Z", "savedBy": "api_key:11", "nodes": 6, "current": true } ] } ``` ## Tipy • Filtr spouštěče počítá dny v časové zóně firmy; `last_order older_than_days 120` znamená „má objednávku a poslední je starší než 120 dní“. • Pro neotevírající odběratele (místo zákazníků) použijte pravidlo `field` `lastOpenAt` `not_in_last_days` `"180"`. • Odměnu v druhém e-mailu dejte jednorázovým kódem (`data.promoCode`), viz [recept na svátky](https://www.postarna.cz/docs/api/recipe-name-days). --- # Recept: přihlašovací formulář s potvrzením **Cíl:** formulář na webu, který po potvrzení e-mailem přidá návštěvníka do seznamu, zapíše souhlas a pošle uvítací e-mail. Tohle je správná cesta, když **nemáte doložený souhlas**: kontakt vznikne jako čekající (`pending`) a přihlášený bude až po kliknutí na odkaz v potvrzovacím e-mailu. Přes `POST /contacts` zakládejte jen kontakty s už doloženým souhlasem. ## 1. Seznam pro odběratele ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/lists" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/lists" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Newsletter z webu", "publicName": "Novinky e-shopu", "shopId": "5", "notifyOnUnsubscribe": false, "notifyOnAdd": false, "note": "" } JSON ``` ```json title="Odpověď: 201 Created" { "id": "42", "name": "Newsletter z webu", "publicName": "Novinky e-shopu", "shopId": "5", "systemKind": null, "locked": false, "manualMembers": true, "tags": [], "counts": { "total": 0, "byBucket": { "active": 0, "unconfirmed": 0, "unsubscribed": 0, "bounced": 0, "complained": 0, "blacklisted": 0 } }, "createdAt": "2026-10-01T08:00:00.000Z", "notifyOnUnsubscribe": false, "notifyOnAdd": false, "note": "" } ``` ## 2. Formulář `purposeId` je účel zpracování, ke kterému se souhlas zapíše; `consentText` je přesné znění souhlasu, které formulář ukáže a Poštárna uloží k přihlášce. `fields` přidá pole kromě e-mailu (`firstName`, `lastName` a další). ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/forms" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/forms" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Patička webu", "shopId": "5", "status": "active", "fields": [ { "field": "firstName", "required": false } ], "listIds": [ "42" ], "purposeId": "3", "consentText": "Souhlasím se zasíláním obchodních sdělení.", "title": "Odebírejte novinky", "description": "Jednou za měsíc tipy a novinky.", "submitLabel": "Přihlásit", "successUrl": "https://www.example.cz/dekujeme", "confirmedUrl": "https://www.example.cz/potvrzeno" } JSON ``` ```json title="Odpověď: 201 Created" { "previewUrl": "https://links.example.cz/f/3/50af3dc2-488b-4715-a1b3-3d059af683d8?preview=1", "id": "21", "name": "Patička webu", "shopId": "5", "status": "active", "listIds": [ "42" ], "purposeId": "3", "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "kind": "classic", "tags": [], "fills": 0, "publicId": "50af3dc2-488b-4715-a1b3-3d059af683d8", "fields": [ { "label": "", "error": "", "placeholder": "", "field": "email", "required": true }, { "label": "", "error": "", "placeholder": "", "field": "firstName", "required": false } ], "consentText": "Souhlasím se zasíláním obchodních sdělení.", "consentVersion": 1, "title": "Odebírejte novinky", "description": "Jednou za měsíc tipy a novinky.", "submitLabel": "Přihlásit", "successUrl": "https://www.example.cz/dekujeme", "confirmedUrl": "https://www.example.cz/potvrzeno", "captcha": false, "hostedUrl": "https://links.example.cz/f/3/50af3dc2-488b-4715-a1b3-3d059af683d8", "popup": null, "scriptUrl": null, "design": { "template": "classic", "style": "basic-bb2d2d", "width": 320, "image": "", "imagePosition": "top", "showTitle": true, "showText": true, "titleColor": "", "textColor": "", "buttonColor": "", "buttonTextColor": "" }, "settings": { "existingMode": "update", "errorUrl": "", "notify": [], "newTab": false, "keepParams": false, "affiliateParam": "", "thanksHtml": "", "typoCheck": true, "doi": true, "doiTemplateId": null, "senderName": "", "senderEmail": "", "replyTo": "", "doiAfter": "thanks", "doiThanksHtml": "", "consentMode": "checkbox", "consentLabel": "", "consentLinkText": "", "consentLinkUrl": "", "extraPurposes": [] } } ``` • `successUrl`: kam formulář přesměruje po odeslání; `confirmedUrl`: kam vede potvrzovací odkaz. • Formulář je ve výchozím nastavení double opt-in. Potvrzovací e-mail je systémový (bez obchodního obsahu a patičky), odchází z odesílatele formuláře (`settings.senderEmail`), jinak z ověřeného výchozího odesílatele e-shopu, a nejvýš 3krát za den na jednu adresu. • `previewUrl` je náhled formuláře, `publicId` jeho veřejné ID. ## 3. Kód pro web ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/forms/21/embed" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/forms/21/embed" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "html": "\n
\n
\n
\n

\n
\n \n

Example s.r.o., Ukázková 1, 110 00 Praha 1 Zásady ochrany osobních údajů

\n
\n", "styled": "\n

Odebírejte novinky

Jednou za měsíc tipy a novinky.

Example s.r.o., Ukázková 1, 110 00 Praha 1 Zásady ochrany osobních údajů

\n", "url": "https://links.example.cz/f/3/50af3dc2-488b-4715-a1b3-3d059af683d8", "script": "" } ``` Vložte `html` na web. Formulář posílá data na odkazovou doménu e-shopu (`/f//`); stránky po odeslání a potvrzení vykresluje Poštárna. • Ochrana proti robotům: skryté pole (vyplněné = tichý úspěch bez zápisu), volitelně captcha. • Limity: 10 odeslání za hodinu z jedné IP adresy na formulář, 3 za den na jednu e-mailovou adresu, 300 za hodinu na firmu (429). • Pro každou adresu je odpověď stejná, takže formulář neprozradí, kdo už je v databázi. ## 4. Co se stane po odeslání 1. Kontakt vznikne (nebo se najde) ve stavu `pending`, členství v seznamech je `unconfirmed`, zapíše se žádost o souhlas s IP adresou, prohlížečem, stránkou a přesným textem souhlasu. 2. Odejde potvrzovací e-mail. Odkaz platí 7 dní. 3. Po kliknutí: kontakt `subscribed` (`consentBasis: "double_opt_in"`), členství `confirmed`, souhlas s účelem formuláře, vyplněná pole formuláře se uloží do kontaktu, přesměrování na `confirmedUrl`. 4. Odhlášený kontakt se tak znovu přihlásí; nedoručitelná adresa nebo stížnost nedostane nic. ## 5. Uvítací e-mail po potvrzení Spouštěč `form_submitted` s `formId` pustí kontakt do scénáře, jakmile potvrdí odběr (nepotvrzený kontakt e-maily nedostává): ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/templates" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/templates" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Uvítání", "subject": "Vítejte mezi odběrateli", "preheader": "Děkujeme za potvrzení odběru", "content": { "editor": "html", "design": null, "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

děkujeme za potvrzení odběru.

{{cl_company}}, {{cl_address}}. Odhlásit odběr

" } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "302", "name": "Uvítání", "subject": "Vítejte mezi odběrateli", "preheader": "Děkujeme za potvrzení odběru", "editor": "html", "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "tags": [], "size": 262, "archived": false, "archivedAt": null, "readOnly": false, "usage": { "campaigns": 0, "automations": 0 }, "lastUsedAt": null, "check": { "errors": [], "warnings": [], "checkedAt": "2026-10-01T08:00:00.000Z" }, "content": { "editor": "html", "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

děkujeme za potvrzení odběru.

{{cl_company}}, {{cl_address}}. Odhlásit odběr

", "design": null, "version": 1, "updatedAt": "2026-10-01T08:00:00.000Z" }, "settings": { "linkParams": [], "headers": [], "unsubscribePageId": null, "footerId": null }, "draft": { "pending": false, "savedAt": null, "publishedAt": null }, "activeUses": { "automations": 0, "emails": 0, "campaigns": 0 }, "publicUrl": "https://links.example.cz/template/3/e2ad6880-3f53-4fc1-988d-a4893a6ab8a3" } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Uvítání z formuláře", "shopId": "5", "graph": { "nodes": [ { "id": "formular", "type": "trigger_event", "config": { "event": "form_submitted", "formId": "21", "reentry": "once" } }, { "id": "uvitani", "type": "send_email", "config": { "templateId": "302" } } ], "edges": [ { "source": "formular", "target": "uvitani" } ] } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "82", "name": "Uvítání z formuláře", "shopId": "5", "status": "draft", "version": 1, "activeSince": null, "firstActivatedAt": null, "pausedReason": null, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "formular", "type": "trigger_event", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "event": "form_submitted", "formId": "21", "reentry": "once" } }, { "id": "uvitani", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "302" } } ], "edges": [ { "source": "formular", "target": "uvitani", "branch": "next" } ] }, "issues": [], "triggers": {} } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/automations/82/activate" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/82/activate" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "82", "name": "Uvítání z formuláře", "shopId": "5", "status": "active", "version": 1, "activeSince": "2026-10-01T08:00:00.000Z", "firstActivatedAt": "2026-10-01T08:00:00.000Z", "pausedReason": null, "tags": [], "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": { "entered": 0, "active": 0, "sent": 0 }, "description": "", "graph": { "nodes": [ { "id": "formular", "type": "trigger_event", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "event": "form_submitted", "formId": "21", "reentry": "once" } }, { "id": "uvitani", "type": "send_email", "name": "", "note": "", "position": { "x": 0, "y": 0 }, "config": { "templateId": "302" } } ], "edges": [ { "source": "formular", "target": "uvitani", "branch": "next" } ] }, "issues": [], "triggers": {} } ``` ## Varianty • **Vlastní formulář na webu:** postavte vlastní HTML a posílejte stejná pole na adresu `action` z kódu formuláře (`email`, pole formuláře, souhlasy). Nevolejte k tomu `POST /contacts`, to je jen pro doložené souhlasy. • **Přihlášení odkudkoli:** místo `form_submitted` použijte `subscribed` se `sources: ["signup_form"]`. • **Pop-up:** formulář s `kind: "popup"` a nastavením `popup` (pole popsaná ve [skupině Formuláře](https://www.postarna.cz/docs/api/reference-forms)). --- # Recept: import kontaktů z CSV **Cíl:** nahrát kontakty z CSV souboru se souhlasem, který máte doložený, a ověřit výsledek. **Potřebujete:** klíč s modulem `contacts` na úrovni `full`. ## 1. Nahrání souboru Dvě možnosti: • `multipart/form-data` s polem `file` (soubor do 64 MB a 300 000 řádků, kódování UTF-8, UTF-16 nebo windows-1250 se pozná samo) a volitelně `delimiter`, `quote`, `hasHeader`, `encoding`. • JSON `{"text": "...", "delimiter", "quote", "hasHeader"}` s obsahem do 5 MB. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/imports/files" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/imports/files" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "text": "email;jmeno;prijmeni;mesto\nmarie.dvorakova@example.cz;Marie;Dvořáková;Praha\ntomas.cerny@example.cz;Tomáš;Černý;Ostrava\nchybna-adresa;Jan;Bez;Plzeň\n", "delimiter": ";", "quote": "\"", "hasHeader": true } JSON ``` ```json title="Odpověď: 201 Created" { "fileId": "71", "fileName": "vlozeny-text.csv", "size": 155, "delimiter": ";", "quote": "\"", "hasHeader": true, "encoding": "utf-8", "columns": [ "email", "jmeno", "prijmeni", "mesto" ], "rowCount": 3, "sample": [ [ "marie.dvorakova@example.cz", "Marie", "Dvořáková", "Praha" ], [ "tomas.cerny@example.cz", "Tomáš", "Černý", "Ostrava" ], [ "chybna-adresa", "Jan", "Bez", "Plzeň" ] ], "suggestedKind": "csv", "suggestedMapping": [ "email", "firstName", "lastName", "city" ] } ``` Odpověď má `fileId`, rozpoznané sloupce, ukázku řádků a `suggestedMapping` (návrh, které pole je ve kterém sloupci). Soubor se drží 24 hodin. ## 2. Náhled `mapping` má jednu položku na sloupec souboru, v pořadí: název pole, nebo `null` (sloupec přeskočit). Právě jeden sloupec musí být `email`. Pole: `email`, `firstName`, `lastName`, `fullName`, `titleBefore`, `titleAfter`, `phone`, `mobile`, `company`, `companyId`, `street`, `city`, `postalCode`, `country`, `language`, `gender`, `birthday`, `note`, `newsletterConsent`, `newsletterConsentAt`, `registeredAt` a vlastní pole. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/imports/preview" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/imports/preview" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "fileId": "71", "mapping": [ "email", "firstName", "lastName", "city" ], "mode": "upsert", "shopId": "9", "listIds": [] } JSON ``` ```json title="Odpověď: 200 OK" { "counts": { "rows": 3, "create": 2, "update": 0, "skipSuppressed": 0, "skipMissing": 0, "invalid": 1, "duplicate": 0, "unsubscribe": 0, "remove": 0, "blacklist": 0 }, "rows": [ { "row": 2, "email": "marie.dvorakova@example.cz", "action": "create", "error": null, "field": null, "values": { "email": "marie.dvorakova@example.cz", "firstName": "Marie", "lastName": "Dvořáková", "city": "Praha" }, "consent": true }, { "row": 3, "email": "tomas.cerny@example.cz", "action": "create", "error": null, "field": null, "values": { "email": "tomas.cerny@example.cz", "firstName": "Tomáš", "lastName": "Černý", "city": "Ostrava" }, "consent": true }, { "row": 4, "email": "chybna-adresa", "action": "invalid", "error": "email_invalid", "field": "email", "values": { "email": "chybna-adresa", "firstName": "Jan", "lastName": "Bez", "city": "Plzeň" }, "consent": null } ], "report": { "consent": { "optIn": 2, "none": 0, "keptUnsubscribed": 0 }, "merge": { "existing": 0, "fromSources": {}, "fieldsUpdated": 0, "fieldsKeptEdited": 0 }, "dropped": {} } } ``` `counts` říká, kolik řádků se založí, aktualizuje, přeskočí (potlačené adresy, chyby) a proč; `rows` ukazuje první řádky s jejich výsledkem. ## 3. Spuštění • `mode`: `upsert` (založit i aktualizovat), `update_only`, nebo hromadné odhlášení `unsubscribe`, odebrání `remove`, blacklist `blacklist`. • `purposeId` a `consentConfirmed: true`: potvrzujete, že ke všem kontaktům máte doložený souhlas s tímto účelem (u `unsubscribe`, `remove` a `blacklist` souhlas potřeba není). • `listIds`: ruční seznamy, do kterých kontakty přibudou. • `runAutomations`: výchozí `false` = import nespustí žádnou automatizaci (ani „nový kontakt“ či „přidání do seznamu“). Zapněte jen vědomě. • `kind`: `csv`, nebo exporty Shoptetu `shoptet_customers` a `shoptet_newsletter`. ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/imports" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/imports" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Kontakty z veletrhu", "source": "csv", "fileId": "71", "mapping": [ "email", "firstName", "lastName", "city" ], "mode": "upsert", "shopId": "9", "listIds": [], "purposeId": "5", "consentConfirmed": true } JSON ``` ```json title="Odpověď: 201 Created" { "id": "61", "name": "Kontakty z veletrhu", "status": "finished", "kind": "csv", "fileName": "vlozeny-text.csv", "shopId": "9", "mode": "upsert", "listIds": [], "createdAt": "2026-10-01T08:00:00.000Z", "startedAt": "2026-10-01T08:00:00.000Z", "finishedAt": "2026-10-01T08:00:00.000Z", "progress": { "processed": 3, "total": 3 }, "counts": { "rows": 3, "create": 2, "remove": 0, "update": 0, "invalid": 1, "blacklist": 0, "duplicate": 0, "skipMissing": 0, "unsubscribe": 0, "skipSuppressed": 0 }, "source": "csv", "purposeId": "5", "addedToLists": 0, "errors": [ { "row": 4, "error": "email_invalid", "field": "email" } ], "runAutomations": false, "options": {}, "report": { "consent": { "none": 0, "optIn": 2, "keptUnsubscribed": 0 }, "merge": { "existing": 0, "fromSources": {}, "fieldsUpdated": 0, "fieldsKeptEdited": 0 }, "dropped": {} } } ``` Do 1 000 řádků proběhne import hned (`status: "finished"`); větší jde do fronty (`queued`, `running` s průběhem `progress`) a dokončí ho worker. ## 4. Výsledek ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/imports/61" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/imports/61" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "61", "name": "Kontakty z veletrhu", "status": "finished", "kind": "csv", "fileName": "vlozeny-text.csv", "shopId": "9", "mode": "upsert", "listIds": [], "createdAt": "2026-10-01T08:00:00.000Z", "startedAt": "2026-10-01T08:00:00.000Z", "finishedAt": "2026-10-01T08:00:00.000Z", "progress": { "processed": 3, "total": 3 }, "counts": { "rows": 3, "create": 2, "remove": 0, "update": 0, "invalid": 1, "blacklist": 0, "duplicate": 0, "skipMissing": 0, "unsubscribe": 0, "skipSuppressed": 0 }, "source": "csv", "purposeId": "5", "addedToLists": 0, "errors": [ { "row": 4, "error": "email_invalid", "field": "email" } ], "runAutomations": false, "options": {}, "report": { "consent": { "none": 0, "optIn": 2, "keptUnsubscribed": 0 }, "merge": { "existing": 0, "fromSources": {}, "fieldsUpdated": 0, "fieldsKeptEdited": 0 }, "dropped": {} } } ``` `errors` uvádí řádky, které neprošly (tady neplatná adresa na řádku 4). ## Pravidla, na která pozor • **Potlačená adresa** (odhlášená, nedoručitelná, stížnost) se importem nikdy znovu nepřihlásí. • Pole, která v aplikaci upravil člověk, import nepřepíše. • Adresa vymazaná na žádost (GDPR) se importem znovu nezaloží. • Import zákazníků bez souhlasu (`shoptet_customers` bez sloupce souhlasu) založí kontakty `customer`, kterým se nepíše. --- # Recept: odeslání kampaně **Cíl:** připravit newsletter pro seznam odběratelů, zkontrolovat obsah a příjemce, poslat test a naplánovat odeslání. **Potřebujete:** klíč s rolí `marketing_manager`, ověřeného odesílatele, testovací adresu firmy (v aplikaci Testovací adresy v nastavení odesílání; přes API `PUT /test-recipients` s rolí správce účtu). ## 1. Příjemci Pro ukázku kontakt se souhlasem a seznam: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/contacts" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "email": "petr.svoboda@example.cz", "shopId": "17", "purposeId": "9", "consentConfirmed": true, "firstName": "Petr", "vocativeFirstName": "Petře" } JSON ``` ```json title="Odpověď: 201 Created" { "id": "1206", "email": "petr.svoboda@example.cz", "firstName": "Petr", "lastName": "", "status": "subscribed", "engagement": "N", "excluded": false, "shopId": "17", "suppressionReason": null, "blacklisted": false, "blacklistedAt": null, "state": null, "createdAt": "2026-10-01T08:00:00.000Z", "phone": "", "mobile": "", "titleBefore": "", "titleAfter": "", "salutation": "", "salutationFormal": "", "vocativeFirstName": "Petře", "vocativeLastName": "", "gender": null, "language": "cs", "company": "", "companyId": "", "street": "", "city": "", "postalCode": "", "note": "", "affiliateId": "", "country": null, "birthday": null, "nameDay": null, "source": "manual", "consentBasis": "imported", "statusAt": "2026-10-01T08:00:00.000Z", "consentAt": "2026-10-01T08:00:00.000Z", "consentWeak": false, "softBounces": 0, "lastSentAt": null, "lastOpenAt": null, "lastClickAt": null, "suppressedAt": null, "engagementAt": null, "suppressionNote": null, "customFields": {}, "updatedAt": "2026-10-01T08:00:00.000Z", "stats90d": { "received": 0, "opened": 0, "clicked": 0, "bestHour": null }, "lists": [], "recentActivities": [ { "id": "consent-7", "type": "status_change", "at": "2026-10-01T08:00:00.000Z", "title": "purpose_assigned" } ], "orders": [], "orderTotals": [], "editedFields": [], "sources": [] } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/lists" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/lists" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Newsletter", "publicName": "Novinky e-shopu", "shopId": "17", "notifyOnUnsubscribe": false, "notifyOnAdd": false, "note": "" } JSON ``` ```json title="Odpověď: 201 Created" { "id": "44", "name": "Newsletter", "publicName": "Novinky e-shopu", "shopId": "17", "systemKind": null, "locked": false, "manualMembers": true, "tags": [], "counts": { "total": 0, "byBucket": { "active": 0, "unconfirmed": 0, "unsubscribed": 0, "bounced": 0, "complained": 0, "blacklisted": 0 } }, "createdAt": "2026-10-01T08:00:00.000Z", "notifyOnUnsubscribe": false, "notifyOnAdd": false, "note": "" } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/lists/44/members" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/lists/44/members" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "contactIds": [ "1206" ] } JSON ``` ```json title="Odpověď: 200 OK" { "added": 1, "alreadyMember": 0, "skipped": 0 } ``` ## 2. Odesílatel ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/senders" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/senders" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "items": [ { "id": "17", "shopId": "17", "name": "Example.cz", "email": "info@example.cz", "replyTo": "", "verified": true, "isDefault": true }, { "id": "18", "shopId": "18", "name": "Example.sk", "email": "info@example.sk", "replyTo": "", "verified": true, "isDefault": true } ] } ``` Odesílat smí jen ověřená adresa (`verified: true`) e-shopu kampaně. ## 3. Koncept kampaně ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/campaigns" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "name": "Říjnový newsletter", "shopId": "17", "senderId": "17", "fromName": "Example.cz", "subject": "Podzimní novinky", "preheader": "Nová káva a tipy na přípravu", "audience": { "listIds": [ "44" ], "segmentIds": [], "excludeListIds": [], "excludeInactive": true, "excludeEmails": [], "onlyWithPurpose": false, "purposeIds": [] } } JSON ``` ```json title="Odpověď: 201 Created" { "id": "151", "name": "Říjnový newsletter", "shopId": "17", "subject": "Podzimní novinky", "status": "draft", "recipients": null, "scheduledAt": null, "startedAt": null, "completedAt": null, "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": null, "variantGroupId": null, "variantLabel": "", "variantPosition": 0, "tags": [], "preheader": "Nová káva a tipy na přípravu", "senderId": "17", "fromName": "Example.cz", "fromEmail": "info@example.cz", "replyTo": "", "templateId": null, "hasContent": false, "audience": { "listIds": [ "44" ], "segmentIds": [], "excludeListIds": [], "excludeInactive": true, "excludeEmails": [], "onlyWithPurpose": false, "purposeIds": [] }, "pausedReason": null, "approvedAt": null, "trackOpens": true, "trackClicks": true, "utm": null, "headers": [], "timing": "later", "plannedAt": null, "linkParams": [], "preferTime": false, "replyToOptions": [ "info@example.cz" ] } ``` ## 4. Obsah `baseVersion: 0` u kampaně, která obsah ještě nemá. Obsah musí mít odkaz na odhlášení (`{{unsubscribe}}`), jinak Poštárna doplní standardní patičku. ```bash title="Požadavek: PUT /api/v1/tenants/{tenant}/campaigns/151/content" curl -sS -X PUT "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/151/content" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "editor": "html", "design": null, "baseVersion": 0, "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

na e-shopu máme novou podzimní kávu.

Prohlédnout novinky

{{cl_company}}, {{cl_address}}. Odhlásit odběr

" } JSON ``` ```json title="Odpověď: 200 OK" { "editor": "html", "html": "

Dobrý den, {{df_salution|default('vážený zákazníku', true)}},

na e-shopu máme novou podzimní kávu.

Prohlédnout novinky

{{cl_company}}, {{cl_address}}. Odhlásit odběr

", "design": null, "version": 1, "updatedAt": "2026-10-01T08:00:00.000Z" } ``` Kontrola obsahu (tady s neznámou značkou a bez odhlášení): ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/content/lint" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/content/lint" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "html": "

Dobrý den, {{df_jmeno}}

", "subject": "Podzimní novinky", "preheader": "" } JSON ``` ```json title="Odpověď: 200 OK" { "issues": [ { "code": "unknown_tag", "severity": "error", "params": { "tags": "{{df_jmeno}}" } }, { "code": "no_unsubscribe", "severity": "warning", "params": {} } ] } ``` ## 5. Počet příjemců ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/campaigns/audience" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/audience" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "shopId": "17", "audience": { "listIds": [ "44" ], "segmentIds": [], "excludeListIds": [], "excludeInactive": true, "excludeEmails": [], "onlyWithPurpose": false, "purposeIds": [] } } JSON ``` ```json title="Odpověď: 200 OK" { "matched": 1, "recipients": 1, "excluded": { "not_mailable": 0, "unconfirmed": 0, "weak_consent": 0, "exception_expired": 0, "no_purpose": 0, "excluded_list": 0, "excluded_manual": 0, "inactive": 0 } } ``` ## 6. Testovací e-mail Jen na testovací adresy firmy (`GET /test-recipients`), nejvýš 10 za 24 hodin: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/campaigns/151/test" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/151/test" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "to": "test@example.cz" } JSON ``` ```json title="Odpověď: 200 OK" { "to": "test@example.cz", "sentAt": "2026-10-01T08:00:00.000Z" } ``` ## 7. Schválení > **Pozor:** schválení posílá e-maily skutečným lidem. Ukažte člověku předmět, odesílatele, čas a počet příjemců (z kroku 5) a pošlete ho jako `expectedRecipients` až po jeho potvrzení. Když počet nesedí (liší se o víc než 5 %), kampaň zůstane konceptem: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/campaigns/151/approve" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/151/approve" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "sendAt": "2026-10-02T07:00:00.000Z", "expectedRecipients": 250 } JSON ``` ```json title="Odpověď: 409 Conflict" { "error": { "code": "conflict", "message": "recipients", "params": { "expected": 250, "actual": 1 } } } ``` Se správným počtem a časem odeslání (`sendAt` 5 minut až 365 dní dopředu, `null` = hned): ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/campaigns/151/approve" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/151/approve" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "sendAt": "2026-10-02T07:00:00.000Z", "expectedRecipients": 1 } JSON ``` ```json title="Odpověď: 200 OK" { "id": "151", "name": "Říjnový newsletter", "shopId": "17", "subject": "Podzimní novinky", "status": "scheduled", "recipients": 1, "scheduledAt": "2026-10-02T07:00:00.000Z", "startedAt": null, "completedAt": null, "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": null, "variantGroupId": null, "variantLabel": "", "variantPosition": 0, "tags": [], "preheader": "Nová káva a tipy na přípravu", "senderId": "17", "fromName": "Example.cz", "fromEmail": "info@example.cz", "replyTo": "", "templateId": null, "hasContent": true, "audience": { "listIds": [ "44" ], "segmentIds": [], "excludeListIds": [], "excludeInactive": true, "excludeEmails": [], "onlyWithPurpose": false, "purposeIds": [] }, "pausedReason": null, "approvedAt": "2026-10-01T08:00:00.000Z", "trackOpens": true, "trackClicks": true, "utm": null, "headers": [], "timing": "later", "plannedAt": null, "linkParams": [], "preferTime": false, "replyToOptions": [ "info@example.cz" ] } ``` ```bash title="Požadavek: GET /api/v1/tenants/{tenant}/campaigns/151" curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/151" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "151", "name": "Říjnový newsletter", "shopId": "17", "subject": "Podzimní novinky", "status": "scheduled", "recipients": 1, "scheduledAt": "2026-10-02T07:00:00.000Z", "startedAt": null, "completedAt": null, "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": null, "variantGroupId": null, "variantLabel": "", "variantPosition": 0, "tags": [], "preheader": "Nová káva a tipy na přípravu", "senderId": "17", "fromName": "Example.cz", "fromEmail": "info@example.cz", "replyTo": "", "templateId": null, "hasContent": true, "audience": { "listIds": [ "44" ], "segmentIds": [], "excludeListIds": [], "excludeInactive": true, "excludeEmails": [], "onlyWithPurpose": false, "purposeIds": [] }, "pausedReason": null, "approvedAt": "2026-10-01T08:00:00.000Z", "trackOpens": true, "trackClicks": true, "utm": null, "headers": [], "timing": "later", "plannedAt": null, "linkParams": [], "preferTime": false, "replyToOptions": [ "info@example.cz" ] } ``` ## 8. Pauza a zrušení Naplánovanou nebo odesílanou kampaň zastaví `POST /campaigns/{id}/pause`, znovu ji pustí `/resume`, úplně zruší `/cancel`: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/campaigns/151/cancel" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/campaigns/151/cancel" \ -H "Authorization: Bearer $POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "id": "151", "name": "Říjnový newsletter", "shopId": "17", "subject": "Podzimní novinky", "status": "cancelled", "recipients": 1, "scheduledAt": "2026-10-02T07:00:00.000Z", "startedAt": null, "completedAt": null, "createdAt": "2026-10-01T08:00:00.000Z", "updatedAt": "2026-10-01T08:00:00.000Z", "stats": null, "variantGroupId": null, "variantLabel": "", "variantPosition": 0, "tags": [], "preheader": "Nová káva a tipy na přípravu", "senderId": "17", "fromName": "Example.cz", "fromEmail": "info@example.cz", "replyTo": "", "templateId": null, "hasContent": true, "audience": { "listIds": [ "44" ], "segmentIds": [], "excludeListIds": [], "excludeInactive": true, "excludeEmails": [], "onlyWithPurpose": false, "purposeIds": [] }, "pausedReason": null, "approvedAt": "2026-10-01T08:00:00.000Z", "trackOpens": true, "trackClicks": true, "utm": null, "headers": [], "timing": "later", "plannedAt": null, "linkParams": [], "preferTime": false, "replyToOptions": [ "info@example.cz" ] } ``` ## Statistiky po odeslání `GET /campaigns/{id}` (`stats`), `GET /stats/campaigns/{id}`, `/recipients?format=csv`, `/conversions`. Viz [Kampaně](https://www.postarna.cz/docs/api/campaigns#statistiky). --- # Recept: příjem webhooků **Cíl:** držet CRM v souladu s Poštárnou: nové kontakty založit, odhlášené označit. **Potřebujete:** klíč s rolí `account_admin` (webhooky jsou v modulu `settings`), e-mail člena firmy pro HTTP Basic, veřejnou adresu `https://` vašeho příjemce. ## 1. Registrace ```bash title="Požadavek: POST /api/v3/web-hooks" curl -sS -X POST "https://www.postarna.cz/api/v3/web-hooks" \ -u "$POSTARNA_USER:$POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "target_url": "https://crm.example.cz/postarna/webhook", "event": "new_contact", "basic_auth": { "login": "postarna", "password": "example-webhook-password" } } JSON ``` ```json title="Odpověď: 201 Created" { "status": "created", "meta": [], "id": 7 } ``` ```bash title="Požadavek: POST /api/v3/web-hooks" curl -sS -X POST "https://www.postarna.cz/api/v3/web-hooks" \ -u "$POSTARNA_USER:$POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "target_url": "https://crm.example.cz/postarna/webhook", "event": "unsubscribed_contact", "basic_auth": { "login": "postarna", "password": "example-webhook-password" } } JSON ``` ```json title="Odpověď: 201 Created" { "status": "created", "meta": [], "id": 8 } ``` Heslo `basic_auth` si vygenerujte náhodně (aspoň 32 znaků) a uložte do proměnné prostředí příjemce. ## 2. Co přijde Po založení a odhlášení kontaktu přijdou dvě volání: ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/contacts" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "email": "eva.horakova@example.cz", "shopId": "19", "purposeId": "10", "consentConfirmed": true, "firstName": "Eva", "lastName": "Horáková" } JSON ``` ```json title="Odpověď: 201 Created" { "id": "1207", "email": "eva.horakova@example.cz", "firstName": "Eva", "lastName": "Horáková", "status": "subscribed", "engagement": "N", "excluded": false, "shopId": "19", "suppressionReason": null, "blacklisted": false, "blacklistedAt": null, "state": null, "createdAt": "2026-10-01T08:00:00.000Z", "phone": "", "mobile": "", "titleBefore": "", "titleAfter": "", "salutation": "", "salutationFormal": "", "vocativeFirstName": "", "vocativeLastName": "", "gender": null, "language": "cs", "company": "", "companyId": "", "street": "", "city": "", "postalCode": "", "note": "", "affiliateId": "", "country": null, "birthday": null, "nameDay": null, "source": "manual", "consentBasis": "imported", "statusAt": "2026-10-01T08:00:00.000Z", "consentAt": "2026-10-01T08:00:00.000Z", "consentWeak": false, "softBounces": 0, "lastSentAt": null, "lastOpenAt": null, "lastClickAt": null, "suppressedAt": null, "engagementAt": null, "suppressionNote": null, "customFields": {}, "updatedAt": "2026-10-01T08:00:00.000Z", "stats90d": { "received": 0, "opened": 0, "clicked": 0, "bestHour": null }, "lists": [], "recentActivities": [ { "id": "consent-8", "type": "status_change", "at": "2026-10-01T08:00:00.000Z", "title": "purpose_assigned" } ], "orders": [], "orderTotals": [], "editedFields": [], "sources": [] } ``` ```bash title="Požadavek: POST /api/v1/tenants/{tenant}/contacts/1207/unsubscribe" curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/contacts/1207/unsubscribe" \ -H "Authorization: Bearer $POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "note": "Odhlášení z CRM" } JSON ``` ```json title="Odpověď: 200 OK" { "id": "1207", "email": "eva.horakova@example.cz", "firstName": "Eva", "lastName": "Horáková", "status": "unsubscribed", "engagement": "N", "excluded": false, "shopId": "19", "suppressionReason": "unsubscribed", "blacklisted": false, "blacklistedAt": null, "state": null, "createdAt": "2026-10-01T08:00:00.000Z", "phone": "", "mobile": "", "titleBefore": "", "titleAfter": "", "salutation": "", "salutationFormal": "", "vocativeFirstName": "", "vocativeLastName": "", "gender": null, "language": "cs", "company": "", "companyId": "", "street": "", "city": "", "postalCode": "", "note": "", "affiliateId": "", "country": null, "birthday": null, "nameDay": null, "source": "manual", "consentBasis": "imported", "statusAt": "2026-10-01T08:00:00.000Z", "consentAt": "2026-10-01T08:00:00.000Z", "consentWeak": false, "softBounces": 0, "lastSentAt": null, "lastOpenAt": null, "lastClickAt": null, "suppressedAt": "2026-10-01T08:00:00.000Z", "engagementAt": null, "suppressionNote": null, "customFields": {}, "updatedAt": "2026-10-01T08:00:00.000Z", "stats90d": { "received": 0, "opened": 0, "clicked": 0, "bestHour": null }, "lists": [], "recentActivities": [ { "id": "consent-9", "type": "status_change", "at": "2026-10-01T08:00:00.000Z", "title": "suppressed" }, { "id": "consent-8", "type": "status_change", "at": "2026-10-01T08:00:00.000Z", "title": "purpose_assigned" }, { "id": "consent-10", "type": "unsubscribed", "at": "2026-10-01T08:00:00.000Z", "title": "admin" } ], "orders": [], "orderTotals": [], "editedFields": [], "sources": [] } ``` ```json title="Webhook doručí (POST na vaši adresu): new_contact" [ { "id": 1207, "guid": null, "emailaddress": "eva.horakova@example.cz", "domain": "example.cz", "name": "Eva", "surname": "Horáková", "titlesbefore": null, "titlesafter": null, "salution": null, "company": null, "street": null, "town": null, "postalcode": null, "country": null, "cellphone": null, "phone": null, "language": "cs_CZ", "birthday": null, "nameday": null, "gender": null, "notes": null, "realname": "Eva Horáková", "blacklisted": 0, "is_blacklisted": false, "hardbounced": 0, "softbounced": 0, "created": "2026-10-01 10:00:00", "updated": "2026-10-01 10:00:00", "created_at": "2026-10-01 10:00:00", "last_updated_at": "2026-10-01 10:00:00", "origin": "manual", "contactlists": [], "customfields": [], "event": "new_contact" } ] ``` ```json title="Webhook doručí (POST na vaši adresu): unsubscribed_contact" [ { "id": 1207, "guid": null, "emailaddress": "eva.horakova@example.cz", "domain": "example.cz", "name": "Eva", "surname": "Horáková", "titlesbefore": null, "titlesafter": null, "salution": null, "company": null, "street": null, "town": null, "postalcode": null, "country": null, "cellphone": null, "phone": null, "language": "cs_CZ", "birthday": null, "nameday": null, "gender": null, "notes": null, "realname": "Eva Horáková", "blacklisted": 0, "is_blacklisted": false, "hardbounced": 0, "softbounced": 0, "created": "2026-10-01 10:00:00", "updated": "2026-10-01 10:00:00", "created_at": "2026-10-01 10:00:00", "last_updated_at": "2026-10-01 10:00:00", "origin": "manual", "contactlists": [], "customfields": [], "event": "unsubscribed_contact", "reason": "admin", "unsubscribed_contactlist_ids": [], "campaign_type": null, "campaign_id": null, "email_statistic_id": null, "trigger_event": null } ] ``` ## 3. Příjemce v Pythonu (Flask) ```python title="app.py" import hmac import os from flask import Flask, abort, request app = Flask(__name__) USER = os.environ['POSTARNA_HOOK_USER'] # login z basic_auth PASSWORD = os.environ['POSTARNA_HOOK_PASSWORD'] # heslo z basic_auth def authorized(): auth = request.authorization return bool(auth) and hmac.compare_digest(auth.username or '', USER) \ and hmac.compare_digest(auth.password or '', PASSWORD) @app.post('/postarna/webhook') def postarna_webhook(): if not authorized(): abort(401) payload = request.get_json(silent=True) items = payload if isinstance(payload, list) else [payload] for item in items: event = item.get('event') if event == 'new_contact': crm_upsert_contact(email=item['emailaddress'], first_name=item.get('name'), last_name=item.get('surname')) elif event == 'unsubscribed_contact': crm_mark_unsubscribed(email=item['emailaddress'], reason=item.get('reason')) return '', 204 # 2xx do 30 s, jinak přijde znovu def crm_upsert_contact(email, first_name, last_name): ... # založit nebo upravit podle e-mailu (opakované doručení nevadí) def crm_mark_unsubscribed(email, reason): ... # nastavit příznak (opakované doručení nevadí) ``` ## 4. Příjemce v Node.js (Express) ```javascript title="server.js" import crypto from 'node:crypto'; import express from 'express'; const app = express(); app.use(express.json({ limit: '1mb' })); const USER = process.env.POSTARNA_HOOK_USER; const PASSWORD = process.env.POSTARNA_HOOK_PASSWORD; function same(a, b) { const x = Buffer.from(a ?? ''); const y = Buffer.from(b ?? ''); return x.length === y.length && crypto.timingSafeEqual(x, y); } function authorized(req) { const [scheme, value] = (req.get('Authorization') ?? '').split(' '); if (scheme !== 'Basic' || !value) return false; const [user, ...rest] = Buffer.from(value, 'base64').toString('utf8').split(':'); return same(user, USER) && same(rest.join(':'), PASSWORD); } app.post('/postarna/webhook', async (req, res) => { if (!authorized(req)) return res.sendStatus(401); const items = Array.isArray(req.body) ? req.body : [req.body]; for (const item of items) { if (item.event === 'new_contact') await crmUpsertContact(item.emailaddress, item.name, item.surname); if (item.event === 'unsubscribed_contact') await crmMarkUnsubscribed(item.emailaddress, item.reason); } res.sendStatus(204); // 2xx do 30 s, jinak přijde znovu }); app.listen(8080); ``` ## 5. Pravidla dobrého příjemce • **Odpovídejte rychle**: delší zpracování dejte do fronty a hned vraťte 2xx. Po 30 sekundách se volání počítá jako chyba. • **Snesete opakování**: stejná položka může přijít víckrát. Zpracování dělejte idempotentní (upsert podle e-mailu, nastavení příznaku), u e-mailových událostí si pamatujte `id`. • **Neodpovídejte chybou na neznámou událost**: vraťte 2xx, jinak se webhook po 10 chybách vypne. • **Hlídejte stav**: `GET /api/v3/web-hooks` ukazuje `active`, `last_response_code`, `last_call_time` a `errors_in_row`. • Odhlášení v CRM pošlete zpátky do Poštárny přes `POST /api/v1/tenants/{tenant}/contacts/{id}/unsubscribe`, ať obě strany drží stejný stav. --- # Webhooky Poštárna umí posílat dva druhy webhooků: | | Účtový webhook | Uzel `webhook` v automatizaci | |---|---|---| | Kdy volá | při události ve firmě (nový kontakt, odhlášení, doručení ...) | když kontakt dojde v automatizaci na uzel | | Registrace | `POST /api/v3/web-hooks` (kompatibilní se SmartEmailingem) | v grafu automatizace | | Tvar dat | pevný, jako SmartEmailing | vlastní tělo se zástupnými značkami | | Opakování | při dalším běhu (každých ~30 s), po 10 chybách v řadě se vypne | 5 pokusů po 5 minutách | ## Účtové webhooky ### Události | `event` | Kdy | Tělo | |---|---|---| | `new_contact` | nový kontakt | pole s jedním kontaktem | | `updated_contact` | změna kontaktu | pole s jedním kontaktem | | `unsubscribed_contact` | odhlášení (ze všeho nebo ze seznamu) | pole s jedním kontaktem a důvodem | | `sent_email` | e-mail odeslán | objekt | | `delivery_status` | doručeno, měkce nebo tvrdě vráceno (s odpovědí serveru) | objekt | | `email_open` | otevření (jen lidé, strojová otevření se nepočítají) | objekt | | `email_click` | klik (jen lidé) | objekt | | `email_delivery_started`, `scoring_result_changed`, `engagement_level_changed`, `sms_delivery_status` | přijmou se kvůli kompatibilitě, **zatím se nikdy nevolají** | | ### Registrace Přihlášení jako u API v3: HTTP Basic (e-mail člena firmy a API klíč) nebo Bearer. Klíč potřebuje modul `settings` na úrovni `full` (role správce účtu). ```bash title="Požadavek: POST /api/v3/web-hooks" curl -sS -X POST "https://www.postarna.cz/api/v3/web-hooks" \ -u "$POSTARNA_USER:$POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "target_url": "https://crm.example.cz/postarna/webhook", "event": "new_contact", "basic_auth": { "login": "postarna", "password": "example-webhook-password" } } JSON ``` ```json title="Odpověď: 201 Created" { "status": "created", "meta": [], "id": 7 } ``` • `target_url`: `http://` nebo `https://` adresa, nejvýš 1 000 znaků. Volat jde jen veřejné adresy (ne interní sítě), přesměrování se nesledují. • `basic_auth` `{login, password}` (nepovinné): Poštárna je pošle v hlavičce `Authorization: Basic`. Heslo se ukládá šifrovaně a nikdy se nevrací (`***`). • Stejná adresa pro stejnou událost podruhé = 409 `Already exists`; nejvýš 50 webhooků na firmu. • Nový webhook začíná u nejnovějšího záznamu: posílá jen to, co se stane po registraci. ```bash title="Požadavek: POST /api/v3/web-hooks" curl -sS -X POST "https://www.postarna.cz/api/v3/web-hooks" \ -u "$POSTARNA_USER:$POSTARNA_API_KEY" \ -H "Content-Type: application/json" \ --data-binary @- <<'JSON' { "target_url": "https://crm.example.cz/postarna/webhook", "event": "new_contact" } JSON ``` ```json title="Odpověď: 409 Conflict" { "status": "error", "meta": [], "message": "Already exists" } ``` ```bash title="Požadavek: GET /api/v3/web-hooks" curl -sS -X GET "https://www.postarna.cz/api/v3/web-hooks" \ -u "$POSTARNA_USER:$POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "status": "ok", "meta": { "total_count": 2, "displayed_count": 2, "offset": 0, "limit": 500 }, "data": [ { "id": 7, "url": "https://crm.example.cz/postarna/webhook", "method": "POST", "event": "new_contact", "active": 1, "timeout": 30, "last_response_code": null, "last_call_time": null, "errors_in_row": 0, "basic_auth": { "login": "***", "password": "***" } }, { "id": 8, "url": "https://crm.example.cz/postarna/webhook", "method": "POST", "event": "unsubscribed_contact", "active": 1, "timeout": 30, "last_response_code": null, "last_call_time": null, "errors_in_row": 0, "basic_auth": { "login": "***", "password": "***" } } ] } ``` Přes API v3 se webhook upravit nedá (stejně jako ve SmartEmailingu); smažte ho a zaregistrujte znovu. V aplikaci v Nastavení › Datové zdroje › Webhooky ho upravíte, vypnete, znovu zapnete i otestujete (API v1 `PATCH` a `POST …/test` na `/tenants/{tenant}/account-webhooks`): ```bash title="Požadavek: DELETE /api/v3/web-hooks/7" curl -sS -X DELETE "https://www.postarna.cz/api/v3/web-hooks/7" \ -u "$POSTARNA_USER:$POSTARNA_API_KEY" ``` ```text title="Odpověď: 204 No Content" (bez těla) ``` ### Tvar dat Každá položka je jeden POST s `Content-Type: application/json` a `User-Agent: Postarna-Webhook/1`. Kontaktové události posílají **pole s jedním kontaktem** ve tvaru API v3 SmartEmailingu (časy `YYYY-MM-DD HH:MM:SS` v místním čase firmy, příznaky 0 a 1, jazyk `cs_CZ`): ```json title="Webhook doručí (POST na vaši adresu): new_contact" [ { "id": 1207, "guid": null, "emailaddress": "eva.horakova@example.cz", "domain": "example.cz", "name": "Eva", "surname": "Horáková", "titlesbefore": null, "titlesafter": null, "salution": null, "company": null, "street": null, "town": null, "postalcode": null, "country": null, "cellphone": null, "phone": null, "language": "cs_CZ", "birthday": null, "nameday": null, "gender": null, "notes": null, "realname": "Eva Horáková", "blacklisted": 0, "is_blacklisted": false, "hardbounced": 0, "softbounced": 0, "created": "2026-10-01 10:00:00", "updated": "2026-10-01 10:00:00", "created_at": "2026-10-01 10:00:00", "last_updated_at": "2026-10-01 10:00:00", "origin": "manual", "contactlists": [], "customfields": [], "event": "new_contact" } ] ``` ```json title="Webhook doručí (POST na vaši adresu): unsubscribed_contact" [ { "id": 1207, "guid": null, "emailaddress": "eva.horakova@example.cz", "domain": "example.cz", "name": "Eva", "surname": "Horáková", "titlesbefore": null, "titlesafter": null, "salution": null, "company": null, "street": null, "town": null, "postalcode": null, "country": null, "cellphone": null, "phone": null, "language": "cs_CZ", "birthday": null, "nameday": null, "gender": null, "notes": null, "realname": "Eva Horáková", "blacklisted": 0, "is_blacklisted": false, "hardbounced": 0, "softbounced": 0, "created": "2026-10-01 10:00:00", "updated": "2026-10-01 10:00:00", "created_at": "2026-10-01 10:00:00", "last_updated_at": "2026-10-01 10:00:00", "origin": "manual", "contactlists": [], "customfields": [], "event": "unsubscribed_contact", "reason": "admin", "unsubscribed_contactlist_ids": [], "campaign_type": null, "campaign_id": null, "email_statistic_id": null, "trigger_event": null } ] ``` E-mailové události posílají objekt: ```json title="sent_email, delivery_status, email_open, email_click" { "event": "email_click", "id": 81234, "contact": {"id": 1207, "emailaddress": "eva.horakova@example.cz"}, "campaign_type": "newsletter", "campaign_id": 151, "email_statistic_id": "c151", "trigger_event": null, "sid": 50211, "url": "https://www.example.cz/novinky", "clicked_at": "2026-10-02 09:14:03" } ``` • `sent_email` a `delivery_status` mají místo `sid`, `url` a `clicked_at` pole `finished_at`, `delivery_status` (`delivered`, `softbounced`, `hardbounced`) a `remote_response` (odpověď poštovního serveru při vrácení); `email_open` má `sid` a `opened_at`. • `campaign_type`: `newsletter`, `automation`, `transactional`, `doi`, `test`. `email_statistic_id`: `c`, nebo `a:` (stejná ID jako v [CSV statistikách](https://www.postarna.cz/docs/api/smartemailing#csv-statistiky)). • `id` e-mailové události je jedinečné; u kontaktových událostí je `id` ID kontaktu. ### Doručování a opakování • Poštárna kontroluje nové události každých zhruba 30 sekund; jeden webhook dostane v jednom běhu nejvýš 20 položek, nejstarší první, každou zvlášť. • Úspěch = odpověď 2xx do 30 sekund. Teprve potom se posune na další položku. • Cokoli jiného (jiný stav, vypršení času, odmítnutá adresa) se počítá jako chyba a stejná položka přijde znovu při dalším běhu. **Nic se nepřeskočí**, ale tatáž položka může přijít víckrát (doručení alespoň jednou). • Po **10 chybách v řadě** se webhook sám vypne (`active: 0`); stav, poslední kód a počet chyb ukáže `GET /api/v3/web-hooks`. Znovu ho zapnete v aplikaci (Nastavení › Datové zdroje › Webhooky, Zapnout; chyby se vynulují) nebo smazáním a novou registrací. ### Zabezpečení Poštárna webhooky **nepodepisuje** (žádná hlavička s HMAC). Ověřujte je takto: • vždy `https://`, • `basic_auth` s dlouhým náhodným heslem a kontrola hlavičky `Authorization` v konstantním čase, • volitelně tajná část cesty (`https://crm.example.cz/postarna/`), • odpovídejte rychle (2xx) a zpracování odložte do fronty; zpracování musí snést opakované doručení. Ukázkový příjemce: [recept](https://www.postarna.cz/docs/api/recipe-webhook-consumer). ## Uzel `webhook` v automatizaci ```json title="Uzel webhook" {"id": "crm", "type": "webhook", "config": { "url": "https://crm.example.cz/hooks/postarna?email={{df_emailaddress}}", "method": "POST", "headers": [{"name": "X-Source", "value": "postarna"}], "body": "{\"email\": \"{{df_emailaddress}}\", \"name\": \"{{df_name}}\", \"event\": \"cart\"}", "basicAuth": {"enabled": true, "username": "postarna", "password": ""}}} ``` • Zástupné značky kontaktu fungují v adrese (hodnoty se zakódují do URL), v těle (u JSON těla se escapují pro řetězec JSON) a v hodnotách hlaviček. POST bez vlastní hlavičky `Content-Type` posílá `application/json`; GET tělo nemá. • Volá se z fronty; neúspěch (jiná odpověď než 2xx, chyba sítě) se opakuje 5krát po 5 minutách, potom se zaznamená selhání akce `other`, na které může reagovat spouštěč `action_failed`. • Heslo `basicAuth` je jen pro zápis: detail ukazuje `passwordSet: true`; bez nového hesla zůstane uložené. Kopie automatizace hesla nekopíruje. Ukládání hesla potřebuje šifrovací klíč serveru (jinak 503 `unavailable` / `data_key`). • Pozastavený scénář, smazaný uzel nebo smazaný kontakt zastaví další pokusy. • Volání (bez adres a osobních údajů) a jejich výsledky ukazuje `GET /automations/{id}/report` v `webhooks`. --- # MCP pro AI asistenty Server MCP (Model Context Protocol) dovolí AI asistentovi pracovat v účtu Poštárny: hledat a upravovat kontakty, zakládat seznamy a segmenty, psát šablony, připravit a poslat kampaň, stavět automatizace a číst statistiky. Asistent pracuje se stejnými pravidly jako API. **Adresa serveru:** `https://www.postarna.cz/mcp` (stejná pro všechny firmy; firmu vyberete při povolení přístupu). ## Připojení ### ChatGPT 1. Zapněte režim vývojáře: Settings › Apps & Connectors › Advanced settings › Developer mode (placené plány; názvy nabídek se v ChatGPT mění). 2. V Apps & Connectors zvolte Create, název Poštárna, adresa serveru výše, ověření OAuth. 3. ChatGPT vás přesměruje do Poštárny: přihlaste se, vyberte firmu a přístup a povolte ho. 4. V novém chatu zapněte konektor Poštárna a napište, co má udělat. ### Claude 1. Settings › Connectors › Add custom connector (ve firemních plánech přidává konektor vlastník organizace). 2. Název Poštárna, adresa serveru výše; OAuth Client ID a Secret nechte prázdné, Claude se zaregistruje sám. 3. Connect, přihlášení do Poštárny, výběr firmy a přístupu, povolení. ### Další klienti • Klienti s OAuth (Claude Code, Cursor, VS Code ...) potřebují jen adresu: například `claude mcp add --transport http postarna https://www.postarna.cz/mcp`. • Klient, který umí jen hlavičku: API klíč v `Authorization: Bearer pst_...` (klíč s přístupem `read` nebo `full`). ## Přístup a rozsahy • **Plný přístup** (`full`): vše, co dovolí role člena, který přístup povolil. • **Jen čtení** (`read`): jen operace s úrovní `read`; zápis vrátí 403 `forbidden` / `scope`. Takové připojení nic nezmění ani neodešle. • Členy, pozvánky, API klíče a připojené aplikace asistent nikdy nespravuje. • Odpojení: Nastavení › Datové zdroje › AI asistenti › Připojené aplikace › Odpojit (nebo odebrání konektoru v klientovi). Připojení skončí i odchodem člena z firmy. ## Nástroje Každý nástroj odpovídá jedné trase API v1 (argumenty pod názvy z API, výsledek JSON). Seznamy vracejí `{items, total, page, pageSize, hasMore, nextPage}`. • Účet: `get_account`, `list_shops`, `get_dashboard`, `search`, `list_notifications`. • Kontakty: `search_contacts`, `get_contact`, `create_contact`, `update_contact`, `unsubscribe_contact`, `delete_contact`, `erase_contact`, `blacklist_contact`, `list_suppressions` a další. • Seznamy, vlastní pole, účely, segmenty, šablony, kampaně, automatizace, formuláře, importy, statistiky, kupóny a nastavení e-shopu. • Obecné: `list_api_endpoints` (všechny trasy, které token smí volat), `call_api` (libovolná z nich) a `get_api_reference` (kontrakt API). Ve [skupině referencí](https://www.postarna.cz/docs/api/reference) má každá operace, kterou nástroj obaluje, v OpenAPI pole `x-mcp-tool` s názvem nástroje. ## Potvrzení před nevratnou akcí Operace, které posílají skutečným lidem nebo mažou data (v OpenAPI `x-mcp-confirm`), nástroj neprovede hned: 1. První volání vrátí **náhled** `{preview: true, confirmRequired: true, action, effect, details, confirm, expiresAt}`: komu, kolik, co se stane. 2. Asistent náhled ukáže člověku a teprve po jeho souhlasu zavolá stejný nástroj se stejnými argumenty a `confirm` = token z náhledu. 3. Token platí 15 minut a jen pro přesně to volání a stav, který náhled ukázal. Když se kampaň, automatizace nebo počty mezitím změní, přijde nový náhled. Týká se to schválení a obnovení kampaně, zapnutí automatizace, ručního přidání kontaktů a uvolnění čekajících, každého mazání, odhlášení a výmazu kontaktu, kontaktu se souhlasem, odvolání souhlasu, odebrání ze seznamu a importu. Stejný krok mají změny, které spustí zapnutou automatizaci (přidání do seznamu, objednávka, úprava šablony, kterou automatizace posílá, událost kontaktu, změna sledovaného pole, uložení běžícího grafu). Odesílací trasy jde volat jen jejich vlastním nástrojem, `call_api` je odmítne. ## Protokol (pro vývojáře klientů) • Streamable HTTP, verze 2025-11-25 (přijme i 2025-06-18 a 2025-03-26), jeden koncový bod `POST /mcp`, JSON-RPC 2.0, dávka nejvýš 20 zpráv. Server je bezstavový (`GET` a `DELETE /mcp` vrací 405). • Bez platného tokenu 401 s `WWW-Authenticate: Bearer resource_metadata="https://www.postarna.cz/.well-known/oauth-protected-resource/mcp"`. • OAuth 2.1: dynamická registrace `POST /oauth/register`, autorizace s PKCE S256 `GET /oauth/authorize`, tokeny `POST /oauth/token` (přístupový `pso_...` 1 hodina, obnovovací `psr_...` 30 dní s rotací), odvolání `POST /oauth/revoke`. Metadata: `/.well-known/oauth-authorization-server`, `/.well-known/oauth-protected-resource`. • Limit 300 zpráv JSON-RPC za minutu na token (429 s `Retry-After: 60`). • Každé volání nástroje se zapíše do historie účtu s názvem aplikace (bez argumentů a osobních údajů). --- # Kompatibilita se SmartEmailingem Integrace napsaná pro REST API v3 SmartEmailingu funguje s Poštárnou po změně adresy, uživatelského jména a klíče: stejné cesty, obálky, chyby, stránkování a formáty. ## Přihlášení • Adresa: `https://www.postarna.cz/api/v3/` (místo `https://app.smartemailing.cz/api/v3/`). • HTTP Basic: uživatelské jméno je **e-mail aktivního člena firmy**, heslo je **API klíč Poštárny** (`pst_...`). Funguje i `Authorization: Bearer pst_...`. • Platí role a přístup klíče i limity požadavků firmy (hlavičky `X-RateLimit-*`, 429). ```bash title="Požadavek: GET /api/v3/account-info" curl -sS -X GET "https://www.postarna.cz/api/v3/account-info" \ -u "$POSTARNA_USER:$POSTARNA_API_KEY" ``` ```json title="Odpověď: 200 OK" { "status": "ok", "meta": [], "data": { "account_id": 4, "guid": "3f6c2a1e-8b7d-4c5e-9f10-2a3b4c5d6e7f", "username": "admin@example.cz", "firstname": null, "surname": null, "company": "Example s.r.o.", "phone": null } } ``` ## Operace | Metoda a cesta | Co dělá | |---|---| | `GET /ping` | test spojení (bez přihlášení) | | `GET`, `POST /check-credentials` | ověření přihlášení | | `GET /account-info` | účet; `guid` je ID firmy pro API v1 | | `GET /contacts` | kontakty: filtry `emailaddress`, `id`, `blacklisted`, `hardbounced`; `expand=customfields` | | `GET /contacts/{id}` | jeden kontakt | | `GET /contactlists`, `GET /contactlists/{id}` | seznamy | | `GET /customfields` | vlastní pole; `expand=customfield_options` | | `GET`, `POST /web-hooks`, `DELETE /web-hooks/{id}` | [účtové webhooky](https://www.postarna.cz/docs/api/webhooks) | • Obálka: `{"status": "ok" | "created" | "error", "meta": [] | {...}, "data": ...}`. • Stránkování `limit` (výchozí a nejvýš 500) a `offset`, `meta` `{total_count, displayed_count, offset, limit}`; `select=a,b` vybere vlastnosti, `sort=a,-b` řadí. • Formáty jako SmartEmailing: časy `YYYY-MM-DD HH:MM:SS` v místním čase firmy, příznaky 0 a 1, pohlaví `M` / `F`, jazyk `cs_CZ`, `sk_SK`. • Chyby: 401 `Authentication Failed`, 403, 404 `Not Found`, 405 `Method not allowed`, 409 `Already exists`, 422 `Validation failed: `, 429 `Rate limit exceeded (...)`, vždy jako `{"status": "error", "meta": [], "message": "..."}`. ## Co zatím chybí **Zápis přes API v3 není**: import kontaktů, úpravy seznamů a odesílání e-mailů přes v3 vrátí 405 (nikdy tichý úspěch). Pro zápis použijte API v1 ([kontakty](https://www.postarna.cz/docs/api/contacts-and-consent), [import](https://www.postarna.cz/docs/api/recipe-import-contacts), [kampaně](https://www.postarna.cz/docs/api/campaigns)). ## CSV statistiky {#csv-statistiky} Na `https://www.postarna.cz/api/csv/` se stejným přihlášením (jen v hlavičce, ne v adrese), CSV se středníkem: • `GET /statistics/email/automation-email-statistic-id[/{automation_id}]`: e-mailové uzly automatizací a jejich ID statistiky. • `GET /statistics/email/{sent|opened|clicked|bounced|unsubscribed}-detail/{email_statistic_id}` s `interval_from` a `interval_to` (`YYYY-MM-DD HH:MM:SS`, místní čas): jeden řádek na kontakt a událost. ID statistiky: `c`, nebo `a:`. Strojová otevření a kliky se nepočítají. • `GET /list-contacts?listid=`: členové seznamu ve všech stavech. Ostatní metody CSV API SmartEmailingu vrací 404. --- # Přehled operací Podrobná technická reference každé skupiny (parametry, těla, odpovědi, chyby a schémata) je anglicky, stejně jako dokument [OpenAPI 3.1](https://www.postarna.cz/api/openapi.json), ze kterého se generuje. Jen jednu skupinu načtete parametrem `?tag=` (například `https://www.postarna.cz/api/openapi.json?tag=Automations`). Každá operace v OpenAPI nese: • `x-postarna-permission`: modul, úroveň a potřebný přístup klíče, • `x-mcp-tool`: nástroj serveru MCP, který ji obaluje, • `x-mcp-confirm`: operace posílá skutečným lidem nebo maže (přes MCP jen s potvrzením), • u odpovědí se seznamem kódů chyb a hodnot `message`, které trasa může vrátit. Cesty se počítají od `https://www.postarna.cz`; `{tenant}` je ID firmy. ### Contacts | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/contacts` | [List contacts (search, filters, paging)](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-list) | | POST | `/api/v1/tenants/{tenant}/contacts` | [Create a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-create) | | POST | `/api/v1/tenants/{tenant}/contacts/bulk` | [Start a bulk action over contacts in the background](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-bulk-start) | | GET | `/api/v1/tenants/{tenant}/contacts/duplicates` | [Find possible duplicate contacts](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-duplicates) | | GET | `/api/v1/tenants/{tenant}/contacts/summary` | [Count contacts by status](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-summary) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}` | [Get a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-detail) | | PATCH | `/api/v1/tenants/{tenant}/contacts/{contact_id}` | [Update a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-update) | | DELETE | `/api/v1/tenants/{tenant}/contacts/{contact_id}` | [Delete a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-delete) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/activities` | [List activities of a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-activities) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/activities` | [Add a manual activity (note) to a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-activity-add) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/automation-runs` | [The real journey of a contact through the automations (runs and steps)](https://www.postarna.cz/docs/api/reference-contacts#op-contact-automation-runs) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/blacklist` | [Blacklist a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-blacklist) | | DELETE | `/api/v1/tenants/{tenant}/contacts/{contact_id}/blacklist` | [Remove a contact from the blacklist](https://www.postarna.cz/docs/api/reference-contacts#op-contact-unblacklist) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/coupons` | [List coupons given to a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-coupons) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/erase` | [Erase a contact (GDPR, irreversible)](https://www.postarna.cz/docs/api/reference-contacts#op-contact-erase) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/export` | [Export all data of a contact (GDPR access)](https://www.postarna.cz/docs/api/reference-contacts#op-contact-export) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/neighbors` | [Previous and next contact of a filtered list](https://www.postarna.cz/docs/api/reference-contacts#op-contact-neighbors) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/purposes` | [List consents (purposes) of a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-purposes) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/purposes` | [Record a consent (purpose) of a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-purpose-assign) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/purposes/{consent_id}/withdraw` | [Withdraw a consent of a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-purpose-withdraw) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/segments` | [List segments a contact belongs to](https://www.postarna.cz/docs/api/reference-contacts#op-contact-segments) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/unsubscribe` | [Unsubscribe a contact from everything](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-unsubscribe) | | GET | `/api/v1/tenants/{tenant}/custom-fields` | [List custom fields](https://www.postarna.cz/docs/api/reference-contacts#op-custom-fields-index) | | POST | `/api/v1/tenants/{tenant}/custom-fields` | [Create a custom field](https://www.postarna.cz/docs/api/reference-contacts#op-custom-fields-create) | | PATCH | `/api/v1/tenants/{tenant}/custom-fields/{field_id}` | [Update a custom field](https://www.postarna.cz/docs/api/reference-contacts#op-custom-fields-update) | | DELETE | `/api/v1/tenants/{tenant}/custom-fields/{field_id}` | [Delete a custom field](https://www.postarna.cz/docs/api/reference-contacts#op-custom-fields-delete) | | GET | `/api/v1/tenants/{tenant}/purposes` | [List purposes of processing (consent types)](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-index) | | POST | `/api/v1/tenants/{tenant}/purposes` | [Create a purpose of processing](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-create) | | PATCH | `/api/v1/tenants/{tenant}/purposes/{purpose_id}` | [Update a purpose of processing](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-update) | | DELETE | `/api/v1/tenants/{tenant}/purposes/{purpose_id}` | [Delete a purpose of processing](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-delete) | | POST | `/api/v1/tenants/{tenant}/purposes/{purpose_id}/to-contact-list` | [Create a list of the contacts with a purpose](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-to-list) | | GET | `/api/v1/tenants/{tenant}/search` | [Search contacts, campaigns, templates and more](https://www.postarna.cz/docs/api/reference-contacts#op-search) | | GET | `/api/v1/tenants/{tenant}/suppressions` | [List suppressed addresses](https://www.postarna.cz/docs/api/reference-contacts#op-suppressions-list) | | POST | `/api/v1/tenants/{tenant}/suppressions` | [Suppress an address](https://www.postarna.cz/docs/api/reference-contacts#op-suppressions-add) | | POST | `/api/v1/tenants/{tenant}/suppressions/blacklist-import` | [Import addresses to the blacklist](https://www.postarna.cz/docs/api/reference-contacts#op-suppressions-blacklist-import) | | DELETE | `/api/v1/tenants/{tenant}/suppressions/{email}` | [Remove one suppression](https://www.postarna.cz/docs/api/reference-contacts#op-suppressions-remove) | ### Lists | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/lists` | [List contact lists](https://www.postarna.cz/docs/api/reference-lists#op-lists-index) | | POST | `/api/v1/tenants/{tenant}/lists` | [Create a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-create) | | POST | `/api/v1/tenants/{tenant}/lists/merge` | [Merge lists into a new list (background)](https://www.postarna.cz/docs/api/reference-lists#op-lists-merge) | | POST | `/api/v1/tenants/{tenant}/lists/tags` | [Change labels of lists](https://www.postarna.cz/docs/api/reference-lists#op-lists-tags) | | GET | `/api/v1/tenants/{tenant}/lists/{list_id}` | [Get a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-show) | | PATCH | `/api/v1/tenants/{tenant}/lists/{list_id}` | [Update a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-update) | | DELETE | `/api/v1/tenants/{tenant}/lists/{list_id}` | [Delete a list (only the list, with its contacts, or keeping contacts in other lists)](https://www.postarna.cz/docs/api/reference-lists#op-lists-delete) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/autofill` | [Fill empty name day, gender and salutations of the members](https://www.postarna.cz/docs/api/reference-lists#op-lists-autofill) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/copy` | [Copy a list with its members](https://www.postarna.cz/docs/api/reference-lists#op-lists-copy) | | GET | `/api/v1/tenants/{tenant}/lists/{list_id}/members` | [List members of a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-members) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/members` | [Add contacts to a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-add-members) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/members/remove` | [Remove contacts from a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-remove-members) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/members/unsubscribe` | [Unsubscribe contacts from a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-unsubscribe-members) | ### Segments | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/segments` | [List segments](https://www.postarna.cz/docs/api/reference-segments#op-segments-index) | | POST | `/api/v1/tenants/{tenant}/segments` | [Create a segment](https://www.postarna.cz/docs/api/reference-segments#op-segments-create) | | POST | `/api/v1/tenants/{tenant}/segments/preview` | [Count the contacts of a segment definition (no save)](https://www.postarna.cz/docs/api/reference-segments#op-segments-preview) | | POST | `/api/v1/tenants/{tenant}/segments/tags` | [Change labels of segments](https://www.postarna.cz/docs/api/reference-segments#op-segments-tags) | | GET | `/api/v1/tenants/{tenant}/segments/{segment}` | [Get a segment](https://www.postarna.cz/docs/api/reference-segments#op-segments-show) | | PATCH | `/api/v1/tenants/{tenant}/segments/{segment}` | [Update a segment](https://www.postarna.cz/docs/api/reference-segments#op-segments-update) | | DELETE | `/api/v1/tenants/{tenant}/segments/{segment}` | [Delete a segment no campaign, segment or automation names](https://www.postarna.cz/docs/api/reference-segments#op-segments-delete) | | GET | `/api/v1/tenants/{tenant}/segments/{segment}/members` | [List the members of a segment](https://www.postarna.cz/docs/api/reference-segments#op-segments-members) | | POST | `/api/v1/tenants/{tenant}/segments/{segment}/recompute` | [Recompute a segment now](https://www.postarna.cz/docs/api/reference-segments#op-segments-recompute) | | POST | `/api/v1/tenants/{tenant}/segments/{segment}/to-list` | [Convert a segment into a manual list of its mailable contacts](https://www.postarna.cz/docs/api/reference-segments#op-segments-to-list) | ### Campaigns | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/campaigns` | [List campaigns](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-index) | | POST | `/api/v1/tenants/{tenant}/campaigns` | [Create a campaign (draft)](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-create) | | POST | `/api/v1/tenants/{tenant}/campaigns/audience` | [Count and explain the recipients of an audience](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-audience) | | POST | `/api/v1/tenants/{tenant}/campaigns/tags` | [Change labels of campaigns](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-tags) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}` | [Get a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-show) | | PATCH | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}` | [Update a campaign draft](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-update) | | DELETE | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}` | [Delete a campaign draft](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-delete) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/approve` | [Approve a campaign: send now or schedule](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-approve) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/cancel` | [Cancel a scheduled or paused campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-cancel) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/content` | [Get the content of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-content) | | PUT | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/content` | [Save the content of a campaign draft](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-save-content) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/pause` | [Pause a sending or scheduled campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-pause) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/preview` | [Render a campaign for one contact](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-preview) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/resume` | [Resume a paused campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-resume) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/stats` | [Statistics of a campaign by provider and domain](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-stats) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/test` | [Send a test e-mail of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-test) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants` | [Get the language variants of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-index) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants` | [Create language variants of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-create) | | PUT | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants` | [Change the language variants of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-arrange) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/approve` | [Approve the language variants (send or schedule)](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-approve) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/cancel` | [Cancel the language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-cancel) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/pause` | [Pause the language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-pause) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/preview` | [Preview the audience split of language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-preview) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/resume` | [Resume the language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-resume) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/stats` | [Statistics of the language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-stats) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/versions` | [List saved content versions of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-versions) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/versions/{version_id}` | [Get one content version of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-version) | | GET | `/api/v1/tenants/{tenant}/senders` | [List verified senders](https://www.postarna.cz/docs/api/reference-campaigns#op-senders-index) | ### Templates and content | Metoda | Cesta | Popis | |---|---|---| | POST | `/api/v1/tenants/{tenant}/content/lint` | [Check e-mail content (merge tags, links, required parts)](https://www.postarna.cz/docs/api/reference-templates#op-content-lint) | | POST | `/api/v1/tenants/{tenant}/content/spam-check` | [Antispam check of e-mail content](https://www.postarna.cz/docs/api/reference-templates#op-content-spam-check) | | GET | `/api/v1/tenants/{tenant}/editor-elements` | [List saved editor elements](https://www.postarna.cz/docs/api/reference-templates#op-editor-elements-index) | | POST | `/api/v1/tenants/{tenant}/editor-elements` | [Save an editor element](https://www.postarna.cz/docs/api/reference-templates#op-editor-elements-create) | | PATCH | `/api/v1/tenants/{tenant}/editor-elements/{element_id}` | [Update a saved editor element](https://www.postarna.cz/docs/api/reference-templates#op-editor-elements-update) | | DELETE | `/api/v1/tenants/{tenant}/editor-elements/{element_id}` | [Delete a saved editor element](https://www.postarna.cz/docs/api/reference-templates#op-editor-elements-delete) | | GET | `/api/v1/tenants/{tenant}/file-folders` | [List folders of the file manager](https://www.postarna.cz/docs/api/reference-templates#op-file-folders-index) | | POST | `/api/v1/tenants/{tenant}/file-folders` | [Create a folder](https://www.postarna.cz/docs/api/reference-templates#op-file-folders-create) | | PATCH | `/api/v1/tenants/{tenant}/file-folders/{folder_id}` | [Rename a folder](https://www.postarna.cz/docs/api/reference-templates#op-file-folders-update) | | DELETE | `/api/v1/tenants/{tenant}/file-folders/{folder_id}` | [Delete a folder](https://www.postarna.cz/docs/api/reference-templates#op-file-folders-delete) | | GET | `/api/v1/tenants/{tenant}/files` | [List files of the file manager](https://www.postarna.cz/docs/api/reference-templates#op-files-index) | | POST | `/api/v1/tenants/{tenant}/files` | [Upload a file (multipart)](https://www.postarna.cz/docs/api/reference-templates#op-files-upload) | | POST | `/api/v1/tenants/{tenant}/files/stock-photo` | [Save a stock photo to the file manager](https://www.postarna.cz/docs/api/reference-templates#op-files-stock-photo) | | POST | `/api/v1/tenants/{tenant}/files/video-thumbnail` | [Create a video thumbnail image](https://www.postarna.cz/docs/api/reference-templates#op-files-video-thumbnail) | | GET | `/api/v1/tenants/{tenant}/files/{asset_id}` | [Get a file](https://www.postarna.cz/docs/api/reference-templates#op-files-show) | | PATCH | `/api/v1/tenants/{tenant}/files/{asset_id}` | [Rename or move a file](https://www.postarna.cz/docs/api/reference-templates#op-files-update) | | DELETE | `/api/v1/tenants/{tenant}/files/{asset_id}` | [Delete a file](https://www.postarna.cz/docs/api/reference-templates#op-files-delete) | | POST | `/api/v1/tenants/{tenant}/files/{asset_id}/picked` | [Record that a file was used](https://www.postarna.cz/docs/api/reference-templates#op-files-picked) | | GET | `/api/v1/tenants/{tenant}/footers` | [List footers](https://www.postarna.cz/docs/api/reference-templates#op-footers-index) | | POST | `/api/v1/tenants/{tenant}/footers` | [Create a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-create) | | GET | `/api/v1/tenants/{tenant}/footers/{footer_id}` | [Get a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-show) | | PATCH | `/api/v1/tenants/{tenant}/footers/{footer_id}` | [Rename a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-rename) | | DELETE | `/api/v1/tenants/{tenant}/footers/{footer_id}` | [Delete a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-delete) | | PUT | `/api/v1/tenants/{tenant}/footers/{footer_id}/content` | [Save the content of a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-content) | | POST | `/api/v1/tenants/{tenant}/footers/{footer_id}/copy` | [Copy a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-copy) | | POST | `/api/v1/tenants/{tenant}/footers/{footer_id}/default` | [Make a footer the default](https://www.postarna.cz/docs/api/reference-templates#op-footers-default) | | DELETE | `/api/v1/tenants/{tenant}/footers/{footer_id}/default` | [Stop using a footer as the default](https://www.postarna.cz/docs/api/reference-templates#op-footers-default-off) | | POST | `/api/v1/tenants/{tenant}/footers/{footer_id}/publish` | [Publish a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-publish) | | GET | `/api/v1/tenants/{tenant}/footers/{footer_id}/versions` | [List saved versions of a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-versions) | | GET | `/api/v1/tenants/{tenant}/footers/{footer_id}/versions/{version_id}` | [Get one version of a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-version) | | GET | `/api/v1/tenants/{tenant}/landing-pages` | [List landing pages](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-index) | | POST | `/api/v1/tenants/{tenant}/landing-pages` | [Create a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-create) | | GET | `/api/v1/tenants/{tenant}/landing-pages/{landing_page_id}` | [Get a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-show) | | PATCH | `/api/v1/tenants/{tenant}/landing-pages/{landing_page_id}` | [Update a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-update) | | DELETE | `/api/v1/tenants/{tenant}/landing-pages/{landing_page_id}` | [Delete a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-delete) | | POST | `/api/v1/tenants/{tenant}/landing-pages/{landing_page_id}/copy` | [Copy a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-copy) | | GET | `/api/v1/tenants/{tenant}/script-templates` | [List script templates (Twig)](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-index) | | POST | `/api/v1/tenants/{tenant}/script-templates` | [Create a script template](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-create) | | GET | `/api/v1/tenants/{tenant}/script-templates/{script_id}` | [Get a script template](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-show) | | PATCH | `/api/v1/tenants/{tenant}/script-templates/{script_id}` | [Update a script template](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-update) | | DELETE | `/api/v1/tenants/{tenant}/script-templates/{script_id}` | [Delete a script template](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-delete) | | GET | `/api/v1/tenants/{tenant}/sms-templates` | [List SMS templates](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-index) | | POST | `/api/v1/tenants/{tenant}/sms-templates` | [Create an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-create) | | GET | `/api/v1/tenants/{tenant}/sms-templates/{sms_template_id}` | [Get an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-show) | | PATCH | `/api/v1/tenants/{tenant}/sms-templates/{sms_template_id}` | [Update an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-update) | | DELETE | `/api/v1/tenants/{tenant}/sms-templates/{sms_template_id}` | [Delete an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-delete) | | POST | `/api/v1/tenants/{tenant}/sms-templates/{sms_template_id}/copy` | [Copy an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-copy) | | GET | `/api/v1/tenants/{tenant}/stock-photos` | [Search stock photos](https://www.postarna.cz/docs/api/reference-templates#op-stock-photos-search) | | GET | `/api/v1/tenants/{tenant}/stock-photos/status` | [Whether the stock photo search is available](https://www.postarna.cz/docs/api/reference-templates#op-stock-photos-status) | | GET | `/api/v1/tenants/{tenant}/surveys` | [List surveys](https://www.postarna.cz/docs/api/reference-templates#op-surveys-index) | | POST | `/api/v1/tenants/{tenant}/surveys` | [Create a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-create) | | GET | `/api/v1/tenants/{tenant}/surveys/{survey_id}` | [Get a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-show) | | PATCH | `/api/v1/tenants/{tenant}/surveys/{survey_id}` | [Update a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-update) | | DELETE | `/api/v1/tenants/{tenant}/surveys/{survey_id}` | [Delete a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-delete) | | POST | `/api/v1/tenants/{tenant}/surveys/{survey_id}/copy` | [Copy a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-copy) | | GET | `/api/v1/tenants/{tenant}/surveys/{survey_id}/responses` | [List responses of a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-responses) | | GET | `/api/v1/tenants/{tenant}/surveys/{survey_id}/results` | [Summary results of a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-results) | | GET | `/api/v1/tenants/{tenant}/templates` | [List templates](https://www.postarna.cz/docs/api/reference-templates#op-templates-index) | | POST | `/api/v1/tenants/{tenant}/templates` | [Create a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-create) | | POST | `/api/v1/tenants/{tenant}/templates/tags` | [Change labels of templates](https://www.postarna.cz/docs/api/reference-templates#op-templates-tags) | | GET | `/api/v1/tenants/{tenant}/templates/{template_id}` | [Get a template with its content](https://www.postarna.cz/docs/api/reference-templates#op-templates-show) | | PATCH | `/api/v1/tenants/{tenant}/templates/{template_id}` | [Update template settings (name, subject, preheader ...)](https://www.postarna.cz/docs/api/reference-templates#op-templates-update) | | DELETE | `/api/v1/tenants/{tenant}/templates/{template_id}` | [Delete a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-delete) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/archive` | [Archive a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-archive) | | PUT | `/api/v1/tenants/{tenant}/templates/{template_id}/content` | [Save the content of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-save-content) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/convert-to-visual` | [Convert an HTML template to the visual editor](https://www.postarna.cz/docs/api/reference-templates#op-templates-convert-to-visual) | | DELETE | `/api/v1/tenants/{tenant}/templates/{template_id}/draft` | [Discard the unpublished draft of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-discard-draft) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/duplicate` | [Duplicate a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-duplicate) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/publish` | [Publish the draft of a template used by an active automation](https://www.postarna.cz/docs/api/reference-templates#op-templates-publish) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/test` | [Send a test e-mail of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-test) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/unarchive` | [Restore an archived template](https://www.postarna.cz/docs/api/reference-templates#op-templates-unarchive) | | GET | `/api/v1/tenants/{tenant}/templates/{template_id}/versions` | [List saved content versions of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-versions) | | GET | `/api/v1/tenants/{tenant}/templates/{template_id}/versions/{version_id}` | [Get one content version of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-version) | | GET | `/api/v1/tenants/{tenant}/test-recipients` | [List the test addresses of the company](https://www.postarna.cz/docs/api/reference-templates#op-test-recipients) | | PUT | `/api/v1/tenants/{tenant}/test-recipients` | [Replace the test addresses of the company](https://www.postarna.cz/docs/api/reference-templates#op-test-recipients-update) | | GET | `/api/v1/tenants/{tenant}/unsubscribe-pages` | [List unsubscribe pages](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-index) | | POST | `/api/v1/tenants/{tenant}/unsubscribe-pages` | [Create an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-create) | | POST | `/api/v1/tenants/{tenant}/unsubscribe-pages/preview` | [Render an unsubscribe page preview](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-preview) | | GET | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}` | [Get an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-show) | | PATCH | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}` | [Update an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-update) | | DELETE | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}` | [Delete an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-delete) | | POST | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}/copy` | [Copy an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-copy) | | POST | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}/default` | [Make an unsubscribe page the default](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-default) | | DELETE | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}/default` | [Stop using an unsubscribe page as the default](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-default-off) | ### Automations | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/automations` | [List automations](https://www.postarna.cz/docs/api/reference-automations#op-automations-index) | | POST | `/api/v1/tenants/{tenant}/automations` | [Create an automation (draft)](https://www.postarna.cz/docs/api/reference-automations#op-automations-create) | | POST | `/api/v1/tenants/{tenant}/automations/resolve-time` | [Resolve a time spec to a moment (preview)](https://www.postarna.cz/docs/api/reference-automations#op-automations-resolve-time) | | POST | `/api/v1/tenants/{tenant}/automations/tags` | [Change labels of automations](https://www.postarna.cz/docs/api/reference-automations#op-automations-tags) | | POST | `/api/v1/tenants/{tenant}/automations/validate` | [Validate a graph without saving](https://www.postarna.cz/docs/api/reference-automations#op-automations-validate) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}` | [Get an automation with its graph and issues](https://www.postarna.cz/docs/api/reference-automations#op-automations-show) | | PATCH | `/api/v1/tenants/{tenant}/automations/{automation_id}` | [Update name, description or labels of an automation](https://www.postarna.cz/docs/api/reference-automations#op-automations-update) | | DELETE | `/api/v1/tenants/{tenant}/automations/{automation_id}` | [Delete an automation that never ran](https://www.postarna.cz/docs/api/reference-automations#op-automations-delete) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/activate` | [Activate (start) an automation](https://www.postarna.cz/docs/api/reference-automations#op-automations-activate) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/contacts` | [Add contacts by hand to a running automation](https://www.postarna.cz/docs/api/reference-automations#op-automations-add-contacts) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/copy` | [Copy an automation as a new draft](https://www.postarna.cz/docs/api/reference-automations#op-automations-copy) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/counts` | [Live counts per node and output](https://www.postarna.cz/docs/api/reference-automations#op-automations-counts) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/editing` | [Report that the editor has a scenario open and see who else has it](https://www.postarna.cz/docs/api/reference-automations#op-automations-editing) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/editor` | [Everything the editor needs in one answer](https://www.postarna.cz/docs/api/reference-automations#op-automations-editor) | | PUT | `/api/v1/tenants/{tenant}/automations/{automation_id}/graph` | [Save the graph of an automation (new version)](https://www.postarna.cz/docs/api/reference-automations#op-automations-save-graph) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/nodes/{key}/passes` | [Contacts that went through a node](https://www.postarna.cz/docs/api/reference-automations#op-automations-node-passes) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/nodes/{key}/release` | [Release the contacts waiting in a node](https://www.postarna.cz/docs/api/reference-automations#op-automations-release) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/nodes/{key}/reschedule` | [Recompute the end of waiting in a node](https://www.postarna.cz/docs/api/reference-automations#op-automations-reschedule) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/pause` | [Pause an automation](https://www.postarna.cz/docs/api/reference-automations#op-automations-pause) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/report` | [Statistics of the e-mail nodes (JSON or CSV)](https://www.postarna.cz/docs/api/reference-automations#op-automations-report) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/runs` | [Run history per contact](https://www.postarna.cz/docs/api/reference-automations#op-automations-runs) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/test` | [Test the scenario on today's data (nothing is sent)](https://www.postarna.cz/docs/api/reference-automations#op-automations-test) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/trace` | [Trace one contact through the scenario (nothing is sent)](https://www.postarna.cz/docs/api/reference-automations#op-automations-trace) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/versions` | [List saved versions of the graph](https://www.postarna.cz/docs/api/reference-automations#op-automations-versions) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/versions/{version}` | [Get one saved version of the graph](https://www.postarna.cz/docs/api/reference-automations#op-automations-version) | | POST | `/api/v1/tenants/{tenant}/contact-events` | [Record an event of a contact (custom event, cart, page visit)](https://www.postarna.cz/docs/api/reference-automations#op-contact-events-create) | ### Forms | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/forms` | [List forms](https://www.postarna.cz/docs/api/reference-forms#op-forms-list) | | POST | `/api/v1/tenants/{tenant}/forms` | [Create a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-create) | | GET | `/api/v1/tenants/{tenant}/forms/doi-templates` | [List templates usable as the double opt-in e-mail](https://www.postarna.cz/docs/api/reference-forms#op-forms-doi-templates) | | POST | `/api/v1/tenants/{tenant}/forms/preview` | [Render a form preview](https://www.postarna.cz/docs/api/reference-forms#op-forms-preview) | | POST | `/api/v1/tenants/{tenant}/forms/tags` | [Change labels of forms](https://www.postarna.cz/docs/api/reference-forms#op-forms-tags) | | GET | `/api/v1/tenants/{tenant}/forms/{form_id}` | [Get a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-show) | | PATCH | `/api/v1/tenants/{tenant}/forms/{form_id}` | [Update a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-update) | | DELETE | `/api/v1/tenants/{tenant}/forms/{form_id}` | [Delete a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-delete) | | POST | `/api/v1/tenants/{tenant}/forms/{form_id}/copy` | [Copy a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-copy) | | GET | `/api/v1/tenants/{tenant}/forms/{form_id}/embed` | [Get the embed code of a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-embed) | | GET | `/api/v1/tenants/{tenant}/forms/{form_id}/history` | [Change history of a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-history) | | GET | `/api/v1/tenants/{tenant}/forms/{form_id}/welcome` | [Get the e-mail after a sign-up (the form's own automation)](https://www.postarna.cz/docs/api/reference-forms#op-forms-welcome) | | PUT | `/api/v1/tenants/{tenant}/forms/{form_id}/welcome` | [Switch the e-mail after a sign-up on or off](https://www.postarna.cz/docs/api/reference-forms#op-forms-welcome-save) | ### Imports and exports | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/export-fields` | [Fields an export can contain](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-export-fields) | | GET | `/api/v1/tenants/{tenant}/exports` | [List exports](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-exports-index) | | POST | `/api/v1/tenants/{tenant}/exports` | [Start a CSV export](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-exports-create) | | GET | `/api/v1/tenants/{tenant}/exports/{export_id}` | [Get an export](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-exports-show) | | GET | `/api/v1/tenants/{tenant}/exports/{export_id}/download` | [Download an export (CSV)](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-exports-download) | | GET | `/api/v1/tenants/{tenant}/imports` | [List imports](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-index) | | POST | `/api/v1/tenants/{tenant}/imports` | [Start an import](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-run) | | POST | `/api/v1/tenants/{tenant}/imports/drafts` | [Start an import draft (wizard)](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-draft-create) | | GET | `/api/v1/tenants/{tenant}/imports/drafts/{import_id}` | [Get an import draft](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-draft-show) | | PUT | `/api/v1/tenants/{tenant}/imports/drafts/{import_id}` | [Save an import draft](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-draft-update) | | POST | `/api/v1/tenants/{tenant}/imports/files` | [Upload a CSV file for import](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-upload) | | POST | `/api/v1/tenants/{tenant}/imports/preview` | [Preview an import: mapping, counts, problems](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-preview) | | GET | `/api/v1/tenants/{tenant}/imports/{import_id}` | [Get an import with its progress and result](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-show) | | DELETE | `/api/v1/tenants/{tenant}/imports/{import_id}` | [Delete an import record](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-delete) | ### Orders, feeds and coupons | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/coupon-stacks` | [List coupon stacks](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-list) | | POST | `/api/v1/tenants/{tenant}/coupon-stacks` | [Create a coupon stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-create) | | GET | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}` | [Get a coupon stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-show) | | DELETE | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}` | [Delete a coupon stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-delete) | | POST | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}/assign` | [Give a coupon of a stack to a contact](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-assign) | | POST | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}/codes` | [Add coupon codes to a stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-import) | | GET | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}/coupons` | [List coupons of a stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-assigned) | | POST | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}/used` | [Mark coupons as used](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-used) | | GET | `/api/v1/tenants/{tenant}/feed-articles` | [Search articles of the article feeds](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feed-articles-search) | | GET | `/api/v1/tenants/{tenant}/feed-products` | [Search products of the product feeds](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feed-products-search) | | GET | `/api/v1/tenants/{tenant}/feeds` | [List feeds](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-list) | | POST | `/api/v1/tenants/{tenant}/feeds` | [Create a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-create) | | GET | `/api/v1/tenants/{tenant}/feeds/{feed_id}` | [Get a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-show) | | PATCH | `/api/v1/tenants/{tenant}/feeds/{feed_id}` | [Update a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-update) | | DELETE | `/api/v1/tenants/{tenant}/feeds/{feed_id}` | [Delete a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-delete) | | POST | `/api/v1/tenants/{tenant}/feeds/{feed_id}/import` | [Import a feed file by upload](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-import) | | GET | `/api/v1/tenants/{tenant}/feeds/{feed_id}/items` | [List items of a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-items) | | GET | `/api/v1/tenants/{tenant}/feeds/{feed_id}/preview` | [Preview a feed (first items, detected fields)](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-preview) | | POST | `/api/v1/tenants/{tenant}/feeds/{feed_id}/refresh` | [Download and process a feed now](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-refresh) | | GET | `/api/v1/tenants/{tenant}/order-states` | [Get the order state mapping](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-order-states-show) | | PUT | `/api/v1/tenants/{tenant}/order-states` | [Replace the order state mapping](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-order-states-replace) | | GET | `/api/v1/tenants/{tenant}/orders` | [List orders](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-orders-list) | | POST | `/api/v1/tenants/{tenant}/orders` | [Create or update an order](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-orders-save) | | POST | `/api/v1/tenants/{tenant}/orders/paid-at` | [Maintenance: fill empty dates of payment of orders (SmartEmailing data)](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-maintenance-orders-paid-at) | | GET | `/api/v1/tenants/{tenant}/orders/{order_id}` | [Get an order](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-orders-show) | ### Statistics | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/conversions` | [Conversions summary](https://www.postarna.cz/docs/api/reference-statistics#op-conversions-summary) | | GET | `/api/v1/tenants/{tenant}/dashboard` | [Dashboard numbers](https://www.postarna.cz/docs/api/reference-statistics#op-dashboard) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}` | [Statistics of an automation](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/activity` | [Activity of an automation over time](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-activity) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/conversions` | [Conversions (orders) of an automation](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-conversions) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/heatmap` | [Click map of an automation](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-heatmap) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/recipients` | [Recipients of an automation with their events (JSON or CSV)](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-recipients) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/report` | [Report of an automation (JSON or CSV)](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-report) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}` | [Statistics of a campaign](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/activity` | [Activity of a campaign over time](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-activity) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/conversions` | [Conversions (orders) of a campaign](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-conversions) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/heatmap` | [Click map of a campaign](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-heatmap) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/recipients` | [Recipients of a campaign with their events (JSON or CSV)](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-recipients) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/report` | [Report of a campaign (JSON or CSV)](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-report) | | GET | `/api/v1/tenants/{tenant}/stats/emails` | [E-mail statistics of campaigns and automations](https://www.postarna.cz/docs/api/reference-statistics#op-stats-emails) | ### Sending and deliverability | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/deliverability/dmarc` | [DMARC summary](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-dmarc) | | GET | `/api/v1/tenants/{tenant}/deliverability/dmarc/report` | [DMARC report detail](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-dmarc-report) | | GET | `/api/v1/tenants/{tenant}/deliverability/domains` | [List domains with their DNS state](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domains) | | POST | `/api/v1/tenants/{tenant}/deliverability/domains` | [Add a domain](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domain-create) | | PATCH | `/api/v1/tenants/{tenant}/deliverability/domains/{domain_id}` | [Update a domain](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domain-update) | | DELETE | `/api/v1/tenants/{tenant}/deliverability/domains/{domain_id}` | [Delete a domain](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domain-delete) | | POST | `/api/v1/tenants/{tenant}/deliverability/domains/{domain_id}/check` | [Check the DNS records of a domain now](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domain-check) | | GET | `/api/v1/tenants/{tenant}/deliverability/senders` | [Senders with their authentication state](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-senders) | | GET | `/api/v1/tenants/{tenant}/sending-defaults` | [Get the default settings of new campaigns (tracking parameters on or off)](https://www.postarna.cz/docs/api/reference-sending#op-sending-defaults) | | PUT | `/api/v1/tenants/{tenant}/sending-defaults` | [Set whether new campaigns start with tracking parameters](https://www.postarna.cz/docs/api/reference-sending#op-sending-defaults-update) | | GET | `/api/v1/tenants/{tenant}/sending-mode` | [Sending mode of the company (switch, limits)](https://www.postarna.cz/docs/api/reference-sending#op-sending-mode) | | POST | `/api/v1/tenants/{tenant}/sending/domains` | [Add a sending domain](https://www.postarna.cz/docs/api/reference-sending#op-sending-domain-add) | | DELETE | `/api/v1/tenants/{tenant}/sending/domains/{domain_id}` | [Delete a sending domain](https://www.postarna.cz/docs/api/reference-sending#op-sending-domain-delete) | | POST | `/api/v1/tenants/{tenant}/sending/domains/{domain_id}/check` | [Check a sending domain](https://www.postarna.cz/docs/api/reference-sending#op-sending-domain-check) | | POST | `/api/v1/tenants/{tenant}/sending/senders` | [Add a sender](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-add) | | PATCH | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}` | [Update a sender](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-update) | | DELETE | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}` | [Delete a sender](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-delete) | | POST | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}/check` | [Check whether a sender address is confirmed](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-check) | | POST | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}/resend` | [Send the confirmation e-mail of a sender address again](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-resend) | | GET | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}/usage` | [Where a sender is used](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-usage) | | GET | `/api/v1/tenants/{tenant}/sending/setup` | [State of the sending setup (domains and senders)](https://www.postarna.cz/docs/api/reference-sending#op-sending-setup) | ### Account and settings | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/public/price-list` | [Public price list (no authentication)](https://www.postarna.cz/docs/api/reference-account#op-price-list) | | GET | `/api/v1/tenants/{tenant}/account-webhooks` | [List account webhooks and their events](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-index) | | POST | `/api/v1/tenants/{tenant}/account-webhooks` | [Create an account webhook](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-create) | | PATCH | `/api/v1/tenants/{tenant}/account-webhooks/{webhook_id}` | [Edit, switch off or on an account webhook](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-update) | | DELETE | `/api/v1/tenants/{tenant}/account-webhooks/{webhook_id}` | [Delete an account webhook](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-delete) | | POST | `/api/v1/tenants/{tenant}/account-webhooks/{webhook_id}/test` | [Send a test call of an account webhook now](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-test) | | GET | `/api/v1/tenants/{tenant}/billing` | [Tariff, usage and balance](https://www.postarna.cz/docs/api/reference-account#op-billing-overview) | | GET | `/api/v1/tenants/{tenant}/billing/cancel` | [What cancelling the tariff would mean](https://www.postarna.cz/docs/api/reference-account#op-billing-cancel-check) | | GET | `/api/v1/tenants/{tenant}/billing/invoices` | [List invoices](https://www.postarna.cz/docs/api/reference-account#op-billing-invoices) | | GET | `/api/v1/tenants/{tenant}/billing/invoices/{invoice_id}/pdf` | [Download an invoice (PDF)](https://www.postarna.cz/docs/api/reference-account#op-billing-invoice-pdf) | | GET | `/api/v1/tenants/{tenant}/billing/invoices/{invoice_id}/qr.svg` | [QR payment code of an invoice (SVG)](https://www.postarna.cz/docs/api/reference-account#op-billing-invoice-qr) | | GET | `/api/v1/tenants/{tenant}/billing/payments` | [List payments](https://www.postarna.cz/docs/api/reference-account#op-billing-payments) | | GET | `/api/v1/tenants/{tenant}/billing/profile` | [Get the billing profile](https://www.postarna.cz/docs/api/reference-account#op-billing-profile) | | GET | `/api/v1/tenants/{tenant}/billing/quote` | [Price of a tariff](https://www.postarna.cz/docs/api/reference-account#op-billing-quote) | | GET | `/api/v1/tenants/{tenant}/company` | [Get the company data](https://www.postarna.cz/docs/api/reference-account#op-account-company) | | PATCH | `/api/v1/tenants/{tenant}/company` | [Update the company data](https://www.postarna.cz/docs/api/reference-account#op-account-company-update) | | GET | `/api/v1/tenants/{tenant}/consent-settings` | [Consent settings of every shop](https://www.postarna.cz/docs/api/reference-account#op-consent-settings-index) | | PATCH | `/api/v1/tenants/{tenant}/consent-settings/{shop_id}` | [Update the customer exception of a shop](https://www.postarna.cz/docs/api/reference-account#op-consent-settings-update) | | GET | `/api/v1/tenants/{tenant}/grid-tags` | [Labels used in a grid](https://www.postarna.cz/docs/api/reference-account#op-grid-tags-index) | | GET | `/api/v1/tenants/{tenant}/labels` | [List labels](https://www.postarna.cz/docs/api/reference-account#op-labels-index) | | POST | `/api/v1/tenants/{tenant}/labels` | [Create a label](https://www.postarna.cz/docs/api/reference-account#op-labels-create) | | PATCH | `/api/v1/tenants/{tenant}/labels/{label_id}` | [Update a label](https://www.postarna.cz/docs/api/reference-account#op-labels-update) | | DELETE | `/api/v1/tenants/{tenant}/labels/{label_id}` | [Delete a label](https://www.postarna.cz/docs/api/reference-account#op-labels-delete) | | POST | `/api/v1/tenants/{tenant}/labels/{label_id}/assign` | [Assign a label to objects](https://www.postarna.cz/docs/api/reference-account#op-labels-assign) | | POST | `/api/v1/tenants/{tenant}/maintenance/phone-landline-mobile` | [Maintenance: move landline-stored mobile numbers to mobile (dry run unless apply)](https://www.postarna.cz/docs/api/reference-account#op-maintenance-phone-landline-mobile) | | POST | `/api/v1/tenants/{tenant}/maintenance/se-backfill-contacts` | [Maintenance: fill empty contact fields from a SmartEmailing backup (dry run unless apply)](https://www.postarna.cz/docs/api/reference-account#op-maintenance-se-backfill) | | POST | `/api/v1/tenants/{tenant}/maintenance/shop-enrich` | [Maintenance: fill empty contact fields from the e-shop feeds (dry run unless apply)](https://www.postarna.cz/docs/api/reference-account#op-maintenance-shop-enrich) | | POST | `/api/v1/tenants/{tenant}/maintenance/shop-lists` | [Maintenance: rebuild the e-shop lists (dry run unless apply)](https://www.postarna.cz/docs/api/reference-account#op-maintenance-shop-lists) | | GET | `/api/v1/tenants/{tenant}/notifications` | [List notifications](https://www.postarna.cz/docs/api/reference-account#op-notifications-list) | | POST | `/api/v1/tenants/{tenant}/notifications/delete` | [Delete notifications](https://www.postarna.cz/docs/api/reference-account#op-notifications-delete) | | POST | `/api/v1/tenants/{tenant}/notifications/read` | [Mark notifications as read](https://www.postarna.cz/docs/api/reference-account#op-notifications-read) | | POST | `/api/v1/tenants/{tenant}/notifications/unread` | [Mark notifications as unread](https://www.postarna.cz/docs/api/reference-account#op-notifications-unread) | | GET | `/api/v1/tenants/{tenant}/onboarding` | [State of the onboarding wizard](https://www.postarna.cz/docs/api/reference-account#op-onboarding-show) | | PATCH | `/api/v1/tenants/{tenant}/onboarding` | [Save the onboarding wizard](https://www.postarna.cz/docs/api/reference-account#op-onboarding-update) | | GET | `/api/v1/tenants/{tenant}/rfm` | [State of the RFM analysis](https://www.postarna.cz/docs/api/reference-account#op-rfm-state) | | POST | `/api/v1/tenants/{tenant}/rfm/enable-request` | [Ask to enable the RFM analysis](https://www.postarna.cz/docs/api/reference-account#op-rfm-enable-request) | | GET | `/api/v1/tenants/{tenant}/running-actions` | [Running background actions (imports, exports ...)](https://www.postarna.cz/docs/api/reference-account#op-running-actions-index) | | GET | `/api/v1/tenants/{tenant}/shop-enrich` | [Whether order feed imports fill empty contact fields](https://www.postarna.cz/docs/api/reference-account#op-shop-enrich-state) | | PUT | `/api/v1/tenants/{tenant}/shop-enrich` | [Turn the ongoing contact data enrichment on or off](https://www.postarna.cz/docs/api/reference-account#op-shop-enrich-switch) | | GET | `/api/v1/tenants/{tenant}/shop-settings` | [Sending company data of every shop](https://www.postarna.cz/docs/api/reference-account#op-shop-settings-index) | | PATCH | `/api/v1/tenants/{tenant}/shop-settings/{shop_id}` | [Update the sending company data of a shop](https://www.postarna.cz/docs/api/reference-account#op-shop-settings-update) | | GET | `/api/v1/tenants/{tenant}/shops` | [List shops (e-shops) of the company](https://www.postarna.cz/docs/api/reference-account#op-shops) | | POST | `/api/v1/tenants/{tenant}/shops` | [Create a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-create) | | GET | `/api/v1/tenants/{tenant}/shops/{shop_id}` | [Get a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-show) | | PATCH | `/api/v1/tenants/{tenant}/shops/{shop_id}` | [Update a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-update) | | GET | `/api/v1/tenants/{tenant}/shops/{shop_id}/brand` | [Get the brand settings of a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-brand) | | PUT | `/api/v1/tenants/{tenant}/shops/{shop_id}/brand` | [Replace the brand settings of a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-brand-update) | | PUT | `/api/v1/tenants/{tenant}/shops/{shop_id}/contact-language` | [Set the default language of new contacts of a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-contact-language) | | POST | `/api/v1/tenants/{tenant}/shops/{shop_id}/disable` | [Switch a shop off](https://www.postarna.cz/docs/api/reference-account#op-shops-disable) | | POST | `/api/v1/tenants/{tenant}/shops/{shop_id}/enable` | [Switch a shop on](https://www.postarna.cz/docs/api/reference-account#op-shops-enable) | | GET | `/api/v1/tenants/{tenant}/site-script` | [Every shop's one script line and connection state](https://www.postarna.cz/docs/api/reference-account#op-site-script-index) | | PATCH | `/api/v1/tenants/{tenant}/site-script/{shop_id}` | [Switch the checkout newsletter box of a shop](https://www.postarna.cz/docs/api/reference-account#op-site-script-update) | | POST | `/api/v1/tenants/{tenant}/site-script/{shop_id}/check` | [Test whether the script is on the shop's homepage](https://www.postarna.cz/docs/api/reference-account#op-site-script-check) | | GET | `/api/v1/tenants/{tenant}/smartemailing` | [State of the SmartEmailing migration](https://www.postarna.cz/docs/api/reference-account#op-smartemailing-state) | | GET | `/api/v1/tenants/{tenant}/smartemailing/migrations/{migration_id}` | [Get one SmartEmailing migration run](https://www.postarna.cz/docs/api/reference-account#op-smartemailing-migration) | | GET | `/api/v1/tenants/{tenant}/web-tracking` | [Web tracking state of every shop](https://www.postarna.cz/docs/api/reference-account#op-web-tracking-index) | | GET | `/api/v1/tenants/{tenant}/web-tracking/events` | [List web tracking events](https://www.postarna.cz/docs/api/reference-account#op-web-tracking-events) | | PATCH | `/api/v1/tenants/{tenant}/web-tracking/{shop_id}` | [Switch web tracking of a shop](https://www.postarna.cz/docs/api/reference-account#op-web-tracking-switch) | ### SmartEmailing compatible API v3 | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v3/account-info` | [Account info (guid = tenant id for API v1)](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-account-info) | | GET | `/api/v3/check-credentials` | [Check the credentials](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-check-credentials) | | POST | `/api/v3/check-credentials` | [Check the credentials](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-check-credentials-post) | | GET | `/api/v3/contactlists` | [List contact lists](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-contactlists) | | GET | `/api/v3/contactlists/{list_id}` | [Get a contact list](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-contactlist) | | GET | `/api/v3/contacts` | [List contacts](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-contacts) | | GET | `/api/v3/contacts/{contact_id}` | [Get a contact](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-contact) | | GET | `/api/v3/customfields` | [List custom fields](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-customfields) | | GET | `/api/v3/ping` | [Ping (no authentication)](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-ping) | | GET | `/api/v3/web-hooks` | [List account webhooks](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-webhooks) | | POST | `/api/v3/web-hooks` | [Register an account webhook](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-webhook-create-post) | | DELETE | `/api/v3/web-hooks/{webhook_id}` | [Delete an account webhook](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-webhook-delete-delete) | ### SmartEmailing compatible CSV statistics | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/csv/list-contacts` | [Members of a list (CSV)](https://www.postarna.cz/docs/api/reference-smartemailing-csv#op-se-csv-list-contacts) | | GET | `/api/csv/statistics/email/automation-email-statistic-id` | [E-mail statistic ids of automation e-mail nodes](https://www.postarna.cz/docs/api/reference-smartemailing-csv#op-se-csv-automation-statistic-ids) | | GET | `/api/csv/statistics/email/automation-email-statistic-id/{automation_id}` | [E-mail statistic ids of automation e-mail nodes of one automation](https://www.postarna.cz/docs/api/reference-smartemailing-csv#op-se-csv-automation-statistic-ids-one) | | GET | `/api/csv/statistics/email/{kind}-detail/{sid}` | [Per-contact events of an e-mail statistic id (sent, opened, clicked, bounced, unsubscribed)](https://www.postarna.cz/docs/api/reference-smartemailing-csv#op-se-csv-email-detail) | ### MCP server for AI assistants | Metoda | Cesta | Popis | |---|---|---| | POST | `/mcp` | [MCP JSON-RPC endpoint (Streamable HTTP, stateless)](https://www.postarna.cz/docs/api/reference-mcp#op-mcp) | ### OAuth 2.1 for AI assistants | Metoda | Cesta | Popis | |---|---|---| | GET | `/.well-known/oauth-authorization-server` | [Authorization server metadata (RFC 8414)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-server-metadata) | | GET | `/.well-known/oauth-authorization-server/mcp` | [Authorization server metadata (RFC 8414)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-server-metadata-mcp) | | GET | `/.well-known/oauth-protected-resource` | [Protected resource metadata (RFC 9728)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-protected-resource) | | GET | `/.well-known/oauth-protected-resource/mcp` | [Protected resource metadata (RFC 9728)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-protected-resource-mcp) | | GET | `/oauth/authorize` | [Authorization (browser redirect to the consent page)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-authorize) | | POST | `/oauth/register` | [Dynamic client registration (RFC 7591, at most 20 an hour per address)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-register) | | POST | `/oauth/revoke` | [Revoke a token (RFC 7009)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-revoke) | | POST | `/oauth/token` | [Tokens: authorization_code or refresh_token (access pso_... 1 hour, refresh psr_... 30 days, rotated)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-token) | ### This document | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/openapi.json` | [This OpenAPI document](https://www.postarna.cz/docs/api/reference-meta#op-openapi-document) | --- # Chyby a limity ## Tvar chyby API v1 vrací při chybě vhodný HTTP stav a tělo: ```json title="Chyba" {"error": {"code": "validation", "message": "definition.0.currency"}} ``` • `code` je stálý strojový kód (tabulka níže). Rozhodujte se podle něj a podle HTTP stavu. • `message` upřesní pole nebo důvod (například `email`, `name`, `version`, `status`, `scope`). Není to text pro lidi. • `params` nese podrobnosti: `issues` (problémy grafu automatizace), `expected` a `actual` (počet příjemců), `current` (verze), `reason`, `retryAfter`. API v3 kompatibilní se SmartEmailingem má vlastní tvar `{"status": "error", "meta": [], "message": "..."}`, viz [Kompatibilita se SmartEmailingem](https://www.postarna.cz/docs/api/smartemailing). ## HTTP stavy | Stav | Kdy | |---|---| | 200, 201, 204 | úspěch (201 = vytvořeno, 204 = bez těla) | | 400 | neplatný vstup (`validation`) | | 401 | chybí nebo neplatí přihlášení (`unauthorized`) | | 403 | přihlášení platí, ale není dovoleno (`forbidden`) | | 404 | objekt neexistuje (nebo patří jiné firmě) | | 405 | trasa nemá tuto metodu | | 409 | změna by porušila stav objektu (`conflict`) | | 410 | objekt už není k dispozici (`expired`) | | 413 | tělo požadavku nad 5 MB | | 415 | tělo není JSON (`validation` / `contentType`) | | 429 | překročený limit (`rate_limited`), hlavička `Retry-After` | | 502 | selhala vnější služba (`upstream`) | | 503 | služba není dostupná (`unavailable`) | | 500 | chyba serveru (`server`) | ## Kódy chyb ### `conflict` {#error-conflict} **Význam:** The change would break the state of the object. `message`: `name` (name taken), `locked` (a list bound to an e-shop), `status` (wrong state, e.g. editing a sent campaign), `recipients` (the audience changed more than 5 % since you counted it, `params.expected` and `params.actual`), `version` (stale `baseVersion`, `params.current`), `confirm` (saving a running automation needs `confirmRunning: true`), `waiting` (contacts wait in a node you remove, `params.nodes`), `runs` (deleting an automation that ran), `trigger` (no manual trigger), `limit` (too many objects). **Co udělat:** Read the object again, then repeat with current data; for `recipients` count the audience again and send the new `expectedRecipients`. ### `count_mismatch` {#error-count-mismatch} **Význam:** `expectedRecipients` does not match the audience. **Co udělat:** Count again with `POST /campaigns/audience` and send the new number. ### `csrf` {#error-csrf} **Význam:** Browser session request without the CSRF header (never with an API key). **Co udělat:** Send the API key in `Authorization` instead of cookies. ### `empty_segment` {#error-empty-segment} **Význam:** The campaign audience has no recipient. **Co udělat:** Change the audience. ### `expired` {#error-expired} **Význam:** The object is no longer available (an export file older than its retention). **Co udělat:** Create it again (POST /exports). ### `forbidden` {#error-forbidden} **Význam:** The credentials are valid but not allowed here. `message`: `tenant` (another company in the path), `scope` (a read-only key on a write route), `api_key` (members, invitations and keys need a signed-in person), a module name (`contacts`, `campaigns`, `content`, `settings`, `billing`: the key's roles lack the level), `read_only` (support view). **Co udělat:** Use the tenant id of the key (`GET /api/v3/account-info`), a key with scope `full`, or a key whose roles include the module (for example marketing_manager). ### `method_not_allowed` {#error-method-not-allowed} **Význam:** The path exists but not with this HTTP method. **Co udělat:** Check the method in this document. ### `not_found` {#error-not-found} **Význam:** The object does not exist in this company (objects of other companies answer the same). **Co udělat:** Check the id; list the objects first. ### `not_implemented` {#error-not-implemented} **Význam:** The feature is not available yet. **Co udělat:** Do not rely on it. ### `rate_limited` {#error-rate-limited} **Význam:** Too many requests: the company's API limit, or the limit of one action (test e-mails, contact events, sign-in attempts). `Retry-After` says after how many seconds to retry. **Co udělat:** Wait `Retry-After` seconds; spread requests (4 a second sustained). ### `recently_sent` {#error-recently-sent} **Význam:** HTTP 423: the contact cannot be deleted yet, a campaign e-mail to it is queued or went out in the last 24 hours (SmartEmailing answers the same). **Co udělat:** Delete it after 24 hours. A request to be forgotten (GDPR) uses POST /contacts/{id}/erase, which is never refused. ### `server` {#error-server} **Význam:** Unexpected server error. **Co udělat:** Retry later; the request may be repeated if it is safe to repeat. ### `suppression_locked` {#error-suppression-locked} **Význam:** The address is suppressed for another reason (bounce, complaint, unsubscribe), so the blacklist cannot be added or removed; `params.reason` names it. **Co udělat:** Leave it: such suppressions protect the sender and are removed only one by one (DELETE /suppressions/{email}) when the reason is gone. ### `unauthorized` {#error-unauthorized} **Význam:** No valid credentials: the API key is unknown, revoked, expired, idle for 180 days, its creator left the company, or the HTTP Basic user name is not an active member. **Co udělat:** Check the key and the header (`Authorization: Bearer pst_...`). Create a new key in Nastavení › Datové zdroje › API klíče. ### `unavailable` {#error-unavailable} **Význam:** A service the action needs is not available (`mail`: the mail backend refused a test e-mail, `data_key`: encryption key for webhook passwords missing). **Co udělat:** Retry later; tell support when it persists. ### `upstream` {#error-upstream} **Význam:** An outside service failed (downloading a file by URL, the stock photo service); `params.reason` says why. **Co udělat:** Check the URL or retry later. ### `validation` {#error-validation} **Význam:** A parameter or body field is missing, has the wrong type or an invalid value. `message` names it (`email`, `definition.1.0.listId`, `graph` ...), `params` may carry details such as `params.issues` of an automation graph or `params.reason`. **Co udělat:** Fix the named field. For 415 `contentType` send `Content-Type: application/json`; for `body` send a JSON object. ## Limity požadavků • Na firmu (všechny klíče dohromady): zásobník 2 500 požadavků doplňovaný 4 požadavky za sekundu a 100 000 požadavků za den. • Hlavičky každé odpovědi: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` (unixový čas plného zásobníku). • Po překročení 429 `rate_limited` (v `message` název zásobníku `per-second` nebo `daily-limit`) a `Retry-After` v sekundách. ## Limity akcí {#limity-akci} | Co | Limit | |---|---| | Tělo požadavku JSON | 5 MB | | CSV import | soubor 64 MB a 300 000 řádků (multipart), text v JSON 5 MB; do 1 000 řádků proběhne hned | | API klíče | 20 platných na firmu; platnost nejvýš 730 dní; nepoužívaný 180 dní přestane platit | | Testovací e-maily | 10 na kampaň nebo šablonu za 24 hodin, jen na testovací adresy | | Události kontaktu (`/contact-events`) | 60 na kontakt za 10 minut | | Přidání do seznamu, ruční vstup do automatizace | 1 až 1 000 kontaktů v jednom požadavku | | Automatizace | 300 uzlů, 600 hran; čekání nejvýš 10 let; nejvýš 10 souběžných běhů kontaktu | | Segment | 8 úrovní skupin, 50 pravidel, řetěz odkazů na segmenty nejvýš 5 | | Kampaň | nejvýš 100 ID seznamů a segmentů v každém poli publika, 1 000 vyloučených adres; odeslání 5 minut až 365 dní dopředu | | Účtové webhooky | 50 na firmu | | Formulář | 10 odeslání za hodinu z IP na formulář, 3 za den na adresu, 300 za hodinu na firmu | | Server MCP | 300 zpráv za minutu na token | | HTML e-mailu | 102 000 bajtů | ## Jak reagovat | Situace | Postup | |---|---| | 400 `validation` | oprava pole podle `message`; neopakovat beze změny | | 401 | zkontrolovat klíč; neopakovat | | 403 `forbidden` | jiný klíč (role, přístup `full`, správná firma); neopakovat | | 404 | ověřit ID (objekt mohl někdo smazat) | | 409 `conflict` | načíst objekt znovu a rozhodnout podle `message` | | 429 | počkat `Retry-After` sekund, pak opakovat | | 5xx | opakovat s rostoucí prodlevou, jen bezpečné operace (viz [Pravidla API](https://www.postarna.cz/docs/api/conventions#opakovani-pozadavku-a-idempotence)) | --- # Historie změn API v1 se mění jen zpětně kompatibilně: přibývají operace, pole v odpovědích a hodnoty výčtů. Klient má neznámá pole ignorovat. Odebrání nebo změna významu pole se ohlásí tady předem. ## 13. 10. 2026 • Transakční automatizace (smluvní e-maily, například upomínky faktur): pole `transactional` u automatizací, spouštěč jen vlastní událost, e-maily i kontaktům bez souhlasu s newsletterem, bez odkazu na odhlášení. Nové kódy problémů `transactional_node`, `transactional_trigger`, `transactional_content`. Podrobnosti v [automatizacích](https://www.postarna.cz/docs/api/automations). • Značka `{{payment_qr}}`: obrázek QR platby z řetězce SPAYD v datech události. ## 12. 10. 2026 • Veřejná dokumentace API na `/docs/api` (česky a slovensky), dokument OpenAPI 3.1 na `/api/openapi.json` (i po skupinách `?tag=`), `/llms.txt` a `/llms-full.txt` pro AI agenty. • Ověřené recepty (opuštěný košík, série po nákupu, svátky, návrat zákazníků, formulář s potvrzením, import, kampaň, příjem webhooků); jejich požadavky a odpovědi se při každém testu pouštějí proti serveru. • API kompatibilní se SmartEmailingem v3 (čtení kontaktů, seznamů a polí, účtové webhooky), CSV statistiky a limity požadavků s hlavičkami `X-RateLimit-*`. ## 8. 10. 2026 • Automatizace v2: víc spouštěčů v jednom scénáři, A/B test, odkladiště, cíl, skok na uzel, webhook, reset, vlastní události, upozornění týmu, časové údaje a 37 podmínek kompatibilních se SmartEmailingem. • Server MCP a OAuth 2.1 pro AI asistenty. --- # Reference API ## Contacts | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/contacts` | [List contacts (search, filters, paging)](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-list) | | POST | `/api/v1/tenants/{tenant}/contacts` | [Create a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-create) | | POST | `/api/v1/tenants/{tenant}/contacts/bulk` | [Start a bulk action over contacts in the background](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-bulk-start) | | GET | `/api/v1/tenants/{tenant}/contacts/duplicates` | [Find possible duplicate contacts](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-duplicates) | | GET | `/api/v1/tenants/{tenant}/contacts/summary` | [Count contacts by status](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-summary) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}` | [Get a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-detail) | | PATCH | `/api/v1/tenants/{tenant}/contacts/{contact_id}` | [Update a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-update) | | DELETE | `/api/v1/tenants/{tenant}/contacts/{contact_id}` | [Delete a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-delete) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/activities` | [List activities of a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-activities) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/activities` | [Add a manual activity (note) to a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-activity-add) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/automation-runs` | [The real journey of a contact through the automations (runs and steps)](https://www.postarna.cz/docs/api/reference-contacts#op-contact-automation-runs) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/blacklist` | [Blacklist a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-blacklist) | | DELETE | `/api/v1/tenants/{tenant}/contacts/{contact_id}/blacklist` | [Remove a contact from the blacklist](https://www.postarna.cz/docs/api/reference-contacts#op-contact-unblacklist) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/coupons` | [List coupons given to a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-coupons) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/erase` | [Erase a contact (GDPR, irreversible)](https://www.postarna.cz/docs/api/reference-contacts#op-contact-erase) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/export` | [Export all data of a contact (GDPR access)](https://www.postarna.cz/docs/api/reference-contacts#op-contact-export) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/neighbors` | [Previous and next contact of a filtered list](https://www.postarna.cz/docs/api/reference-contacts#op-contact-neighbors) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/purposes` | [List consents (purposes) of a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-purposes) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/purposes` | [Record a consent (purpose) of a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-purpose-assign) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/purposes/{consent_id}/withdraw` | [Withdraw a consent of a contact](https://www.postarna.cz/docs/api/reference-contacts#op-contact-purpose-withdraw) | | GET | `/api/v1/tenants/{tenant}/contacts/{contact_id}/segments` | [List segments a contact belongs to](https://www.postarna.cz/docs/api/reference-contacts#op-contact-segments) | | POST | `/api/v1/tenants/{tenant}/contacts/{contact_id}/unsubscribe` | [Unsubscribe a contact from everything](https://www.postarna.cz/docs/api/reference-contacts#op-contacts-unsubscribe) | | GET | `/api/v1/tenants/{tenant}/custom-fields` | [List custom fields](https://www.postarna.cz/docs/api/reference-contacts#op-custom-fields-index) | | POST | `/api/v1/tenants/{tenant}/custom-fields` | [Create a custom field](https://www.postarna.cz/docs/api/reference-contacts#op-custom-fields-create) | | PATCH | `/api/v1/tenants/{tenant}/custom-fields/{field_id}` | [Update a custom field](https://www.postarna.cz/docs/api/reference-contacts#op-custom-fields-update) | | DELETE | `/api/v1/tenants/{tenant}/custom-fields/{field_id}` | [Delete a custom field](https://www.postarna.cz/docs/api/reference-contacts#op-custom-fields-delete) | | GET | `/api/v1/tenants/{tenant}/purposes` | [List purposes of processing (consent types)](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-index) | | POST | `/api/v1/tenants/{tenant}/purposes` | [Create a purpose of processing](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-create) | | PATCH | `/api/v1/tenants/{tenant}/purposes/{purpose_id}` | [Update a purpose of processing](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-update) | | DELETE | `/api/v1/tenants/{tenant}/purposes/{purpose_id}` | [Delete a purpose of processing](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-delete) | | POST | `/api/v1/tenants/{tenant}/purposes/{purpose_id}/to-contact-list` | [Create a list of the contacts with a purpose](https://www.postarna.cz/docs/api/reference-contacts#op-purposes-to-list) | | GET | `/api/v1/tenants/{tenant}/search` | [Search contacts, campaigns, templates and more](https://www.postarna.cz/docs/api/reference-contacts#op-search) | | GET | `/api/v1/tenants/{tenant}/suppressions` | [List suppressed addresses](https://www.postarna.cz/docs/api/reference-contacts#op-suppressions-list) | | POST | `/api/v1/tenants/{tenant}/suppressions` | [Suppress an address](https://www.postarna.cz/docs/api/reference-contacts#op-suppressions-add) | | POST | `/api/v1/tenants/{tenant}/suppressions/blacklist-import` | [Import addresses to the blacklist](https://www.postarna.cz/docs/api/reference-contacts#op-suppressions-blacklist-import) | | DELETE | `/api/v1/tenants/{tenant}/suppressions/{email}` | [Remove one suppression](https://www.postarna.cz/docs/api/reference-contacts#op-suppressions-remove) | ## Lists | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/lists` | [List contact lists](https://www.postarna.cz/docs/api/reference-lists#op-lists-index) | | POST | `/api/v1/tenants/{tenant}/lists` | [Create a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-create) | | POST | `/api/v1/tenants/{tenant}/lists/merge` | [Merge lists into a new list (background)](https://www.postarna.cz/docs/api/reference-lists#op-lists-merge) | | POST | `/api/v1/tenants/{tenant}/lists/tags` | [Change labels of lists](https://www.postarna.cz/docs/api/reference-lists#op-lists-tags) | | GET | `/api/v1/tenants/{tenant}/lists/{list_id}` | [Get a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-show) | | PATCH | `/api/v1/tenants/{tenant}/lists/{list_id}` | [Update a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-update) | | DELETE | `/api/v1/tenants/{tenant}/lists/{list_id}` | [Delete a list (only the list, with its contacts, or keeping contacts in other lists)](https://www.postarna.cz/docs/api/reference-lists#op-lists-delete) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/autofill` | [Fill empty name day, gender and salutations of the members](https://www.postarna.cz/docs/api/reference-lists#op-lists-autofill) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/copy` | [Copy a list with its members](https://www.postarna.cz/docs/api/reference-lists#op-lists-copy) | | GET | `/api/v1/tenants/{tenant}/lists/{list_id}/members` | [List members of a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-members) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/members` | [Add contacts to a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-add-members) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/members/remove` | [Remove contacts from a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-remove-members) | | POST | `/api/v1/tenants/{tenant}/lists/{list_id}/members/unsubscribe` | [Unsubscribe contacts from a list](https://www.postarna.cz/docs/api/reference-lists#op-lists-unsubscribe-members) | ## Segments | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/segments` | [List segments](https://www.postarna.cz/docs/api/reference-segments#op-segments-index) | | POST | `/api/v1/tenants/{tenant}/segments` | [Create a segment](https://www.postarna.cz/docs/api/reference-segments#op-segments-create) | | POST | `/api/v1/tenants/{tenant}/segments/preview` | [Count the contacts of a segment definition (no save)](https://www.postarna.cz/docs/api/reference-segments#op-segments-preview) | | POST | `/api/v1/tenants/{tenant}/segments/tags` | [Change labels of segments](https://www.postarna.cz/docs/api/reference-segments#op-segments-tags) | | GET | `/api/v1/tenants/{tenant}/segments/{segment}` | [Get a segment](https://www.postarna.cz/docs/api/reference-segments#op-segments-show) | | PATCH | `/api/v1/tenants/{tenant}/segments/{segment}` | [Update a segment](https://www.postarna.cz/docs/api/reference-segments#op-segments-update) | | DELETE | `/api/v1/tenants/{tenant}/segments/{segment}` | [Delete a segment no campaign, segment or automation names](https://www.postarna.cz/docs/api/reference-segments#op-segments-delete) | | GET | `/api/v1/tenants/{tenant}/segments/{segment}/members` | [List the members of a segment](https://www.postarna.cz/docs/api/reference-segments#op-segments-members) | | POST | `/api/v1/tenants/{tenant}/segments/{segment}/recompute` | [Recompute a segment now](https://www.postarna.cz/docs/api/reference-segments#op-segments-recompute) | | POST | `/api/v1/tenants/{tenant}/segments/{segment}/to-list` | [Convert a segment into a manual list of its mailable contacts](https://www.postarna.cz/docs/api/reference-segments#op-segments-to-list) | ## Campaigns | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/campaigns` | [List campaigns](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-index) | | POST | `/api/v1/tenants/{tenant}/campaigns` | [Create a campaign (draft)](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-create) | | POST | `/api/v1/tenants/{tenant}/campaigns/audience` | [Count and explain the recipients of an audience](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-audience) | | POST | `/api/v1/tenants/{tenant}/campaigns/tags` | [Change labels of campaigns](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-tags) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}` | [Get a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-show) | | PATCH | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}` | [Update a campaign draft](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-update) | | DELETE | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}` | [Delete a campaign draft](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-delete) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/approve` | [Approve a campaign: send now or schedule](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-approve) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/cancel` | [Cancel a scheduled or paused campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-cancel) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/content` | [Get the content of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-content) | | PUT | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/content` | [Save the content of a campaign draft](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-save-content) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/pause` | [Pause a sending or scheduled campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-pause) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/preview` | [Render a campaign for one contact](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-preview) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/resume` | [Resume a paused campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-resume) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/stats` | [Statistics of a campaign by provider and domain](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-stats) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/test` | [Send a test e-mail of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-test) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants` | [Get the language variants of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-index) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants` | [Create language variants of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-create) | | PUT | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants` | [Change the language variants of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-arrange) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/approve` | [Approve the language variants (send or schedule)](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-approve) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/cancel` | [Cancel the language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-cancel) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/pause` | [Pause the language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-pause) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/preview` | [Preview the audience split of language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-preview) | | POST | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/resume` | [Resume the language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-resume) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/stats` | [Statistics of the language variants](https://www.postarna.cz/docs/api/reference-campaigns#op-variants-stats) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/versions` | [List saved content versions of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-versions) | | GET | `/api/v1/tenants/{tenant}/campaigns/{campaign_id}/versions/{version_id}` | [Get one content version of a campaign](https://www.postarna.cz/docs/api/reference-campaigns#op-campaigns-version) | | GET | `/api/v1/tenants/{tenant}/senders` | [List verified senders](https://www.postarna.cz/docs/api/reference-campaigns#op-senders-index) | ## Templates and content | Metoda | Cesta | Popis | |---|---|---| | POST | `/api/v1/tenants/{tenant}/content/lint` | [Check e-mail content (merge tags, links, required parts)](https://www.postarna.cz/docs/api/reference-templates#op-content-lint) | | POST | `/api/v1/tenants/{tenant}/content/spam-check` | [Antispam check of e-mail content](https://www.postarna.cz/docs/api/reference-templates#op-content-spam-check) | | GET | `/api/v1/tenants/{tenant}/editor-elements` | [List saved editor elements](https://www.postarna.cz/docs/api/reference-templates#op-editor-elements-index) | | POST | `/api/v1/tenants/{tenant}/editor-elements` | [Save an editor element](https://www.postarna.cz/docs/api/reference-templates#op-editor-elements-create) | | PATCH | `/api/v1/tenants/{tenant}/editor-elements/{element_id}` | [Update a saved editor element](https://www.postarna.cz/docs/api/reference-templates#op-editor-elements-update) | | DELETE | `/api/v1/tenants/{tenant}/editor-elements/{element_id}` | [Delete a saved editor element](https://www.postarna.cz/docs/api/reference-templates#op-editor-elements-delete) | | GET | `/api/v1/tenants/{tenant}/file-folders` | [List folders of the file manager](https://www.postarna.cz/docs/api/reference-templates#op-file-folders-index) | | POST | `/api/v1/tenants/{tenant}/file-folders` | [Create a folder](https://www.postarna.cz/docs/api/reference-templates#op-file-folders-create) | | PATCH | `/api/v1/tenants/{tenant}/file-folders/{folder_id}` | [Rename a folder](https://www.postarna.cz/docs/api/reference-templates#op-file-folders-update) | | DELETE | `/api/v1/tenants/{tenant}/file-folders/{folder_id}` | [Delete a folder](https://www.postarna.cz/docs/api/reference-templates#op-file-folders-delete) | | GET | `/api/v1/tenants/{tenant}/files` | [List files of the file manager](https://www.postarna.cz/docs/api/reference-templates#op-files-index) | | POST | `/api/v1/tenants/{tenant}/files` | [Upload a file (multipart)](https://www.postarna.cz/docs/api/reference-templates#op-files-upload) | | POST | `/api/v1/tenants/{tenant}/files/stock-photo` | [Save a stock photo to the file manager](https://www.postarna.cz/docs/api/reference-templates#op-files-stock-photo) | | POST | `/api/v1/tenants/{tenant}/files/video-thumbnail` | [Create a video thumbnail image](https://www.postarna.cz/docs/api/reference-templates#op-files-video-thumbnail) | | GET | `/api/v1/tenants/{tenant}/files/{asset_id}` | [Get a file](https://www.postarna.cz/docs/api/reference-templates#op-files-show) | | PATCH | `/api/v1/tenants/{tenant}/files/{asset_id}` | [Rename or move a file](https://www.postarna.cz/docs/api/reference-templates#op-files-update) | | DELETE | `/api/v1/tenants/{tenant}/files/{asset_id}` | [Delete a file](https://www.postarna.cz/docs/api/reference-templates#op-files-delete) | | POST | `/api/v1/tenants/{tenant}/files/{asset_id}/picked` | [Record that a file was used](https://www.postarna.cz/docs/api/reference-templates#op-files-picked) | | GET | `/api/v1/tenants/{tenant}/footers` | [List footers](https://www.postarna.cz/docs/api/reference-templates#op-footers-index) | | POST | `/api/v1/tenants/{tenant}/footers` | [Create a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-create) | | GET | `/api/v1/tenants/{tenant}/footers/{footer_id}` | [Get a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-show) | | PATCH | `/api/v1/tenants/{tenant}/footers/{footer_id}` | [Rename a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-rename) | | DELETE | `/api/v1/tenants/{tenant}/footers/{footer_id}` | [Delete a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-delete) | | PUT | `/api/v1/tenants/{tenant}/footers/{footer_id}/content` | [Save the content of a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-content) | | POST | `/api/v1/tenants/{tenant}/footers/{footer_id}/copy` | [Copy a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-copy) | | POST | `/api/v1/tenants/{tenant}/footers/{footer_id}/default` | [Make a footer the default](https://www.postarna.cz/docs/api/reference-templates#op-footers-default) | | DELETE | `/api/v1/tenants/{tenant}/footers/{footer_id}/default` | [Stop using a footer as the default](https://www.postarna.cz/docs/api/reference-templates#op-footers-default-off) | | POST | `/api/v1/tenants/{tenant}/footers/{footer_id}/publish` | [Publish a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-publish) | | GET | `/api/v1/tenants/{tenant}/footers/{footer_id}/versions` | [List saved versions of a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-versions) | | GET | `/api/v1/tenants/{tenant}/footers/{footer_id}/versions/{version_id}` | [Get one version of a footer](https://www.postarna.cz/docs/api/reference-templates#op-footers-version) | | GET | `/api/v1/tenants/{tenant}/landing-pages` | [List landing pages](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-index) | | POST | `/api/v1/tenants/{tenant}/landing-pages` | [Create a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-create) | | GET | `/api/v1/tenants/{tenant}/landing-pages/{landing_page_id}` | [Get a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-show) | | PATCH | `/api/v1/tenants/{tenant}/landing-pages/{landing_page_id}` | [Update a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-update) | | DELETE | `/api/v1/tenants/{tenant}/landing-pages/{landing_page_id}` | [Delete a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-delete) | | POST | `/api/v1/tenants/{tenant}/landing-pages/{landing_page_id}/copy` | [Copy a landing page](https://www.postarna.cz/docs/api/reference-templates#op-landing-pages-copy) | | GET | `/api/v1/tenants/{tenant}/script-templates` | [List script templates (Twig)](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-index) | | POST | `/api/v1/tenants/{tenant}/script-templates` | [Create a script template](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-create) | | GET | `/api/v1/tenants/{tenant}/script-templates/{script_id}` | [Get a script template](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-show) | | PATCH | `/api/v1/tenants/{tenant}/script-templates/{script_id}` | [Update a script template](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-update) | | DELETE | `/api/v1/tenants/{tenant}/script-templates/{script_id}` | [Delete a script template](https://www.postarna.cz/docs/api/reference-templates#op-script-templates-delete) | | GET | `/api/v1/tenants/{tenant}/sms-templates` | [List SMS templates](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-index) | | POST | `/api/v1/tenants/{tenant}/sms-templates` | [Create an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-create) | | GET | `/api/v1/tenants/{tenant}/sms-templates/{sms_template_id}` | [Get an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-show) | | PATCH | `/api/v1/tenants/{tenant}/sms-templates/{sms_template_id}` | [Update an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-update) | | DELETE | `/api/v1/tenants/{tenant}/sms-templates/{sms_template_id}` | [Delete an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-delete) | | POST | `/api/v1/tenants/{tenant}/sms-templates/{sms_template_id}/copy` | [Copy an SMS template](https://www.postarna.cz/docs/api/reference-templates#op-sms-templates-copy) | | GET | `/api/v1/tenants/{tenant}/stock-photos` | [Search stock photos](https://www.postarna.cz/docs/api/reference-templates#op-stock-photos-search) | | GET | `/api/v1/tenants/{tenant}/stock-photos/status` | [Whether the stock photo search is available](https://www.postarna.cz/docs/api/reference-templates#op-stock-photos-status) | | GET | `/api/v1/tenants/{tenant}/surveys` | [List surveys](https://www.postarna.cz/docs/api/reference-templates#op-surveys-index) | | POST | `/api/v1/tenants/{tenant}/surveys` | [Create a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-create) | | GET | `/api/v1/tenants/{tenant}/surveys/{survey_id}` | [Get a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-show) | | PATCH | `/api/v1/tenants/{tenant}/surveys/{survey_id}` | [Update a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-update) | | DELETE | `/api/v1/tenants/{tenant}/surveys/{survey_id}` | [Delete a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-delete) | | POST | `/api/v1/tenants/{tenant}/surveys/{survey_id}/copy` | [Copy a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-copy) | | GET | `/api/v1/tenants/{tenant}/surveys/{survey_id}/responses` | [List responses of a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-responses) | | GET | `/api/v1/tenants/{tenant}/surveys/{survey_id}/results` | [Summary results of a survey](https://www.postarna.cz/docs/api/reference-templates#op-surveys-results) | | GET | `/api/v1/tenants/{tenant}/templates` | [List templates](https://www.postarna.cz/docs/api/reference-templates#op-templates-index) | | POST | `/api/v1/tenants/{tenant}/templates` | [Create a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-create) | | POST | `/api/v1/tenants/{tenant}/templates/tags` | [Change labels of templates](https://www.postarna.cz/docs/api/reference-templates#op-templates-tags) | | GET | `/api/v1/tenants/{tenant}/templates/{template_id}` | [Get a template with its content](https://www.postarna.cz/docs/api/reference-templates#op-templates-show) | | PATCH | `/api/v1/tenants/{tenant}/templates/{template_id}` | [Update template settings (name, subject, preheader ...)](https://www.postarna.cz/docs/api/reference-templates#op-templates-update) | | DELETE | `/api/v1/tenants/{tenant}/templates/{template_id}` | [Delete a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-delete) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/archive` | [Archive a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-archive) | | PUT | `/api/v1/tenants/{tenant}/templates/{template_id}/content` | [Save the content of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-save-content) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/convert-to-visual` | [Convert an HTML template to the visual editor](https://www.postarna.cz/docs/api/reference-templates#op-templates-convert-to-visual) | | DELETE | `/api/v1/tenants/{tenant}/templates/{template_id}/draft` | [Discard the unpublished draft of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-discard-draft) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/duplicate` | [Duplicate a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-duplicate) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/publish` | [Publish the draft of a template used by an active automation](https://www.postarna.cz/docs/api/reference-templates#op-templates-publish) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/test` | [Send a test e-mail of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-test) | | POST | `/api/v1/tenants/{tenant}/templates/{template_id}/unarchive` | [Restore an archived template](https://www.postarna.cz/docs/api/reference-templates#op-templates-unarchive) | | GET | `/api/v1/tenants/{tenant}/templates/{template_id}/versions` | [List saved content versions of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-versions) | | GET | `/api/v1/tenants/{tenant}/templates/{template_id}/versions/{version_id}` | [Get one content version of a template](https://www.postarna.cz/docs/api/reference-templates#op-templates-version) | | GET | `/api/v1/tenants/{tenant}/test-recipients` | [List the test addresses of the company](https://www.postarna.cz/docs/api/reference-templates#op-test-recipients) | | PUT | `/api/v1/tenants/{tenant}/test-recipients` | [Replace the test addresses of the company](https://www.postarna.cz/docs/api/reference-templates#op-test-recipients-update) | | GET | `/api/v1/tenants/{tenant}/unsubscribe-pages` | [List unsubscribe pages](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-index) | | POST | `/api/v1/tenants/{tenant}/unsubscribe-pages` | [Create an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-create) | | POST | `/api/v1/tenants/{tenant}/unsubscribe-pages/preview` | [Render an unsubscribe page preview](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-preview) | | GET | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}` | [Get an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-show) | | PATCH | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}` | [Update an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-update) | | DELETE | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}` | [Delete an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-delete) | | POST | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}/copy` | [Copy an unsubscribe page](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-copy) | | POST | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}/default` | [Make an unsubscribe page the default](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-default) | | DELETE | `/api/v1/tenants/{tenant}/unsubscribe-pages/{unsub_page_id}/default` | [Stop using an unsubscribe page as the default](https://www.postarna.cz/docs/api/reference-templates#op-unsubscribe-pages-default-off) | ## Automations | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/automations` | [List automations](https://www.postarna.cz/docs/api/reference-automations#op-automations-index) | | POST | `/api/v1/tenants/{tenant}/automations` | [Create an automation (draft)](https://www.postarna.cz/docs/api/reference-automations#op-automations-create) | | POST | `/api/v1/tenants/{tenant}/automations/resolve-time` | [Resolve a time spec to a moment (preview)](https://www.postarna.cz/docs/api/reference-automations#op-automations-resolve-time) | | POST | `/api/v1/tenants/{tenant}/automations/tags` | [Change labels of automations](https://www.postarna.cz/docs/api/reference-automations#op-automations-tags) | | POST | `/api/v1/tenants/{tenant}/automations/validate` | [Validate a graph without saving](https://www.postarna.cz/docs/api/reference-automations#op-automations-validate) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}` | [Get an automation with its graph and issues](https://www.postarna.cz/docs/api/reference-automations#op-automations-show) | | PATCH | `/api/v1/tenants/{tenant}/automations/{automation_id}` | [Update name, description or labels of an automation](https://www.postarna.cz/docs/api/reference-automations#op-automations-update) | | DELETE | `/api/v1/tenants/{tenant}/automations/{automation_id}` | [Delete an automation that never ran](https://www.postarna.cz/docs/api/reference-automations#op-automations-delete) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/activate` | [Activate (start) an automation](https://www.postarna.cz/docs/api/reference-automations#op-automations-activate) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/contacts` | [Add contacts by hand to a running automation](https://www.postarna.cz/docs/api/reference-automations#op-automations-add-contacts) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/copy` | [Copy an automation as a new draft](https://www.postarna.cz/docs/api/reference-automations#op-automations-copy) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/counts` | [Live counts per node and output](https://www.postarna.cz/docs/api/reference-automations#op-automations-counts) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/editing` | [Report that the editor has a scenario open and see who else has it](https://www.postarna.cz/docs/api/reference-automations#op-automations-editing) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/editor` | [Everything the editor needs in one answer](https://www.postarna.cz/docs/api/reference-automations#op-automations-editor) | | PUT | `/api/v1/tenants/{tenant}/automations/{automation_id}/graph` | [Save the graph of an automation (new version)](https://www.postarna.cz/docs/api/reference-automations#op-automations-save-graph) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/nodes/{key}/passes` | [Contacts that went through a node](https://www.postarna.cz/docs/api/reference-automations#op-automations-node-passes) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/nodes/{key}/release` | [Release the contacts waiting in a node](https://www.postarna.cz/docs/api/reference-automations#op-automations-release) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/nodes/{key}/reschedule` | [Recompute the end of waiting in a node](https://www.postarna.cz/docs/api/reference-automations#op-automations-reschedule) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/pause` | [Pause an automation](https://www.postarna.cz/docs/api/reference-automations#op-automations-pause) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/report` | [Statistics of the e-mail nodes (JSON or CSV)](https://www.postarna.cz/docs/api/reference-automations#op-automations-report) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/runs` | [Run history per contact](https://www.postarna.cz/docs/api/reference-automations#op-automations-runs) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/test` | [Test the scenario on today's data (nothing is sent)](https://www.postarna.cz/docs/api/reference-automations#op-automations-test) | | POST | `/api/v1/tenants/{tenant}/automations/{automation_id}/trace` | [Trace one contact through the scenario (nothing is sent)](https://www.postarna.cz/docs/api/reference-automations#op-automations-trace) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/versions` | [List saved versions of the graph](https://www.postarna.cz/docs/api/reference-automations#op-automations-versions) | | GET | `/api/v1/tenants/{tenant}/automations/{automation_id}/versions/{version}` | [Get one saved version of the graph](https://www.postarna.cz/docs/api/reference-automations#op-automations-version) | | POST | `/api/v1/tenants/{tenant}/contact-events` | [Record an event of a contact (custom event, cart, page visit)](https://www.postarna.cz/docs/api/reference-automations#op-contact-events-create) | ## Forms | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/forms` | [List forms](https://www.postarna.cz/docs/api/reference-forms#op-forms-list) | | POST | `/api/v1/tenants/{tenant}/forms` | [Create a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-create) | | GET | `/api/v1/tenants/{tenant}/forms/doi-templates` | [List templates usable as the double opt-in e-mail](https://www.postarna.cz/docs/api/reference-forms#op-forms-doi-templates) | | POST | `/api/v1/tenants/{tenant}/forms/preview` | [Render a form preview](https://www.postarna.cz/docs/api/reference-forms#op-forms-preview) | | POST | `/api/v1/tenants/{tenant}/forms/tags` | [Change labels of forms](https://www.postarna.cz/docs/api/reference-forms#op-forms-tags) | | GET | `/api/v1/tenants/{tenant}/forms/{form_id}` | [Get a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-show) | | PATCH | `/api/v1/tenants/{tenant}/forms/{form_id}` | [Update a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-update) | | DELETE | `/api/v1/tenants/{tenant}/forms/{form_id}` | [Delete a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-delete) | | POST | `/api/v1/tenants/{tenant}/forms/{form_id}/copy` | [Copy a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-copy) | | GET | `/api/v1/tenants/{tenant}/forms/{form_id}/embed` | [Get the embed code of a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-embed) | | GET | `/api/v1/tenants/{tenant}/forms/{form_id}/history` | [Change history of a form](https://www.postarna.cz/docs/api/reference-forms#op-forms-history) | | GET | `/api/v1/tenants/{tenant}/forms/{form_id}/welcome` | [Get the e-mail after a sign-up (the form's own automation)](https://www.postarna.cz/docs/api/reference-forms#op-forms-welcome) | | PUT | `/api/v1/tenants/{tenant}/forms/{form_id}/welcome` | [Switch the e-mail after a sign-up on or off](https://www.postarna.cz/docs/api/reference-forms#op-forms-welcome-save) | ## Imports and exports | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/export-fields` | [Fields an export can contain](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-export-fields) | | GET | `/api/v1/tenants/{tenant}/exports` | [List exports](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-exports-index) | | POST | `/api/v1/tenants/{tenant}/exports` | [Start a CSV export](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-exports-create) | | GET | `/api/v1/tenants/{tenant}/exports/{export_id}` | [Get an export](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-exports-show) | | GET | `/api/v1/tenants/{tenant}/exports/{export_id}/download` | [Download an export (CSV)](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-exports-download) | | GET | `/api/v1/tenants/{tenant}/imports` | [List imports](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-index) | | POST | `/api/v1/tenants/{tenant}/imports` | [Start an import](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-run) | | POST | `/api/v1/tenants/{tenant}/imports/drafts` | [Start an import draft (wizard)](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-draft-create) | | GET | `/api/v1/tenants/{tenant}/imports/drafts/{import_id}` | [Get an import draft](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-draft-show) | | PUT | `/api/v1/tenants/{tenant}/imports/drafts/{import_id}` | [Save an import draft](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-draft-update) | | POST | `/api/v1/tenants/{tenant}/imports/files` | [Upload a CSV file for import](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-upload) | | POST | `/api/v1/tenants/{tenant}/imports/preview` | [Preview an import: mapping, counts, problems](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-preview) | | GET | `/api/v1/tenants/{tenant}/imports/{import_id}` | [Get an import with its progress and result](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-show) | | DELETE | `/api/v1/tenants/{tenant}/imports/{import_id}` | [Delete an import record](https://www.postarna.cz/docs/api/reference-imports-and-exports#op-imports-delete) | ## Orders, feeds and coupons | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/coupon-stacks` | [List coupon stacks](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-list) | | POST | `/api/v1/tenants/{tenant}/coupon-stacks` | [Create a coupon stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-create) | | GET | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}` | [Get a coupon stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-show) | | DELETE | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}` | [Delete a coupon stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-delete) | | POST | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}/assign` | [Give a coupon of a stack to a contact](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-assign) | | POST | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}/codes` | [Add coupon codes to a stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-import) | | GET | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}/coupons` | [List coupons of a stack](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-assigned) | | POST | `/api/v1/tenants/{tenant}/coupon-stacks/{stack_id}/used` | [Mark coupons as used](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-coupon-stacks-used) | | GET | `/api/v1/tenants/{tenant}/feed-articles` | [Search articles of the article feeds](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feed-articles-search) | | GET | `/api/v1/tenants/{tenant}/feed-products` | [Search products of the product feeds](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feed-products-search) | | GET | `/api/v1/tenants/{tenant}/feeds` | [List feeds](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-list) | | POST | `/api/v1/tenants/{tenant}/feeds` | [Create a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-create) | | GET | `/api/v1/tenants/{tenant}/feeds/{feed_id}` | [Get a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-show) | | PATCH | `/api/v1/tenants/{tenant}/feeds/{feed_id}` | [Update a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-update) | | DELETE | `/api/v1/tenants/{tenant}/feeds/{feed_id}` | [Delete a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-delete) | | POST | `/api/v1/tenants/{tenant}/feeds/{feed_id}/import` | [Import a feed file by upload](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-import) | | GET | `/api/v1/tenants/{tenant}/feeds/{feed_id}/items` | [List items of a feed](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-items) | | GET | `/api/v1/tenants/{tenant}/feeds/{feed_id}/preview` | [Preview a feed (first items, detected fields)](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-preview) | | POST | `/api/v1/tenants/{tenant}/feeds/{feed_id}/refresh` | [Download and process a feed now](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-feeds-refresh) | | GET | `/api/v1/tenants/{tenant}/order-states` | [Get the order state mapping](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-order-states-show) | | PUT | `/api/v1/tenants/{tenant}/order-states` | [Replace the order state mapping](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-order-states-replace) | | GET | `/api/v1/tenants/{tenant}/orders` | [List orders](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-orders-list) | | POST | `/api/v1/tenants/{tenant}/orders` | [Create or update an order](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-orders-save) | | POST | `/api/v1/tenants/{tenant}/orders/paid-at` | [Maintenance: fill empty dates of payment of orders (SmartEmailing data)](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-maintenance-orders-paid-at) | | GET | `/api/v1/tenants/{tenant}/orders/{order_id}` | [Get an order](https://www.postarna.cz/docs/api/reference-orders-and-feeds#op-orders-show) | ## Statistics | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/conversions` | [Conversions summary](https://www.postarna.cz/docs/api/reference-statistics#op-conversions-summary) | | GET | `/api/v1/tenants/{tenant}/dashboard` | [Dashboard numbers](https://www.postarna.cz/docs/api/reference-statistics#op-dashboard) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}` | [Statistics of an automation](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/activity` | [Activity of an automation over time](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-activity) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/conversions` | [Conversions (orders) of an automation](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-conversions) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/heatmap` | [Click map of an automation](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-heatmap) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/recipients` | [Recipients of an automation with their events (JSON or CSV)](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-recipients) | | GET | `/api/v1/tenants/{tenant}/stats/automations/{automation_id}/report` | [Report of an automation (JSON or CSV)](https://www.postarna.cz/docs/api/reference-statistics#op-stats-automation-report) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}` | [Statistics of a campaign](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/activity` | [Activity of a campaign over time](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-activity) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/conversions` | [Conversions (orders) of a campaign](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-conversions) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/heatmap` | [Click map of a campaign](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-heatmap) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/recipients` | [Recipients of a campaign with their events (JSON or CSV)](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-recipients) | | GET | `/api/v1/tenants/{tenant}/stats/campaigns/{campaign_id}/report` | [Report of a campaign (JSON or CSV)](https://www.postarna.cz/docs/api/reference-statistics#op-stats-campaign-report) | | GET | `/api/v1/tenants/{tenant}/stats/emails` | [E-mail statistics of campaigns and automations](https://www.postarna.cz/docs/api/reference-statistics#op-stats-emails) | ## Sending and deliverability | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/tenants/{tenant}/deliverability/dmarc` | [DMARC summary](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-dmarc) | | GET | `/api/v1/tenants/{tenant}/deliverability/dmarc/report` | [DMARC report detail](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-dmarc-report) | | GET | `/api/v1/tenants/{tenant}/deliverability/domains` | [List domains with their DNS state](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domains) | | POST | `/api/v1/tenants/{tenant}/deliverability/domains` | [Add a domain](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domain-create) | | PATCH | `/api/v1/tenants/{tenant}/deliverability/domains/{domain_id}` | [Update a domain](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domain-update) | | DELETE | `/api/v1/tenants/{tenant}/deliverability/domains/{domain_id}` | [Delete a domain](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domain-delete) | | POST | `/api/v1/tenants/{tenant}/deliverability/domains/{domain_id}/check` | [Check the DNS records of a domain now](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-domain-check) | | GET | `/api/v1/tenants/{tenant}/deliverability/senders` | [Senders with their authentication state](https://www.postarna.cz/docs/api/reference-sending#op-deliverability-senders) | | GET | `/api/v1/tenants/{tenant}/sending-defaults` | [Get the default settings of new campaigns (tracking parameters on or off)](https://www.postarna.cz/docs/api/reference-sending#op-sending-defaults) | | PUT | `/api/v1/tenants/{tenant}/sending-defaults` | [Set whether new campaigns start with tracking parameters](https://www.postarna.cz/docs/api/reference-sending#op-sending-defaults-update) | | GET | `/api/v1/tenants/{tenant}/sending-mode` | [Sending mode of the company (switch, limits)](https://www.postarna.cz/docs/api/reference-sending#op-sending-mode) | | POST | `/api/v1/tenants/{tenant}/sending/domains` | [Add a sending domain](https://www.postarna.cz/docs/api/reference-sending#op-sending-domain-add) | | DELETE | `/api/v1/tenants/{tenant}/sending/domains/{domain_id}` | [Delete a sending domain](https://www.postarna.cz/docs/api/reference-sending#op-sending-domain-delete) | | POST | `/api/v1/tenants/{tenant}/sending/domains/{domain_id}/check` | [Check a sending domain](https://www.postarna.cz/docs/api/reference-sending#op-sending-domain-check) | | POST | `/api/v1/tenants/{tenant}/sending/senders` | [Add a sender](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-add) | | PATCH | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}` | [Update a sender](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-update) | | DELETE | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}` | [Delete a sender](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-delete) | | POST | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}/check` | [Check whether a sender address is confirmed](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-check) | | POST | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}/resend` | [Send the confirmation e-mail of a sender address again](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-resend) | | GET | `/api/v1/tenants/{tenant}/sending/senders/{sender_id}/usage` | [Where a sender is used](https://www.postarna.cz/docs/api/reference-sending#op-sending-sender-usage) | | GET | `/api/v1/tenants/{tenant}/sending/setup` | [State of the sending setup (domains and senders)](https://www.postarna.cz/docs/api/reference-sending#op-sending-setup) | ## Account and settings | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v1/public/price-list` | [Public price list (no authentication)](https://www.postarna.cz/docs/api/reference-account#op-price-list) | | GET | `/api/v1/tenants/{tenant}/account-webhooks` | [List account webhooks and their events](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-index) | | POST | `/api/v1/tenants/{tenant}/account-webhooks` | [Create an account webhook](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-create) | | PATCH | `/api/v1/tenants/{tenant}/account-webhooks/{webhook_id}` | [Edit, switch off or on an account webhook](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-update) | | DELETE | `/api/v1/tenants/{tenant}/account-webhooks/{webhook_id}` | [Delete an account webhook](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-delete) | | POST | `/api/v1/tenants/{tenant}/account-webhooks/{webhook_id}/test` | [Send a test call of an account webhook now](https://www.postarna.cz/docs/api/reference-account#op-account-webhooks-test) | | GET | `/api/v1/tenants/{tenant}/billing` | [Tariff, usage and balance](https://www.postarna.cz/docs/api/reference-account#op-billing-overview) | | GET | `/api/v1/tenants/{tenant}/billing/cancel` | [What cancelling the tariff would mean](https://www.postarna.cz/docs/api/reference-account#op-billing-cancel-check) | | GET | `/api/v1/tenants/{tenant}/billing/invoices` | [List invoices](https://www.postarna.cz/docs/api/reference-account#op-billing-invoices) | | GET | `/api/v1/tenants/{tenant}/billing/invoices/{invoice_id}/pdf` | [Download an invoice (PDF)](https://www.postarna.cz/docs/api/reference-account#op-billing-invoice-pdf) | | GET | `/api/v1/tenants/{tenant}/billing/invoices/{invoice_id}/qr.svg` | [QR payment code of an invoice (SVG)](https://www.postarna.cz/docs/api/reference-account#op-billing-invoice-qr) | | GET | `/api/v1/tenants/{tenant}/billing/payments` | [List payments](https://www.postarna.cz/docs/api/reference-account#op-billing-payments) | | GET | `/api/v1/tenants/{tenant}/billing/profile` | [Get the billing profile](https://www.postarna.cz/docs/api/reference-account#op-billing-profile) | | GET | `/api/v1/tenants/{tenant}/billing/quote` | [Price of a tariff](https://www.postarna.cz/docs/api/reference-account#op-billing-quote) | | GET | `/api/v1/tenants/{tenant}/company` | [Get the company data](https://www.postarna.cz/docs/api/reference-account#op-account-company) | | PATCH | `/api/v1/tenants/{tenant}/company` | [Update the company data](https://www.postarna.cz/docs/api/reference-account#op-account-company-update) | | GET | `/api/v1/tenants/{tenant}/consent-settings` | [Consent settings of every shop](https://www.postarna.cz/docs/api/reference-account#op-consent-settings-index) | | PATCH | `/api/v1/tenants/{tenant}/consent-settings/{shop_id}` | [Update the customer exception of a shop](https://www.postarna.cz/docs/api/reference-account#op-consent-settings-update) | | GET | `/api/v1/tenants/{tenant}/grid-tags` | [Labels used in a grid](https://www.postarna.cz/docs/api/reference-account#op-grid-tags-index) | | GET | `/api/v1/tenants/{tenant}/labels` | [List labels](https://www.postarna.cz/docs/api/reference-account#op-labels-index) | | POST | `/api/v1/tenants/{tenant}/labels` | [Create a label](https://www.postarna.cz/docs/api/reference-account#op-labels-create) | | PATCH | `/api/v1/tenants/{tenant}/labels/{label_id}` | [Update a label](https://www.postarna.cz/docs/api/reference-account#op-labels-update) | | DELETE | `/api/v1/tenants/{tenant}/labels/{label_id}` | [Delete a label](https://www.postarna.cz/docs/api/reference-account#op-labels-delete) | | POST | `/api/v1/tenants/{tenant}/labels/{label_id}/assign` | [Assign a label to objects](https://www.postarna.cz/docs/api/reference-account#op-labels-assign) | | POST | `/api/v1/tenants/{tenant}/maintenance/phone-landline-mobile` | [Maintenance: move landline-stored mobile numbers to mobile (dry run unless apply)](https://www.postarna.cz/docs/api/reference-account#op-maintenance-phone-landline-mobile) | | POST | `/api/v1/tenants/{tenant}/maintenance/se-backfill-contacts` | [Maintenance: fill empty contact fields from a SmartEmailing backup (dry run unless apply)](https://www.postarna.cz/docs/api/reference-account#op-maintenance-se-backfill) | | POST | `/api/v1/tenants/{tenant}/maintenance/shop-enrich` | [Maintenance: fill empty contact fields from the e-shop feeds (dry run unless apply)](https://www.postarna.cz/docs/api/reference-account#op-maintenance-shop-enrich) | | POST | `/api/v1/tenants/{tenant}/maintenance/shop-lists` | [Maintenance: rebuild the e-shop lists (dry run unless apply)](https://www.postarna.cz/docs/api/reference-account#op-maintenance-shop-lists) | | GET | `/api/v1/tenants/{tenant}/notifications` | [List notifications](https://www.postarna.cz/docs/api/reference-account#op-notifications-list) | | POST | `/api/v1/tenants/{tenant}/notifications/delete` | [Delete notifications](https://www.postarna.cz/docs/api/reference-account#op-notifications-delete) | | POST | `/api/v1/tenants/{tenant}/notifications/read` | [Mark notifications as read](https://www.postarna.cz/docs/api/reference-account#op-notifications-read) | | POST | `/api/v1/tenants/{tenant}/notifications/unread` | [Mark notifications as unread](https://www.postarna.cz/docs/api/reference-account#op-notifications-unread) | | GET | `/api/v1/tenants/{tenant}/onboarding` | [State of the onboarding wizard](https://www.postarna.cz/docs/api/reference-account#op-onboarding-show) | | PATCH | `/api/v1/tenants/{tenant}/onboarding` | [Save the onboarding wizard](https://www.postarna.cz/docs/api/reference-account#op-onboarding-update) | | GET | `/api/v1/tenants/{tenant}/rfm` | [State of the RFM analysis](https://www.postarna.cz/docs/api/reference-account#op-rfm-state) | | POST | `/api/v1/tenants/{tenant}/rfm/enable-request` | [Ask to enable the RFM analysis](https://www.postarna.cz/docs/api/reference-account#op-rfm-enable-request) | | GET | `/api/v1/tenants/{tenant}/running-actions` | [Running background actions (imports, exports ...)](https://www.postarna.cz/docs/api/reference-account#op-running-actions-index) | | GET | `/api/v1/tenants/{tenant}/shop-enrich` | [Whether order feed imports fill empty contact fields](https://www.postarna.cz/docs/api/reference-account#op-shop-enrich-state) | | PUT | `/api/v1/tenants/{tenant}/shop-enrich` | [Turn the ongoing contact data enrichment on or off](https://www.postarna.cz/docs/api/reference-account#op-shop-enrich-switch) | | GET | `/api/v1/tenants/{tenant}/shop-settings` | [Sending company data of every shop](https://www.postarna.cz/docs/api/reference-account#op-shop-settings-index) | | PATCH | `/api/v1/tenants/{tenant}/shop-settings/{shop_id}` | [Update the sending company data of a shop](https://www.postarna.cz/docs/api/reference-account#op-shop-settings-update) | | GET | `/api/v1/tenants/{tenant}/shops` | [List shops (e-shops) of the company](https://www.postarna.cz/docs/api/reference-account#op-shops) | | POST | `/api/v1/tenants/{tenant}/shops` | [Create a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-create) | | GET | `/api/v1/tenants/{tenant}/shops/{shop_id}` | [Get a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-show) | | PATCH | `/api/v1/tenants/{tenant}/shops/{shop_id}` | [Update a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-update) | | GET | `/api/v1/tenants/{tenant}/shops/{shop_id}/brand` | [Get the brand settings of a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-brand) | | PUT | `/api/v1/tenants/{tenant}/shops/{shop_id}/brand` | [Replace the brand settings of a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-brand-update) | | PUT | `/api/v1/tenants/{tenant}/shops/{shop_id}/contact-language` | [Set the default language of new contacts of a shop](https://www.postarna.cz/docs/api/reference-account#op-shops-contact-language) | | POST | `/api/v1/tenants/{tenant}/shops/{shop_id}/disable` | [Switch a shop off](https://www.postarna.cz/docs/api/reference-account#op-shops-disable) | | POST | `/api/v1/tenants/{tenant}/shops/{shop_id}/enable` | [Switch a shop on](https://www.postarna.cz/docs/api/reference-account#op-shops-enable) | | GET | `/api/v1/tenants/{tenant}/site-script` | [Every shop's one script line and connection state](https://www.postarna.cz/docs/api/reference-account#op-site-script-index) | | PATCH | `/api/v1/tenants/{tenant}/site-script/{shop_id}` | [Switch the checkout newsletter box of a shop](https://www.postarna.cz/docs/api/reference-account#op-site-script-update) | | POST | `/api/v1/tenants/{tenant}/site-script/{shop_id}/check` | [Test whether the script is on the shop's homepage](https://www.postarna.cz/docs/api/reference-account#op-site-script-check) | | GET | `/api/v1/tenants/{tenant}/smartemailing` | [State of the SmartEmailing migration](https://www.postarna.cz/docs/api/reference-account#op-smartemailing-state) | | GET | `/api/v1/tenants/{tenant}/smartemailing/migrations/{migration_id}` | [Get one SmartEmailing migration run](https://www.postarna.cz/docs/api/reference-account#op-smartemailing-migration) | | GET | `/api/v1/tenants/{tenant}/web-tracking` | [Web tracking state of every shop](https://www.postarna.cz/docs/api/reference-account#op-web-tracking-index) | | GET | `/api/v1/tenants/{tenant}/web-tracking/events` | [List web tracking events](https://www.postarna.cz/docs/api/reference-account#op-web-tracking-events) | | PATCH | `/api/v1/tenants/{tenant}/web-tracking/{shop_id}` | [Switch web tracking of a shop](https://www.postarna.cz/docs/api/reference-account#op-web-tracking-switch) | ## SmartEmailing compatible API v3 | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/v3/account-info` | [Account info (guid = tenant id for API v1)](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-account-info) | | GET | `/api/v3/check-credentials` | [Check the credentials](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-check-credentials) | | POST | `/api/v3/check-credentials` | [Check the credentials](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-check-credentials-post) | | GET | `/api/v3/contactlists` | [List contact lists](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-contactlists) | | GET | `/api/v3/contactlists/{list_id}` | [Get a contact list](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-contactlist) | | GET | `/api/v3/contacts` | [List contacts](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-contacts) | | GET | `/api/v3/contacts/{contact_id}` | [Get a contact](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-contact) | | GET | `/api/v3/customfields` | [List custom fields](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-customfields) | | GET | `/api/v3/ping` | [Ping (no authentication)](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-ping) | | GET | `/api/v3/web-hooks` | [List account webhooks](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-webhooks) | | POST | `/api/v3/web-hooks` | [Register an account webhook](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-webhook-create-post) | | DELETE | `/api/v3/web-hooks/{webhook_id}` | [Delete an account webhook](https://www.postarna.cz/docs/api/reference-smartemailing-v3#op-se-v3-webhook-delete-delete) | ## SmartEmailing compatible CSV statistics | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/csv/list-contacts` | [Members of a list (CSV)](https://www.postarna.cz/docs/api/reference-smartemailing-csv#op-se-csv-list-contacts) | | GET | `/api/csv/statistics/email/automation-email-statistic-id` | [E-mail statistic ids of automation e-mail nodes](https://www.postarna.cz/docs/api/reference-smartemailing-csv#op-se-csv-automation-statistic-ids) | | GET | `/api/csv/statistics/email/automation-email-statistic-id/{automation_id}` | [E-mail statistic ids of automation e-mail nodes of one automation](https://www.postarna.cz/docs/api/reference-smartemailing-csv#op-se-csv-automation-statistic-ids-one) | | GET | `/api/csv/statistics/email/{kind}-detail/{sid}` | [Per-contact events of an e-mail statistic id (sent, opened, clicked, bounced, unsubscribed)](https://www.postarna.cz/docs/api/reference-smartemailing-csv#op-se-csv-email-detail) | ## MCP server for AI assistants | Metoda | Cesta | Popis | |---|---|---| | POST | `/mcp` | [MCP JSON-RPC endpoint (Streamable HTTP, stateless)](https://www.postarna.cz/docs/api/reference-mcp#op-mcp) | ## OAuth 2.1 for AI assistants | Metoda | Cesta | Popis | |---|---|---| | GET | `/.well-known/oauth-authorization-server` | [Authorization server metadata (RFC 8414)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-server-metadata) | | GET | `/.well-known/oauth-authorization-server/mcp` | [Authorization server metadata (RFC 8414)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-server-metadata-mcp) | | GET | `/.well-known/oauth-protected-resource` | [Protected resource metadata (RFC 9728)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-protected-resource) | | GET | `/.well-known/oauth-protected-resource/mcp` | [Protected resource metadata (RFC 9728)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-protected-resource-mcp) | | GET | `/oauth/authorize` | [Authorization (browser redirect to the consent page)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-authorize) | | POST | `/oauth/register` | [Dynamic client registration (RFC 7591, at most 20 an hour per address)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-register) | | POST | `/oauth/revoke` | [Revoke a token (RFC 7009)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-revoke) | | POST | `/oauth/token` | [Tokens: authorization_code or refresh_token (access pso_... 1 hour, refresh psr_... 30 days, rotated)](https://www.postarna.cz/docs/api/reference-oauth#op-oauth-token) | ## This document | Metoda | Cesta | Popis | |---|---|---| | GET | `/api/openapi.json` | [This OpenAPI document](https://www.postarna.cz/docs/api/reference-meta#op-openapi-document) |