Přeskočit na obsah
API dokumentace

Webhooky

Poštárna umí posílat dva druhy webhooků:

Účtový webhookUzel webhook v automatizaci
Kdy volápři události ve firmě (nový kontakt, odhlášení, doručení ...)když kontakt dojde v automatizaci na uzel
RegistracePOST /api/v3/web-hooks (kompatibilní se SmartEmailingem)v grafu automatizace
Tvar datpevný, jako SmartEmailingvlastní 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 vypne5 pokusů po 5 minutách

Účtové webhooky

Události

eventKdyTělo
new_contactnový kontaktpole s jedním kontaktem
updated_contactzměna kontaktupole s jedním kontaktem
unsubscribed_contactodhlášení (ze všeho nebo ze seznamu)pole s jedním kontaktem a důvodem
sent_emaile-mail odeslánobjekt
delivery_statusdoručeno, měkce nebo tvrdě vráceno (s odpovědí serveru)objekt
email_openotevření (jen lidé, strojová otevření se nepočítají)objekt
email_clickklik (jen lidé)objekt
email_delivery_started, scoring_result_changed, engagement_level_changed, sms_delivery_statuspř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).

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
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.
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
Odpověď: 409 Conflict
{
  "status": "error",
  "meta": [],
  "message": "Already exists"
}
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"
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):

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"
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):

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"
  }
]
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:

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<id kampaně>, nebo a<id automatizace>:<klíč uzlu> (stejná ID jako v CSV statistikách).
  • 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/<náhodný-token>),
  • odpovídejte rychle (2xx) a zpracování odložte do fronty; zpracování musí snést opakované doručení.

Ukázkový příjemce: recept.

Uzel webhook v automatizaci

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": "<heslo>"}}}
  • 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.