Přeskočit na obsah
API dokumentace

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í. Hotové scénáře: recepty.

Graf

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ů

SkupinaTypy
Spouštěčetrigger_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átorycondition (ano / ne), wait (čekání), ab_test, holding (odkladiště), goal (cíl scénáře)
Akcesend_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álostKdyNastavení
order_creatednová objednávkashopId
order_completedobjednávka dokončena (zaplacena, odeslána, doručena)shopId
order_changedobjednávka změnila stavshopId, state
cart_updatedzměna košíku (POST /contact-events typ cart)shopId
page_visitnávštěva stránky (POST /contact-events typ visit)shopId, url, urlOperator, visitType
customvlastní událost (POST /contact-events typ custom, nebo uzel fire_event jiného scénáře)customEvent
subscribedkontakt se přihlásil k odběrusources
contact_creatednový kontakt
contact_updatedzměna pole kontaktufieldFilter
list_addedpřidání do seznamulistId
list_status_changedzměna stavu v seznamulistId, status
form_submittedodeslaný a potvrzený formulářformId
email_sent, link_clickede-mail nebo klik z uzlu jiného scénářeemailNode, link, compareParams
engagement_changedzměna angažovanosti
blacklistedkontakt na blacklistu
action_failedselhala akce automatizacefailureType, failureNode
manualruč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, jehož pravidla smí být i podmínky automatizace.

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 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í.

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á
durationvalue jednotek unit (minuty až roky)
time_of_dayna nejbližší time ("09:00")
weekdayna nejbližší den z weekdays (1 = pondělí) v čase time
datena místní datum a čas date ("2026-12-24T09:00")
timena časový údaj spec (countFrom node = od příchodu do uzlu, scenario = od vstupu do scénáře)
preferredna obvyklou dobu, kdy kontakt otevírá e-maily (bez historie nečeká)
spreadrozloží 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

StavVýznam
draftkoncept, nikdy nespuštěný
activeběží
pausedzastavený 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 „<název> - kopie“ (bez hesel webhooků).

Validace a problémy grafu

Problémy mají tvar {"node": "<klíč>" | null, "field": "<pole>", "code": "<kód>"} 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í:

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
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}.
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
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ů.
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
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.

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.<klíč>}} (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/<token>.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).