Recept: přihlašovací formulář s potvrzením (double opt-in)
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
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{
"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ší).
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{
"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. previewUrlje náhled formuláře,publicIdjeho veřejné ID.
3. Kód pro web
curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/forms/21/embed" \
-H "Authorization: Bearer $POSTARNA_API_KEY"{
"html": "<!-- Formulář Poštárny: Patička webu -->\n<form method=\"post\" action=\"https://links.example.cz/f/3/50af3dc2-488b-4715-a1b3-3d059af683d8\" accept-charset=\"UTF-8\">\n <div class=\"pf-row\" data-field=\"email\"><label for=\"pf-email\">E-mailová adresa <span class=\"pf-req\">*</span></label><input id=\"pf-email\" type=\"email\" name=\"email\" maxlength=\"254\" autocomplete=\"email\" required><p class=\"pf-typo\" hidden></p></div>\n <div class=\"pf-row\" data-field=\"firstName\"><label for=\"pf-firstName\">Jméno</label><input id=\"pf-firstName\" type=\"text\" name=\"firstName\" maxlength=\"200\" autocomplete=\"given-name\"></div>\n <p style=\"position:absolute;left:-10000px\" aria-hidden=\"true\"><input type=\"text\" name=\"pa_website\" tabindex=\"-1\" autocomplete=\"off\"></p>\n <div class=\"pf-row\"><label class=\"pf-choice\"><input type=\"checkbox\" name=\"consent\" value=\"1\" required> <span>Souhlasím se zasíláním obchodních sdělení.</span></label></div>\n <button type=\"submit\">Přihlásit</button>\n <p><small>Example s.r.o., Ukázková 1, 110 00 Praha 1 <a href=\"https://shop-cz.example.test/ochrana-osobnich-udaju/\">Zásady ochrany osobních údajů</a></small></p>\n</form>\n",
"styled": "<!-- Formulář Poštárny: Patička webu -->\n<style>.pf-50af3dc2{box-sizing:border-box;max-width:320px;width:100%;margin:0 auto;background:#ececec;color:#333333;border-radius:4px;font:15px/1.45 Arial,Helvetica,sans-serif;}.pf-50af3dc2 *{box-sizing:border-box}.pf-50af3dc2 .pf-in{padding:20px 22px}.pf-50af3dc2 .pf-flex{display:flex;align-items:stretch}.pf-50af3dc2 .pf-flex .pf-side{flex:0 0 42%;background-size:cover;background-position:center}.pf-50af3dc2 .pf-flex .pf-in{flex:1 1 auto;min-width:0}.pf-50af3dc2 img.pf-img{display:block;width:calc(100% + 44px);max-width:none;height:auto;margin:4px -22px 14px}.pf-50af3dc2 h2.pf-title{margin:0 0 8px;font-size:22px;line-height:1.25;color:#bb2d2d;text-align:center}.pf-50af3dc2 p.pf-text{margin:0 0 12px;color:#333333;text-align:center}.pf-50af3dc2 .pf-row{margin:0 0 12px}.pf-50af3dc2 label{display:block;margin:0 0 4px;font-weight:700;font-size:13px;color:#333333}.pf-50af3dc2 label .pf-req{color:#d0021b}.pf-50af3dc2 input[type=text],.pf-50af3dc2 input[type=email],.pf-50af3dc2 input[type=tel],.pf-50af3dc2 input[type=date],.pf-50af3dc2 input[type=number],.pf-50af3dc2 select,.pf-50af3dc2 textarea{width:100%;padding:9px 10px;font:inherit;font-size:16px;color:#222;background:#fff;border:1px solid #c9c9c9;border-radius:3px}.pf-50af3dc2 textarea{min-height:80px}.pf-50af3dc2 .pf-choice{display:flex;gap:8px;align-items:flex-start;font-weight:400}.pf-50af3dc2 .pf-choice input{margin-top:3px;flex:none}.pf-50af3dc2 .pf-note{font-size:12px;margin:0 0 10px;color:#333333}.pf-50af3dc2 .pf-note a,.pf-50af3dc2 .pf-choice a{color:#bb2d2d}.pf-50af3dc2 .pf-err{color:#d0021b;font-size:13px;margin:4px 0 0}.pf-50af3dc2 .pf-typo{font-size:13px;margin:4px 0 0}.pf-50af3dc2 .pf-actions{text-align:center}.pf-50af3dc2 button.pf-btn{display:inline-block;padding:11px 22px;font:700 16px Arial,Helvetica,sans-serif;color:#ffffff;background:#bb2d2d;border:0;border-radius:4px;cursor:pointer;min-width:50%}.pf-50af3dc2 .pf-hp{position:absolute;left:-10000px;top:auto;width:1px;height:1px;overflow:hidden}@media (max-width:479px){.pf-50af3dc2 .pf-flex{display:block}.pf-50af3dc2 .pf-flex .pf-side{height:160px}}</style><div class=\"pf-50af3dc2 pf pf-basic\" data-template=\"classic\"><div class=\"pf-in\"><h2 class=\"pf-title\">Odebírejte novinky</h2><p class=\"pf-text\">Jednou za měsíc tipy a novinky.</p><form method=\"post\" action=\"https://links.example.cz/f/3/50af3dc2-488b-4715-a1b3-3d059af683d8\" accept-charset=\"UTF-8\" novalidate data-typo=\"1\"><div class=\"pf-row\" data-field=\"email\"><label for=\"pf-50af3dc2-email\">E-mailová adresa <span class=\"pf-req\">*</span></label><input id=\"pf-50af3dc2-email\" type=\"email\" name=\"email\" maxlength=\"254\" autocomplete=\"email\" required><p class=\"pf-typo\" hidden></p></div><div class=\"pf-row\" data-field=\"firstName\"><label for=\"pf-50af3dc2-firstName\">Jméno</label><input id=\"pf-50af3dc2-firstName\" type=\"text\" name=\"firstName\" maxlength=\"200\" autocomplete=\"given-name\"></div><p class=\"pf-hp\" aria-hidden=\"true\"><label>Toto pole nevyplňujte <input type=\"text\" name=\"pa_website\" tabindex=\"-1\" autocomplete=\"off\"></label></p><div class=\"pf-row\"><label class=\"pf-choice\"><input type=\"checkbox\" name=\"consent\" value=\"1\" required> <span>Souhlasím se zasíláním obchodních sdělení.</span></label></div><div class=\"pf-actions\"><button type=\"submit\" class=\"pf-btn primary\">Přihlásit</button></div><p><small>Example s.r.o., Ukázková 1, 110 00 Praha 1 <a href=\"https://shop-cz.example.test/ochrana-osobnich-udaju/\">Zásady ochrany osobních údajů</a></small></p></form></div></div>\n",
"url": "https://links.example.cz/f/3/50af3dc2-488b-4715-a1b3-3d059af683d8",
"script": "<script src=\"https://links.example.cz/f/3/50af3dc2-488b-4715-a1b3-3d059af683d8/form.js\" async></script>"
}Vložte html na web. Formulář posílá data na odkazovou doménu e-shopu (/f/<firma>/<publicId>); 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í
- Kontakt vznikne (nebo se najde) ve stavu
pending, členství v seznamech jeunconfirmed, zapíše se žádost o souhlas s IP adresou, prohlížečem, stránkou a přesným textem souhlasu. - Odejde potvrzovací e-mail. Odkaz platí 7 dní.
- 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í naconfirmedUrl. - 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á):
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": "<!doctype html><html><body><p>Dobrý den, {{df_salution|default('vážený zákazníku', true)}},</p><p>děkujeme za potvrzení odběru.</p><p style=\"font-size:12px\">{{cl_company}}, {{cl_address}}. <a href=\"{{unsubscribe}}\">Odhlásit odběr</a></p></body></html>"
}
}
JSON{
"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": "<!doctype html><html><body><p>Dobrý den, {{df_salution|default('vážený zákazníku', true)}},</p><p>děkujeme za potvrzení odběru.</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/3/e2ad6880-3f53-4fc1-988d-a4893a6ab8a3"
}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{
"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": {}
}curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/82/activate" \
-H "Authorization: Bearer $POSTARNA_API_KEY"{
"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
actionz kódu formuláře (email, pole formuláře, souhlasy). Nevolejte k tomuPOST /contacts, to je jen pro doložené souhlasy. - Přihlášení odkudkoli: místo
form_submittedpoužijtesubscribedsesources: ["signup_form"]. - Pop-up: formulář s
kind: "popup"a nastavenímpopup(pole popsaná ve skupině Formuláře).