Preskočiť na obsah
API dokumentácia

Recept: prihlasovací formulár s potvrdením (double opt-in)

Cieľ: formulár na webe, ktorý po potvrdení e-mailom pridá návštevníka do zoznamu, zapíše súhlas a pošle uvítací e-mail.

Toto je správna cesta, keď nemáte doložený súhlas: kontakt vznikne ako čakajúci (pending) a prihlásený bude až po kliknutí na odkaz v potvrdzovacom e-maile. Cez POST /contacts zakladajte len kontakty s už doloženým súhlasom.

1. Zoznam pre odberateľov

Požiadavka: POST /api/v1/tenants/{tenant}/lists
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
Odpoveď: 201 Created
{
  "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ár

purposeId je účel spracúvania, ku ktorému sa súhlas zapíše; consentText je presné znenie súhlasu, ktoré formulár ukáže a Poštárna uloží k prihláške. fields pridá polia okrem e-mailu (firstName, lastName a ďalšie).

Požiadavka: POST /api/v1/tenants/{tenant}/forms
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
Odpoveď: 201 Created
{
  "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ár presmeruje po odoslaní; confirmedUrl: kam vedie potvrdzovací odkaz.
  • Formulár je v východiskovom nastavení double opt-in. Potvrdzovací e-mail je systémový (bez obchodného obsahu a pätičky), odchádza od odosielateľa formulára (settings.senderEmail), inak od overeného východiskového odosielateľa e-shopu, a najviac 3-krát za deň na jednu adresu.
  • previewUrl je náhľad formulára, publicId jeho verejné ID.

3. Kód pre web

Požiadavka: GET /api/v1/tenants/{tenant}/forms/21/embed
curl -sS -X GET "https://www.postarna.cz/api/v1/tenants/$TENANT/forms/21/embed" \
  -H "Authorization: Bearer $POSTARNA_API_KEY"
Odpoveď: 200 OK
{
  "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ár posiela dáta na odkazovú doménu e-shopu (/f/<firma>/<publicId>); stránky po odoslaní a potvrdení vykresľuje Poštárna.

  • Ochrana proti robotom: skryté pole (vyplnené = tichý úspech bez zápisu), voliteľne captcha.
  • Limity: 10 odoslaní za hodinu z jednej IP adresy na formulár, 3 za deň na jednu e-mailovú adresu, 300 za hodinu na firmu (429).
  • Pre každú adresu je odpoveď rovnaká, takže formulár neprezradí, kto už je v databáze.

4. Čo sa stane po odoslaní

  1. Kontakt vznikne (alebo sa nájde) v stave pending, členstvo v zoznamoch je unconfirmed, zapíše sa žiadosť o súhlas s IP adresou, prehliadačom, stránkou a presným textom súhlasu.
  2. Odíde potvrdzovací e-mail. Odkaz platí 7 dní.
  3. Po kliknutí: kontakt subscribed (consentBasis: "double_opt_in"), členstvo confirmed, súhlas s účelom formulára, vyplnené polia formulára sa uložia do kontaktu, presmerovanie na confirmedUrl.
  4. Odhlásený kontakt sa tak znovu prihlási; nedoručiteľná adresa alebo sťažnosť nedostane nič.

5. Uvítací e-mail po potvrdení

Spúšťač form_submitted s formId pustí kontakt do scenára, hneď ako potvrdí odber (nepotvrdený kontakt e-maily nedostáva):

Požiadavka: POST /api/v1/tenants/{tenant}/templates
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
Odpoveď: 201 Created
{
  "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"
}
Požiadavka: POST /api/v1/tenants/{tenant}/automations
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
Odpoveď: 201 Created
{
  "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": {}
}
Požiadavka: POST /api/v1/tenants/{tenant}/automations/82/activate
curl -sS -X POST "https://www.postarna.cz/api/v1/tenants/$TENANT/automations/82/activate" \
  -H "Authorization: Bearer $POSTARNA_API_KEY"
Odpoveď: 200 OK
{
  "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ár na webe: postavte vlastné HTML a posielajte rovnaké polia na adresu action z kódu formulára (email, polia formulára, súhlasy). Nevolajte na to POST /contacts, to je len pre doložené súhlasy.
  • Prihlásenie odkiaľkoľvek: namiesto form_submitted použite subscribed so sources: ["signup_form"].
  • Pop-up: formulár s kind: "popup" a nastavením popup (polia popísané v skupine Formuláre).