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).
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{
"status": "created",
"meta": [],
"id": 7
}target_url:http://nebohttps://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čceAuthorization: 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.
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{
"status": "error",
"meta": [],
"message": "Already exists"
}curl -sS -X GET "https://www.postarna.cz/api/v3/web-hooks" \
-u "$POSTARNA_USER:$POSTARNA_API_KEY"{
"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):
curl -sS -X DELETE "https://www.postarna.cz/api/v3/web-hooks/7" \
-u "$POSTARNA_USER:$POSTARNA_API_KEY"(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):
[
{
"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"
}
][
{
"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:
{
"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_emailadelivery_statusmají místosid,urlaclicked_atpolefinished_at,delivery_status(delivered,softbounced,hardbounced) aremote_response(odpověď poštovního serveru při vrácení);email_openmásidaopened_at.campaign_type:newsletter,automation,transactional,doi,test.email_statistic_id:c<id kampaně>, neboa<id automatizace>:<klíč uzlu>(stejná ID jako v CSV statistikách).ide-mailové události je jedinečné; u kontaktových událostí jeidID 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ážeGET /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_auths dlouhým náhodným heslem a kontrola hlavičkyAuthorizationv 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
{"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-Typeposí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
basicAuthje jen pro zápis: detail ukazujepasswordSet: true; bez nového hesla zůstane uložené. Kopie automatizace hesla nekopíruje. Ukládání hesla potřebuje šifrovací klíč serveru (jinak 503unavailable/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}/reportvwebhooks.