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
[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-eventstypcart) je událostcart_updated. Díkyreentry: "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: novyloučí 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):
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": "<!doctype html><html><body><p>Dobrý den, {{df_salution|default('vážený zákazníku', true)}},</p><p>ve vašem košíku zůstalo {{ metadata.event.attributes.itemCount }} ks zboží za {{ metadata.event.attributes.total }} {{ metadata.event.attributes.currency }}.</p><p><a href=\"https://www.example.cz/kosik/\">Dokončit objednávku</a></p><p style=\"font-size:12px\">{{cl_company}}, {{cl_address}}. <a href=\"{{unsubscribe}}\">Odhlásit odběr</a></p></body></html>"
}
}
JSON{
"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": "<!doctype html><html><body><p>Dobrý den, {{df_salution|default('vážený zákazníku', true)}},</p><p>ve vašem košíku zůstalo {{ metadata.event.attributes.itemCount }} ks zboží za {{ metadata.event.attributes.total }} {{ metadata.event.attributes.currency }}.</p><p><a href=\"https://www.example.cz/kosik/\">Dokončit objednávku</a></p><p style=\"font-size:12px\">{{cl_company}}, {{cl_address}}. <a href=\"{{unsubscribe}}\">Odhlásit odběr</a></p></body></html>",
"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"
}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:
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{
"errors": [],
"incomplete": [
{
"node": "email",
"field": "templateId",
"code": "required"
}
]
}3. Založení automatizace
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{
"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í
curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/81/activate" \
-H "Authorization: Bearer $POSTARNA_API_KEY"{
"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).
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{
"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": []
}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{
"id": "9004"
}Vyprázdněný košík (nebo dokončená objednávka) pošlete jako prázdné items:
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{
"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; podmínkaordered_since_entryji uvidí.
6. Sledování
Počty po uzlech (waiting = kontakty, které právě čekají):
curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/81/counts" \
-H "Authorization: Bearer $POSTARNA_API_KEY"{
"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:
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{
"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
goals pravidlemordered_since_entry: yesukončí běh, jakmile zákazník objedná, ať je kdekoli.