{"openapi":"3.1.0","jsonSchemaDialect":"https://spec.openapis.org/oas/3.1/dialect/base","info":{"title":"Poštárna API","version":"1.0.0","description":"Poštárna is a multi-tenant e-mail marketing platform with statistics for companies and e-shops (Czech and Slovak). This document describes every\nroute an integration can call. Guides in Czech and Slovak: https://www.postarna.cz/docs/api (index for AI agents:\nhttps://www.postarna.cz/llms.txt, everything in one Markdown file: https://www.postarna.cz/llms-full.txt).\n\n## Three APIs\n* **API v1** (`/api/v1/tenants/{tenant}/...`): the full API, the same one the Poštárna web app uses. JSON in UTF-8.\n* **SmartEmailing compatible API v3** (`/api/v3/...`) and its CSV statistics (`/api/csv/...`): the same paths,\n  envelopes and errors as SmartEmailing's REST API v3, so an existing SE integration only changes the address, the\n  user name and the key. Read operations plus account webhooks.\n* **MCP server** (`POST /mcp`): Model Context Protocol for AI assistants (ChatGPT, Claude, Cursor ...), OAuth 2.1 or an\n  API key.\n\n## Authentication\nCreate an API key in the app: Nastavení › Datové zdroje › API klíče (Settings › Data sources › API keys). The key\n(`pst_` + 43 characters) is shown once. Send it as `Authorization: Bearer pst_...`, or as HTTP Basic with the e-mail\nof an active member of the company as the user name and the key as the password (both work on v1 and v3). A key\nworks only in its own company (tenant), with the roles it was given (never more than its creator has), and with\nscope `full` (read and write) or `read` (only routes whose permission level is read). Keys never reach the members,\ninvitations, API keys and connected apps (those need a signed-in person: 403 `forbidden` / `api_key`).\n\n`{tenant}` in v1 paths is the company's public id (a UUID). Find it with `GET /api/v3/account-info` (`data.guid`) or\nin the app on the API keys page.\n\n## Conventions (API v1)\n* IDs are strings. Times are ISO 8601 in UTC with milliseconds (`2026-09-30T08:00:00.000Z`); local calendar days of\n  the company are `YYYY-MM-DD`; automation settings use local `YYYY-MM-DDTHH:MM` and `HH:MM`.\n* Money is a decimal string next to its `currency` (`\"1290.00\"`, `\"CZK\"`). CZK and EUR are never added up or\n  converted: every sum is per currency.\n* Lists are paged: `page` from 1, `pageSize` 1 to 100 (default 25); the answer is `{items, total, page, pageSize}`.\n  Some grids take `sort` (`name,-createdAt`, at most 3 fields, `-` = descending).\n* Request bodies of POST, PUT and PATCH are `application/json` (415 `validation` / `contentType` otherwise); CSV\n  import and file upload also take `multipart/form-data`. Unknown body fields are ignored.\n* Errors: `{\"error\": {\"code\": \"...\", \"message\": \"<field or detail>\", \"params\": {...}}}`. `code` is stable and\n  machine readable, `message` names the field or the reason, `params` carries details (for example the issues of an\n  automation graph). The API never sends texts for people.\n* No idempotency keys: retry only requests that are safe to repeat (GET, PUT of a whole object, DELETE). For POST,\n  read the state first (for example list the contacts by e-mail) before you retry after a timeout. Concurrent\n  edits of content and automation graphs are guarded by versions (`baseVersion`, 409 `conflict` / `version`).\n\n## Limits\nPer company (all keys together): a bucket of 2 500 requests refilled with 4 requests a second, and 100 000 requests a\nday (refilled continuously). Every answer to a key carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and\n`X-RateLimit-Reset` (unix time when the bucket is full again) of the bucket nearest to running out. Over the limit:\n429 `rate_limited` with `Retry-After` (seconds). Some actions have their own limits (test e-mails 10 per day per\ncampaign or template, contact events 60 per contact in 10 minutes, MCP 300 messages a minute).\n\n## Consent and sending\nPoštárna never e-mails a contact who unsubscribed, bounced, complained or is suppressed, and campaigns only reach\ncontacts with a valid marketing consent. Sending to real recipients (approving a campaign, activating an automation)\nis irreversible: check the audience first (`POST .../campaigns/audience`, `POST .../automations/{id}/test`). Test\ne-mails go only to the company's test addresses (`GET .../test-recipients`).\n","contact":{"name":"deriverge s.r.o.","url":"https://www.postarna.cz/docs/api"},"x-guides":{"cs":"https://www.postarna.cz/docs/api","sk":"https://www.postarna.sk/docs/api","llms":"https://www.postarna.cz/llms.txt","llmsFull":"https://www.postarna.cz/llms-full.txt"}},"servers":[{"url":"https://www.postarna.cz","description":"Production (the same API answers on www.postarna.sk)"}],"security":[{"bearerAuth":[]},{"basicAuth":[]}],"tags":[{"name":"Campaigns","x-displayName":"Campaigns","description":"One-off e-mail campaigns (newsletters): draft, audience, content, test, approve (send now or schedule), pause, resume, cancel, language variants."}],"x-error-codes":{"conflict":{"meaning":"The change would break the state of the object. `message`: `name` (name taken), `locked` (a list bound to an e-shop), `status` (wrong state, e.g. editing a sent campaign), `recipients` (the audience changed more than 5 % since you counted it, `params.expected` and `params.actual`), `version` (stale `baseVersion`, `params.current`), `confirm` (saving a running automation needs `confirmRunning: true`), `waiting` (contacts wait in a node you remove, `params.nodes`), `runs` (deleting an automation that ran), `trigger` (no manual trigger), `limit` (too many objects).","fix":"Read the object again, then repeat with current data; for `recipients` count the audience again and send the new `expectedRecipients`."},"count_mismatch":{"meaning":"`expectedRecipients` does not match the audience.","fix":"Count again with `POST /campaigns/audience` and send the new number."},"csrf":{"meaning":"Browser session request without the CSRF header (never with an API key).","fix":"Send the API key in `Authorization` instead of cookies."},"empty_segment":{"meaning":"The campaign audience has no recipient.","fix":"Change the audience."},"expired":{"meaning":"The object is no longer available (an export file older than its retention).","fix":"Create it again (POST /exports)."},"forbidden":{"meaning":"The credentials are valid but not allowed here. `message`: `tenant` (another company in the path), `scope` (a read-only key on a write route), `api_key` (members, invitations and keys need a signed-in person), a module name (`contacts`, `campaigns`, `content`, `settings`, `billing`: the key's roles lack the level), `read_only` (support view).","fix":"Use the tenant id of the key (`GET /api/v3/account-info`), a key with scope `full`, or a key whose roles include the module (for example marketing_manager)."},"method_not_allowed":{"meaning":"The path exists but not with this HTTP method.","fix":"Check the method in this document."},"not_found":{"meaning":"The object does not exist in this company (objects of other companies answer the same).","fix":"Check the id; list the objects first."},"not_implemented":{"meaning":"The feature is not available yet.","fix":"Do not rely on it."},"rate_limited":{"meaning":"Too many requests: the company's API limit, or the limit of one action (test e-mails, contact events, sign-in attempts). `Retry-After` says after how many seconds to retry.","fix":"Wait `Retry-After` seconds; spread requests (4 a second sustained)."},"recently_sent":{"meaning":"HTTP 423: the contact cannot be deleted yet, a campaign e-mail to it is queued or went out in the last 24 hours (SmartEmailing answers the same).","fix":"Delete it after 24 hours. A request to be forgotten (GDPR) uses POST /contacts/{id}/erase, which is never refused."},"server":{"meaning":"Unexpected server error.","fix":"Retry later; the request may be repeated if it is safe to repeat."},"suppression_locked":{"meaning":"The address is suppressed for another reason (bounce, complaint, unsubscribe), so the blacklist cannot be added or removed; `params.reason` names it.","fix":"Leave it: such suppressions protect the sender and are removed only one by one (DELETE /suppressions/{email}) when the reason is gone."},"unauthorized":{"meaning":"No valid credentials: the API key is unknown, revoked, expired, idle for 180 days, its creator left the company, or the HTTP Basic user name is not an active member.","fix":"Check the key and the header (`Authorization: Bearer pst_...`). Create a new key in Nastavení › Datové zdroje › API klíče."},"unavailable":{"meaning":"A service the action needs is not available (`mail`: the mail backend refused a test e-mail, `data_key`: encryption key for webhook passwords missing).","fix":"Retry later; tell support when it persists."},"upstream":{"meaning":"An outside service failed (downloading a file by URL, the stock photo service); `params.reason` says why.","fix":"Check the URL or retry later."},"validation":{"meaning":"A parameter or body field is missing, has the wrong type or an invalid value. `message` names it (`email`, `definition.1.0.listId`, `graph` ...), `params` may carry details such as `params.issues` of an automation graph or `params.reason`.","fix":"Fix the named field. For 415 `contentType` send `Content-Type: application/json`; for `body` send a JSON object."}},"paths":{"/api/v1/tenants/{tenant}/campaigns":{"get":{"operationId":"campaigns_index","summary":"List campaigns","tags":["Campaigns"],"description":"Campaigns (draft, scheduled, sending, paused, completed, cancelled) with recipients and stats.\n\nContract notes (cs):\n\nParametry `q` (název nebo předmět), `status`, `shop`, `page`, `pageSize`; nejnovější první. Položka `CampaignListItem`: `{ \"id\", \"name\", \"shopId\", \"subject\", \"status\", \"recipients\", \"scheduledAt\", \"startedAt\", \"completedAt\", \"createdAt\", \"updatedAt\", \"stats\" }`.\n• `recipients` = počet příjemců zmrazený při schválení (`expected_recipients`), u konceptu null.\n• `stats` = null, dokud odesílání nezačne, jinak `{ \"sent\", \"delivered\", \"opened\", \"clicked\", \"bounced\", \"complained\", \"unsubscribed\" }`, unikátní kontakty z `events`. Platí `delivered + bounced = sent`. Podíly počítá UI: doručeno a vráceno z odeslaných, otevřeno, prokliky, stížnosti a odhlášení z doručených.","parameters":[{"$ref":"#/components/parameters/tenant"},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/pageSize"},{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":200},"description":"Search text."},{"name":"shop","in":"query","required":false,"schema":{"type":"string"},"description":"Shop id filter."},{"$ref":"#/components/parameters/sort"},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","scheduled","sending","paused","completed","cancelled"]},"description":"Status filter."},{"name":"tag","in":"query","required":false,"schema":{"type":"string"},"description":"Label filter; repeat for more labels."}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"x-mcp-tool":"list_campaigns","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CampaignListItem"}},"total":{"type":"number"},"page":{"type":"number"},"pageSize":{"type":"number"}},"required":["items","total","page","pageSize"]}}}},"400":{"description":"`validation` (message: q, sort, status, tag)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"operationId":"campaigns_create","summary":"Create a campaign (draft)","tags":["Campaigns"],"description":"Creates a campaign draft (only name and shopId are required). Then save_campaign_content, preview_campaign_audience, send_campaign_test and send_campaign.\n\nContract notes (cs):\n\nTělo `CampaignInput`: `{ \"name\", \"shopId\", \"senderId\", \"fromName\", \"subject\", \"preheader\", \"templateId\", \"audience\", \"trackOpens\"?, \"trackClicks\"?, \"utm\"?, \"headers\"?, \"timing\"?, \"plannedAt\"?, \"replyTo\"?, \"linkParams\"?, \"preferTime\"?, \"unsubscribePageId\"?, \"footerId\"? }`. `footerId` (Vybraná patička v Magic editoru, Patička emailu pod HTML editorem, migrace 0410) = publikovaná patička tenanta nebo null (400 `footerId`); koncept ze šablony bez tohoto pole převezme patičku šablony. E-mail kampaně (i testovací, náhled a online verze) končí patičkou kampaně, jinak patičkou šablony, jinak výchozí patičkou editoru, jinak standardní patičkou e-shopu. `unsubscribePageId` (SE krok 3 Odhlašovací stránka, migrace 0391) = aktivní odhlašovací stránka tenanta nebo null (400 `unsubscribePageId`); koncept vytvořený ze šablony bez tohoto pole převezme stránku šablony. Odeslaný e-mail kampaně ukáže stránku kampaně, jinak stránku šablony, jinak výchozí. Koncept smí být neúplný: povinné jsou jen `name` (1 až 150 znaků) a `shopId`. Kontroly: `senderId` = adresa odesílatele téhož e-shopu (400 `senderId`), `templateId` = šablona tenanta (400 `templateId`), `fromName` do 100, `subject` a `preheader` do 200 znaků. Server ke kampani zkopíruje `fromEmail` a `replyTo` odesílatele.\n\n`audience`: `{ \"listIds\", \"segmentIds\", \"excludeListIds\", \"excludeInactive\", \"excludeEmails\", \"onlyWithPurpose\", \"purposeIds\" }`, nejvýš 100 id v každém poli id a nejvýš 1000 adres v `excludeEmails`. Seznamy musí patřit e-shopu kampaně nebo celé firmě, segmenty e-shopu kampaně, `purposeIds` účely tenanta (jinak 400 `audience`).\n• `excludeEmails`: adresy vyloučené ručně (normalizované, bez ohledu na to, jestli jsou kontaktem).\n• `onlyWithPurpose` a `purposeIds`: jen kontakty s platným (nevzatým zpět, v platnosti) souhlasem pro některý z `purposeIds`; prázdné `purposeIds` = libovolný účel stačí.\n\n`trackOpens`, `trackClicks`: musí být boolean. `utm`: `null` nebo `{}` = vypnuto; jinak `source`, `medium` a `campaign` povinné (1 až 100 znaků), `term` a `content` nepovinné; neúplná trojice = 400 `utm`. UTM se doplní jen do odkazů na e-shop kampaně (existující parametry se nepřepíšou), ne do odkazů `/m/…` ani cizích domén. `headers`: pole `{ \"name\", \"value\" }`, `name` `X-[A-Za-z0-9][A-Za-z0-9-]{0,62}` a jedinečné bez ohledu na velikost písmen, `value` do 200 znaků na jednom řádku; 400 `headers`. `timing`: `now` | `schedule` | `later`; jiná hodnota 400 `timing`. `plannedAt`: ISO čas s zónou nebo null; 400 `plannedAt`. Průvodce 1:1 se SE (krok 1 a 3): `replyTo` = jedna z `replyToOptions` (bez ohledu na velikost písmen; `\"\"` = adresa pro odpovědi odesílatele; jiná 400 `replyTo`), schválení ji ponechá; bez `replyTo` se při změně odesílatele nebo e-shopu vezme odesílatelova. `linkParams` = trackovací parametry SE jako volné dvojice `[{ \"name\", \"value\" }]` (nejvýš 20, název `[A-Za-z0-9_.\\[\\]-]{1,64}` jedinečný bez ohledu na velikost písmen, hodnota 1 až 200 znaků na jednom řádku, smí obsahovat merge tagy); doplní se do odkazů na e-shop kampaně jako UTM (parametr, který odkaz už má, zůstane); 400 `linkParams`. `preferTime` (boolean, 400 `preferTime`) = „Ideální čas odeslání“: při startu každá zpráva počká do nejbližší celé hodiny, kdy kontakt nejčastěji otevírá (nejvýš 24 hodin), kontakty bez otevření jdou hned.","parameters":[{"$ref":"#/components/parameters/tenant"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignInput"},"examples":{"send-campaign-create":{"summary":"docs/api-examples/send-campaign.json create","value":{"name":"Říjnový newsletter","shopId":"17","senderId":"17","fromName":"Example.cz","subject":"Podzimní novinky","preheader":"Nová káva a tipy na přípravu","audience":{"listIds":["44"],"segmentIds":[],"excludeListIds":[],"excludeInactive":true,"excludeEmails":[],"onlyWithPurpose":false,"purposeIds":[]}}}}}}},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-tool":"create_campaign","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDetail"},"examples":{"send-campaign-create":{"summary":"docs/api-examples/send-campaign.json create","value":{"id":"151","name":"Říjnový newsletter","shopId":"17","subject":"Podzimní novinky","status":"draft","recipients":null,"scheduledAt":null,"startedAt":null,"completedAt":null,"createdAt":"2026-10-01T08:00:00.000Z","updatedAt":"2026-10-01T08:00:00.000Z","stats":null,"variantGroupId":null,"variantLabel":"","variantPosition":0,"tags":[],"preheader":"Nová káva a tipy na přípravu","senderId":"17","fromName":"Example.cz","fromEmail":"info@example.cz","replyTo":"","templateId":null,"hasContent":false,"audience":{"listIds":["44"],"segmentIds":[],"excludeListIds":[],"excludeInactive":true,"excludeEmails":[],"onlyWithPurpose":false,"purposeIds":[]},"pausedReason":null,"approvedAt":null,"trackOpens":true,"trackClicks":true,"utm":null,"headers":[],"timing":"later","plannedAt":null,"linkParams":[],"preferTime":false,"replyToOptions":["info@example.cz"]}}}}}},"400":{"description":"`validation` (message: audience, footerId, preferTime, replyTo, senderId, templateId, timing, unsubscribePageId)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/audience":{"post":{"operationId":"campaigns_audience","summary":"Count and explain the recipients of an audience","tags":["Campaigns"],"description":"Counts recipients of an audience without saving: matched, recipients and every excluded reason.\n\nAudienceCount of an audience for a shop: matched, recipients and one reason per left-out contact. anyShop true = the audience of a language variant (lists and segments of any shop).\n\nContract notes (cs):\n\nTělo `{ \"shopId\", \"audience\" }`. Odpověď `{ \"matched\", \"recipients\", \"excluded\": { \"not_mailable\", \"unconfirmed\", \"weak_consent\", \"exception_expired\", \"no_purpose\", \"excluded_list\", \"excluded_manual\", \"inactive\" } }`.\n• `matched` = unikátní kontakty vybraných seznamů (členství kromě `removed`) a segmentů.\n• Každý nepřijatý kontakt má jeden důvod v tomto pořadí: `unconfirmed` (stav `pending`), `not_mailable` (odhlášený, vrácený, stížnost, potlačení, nebo je ve vybraných seznamech jen jako odhlášený), `unconfirmed` (jen nepotvrzené členství), `weak_consent` (slabý souhlas, výchozí D6), `exception_expired` (zákaznická výjimka e-shopu bez dokončené objednávky tolik měsíců: slovenský e-shop 12 měsíců podle zákona, i bez nastavení, jiný e-shop vypnuto, pokud ho tenant nenastaví v `GET`/`PATCH /tenants/{t}/consent-settings`), `no_purpose` (`onlyWithPurpose` a žádný platný souhlas pro `purposeIds`), `excluded_list`, `excluded_manual` (adresa v `excludeEmails`), `inactive` (angažovanost E nebo stav vyloučen při `excludeInactive`). Platí `recipients + součet excluded = matched`.","parameters":[{"$ref":"#/components/parameters/tenant"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"shopId":{"type":"string"},"audience":{"$ref":"#/components/schemas/CampaignAudience"},"anyShop":{"type":"boolean"}},"required":["shopId","audience","anyShop"]},{"type":"object","properties":{"shopId":{"type":"string"},"audience":{"$ref":"#/components/schemas/CampaignAudience"}},"required":["shopId","audience"]}]},"examples":{"send-campaign-audience":{"summary":"docs/api-examples/send-campaign.json audience","value":{"shopId":"17","audience":{"listIds":["44"],"segmentIds":[],"excludeListIds":[],"excludeInactive":true,"excludeEmails":[],"onlyWithPurpose":false,"purposeIds":[]}}}}}}},"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"x-mcp-tool":"preview_campaign_audience","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AudienceCount"},"examples":{"send-campaign-audience":{"summary":"docs/api-examples/send-campaign.json audience","value":{"matched":1,"recipients":1,"excluded":{"not_mailable":0,"unconfirmed":0,"weak_consent":0,"exception_expired":0,"no_purpose":0,"excluded_list":0,"excluded_manual":0,"inactive":0}}}}}}},"400":{"description":"`validation` (message: anyShop, audience)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/tags":{"post":{"operationId":"campaigns_tags","summary":"Change labels of campaigns","tags":["Campaigns"],"parameters":[{"$ref":"#/components/parameters/tenant"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTagsInput"}}},"description":"Required by the server: ids."},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"number"}},"required":["updated"]}}}},"400":{"description":"`validation` (message: ids)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}":{"delete":{"operationId":"campaigns_delete","summary":"Delete a campaign draft","tags":["Campaigns"],"description":"Deletes a draft campaign that sent nothing.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-confirm":"delete","x-mcp-tool":"delete_campaign","responses":{"204":{"description":"No content"},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: status)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"get":{"operationId":"campaigns_show","summary":"Get a campaign","tags":["Campaigns"],"description":"One campaign with audience, sender, tracking and state.\n\nContract notes (cs):\n\n`CampaignDetail` = položka a navíc `preheader`, `senderId`, `fromName`, `fromEmail`, `replyTo`, `templateId`, `hasContent`, `audience`, `pausedReason`, `approvedAt`, `trackOpens`, `trackClicks`, `utm`, `headers`, `timing`, `plannedAt`, `linkParams`, `preferTime`, `replyToOptions` (adresy e-shopu, které smí být „E-mail pro odpovědi“: adresy odesílatelů a jejich adresy pro odpovědi), `unsubscribePageId` (vlastní odhlašovací stránka kampaně, null = stránka šablony, jinak výchozí), `footerId` (vybraná patička kampaně, null = patička šablony, jinak výchozí).\n• `templateId` = šablona, ze které se obsah zkopíroval (jen informace; pozdější úpravy šablony kampaň nemění, po smazání šablony je null). Obsah má kampaň vlastní (`GET …/content`).\n• `hasContent` = kampaň má neprázdné HTML.\n• `pausedReason`: `manual`, `bounce_rate`, `complaint_rate`, `unsubscribe_rate` (automatická pauza jádra podle prahů `tenant.DEFAULT_SENDING.thresholds`), `recipient_drift` (při startu se počet příjemců liší od schváleného o víc než `recipient_drift_pct`, výchozí 5 %).\n• Krok „Rozšířené\": `trackOpens`, `trackClicks` (výchozí true jako v SE), `utm` = `{ \"source\", \"medium\", \"campaign\", \"term\"?, \"content\"? }` nebo null (vypnuto), `headers` = `[{ \"name\", \"value\" }]` (nejvýš 10, jméno `X-…`, `X-SES-…` a `X-Postarna-…` vyhrazené platformě). `timing` (`now` | `schedule` | `later`) a `plannedAt` jsou čas odeslání zvolený v průvodci (koncept si ho pamatuje); skutečný čas odeslání dá až `POST …/approve`.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"x-mcp-tool":"get_campaign","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDetail"},"examples":{"send-campaign-show":{"summary":"docs/api-examples/send-campaign.json show","value":{"id":"151","name":"Říjnový newsletter","shopId":"17","subject":"Podzimní novinky","status":"scheduled","recipients":1,"scheduledAt":"2026-10-02T07:00:00.000Z","startedAt":null,"completedAt":null,"createdAt":"2026-10-01T08:00:00.000Z","updatedAt":"2026-10-01T08:00:00.000Z","stats":null,"variantGroupId":null,"variantLabel":"","variantPosition":0,"tags":[],"preheader":"Nová káva a tipy na přípravu","senderId":"17","fromName":"Example.cz","fromEmail":"info@example.cz","replyTo":"","templateId":null,"hasContent":true,"audience":{"listIds":["44"],"segmentIds":[],"excludeListIds":[],"excludeInactive":true,"excludeEmails":[],"onlyWithPurpose":false,"purposeIds":[]},"pausedReason":null,"approvedAt":"2026-10-01T08:00:00.000Z","trackOpens":true,"trackClicks":true,"utm":null,"headers":[],"timing":"later","plannedAt":null,"linkParams":[],"preferTime":false,"replyToOptions":["info@example.cz"]}}}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"patch":{"operationId":"campaigns_update","summary":"Update a campaign draft","tags":["Campaigns"],"description":"Changes a draft campaign (any CampaignInput field).\n\nContract notes (cs):\n\nTělo `CampaignInput`: `{ \"name\", \"shopId\", \"senderId\", \"fromName\", \"subject\", \"preheader\", \"templateId\", \"audience\", \"trackOpens\"?, \"trackClicks\"?, \"utm\"?, \"headers\"?, \"timing\"?, \"plannedAt\"?, \"replyTo\"?, \"linkParams\"?, \"preferTime\"?, \"unsubscribePageId\"?, \"footerId\"? }`. `footerId` (Vybraná patička v Magic editoru, Patička emailu pod HTML editorem, migrace 0410) = publikovaná patička tenanta nebo null (400 `footerId`); koncept ze šablony bez tohoto pole převezme patičku šablony. E-mail kampaně (i testovací, náhled a online verze) končí patičkou kampaně, jinak patičkou šablony, jinak výchozí patičkou editoru, jinak standardní patičkou e-shopu. `unsubscribePageId` (SE krok 3 Odhlašovací stránka, migrace 0391) = aktivní odhlašovací stránka tenanta nebo null (400 `unsubscribePageId`); koncept vytvořený ze šablony bez tohoto pole převezme stránku šablony. Odeslaný e-mail kampaně ukáže stránku kampaně, jinak stránku šablony, jinak výchozí. Koncept smí být neúplný: povinné jsou jen `name` (1 až 150 znaků) a `shopId`. Kontroly: `senderId` = adresa odesílatele téhož e-shopu (400 `senderId`), `templateId` = šablona tenanta (400 `templateId`), `fromName` do 100, `subject` a `preheader` do 200 znaků. Server ke kampani zkopíruje `fromEmail` a `replyTo` odesílatele.\n\n`audience`: `{ \"listIds\", \"segmentIds\", \"excludeListIds\", \"excludeInactive\", \"excludeEmails\", \"onlyWithPurpose\", \"purposeIds\" }`, nejvýš 100 id v každém poli id a nejvýš 1000 adres v `excludeEmails`. Seznamy musí patřit e-shopu kampaně nebo celé firmě, segmenty e-shopu kampaně, `purposeIds` účely tenanta (jinak 400 `audience`).\n• `excludeEmails`: adresy vyloučené ručně (normalizované, bez ohledu na to, jestli jsou kontaktem).\n• `onlyWithPurpose` a `purposeIds`: jen kontakty s platným (nevzatým zpět, v platnosti) souhlasem pro některý z `purposeIds`; prázdné `purposeIds` = libovolný účel stačí.\n\n`trackOpens`, `trackClicks`: musí být boolean. `utm`: `null` nebo `{}` = vypnuto; jinak `source`, `medium` a `campaign` povinné (1 až 100 znaků), `term` a `content` nepovinné; neúplná trojice = 400 `utm`. UTM se doplní jen do odkazů na e-shop kampaně (existující parametry se nepřepíšou), ne do odkazů `/m/…` ani cizích domén. `headers`: pole `{ \"name\", \"value\" }`, `name` `X-[A-Za-z0-9][A-Za-z0-9-]{0,62}` a jedinečné bez ohledu na velikost písmen, `value` do 200 znaků na jednom řádku; 400 `headers`. `timing`: `now` | `schedule` | `later`; jiná hodnota 400 `timing`. `plannedAt`: ISO čas s zónou nebo null; 400 `plannedAt`. Průvodce 1:1 se SE (krok 1 a 3): `replyTo` = jedna z `replyToOptions` (bez ohledu na velikost písmen; `\"\"` = adresa pro odpovědi odesílatele; jiná 400 `replyTo`), schválení ji ponechá; bez `replyTo` se při změně odesílatele nebo e-shopu vezme odesílatelova. `linkParams` = trackovací parametry SE jako volné dvojice `[{ \"name\", \"value\" }]` (nejvýš 20, název `[A-Za-z0-9_.\\[\\]-]{1,64}` jedinečný bez ohledu na velikost písmen, hodnota 1 až 200 znaků na jednom řádku, smí obsahovat merge tagy); doplní se do odkazů na e-shop kampaně jako UTM (parametr, který odkaz už má, zůstane); 400 `linkParams`. `preferTime` (boolean, 400 `preferTime`) = „Ideální čas odeslání“: při startu každá zpráva počká do nejbližší celé hodiny, kdy kontakt nejčastěji otevírá (nejvýš 24 hodin), kontakty bez otevření jdou hned.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"shopId":{"type":"string"},"senderId":{"type":["string","null"],"description":"A sender address of the campaign shop; it must be verified for approval."},"fromName":{"type":"string"},"subject":{"type":"string"},"preheader":{"type":"string"},"templateId":{"type":["string","null"],"description":"Template the content was copied from; the content itself is saved with saveCampaignContent."},"audience":{"$ref":"#/components/schemas/CampaignAudience"},"trackOpens":{"type":"boolean"},"trackClicks":{"type":"boolean"},"utm":{"anyOf":[{"$ref":"#/components/schemas/CampaignUtm"},{"type":"null"}]},"headers":{"type":"array","items":{"$ref":"#/components/schemas/CampaignHeader"}},"timing":{"type":"string","enum":["now","schedule","later"]},"plannedAt":{"type":["string","null"]},"replyTo":{"type":"string","description":"One of replyToOptions; '' = the sender's own reply-to."},"linkParams":{"type":"array","items":{"$ref":"#/components/schemas/CampaignLinkParam"}},"preferTime":{"type":"boolean"},"unsubscribePageId":{"type":["string","null"],"description":"An active unsubscribe page of the tenant, null = the template's or the default; left out on a new draft made\nfrom a template = the template's page."},"footerId":{"type":["string","null"],"description":"A published footer of the tenant, null = the template's or the default; left out on a new draft made from a\ntemplate = the template's footer."}}}}}},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-tool":"update_campaign","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDetail"}}}},"400":{"description":"`validation` (message: audience, footerId, preferTime, replyTo, senderId, templateId, timing, unsubscribePageId)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: status)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/approve":{"post":{"operationId":"campaigns_approve","summary":"Approve a campaign: send now or schedule","tags":["Campaigns"],"description":"Approves a draft campaign and sends it now (sendAt null) or schedules it (sendAt ISO time, 5 minutes to 365 days ahead). The preview shows subject, sender and the exact recipient count; expectedRecipients defaults to that count.\n\nBody {sendAt: ISO time in UTC or null (now), expectedRecipients: the number the user confirmed}.\n\nContract notes (cs):\n\nTělo `{ \"sendAt\": \"2026-10-02T07:00:00.000Z\" | null, \"expectedRecipients\": 123 }`. Krok „Schválení“: UI ukáže počet a čas a uživatel je výslovně potvrdí. Kontroly v pořadí: stav `draft` (409 `status`), `subject`, `fromName`, `senderId` (ověřený odesílatel téhož e-shopu), `content` (bez obsahu nejde odeslat), `lint` (kontrola obsahu s pravidly tenanta našla chybu; UI si nálezy načte přes `POST …/content/lint`), `audience` (aspoň jeden seznam nebo segment a aspoň 1 příjemce), `sendAt` (null = hned, jinak za 5 minut až 365 dní), `expectedRecipients` (celé číslo). Když se skutečný počet liší od potvrzeného o víc než 5 % (zaokrouhleno dolů), odpověď je 409 `recipients` a kampaň zůstane konceptem; UI načte nový počet a chce nové potvrzení. Úspěch uloží `approvedAt`, `recipients` a vrátí `CampaignDetail`.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveInput"},"examples":{"send-campaign-approve-stale":{"summary":"docs/api-examples/send-campaign.json approve-stale","value":{"sendAt":"2026-10-02T07:00:00.000Z","expectedRecipients":250}}}}}},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-confirm":"send","x-mcp-tool":"send_campaign","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDetail"},"examples":{"send-campaign-approve":{"summary":"docs/api-examples/send-campaign.json approve","value":{"id":"151","name":"Říjnový newsletter","shopId":"17","subject":"Podzimní novinky","status":"scheduled","recipients":1,"scheduledAt":"2026-10-02T07:00:00.000Z","startedAt":null,"completedAt":null,"createdAt":"2026-10-01T08:00:00.000Z","updatedAt":"2026-10-01T08:00:00.000Z","stats":null,"variantGroupId":null,"variantLabel":"","variantPosition":0,"tags":[],"preheader":"Nová káva a tipy na přípravu","senderId":"17","fromName":"Example.cz","fromEmail":"info@example.cz","replyTo":"","templateId":null,"hasContent":true,"audience":{"listIds":["44"],"segmentIds":[],"excludeListIds":[],"excludeInactive":true,"excludeEmails":[],"onlyWithPurpose":false,"purposeIds":[]},"pausedReason":null,"approvedAt":"2026-10-01T08:00:00.000Z","trackOpens":true,"trackClicks":true,"utm":null,"headers":[],"timing":"later","plannedAt":null,"linkParams":[],"preferTime":false,"replyToOptions":["info@example.cz"]}}}}}},"400":{"description":"`validation` (message: sendAt)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: test_only)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"send-campaign-approve-stale":{"summary":"docs/api-examples/send-campaign.json approve-stale","value":{"error":{"code":"conflict","message":"recipients","params":{"expected":250,"actual":1}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/cancel":{"post":{"operationId":"campaigns_cancel","summary":"Cancel a scheduled or paused campaign","tags":["Campaigns"],"description":"Cancels a campaign for good (what was sent stays in the statistics).\n\nContract notes (cs):\n\nBez těla, vrací `CampaignDetail`. Obnovení po pauze `recipient_drift` přijme aktuální počet příjemců (UI na to předem upozorní). Zrušení odesílané kampaně zastaví zbytek; co odešlo, zůstane ve statistikách.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-tool":"cancel_campaign","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDetail"},"examples":{"send-campaign-cancel":{"summary":"docs/api-examples/send-campaign.json cancel","value":{"id":"151","name":"Říjnový newsletter","shopId":"17","subject":"Podzimní novinky","status":"cancelled","recipients":1,"scheduledAt":"2026-10-02T07:00:00.000Z","startedAt":null,"completedAt":null,"createdAt":"2026-10-01T08:00:00.000Z","updatedAt":"2026-10-01T08:00:00.000Z","stats":null,"variantGroupId":null,"variantLabel":"","variantPosition":0,"tags":[],"preheader":"Nová káva a tipy na přípravu","senderId":"17","fromName":"Example.cz","fromEmail":"info@example.cz","replyTo":"","templateId":null,"hasContent":true,"audience":{"listIds":["44"],"segmentIds":[],"excludeListIds":[],"excludeInactive":true,"excludeEmails":[],"onlyWithPurpose":false,"purposeIds":[]},"pausedReason":null,"approvedAt":"2026-10-01T08:00:00.000Z","trackOpens":true,"trackClicks":true,"utm":null,"headers":[],"timing":"later","plannedAt":null,"linkParams":[],"preferTime":false,"replyToOptions":["info@example.cz"]}}}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: status)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/content":{"get":{"operationId":"campaigns_content","summary":"Get the content of a campaign","tags":["Campaigns"],"description":"Content of a campaign (editor, html, design, version).\n\nContract notes (cs):\n\nObsah kampaně, stejná pravidla jako u šablony. Měnit jde jen koncept (409 `status`). Kampaň bez obsahu vrací `version` 0 a prázdné `html`. `saveKind` a historie uložení jako u šablony.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"x-mcp-tool":"get_campaign_content","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailContent"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"put":{"operationId":"campaigns_save_content","summary":"Save the content of a campaign draft","tags":["Campaigns"],"description":"Saves the content of a draft campaign (copy a template: get_template, then save its content here).\n\nContract notes (cs):\n\nObsah kampaně, stejná pravidla jako u šablony. Měnit jde jen koncept (409 `status`). Kampaň bez obsahu vrací `version` 0 a prázdné `html`. `saveKind` a historie uložení jako u šablony.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailContentInput"},"examples":{"send-campaign-content":{"summary":"docs/api-examples/send-campaign.json content","value":{"editor":"html","design":null,"baseVersion":0,"html":"<!doctype html><html><body><p>Dobrý den, {{df_salution|default('vážený zákazníku', true)}},</p><p>na e-shopu máme novou podzimní kávu.</p><p><a href=\"https://www.example.cz/novinky\">Prohlédnout novinky</a></p><p style=\"font-size:12px\">{{cl_company}}, {{cl_address}}. <a href=\"{{unsubscribe}}\">Odhlásit odběr</a></p></body></html>"}}}}}},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-tool":"save_campaign_content","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailContent"},"examples":{"send-campaign-content":{"summary":"docs/api-examples/send-campaign.json content","value":{"editor":"html","html":"<!doctype html><html><body><p>Dobrý den, {{df_salution|default('vážený zákazníku', true)}},</p><p>na e-shopu máme novou podzimní kávu.</p><p><a href=\"https://www.example.cz/novinky\">Prohlédnout novinky</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"}}}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/pause":{"post":{"operationId":"campaigns_pause","summary":"Pause a sending or scheduled campaign","tags":["Campaigns"],"description":"Pauses a scheduled or sending campaign.\n\nContract notes (cs):\n\nBez těla, vrací `CampaignDetail`. Obnovení po pauze `recipient_drift` přijme aktuální počet příjemců (UI na to předem upozorní). Zrušení odesílané kampaně zastaví zbytek; co odešlo, zůstane ve statistikách.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-tool":"pause_campaign","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDetail"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: status)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/preview":{"post":{"operationId":"campaigns_preview","summary":"Render a campaign for one contact","tags":["Campaigns"],"description":"The e-mail as one contact would get it: body {email} of a contact of the tenant; answers {subject, preheader, html} with every merge tag filled and sample links. Nothing is sent or recorded. It shows one contact's data (name, e-mail, custom fields, orders in scripts), so it needs the module contacts too (read): campaigns read alone (content manager, developer) neither reads a contact nor learns whether an address is one (review of batch 8).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"}},"required":["email"]}}},"description":"Required by the server: email."},"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignPreview"}}}},"400":{"description":"`validation` (message: script)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"`forbidden` (message: contacts)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/resume":{"post":{"operationId":"campaigns_resume","summary":"Resume a paused campaign","tags":["Campaigns"],"description":"Resumes a paused campaign (it sends again, or goes back to scheduled when its time is ahead).\n\nContract notes (cs):\n\nBez těla, vrací `CampaignDetail`. Obnovení po pauze `recipient_drift` přijme aktuální počet příjemců (UI na to předem upozorní). Zrušení odesílané kampaně zastaví zbytek; co odešlo, zůstane ve statistikách.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-confirm":"send","x-mcp-tool":"resume_campaign","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignDetail"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: status)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/stats":{"get":{"operationId":"campaigns_stats","summary":"Statistics of a campaign by provider and domain","tags":["Campaigns"],"parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"total":{"type":"object","additionalProperties":true,"description":"Counts and rates: sent, delivered, bounces, softBounces, complaints, unsubscribes, opens, clicks, queued, failed, skipped and their rates (engine._rates in camelCase)."},"providers":{"type":"object","additionalProperties":{"type":"object","additionalProperties":true,"description":"Counts and rates: sent, delivered, bounces, softBounces, complaints, unsubscribes, opens, clicks, queued, failed, skipped and their rates (engine._rates in camelCase)."}},"domains":{"type":"array","items":{"type":"object","additionalProperties":true,"description":"Counts and rates: sent, delivered, bounces, softBounces, complaints, unsubscribes, opens, clicks, queued, failed, skipped and their rates (engine._rates in camelCase)."}}}}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/test":{"post":{"operationId":"campaigns_test","summary":"Send a test e-mail of a campaign","tags":["Campaigns"],"description":"Sends a test e-mail of the campaign to the account's test addresses only (list_test_recipients).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string"}},"required":["to"]},"examples":{"send-campaign-test":{"summary":"docs/api-examples/send-campaign.json test","value":{"to":"test@example.cz"}}}}}},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-tool":"send_campaign_test","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSendResult"},"examples":{"send-campaign-test":{"summary":"docs/api-examples/send-campaign.json test","value":{"to":"test@example.cz","sentAt":"2026-10-01T08:00:00.000Z"}}}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`unavailable` (message: mail)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants":{"get":{"operationId":"variants_index","summary":"Get the language variants of a campaign","tags":["Campaigns"],"parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignVariantGroup"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"operationId":"variants_create","summary":"Create language variants of a campaign","tags":["Campaigns"],"description":"Duplicate as variant: body {shopId, label, sourceLabel?}. Answers the new variant's id and the group.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"shopId":{"type":"string"},"label":{"type":"string"},"sourceLabel":{"type":"string"}},"required":["shopId","label"]}}},"description":"Required by the server: label, shopId."},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignVariantGroup"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"put":{"operationId":"variants_arrange","summary":"Change the language variants of a campaign","tags":["Campaigns"],"description":"Order and labels of the group: body {variants: [{id, label}] in the new order, every variant once}.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"variants":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"}},"required":["id","label"]}}},"required":["variants"]}}},"description":"Required by the server: variants."},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignVariantGroup"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/approve":{"post":{"operationId":"variants_approve","summary":"Approve the language variants (send or schedule)","tags":["Campaigns"],"description":"One send action for every variant: body {sendAt: ISO time or null (now), expectedRecipients: {id: final}}.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariantApproveInput"}}}},"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-confirm":"send","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignVariantGroup"}}}},"400":{"description":"`validation` (message: sendAt)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: test_only)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/cancel":{"post":{"operationId":"variants_cancel","summary":"Cancel the language variants","tags":["Campaigns"],"parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignVariantGroup"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: status, variants)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/pause":{"post":{"operationId":"variants_pause","summary":"Pause the language variants","tags":["Campaigns"],"parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignVariantGroup"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: status, variants)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/preview":{"post":{"operationId":"variants_preview","summary":"Preview the audience split of language variants","tags":["Campaigns"],"description":"Final numbers per variant: matched, recipients of its own audience, taken by an earlier variant, final.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariantPreview"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/resume":{"post":{"operationId":"variants_resume","summary":"Resume the language variants","tags":["Campaigns"],"parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"full","keyScope":"full"},"x-mcp-confirm":"send","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignVariantGroup"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"`conflict` (message: status, variants)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/variants/stats":{"get":{"operationId":"variants_stats","summary":"Statistics of the language variants","tags":["Campaigns"],"description":"Statistics per variant and combined (unique contacts: one variant per contact, so the sums add up).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariantStats"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/versions":{"get":{"operationId":"campaigns_versions","summary":"List saved content versions of a campaign","tags":["Campaigns"],"parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}},{"name":"before","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentVersionList"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/campaigns/{campaign_id}/versions/{version_id}":{"get":{"operationId":"campaigns_version","summary":"Get one content version of a campaign","tags":["Campaigns"],"parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"campaign_id","in":"path","required":true,"description":"Id of the campaign (string of digits).","schema":{"type":"string"}},{"name":"version_id","in":"path","required":true,"description":"Id of the version (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentVersionDetail"}}}},"400":{"description":"`validation`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"`not_found`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/senders":{"get":{"operationId":"senders_index","summary":"List verified senders","tags":["Campaigns"],"description":"Sender addresses per shop (only verified ones may send).\n\nContract notes (cs):\n\n`{ \"items\": [ { \"id\", \"shopId\", \"name\", \"email\", \"replyTo\", \"verified\", \"isDefault\" } ] }`. Odesílat smí jen ověřená adresa (SPF, DKIM, DMARC). Adresy odebrané v Nastavení › Odesílání se nevracejí. Zdroj dnes `ShopSettings.sender_name` a `sender_email`, později tabulka odesílacích adres (se-spec 06).","parameters":[{"$ref":"#/components/parameters/tenant"}],"x-postarna-permission":{"module":"campaigns","level":"read","keyScope":"read or full"},"x-mcp-tool":"list_senders","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Sender"}}},"required":["items"]},"examples":{"send-campaign-senders":{"summary":"docs/api-examples/send-campaign.json senders","value":{"items":[{"id":"17","shopId":"17","name":"Example.cz","email":"info@example.cz","replyTo":"","verified":true,"isDefault":true},{"id":"18","shopId":"18","name":"Example.sk","email":"info@example.sk","replyTo":"","verified":true,"isDefault":true}]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"pst_ API key","description":"An API key of the company: Authorization: Bearer pst_... (Nastavení › Datové zdroje › API klíče). Scope read or full, roles of the key."},"basicAuth":{"type":"http","scheme":"basic","description":"HTTP Basic as SmartEmailing: user name = e-mail of an active member of the company, password = the API key."},"oauth2":{"type":"oauth2","description":"OAuth 2.1 for MCP clients (AI assistants) only: authorization code with PKCE S256, dynamic registration.","flows":{"authorizationCode":{"authorizationUrl":"https://www.postarna.cz/oauth/authorize","tokenUrl":"https://www.postarna.cz/oauth/token","refreshUrl":"https://www.postarna.cz/oauth/token","scopes":{"read":"Read only (routes whose permission level is read).","full":"Everything the member's roles allow."}}}}},"parameters":{"tenant":{"name":"tenant","in":"path","required":true,"description":"Public id of the company (tenant), a UUID: GET /api/v3/account-info answers it as data.guid; the app shows it on the API keys page.","schema":{"type":"string","format":"uuid"}},"page":{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1},"description":"Page number, from 1."},"pageSize":{"name":"pageSize","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"description":"Items per page, 1 to 100."},"sort":{"name":"sort","in":"query","required":false,"schema":{"type":"string"},"description":"Sort fields separated by commas, \"-\" = descending, at most 3 (e.g. name,-id)."}},"headers":{"X-RateLimit-Limit":{"description":"Size of the bucket nearest to running out (2 500 per second bucket or 100 000 daily).","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in that bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix time when that bucket is full again.","schema":{"type":"integer"}},"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}}},"responses":{"Unauthorized":{"description":"401 unauthorized: missing, unknown, revoked, expired or idle API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"unauthorized","message":"api_key"}}}}},"Forbidden":{"description":"403 forbidden: message tenant (another company), scope (read-only key), api_key (person only), or the module the key's roles lack.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"forbidden","message":"scope"}}}}},"RateLimited":{"description":"429 rate_limited: wait Retry-After seconds.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"code":"rate_limited","message":"per-second"}}}}}},"schemas":{"ApproveInput":{"type":"object","properties":{"sendAt":{"type":["string","null"],"description":"null = send now; otherwise at least 5 minutes and at most 365 days ahead."},"expectedRecipients":{"type":"number","description":"The number the user confirmed; the server refuses (409 recipients) when the audience drifted more than 5 %."}},"required":["sendAt","expectedRecipients"]},"AudienceCount":{"type":"object","properties":{"matched":{"type":"number","description":"Unique contacts in the chosen lists and segments."},"recipients":{"type":"number","description":"Who would receive the campaign now."},"excluded":{"type":"object","properties":{"unconfirmed":{"type":"number"},"not_mailable":{"type":"number"},"weak_consent":{"type":"number"},"exception_expired":{"type":"number"},"no_purpose":{"type":"number"},"excluded_list":{"type":"number"},"excluded_manual":{"type":"number"},"inactive":{"type":"number"}},"required":["unconfirmed","not_mailable","weak_consent","exception_expired","no_purpose","excluded_list","excluded_manual","inactive"]}},"required":["matched","recipients","excluded"]},"BoxPadding":{"type":"object","properties":{"top":{"type":"number"},"right":{"type":"number"},"bottom":{"type":"number"},"left":{"type":"number"}},"required":["top","right","bottom","left"]},"CampaignAudience":{"type":"object","properties":{"listIds":{"type":"array","items":{"type":"string"}},"segmentIds":{"type":"array","items":{"type":"string"},"description":"Segments of the campaign shop."},"excludeListIds":{"type":"array","items":{"type":"string"},"description":"Members of these lists are left out."},"excludeInactive":{"type":"boolean","description":"Leave out engagement E and the excluded state (long inactive); recommended."},"excludeEmails":{"type":"array","items":{"type":"string"},"description":"Addresses left out by hand (at most 1000)."},"onlyWithPurpose":{"type":"boolean","description":"Only contacts with a valid consent for one of purposeIds (any purpose when empty)."},"purposeIds":{"type":"array","items":{"type":"string"}}},"required":["listIds","segmentIds","excludeListIds","excludeInactive","excludeEmails","onlyWithPurpose","purposeIds"]},"CampaignDetail":{"type":"object","properties":{"preheader":{"type":"string"},"senderId":{"type":["string","null"]},"fromName":{"type":"string"},"fromEmail":{"type":"string"},"replyTo":{"type":"string"},"templateId":{"type":["string","null"],"description":"Template the content was copied from (information only; later template edits do not change the campaign)."},"hasContent":{"type":"boolean","description":"The campaign has its own content (GET …/content); without it the approval answers 400 content."},"audience":{"$ref":"#/components/schemas/CampaignAudience"},"pausedReason":{"type":["string","null"],"enum":["manual","bounce_rate","complaint_rate","unsubscribe_rate","recipient_drift","template_error",null]},"approvedAt":{"type":["string","null"],"description":"SE's Aktivováno: when the campaign was approved for sending (null for drafts)."},"trackOpens":{"type":"boolean","description":"Advanced step: tracking (on by default as in SE), UTM on links of the campaign's e-shop, own X- headers."},"trackClicks":{"type":"boolean"},"utm":{"anyOf":[{"$ref":"#/components/schemas/CampaignUtm"},{"type":"null"}]},"headers":{"type":"array","items":{"$ref":"#/components/schemas/CampaignHeader"}},"timing":{"allOf":[{"$ref":"#/components/schemas/SendTiming"}],"description":"Send time chosen in step 1 of the draft; the approval still takes the time explicitly."},"plannedAt":{"type":["string","null"]},"linkParams":{"type":"array","items":{"$ref":"#/components/schemas/CampaignLinkParam"},"description":"Step 3 \"Sledování odkazů\" (SE): free name / value pairs added to links of the campaign's e-shop."},"preferTime":{"type":"boolean","description":"Step 3 \"Ideální čas odeslání\": each contact at the hour of his or her usual opens, within 24 hours."},"replyToOptions":{"type":"array","items":{"type":"string"},"description":"Addresses that may receive replies (the shop's sender addresses and their reply-to)."},"unsubscribePageId":{"type":["string","null"],"description":"Step 3 Odhlašovací stránka (SE, migration 0391): the campaign's own page; null = the template's or the default."},"footerId":{"type":["string","null"],"description":"Vybraná patička / Patička emailu (PA-01, migration 0410): a published footer; null = the template's or the\ndefault one."},"id":{"type":"string"},"name":{"type":"string"},"shopId":{"type":"string"},"subject":{"type":"string"},"status":{"type":"string","enum":["cancelled","completed","draft","scheduled","sending","paused"]},"recipients":{"type":["number","null"],"description":"Recipients frozen at approval (expected_recipients); null for drafts."},"scheduledAt":{"type":["string","null"]},"startedAt":{"type":["string","null"]},"completedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"publicUrl":{"type":"string","description":"Odkaz ke sdílení: the campaign's public preview (merge tags unfilled); absent from older servers."},"stats":{"anyOf":[{"$ref":"#/components/schemas/CampaignStats"},{"type":"null"}],"description":"null until sending starts."},"variantGroupId":{"type":["string","null"],"description":"Language variants sent together (Kampaně › Varianty): the group's id, null or absent for a single campaign."},"variantLabel":{"type":"string","description":"Short name of the variant (CZ, SK ...); '' for a single campaign."},"variantPosition":{"type":"number","description":"Order in the group: a contact in several variants' audiences receives only the first one."},"tags":{"type":"array","items":{"type":"string"},"description":"Labels (Štítky, set from the grid's ⋮ menu or as a bulk action); absent from older servers."}},"required":["preheader","senderId","fromName","fromEmail","replyTo","templateId","hasContent","audience","pausedReason","approvedAt","trackOpens","trackClicks","utm","headers","timing","plannedAt","linkParams","preferTime","replyToOptions","id","name","shopId","subject","status","recipients","scheduledAt","startedAt","completedAt","createdAt","updatedAt","stats"]},"CampaignHeader":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"CampaignInput":{"type":"object","properties":{"name":{"type":"string"},"shopId":{"type":"string"},"senderId":{"type":["string","null"],"description":"A sender address of the campaign shop; it must be verified for approval."},"fromName":{"type":"string"},"subject":{"type":"string"},"preheader":{"type":"string"},"templateId":{"type":["string","null"],"description":"Template the content was copied from; the content itself is saved with saveCampaignContent."},"audience":{"$ref":"#/components/schemas/CampaignAudience"},"trackOpens":{"type":"boolean"},"trackClicks":{"type":"boolean"},"utm":{"anyOf":[{"$ref":"#/components/schemas/CampaignUtm"},{"type":"null"}]},"headers":{"type":"array","items":{"$ref":"#/components/schemas/CampaignHeader"}},"timing":{"type":"string","enum":["now","schedule","later"]},"plannedAt":{"type":["string","null"]},"replyTo":{"type":"string","description":"One of replyToOptions; '' = the sender's own reply-to."},"linkParams":{"type":"array","items":{"$ref":"#/components/schemas/CampaignLinkParam"}},"preferTime":{"type":"boolean"},"unsubscribePageId":{"type":["string","null"],"description":"An active unsubscribe page of the tenant, null = the template's or the default; left out on a new draft made\nfrom a template = the template's page."},"footerId":{"type":["string","null"],"description":"A published footer of the tenant, null = the template's or the default; left out on a new draft made from a\ntemplate = the template's footer."}},"required":["name","shopId","senderId","fromName","subject","preheader","templateId","audience"]},"CampaignLinkParam":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"CampaignListItem":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"shopId":{"type":"string"},"subject":{"type":"string"},"status":{"type":"string","enum":["cancelled","completed","draft","scheduled","sending","paused"]},"recipients":{"type":["number","null"],"description":"Recipients frozen at approval (expected_recipients); null for drafts."},"scheduledAt":{"type":["string","null"]},"startedAt":{"type":["string","null"]},"completedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"approvedAt":{"type":["string","null"],"description":"SE's Aktivováno: when the campaign was approved for sending (null for drafts)."},"publicUrl":{"type":"string","description":"Odkaz ke sdílení: the campaign's public preview (merge tags unfilled); absent from older servers."},"stats":{"anyOf":[{"$ref":"#/components/schemas/CampaignStats"},{"type":"null"}],"description":"null until sending starts."},"variantGroupId":{"type":["string","null"],"description":"Language variants sent together (Kampaně › Varianty): the group's id, null or absent for a single campaign."},"variantLabel":{"type":"string","description":"Short name of the variant (CZ, SK ...); '' for a single campaign."},"variantPosition":{"type":"number","description":"Order in the group: a contact in several variants' audiences receives only the first one."},"tags":{"type":"array","items":{"type":"string"},"description":"Labels (Štítky, set from the grid's ⋮ menu or as a bulk action); absent from older servers."}},"required":["id","name","shopId","subject","status","recipients","scheduledAt","startedAt","completedAt","createdAt","updatedAt","stats"]},"CampaignPreview":{"type":"object","properties":{"subject":{"type":"string"},"preheader":{"type":"string"},"html":{"type":"string"}},"required":["subject","preheader","html"],"description":"The e-mail as one contact would get it (POST /campaigns/{id}/preview): every merge tag filled, sample links."},"CampaignStats":{"type":"object","properties":{"sent":{"type":"number"},"delivered":{"type":"number"},"opened":{"type":"number"},"clicked":{"type":"number"},"bounced":{"type":"number"},"complained":{"type":"number"},"unsubscribed":{"type":"number"}},"required":["sent","delivered","opened","clicked","bounced","complained","unsubscribed"],"description":"Unique contacts per event type."},"CampaignUtm":{"type":"object","properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}},"required":["source","medium","campaign"]},"CampaignVariant":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"label":{"type":"string"},"position":{"type":"number"},"shopId":{"type":"string"},"shopCode":{"type":"string"},"currency":{"$ref":"#/components/schemas/Currency"},"language":{"$ref":"#/components/schemas/Lang"},"subject":{"type":"string"},"preheader":{"type":"string"},"status":{"type":"string","enum":["cancelled","completed","draft","scheduled","sending","paused"]},"senderId":{"type":["string","null"]},"fromName":{"type":"string"},"hasContent":{"type":"boolean"},"listIds":{"type":"array","items":{"type":"string"}},"segmentIds":{"type":"array","items":{"type":"string"}},"recipients":{"type":["number","null"],"description":"Final number frozen at the approval; null for drafts."},"scheduledAt":{"type":["string","null"]},"pausedReason":{"type":["string","null"],"enum":["manual","bounce_rate","complaint_rate","unsubscribe_rate","recipient_drift","template_error",null]},"stats":{"anyOf":[{"$ref":"#/components/schemas/CampaignStats"},{"type":"null"}]}},"required":["id","name","label","position","shopId","shopCode","currency","language","subject","preheader","status","senderId","fromName","hasContent","listIds","segmentIds","recipients","scheduledAt","pausedReason","stats"],"description":"One variant: a whole campaign of its own shop (content, subject, sender, feeds) with an audience chosen by hand."},"CampaignVariantGroup":{"type":"object","properties":{"groupId":{"type":["string","null"],"description":"null = a single campaign (no variants yet)."},"variants":{"type":"array","items":{"$ref":"#/components/schemas/CampaignVariant"},"description":"In their order."},"created":{"type":"string","description":"Id of the variant just created by addCampaignVariant."}},"required":["groupId","variants"]},"ContentVersion":{"type":"object","properties":{"id":{"type":"string"},"version":{"type":"number"},"kind":{"type":"string","enum":["manual","auto","restore"]},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"],"description":"Name or e-mail of the user; null for the API or unknown."}},"required":["id","version","kind","createdAt","createdBy"],"description":"One entry of the content history (Historie uložení)."},"ContentVersionDetail":{"type":"object","properties":{"content":{"type":"object","properties":{"editor":{"type":"string","enum":["visual","html"]},"html":{"type":"string"},"design":{"anyOf":[{"$ref":"#/components/schemas/EmailDesign"},{"type":"null"}]}},"required":["editor","html","design"]},"id":{"type":"string"},"version":{"type":"number"},"kind":{"type":"string","enum":["manual","auto","restore"]},"createdAt":{"type":"string"},"createdBy":{"type":["string","null"],"description":"Name or e-mail of the user; null for the API or unknown."}},"required":["content","id","version","kind","createdAt","createdBy"]},"ContentVersionList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ContentVersion"}},"more":{"type":"boolean"}},"required":["items","more"]},"Currency":{"type":"string","enum":["CZK","EUR"]},"EmailContent":{"type":"object","properties":{"editor":{"type":"string","enum":["visual","html"]},"html":{"type":"string","description":"HTML with merge tags left in place (compiled from the design, or written by hand); the core personalises and sends it."},"design":{"anyOf":[{"$ref":"#/components/schemas/EmailDesign"},{"type":"null"}],"description":"Visual editor only."},"version":{"type":"number","description":"0 = no content yet; every save adds one."},"updatedAt":{"type":["string","null"]}},"required":["editor","html","design","version","updatedAt"],"description":"E-mail content of a template or a campaign."},"EmailContentInput":{"type":"object","properties":{"editor":{"type":"string","enum":["visual","html"]},"html":{"type":"string"},"design":{"anyOf":[{"$ref":"#/components/schemas/EmailDesign"},{"type":"null"}]},"baseVersion":{"type":"number","description":"The version the editor started from; a newer one on the server answers 409 version (saved elsewhere meanwhile)."},"saveKind":{"type":"string","enum":["manual","auto","restore"],"description":"History entry kind: auto (autosave, journaled), manual (Uložit), restore (a version taken back). Default auto."}},"required":["editor","html","design","baseVersion"]},"EmailDesign":{"type":"object","properties":{"format":{"type":"string","const":"mjml-1","description":"Format version; a later editor migrates older designs."},"mjml":{"type":"string"},"styles":{"$ref":"#/components/schemas/EmailStyles"}},"required":["format","mjml","styles"],"description":"Source of a visual design: MJML plus the global styles, so the editor reopens it exactly."},"EmailStyles":{"type":"object","properties":{"fontFamily":{"type":"string","description":"One of EMAIL_FONTS (web-safe stacks; recipients' clients have no web fonts by default)."},"headingFontFamily":{"type":"string"},"fontSize":{"type":"number","description":"Base text size in px (12 to 20)."},"textColor":{"type":"string"},"headingColor":{"type":"string"},"linkColor":{"type":"string"},"buttonColor":{"type":"string"},"buttonTextColor":{"type":"string"},"backgroundColor":{"type":"string","description":"Around the e-mail."},"contentColor":{"type":"string","description":"Body of the e-mail."},"width":{"type":"number","description":"Width of the e-mail in px (480 to 800)."},"magic":{"allOf":[{"$ref":"#/components/schemas/MagicStyles"}],"description":"Settings of the Magic editor (e-mail paddings, text styles, dark mode, element defaults); the server keeps the\nobject as it is (bounded JSON, API-CONTRACT.md). Absent in designs saved before it."}},"required":["fontFamily","headingFontFamily","fontSize","textColor","headingColor","linkColor","buttonColor","buttonTextColor","backgroundColor","contentColor","width"],"description":"Global look of a visual design. The editor writes it as MJML attributes; every element can override it."},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["conflict","count_mismatch","csrf","empty_segment","expired","forbidden","method_not_allowed","not_found","not_implemented","rate_limited","recently_sent","server","suppression_locked","unauthorized","unavailable","upstream","validation"],"description":"Stable machine readable code (see the error catalog in the guides)."},"message":{"type":"string","description":"The field or the reason (technical, not for people), e.g. \"email\", \"definition.1.0.listId\", \"name\"."},"params":{"type":"object","additionalProperties":true,"description":"Details: issues of a graph, expected and actual counts, retryAfter ..."}}}},"examples":[{"error":{"code":"validation","message":"email"}},{"error":{"code":"conflict","message":"version","params":{"current":4}}}]},"GridTagsInput":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"}},"add":{"type":"array","items":{"type":"string"}},"remove":{"type":"array","items":{"type":"string"}},"tags":{"type":"array","items":{"type":"string"}}},"required":["ids"],"description":"Bulk label change: add and remove, or tags = the new labels of every row."},"Lang":{"type":"string","enum":["cs","sk"]},"MagicBackground":{"type":"object","properties":{"type":{"type":"string","enum":["color","gradient","image"]},"from":{"type":"string"},"to":{"type":"string"},"angle":{"type":"number","description":"Gradient direction in degrees (180 = top to bottom)."},"image":{"type":"string"},"fit":{"type":"string","enum":["cover","repeat","original"],"description":"Picture: cover the area, tile, or the original size once."}},"required":["type"],"description":"A background of the Magic editor: a plain colour, a linear gradient or a picture (https)."},"MagicStyles":{"type":"object","properties":{"padding":{"allOf":[{"$ref":"#/components/schemas/BoxPadding"}],"description":"Space around the e-mail body, desktop and mobile."},"paddingMobile":{"$ref":"#/components/schemas/BoxPadding"},"darkMode":{"type":"boolean","description":"Dark mode in the recipient's app (prefers-color-scheme) with its colours."},"darkBackgroundColor":{"type":"string"},"darkContentColor":{"type":"string"},"darkTextColor":{"type":"string"},"darkHeadingColor":{"type":"string"},"darkLinkColor":{"type":"string"},"darkButtonColor":{"type":"string","description":"Dark mode colours of the buttons and the divider (SE: every colour has its \"(tmavé schéma)\" variant)."},"darkButtonTextColor":{"type":"string"},"darkButton2Color":{"type":"string"},"darkButton2TextColor":{"type":"string"},"darkDividerColor":{"type":"string"},"background":{"allOf":[{"$ref":"#/components/schemas/MagicBackground"}],"description":"SE \"Typ pozadí\" of the e-mail (around the body) and of the body: a gradient or a picture over the colour\n(backgroundColor / contentColor stay the fallback of clients without head styles)."},"bodyBackground":{"$ref":"#/components/schemas/MagicBackground"},"button2Color":{"type":"string","description":"Secondary button and divider colours."},"button2TextColor":{"type":"string"},"button2BorderColor":{"type":"string"},"buttonBorderColor":{"type":"string"},"dividerColor":{"type":"string"},"footerDefault":{"type":"boolean","description":"System footer (SmartEmailing \"Patička\"): its own default look instead of the e-mail's, and no background."},"footerTransparent":{"type":"boolean"},"text":{"type":"object","properties":{"h1":{"type":"object","properties":{"fontFamily":{"type":"string","description":"'' = the e-mail's font (fontFamily, or headingFontFamily for headings)."},"fontSize":{"type":"number"},"lineHeight":{"type":"number","description":"Relative to the font size (0.8 to 2.0)."},"letterSpacing":{"type":"number","description":"px (0 to 15)."},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"align":{"type":"string","enum":["left","center","right","justify"]},"color":{"type":"string","description":"'' = the e-mail's colour for the style."}}},"h2":{"type":"object","properties":{"fontFamily":{"type":"string","description":"'' = the e-mail's font (fontFamily, or headingFontFamily for headings)."},"fontSize":{"type":"number"},"lineHeight":{"type":"number","description":"Relative to the font size (0.8 to 2.0)."},"letterSpacing":{"type":"number","description":"px (0 to 15)."},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"align":{"type":"string","enum":["left","center","right","justify"]},"color":{"type":"string","description":"'' = the e-mail's colour for the style."}}},"h3":{"type":"object","properties":{"fontFamily":{"type":"string","description":"'' = the e-mail's font (fontFamily, or headingFontFamily for headings)."},"fontSize":{"type":"number"},"lineHeight":{"type":"number","description":"Relative to the font size (0.8 to 2.0)."},"letterSpacing":{"type":"number","description":"px (0 to 15)."},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"align":{"type":"string","enum":["left","center","right","justify"]},"color":{"type":"string","description":"'' = the e-mail's colour for the style."}}},"p":{"type":"object","properties":{"fontFamily":{"type":"string","description":"'' = the e-mail's font (fontFamily, or headingFontFamily for headings)."},"fontSize":{"type":"number"},"lineHeight":{"type":"number","description":"Relative to the font size (0.8 to 2.0)."},"letterSpacing":{"type":"number","description":"px (0 to 15)."},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"align":{"type":"string","enum":["left","center","right","justify"]},"color":{"type":"string","description":"'' = the e-mail's colour for the style."}}},"link":{"type":"object","properties":{"fontFamily":{"type":"string","description":"'' = the e-mail's font (fontFamily, or headingFontFamily for headings)."},"fontSize":{"type":"number"},"lineHeight":{"type":"number","description":"Relative to the font size (0.8 to 2.0)."},"letterSpacing":{"type":"number","description":"px (0 to 15)."},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"align":{"type":"string","enum":["left","center","right","justify"]},"color":{"type":"string","description":"'' = the e-mail's colour for the style."}}},"button":{"type":"object","properties":{"fontFamily":{"type":"string","description":"'' = the e-mail's font (fontFamily, or headingFontFamily for headings)."},"fontSize":{"type":"number"},"lineHeight":{"type":"number","description":"Relative to the font size (0.8 to 2.0)."},"letterSpacing":{"type":"number","description":"px (0 to 15)."},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"align":{"type":"string","enum":["left","center","right","justify"]},"color":{"type":"string","description":"'' = the e-mail's colour for the style."}}},"button2":{"type":"object","properties":{"fontFamily":{"type":"string","description":"'' = the e-mail's font (fontFamily, or headingFontFamily for headings)."},"fontSize":{"type":"number"},"lineHeight":{"type":"number","description":"Relative to the font size (0.8 to 2.0)."},"letterSpacing":{"type":"number","description":"px (0 to 15)."},"bold":{"type":"boolean"},"italic":{"type":"boolean"},"underline":{"type":"boolean"},"strike":{"type":"boolean"},"align":{"type":"string","enum":["left","center","right","justify"]},"color":{"type":"string","description":"'' = the e-mail's colour for the style."}}}},"description":"Text styles per kind; missing keys = defaults. Mobile values override desktop ones under 480 px."},"textMobile":{"type":"object","properties":{"h1":{"type":"object","properties":{"fontSize":{"type":"number"},"lineHeight":{"type":"number"},"letterSpacing":{"type":"number"},"align":{"type":"string","enum":["left","center","right","justify"]}}},"h2":{"type":"object","properties":{"fontSize":{"type":"number"},"lineHeight":{"type":"number"},"letterSpacing":{"type":"number"},"align":{"type":"string","enum":["left","center","right","justify"]}}},"h3":{"type":"object","properties":{"fontSize":{"type":"number"},"lineHeight":{"type":"number"},"letterSpacing":{"type":"number"},"align":{"type":"string","enum":["left","center","right","justify"]}}},"p":{"type":"object","properties":{"fontSize":{"type":"number"},"lineHeight":{"type":"number"},"letterSpacing":{"type":"number"},"align":{"type":"string","enum":["left","center","right","justify"]}}},"link":{"type":"object","properties":{"fontSize":{"type":"number"},"lineHeight":{"type":"number"},"letterSpacing":{"type":"number"},"align":{"type":"string","enum":["left","center","right","justify"]}}},"button":{"type":"object","properties":{"fontSize":{"type":"number"},"lineHeight":{"type":"number"},"letterSpacing":{"type":"number"},"align":{"type":"string","enum":["left","center","right","justify"]}}},"button2":{"type":"object","properties":{"fontSize":{"type":"number"},"lineHeight":{"type":"number"},"letterSpacing":{"type":"number"},"align":{"type":"string","enum":["left","center","right","justify"]}}}}},"defaults":{"type":"object","properties":{"rowPadding":{"$ref":"#/components/schemas/BoxPadding"},"columnPadding":{"$ref":"#/components/schemas/BoxPadding"},"textPadding":{"$ref":"#/components/schemas/BoxPadding"},"imagePadding":{"$ref":"#/components/schemas/BoxPadding"},"buttonPadding":{"$ref":"#/components/schemas/BoxPadding"},"buttonInnerPadding":{"type":"object","properties":{"vertical":{"type":"number"},"horizontal":{"type":"number"}},"required":["vertical","horizontal"]},"buttonRadius":{"type":"number"},"buttonFullWidth":{"type":"boolean"},"dividerPadding":{"$ref":"#/components/schemas/BoxPadding"},"dividerWidth":{"type":"number"},"dividerStyle":{"type":"string","enum":["solid","dashed","dotted"]},"spacerHeight":{"type":"number"},"imageRadius":{"type":"number"}},"description":"Defaults of new elements (SmartEmailing \"Prvky\")."}}},"SendTiming":{"type":"string","enum":["now","schedule","later"]},"Sender":{"type":"object","properties":{"id":{"type":"string"},"shopId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"replyTo":{"type":"string"},"verified":{"type":"boolean","description":"Domain verified (SPF, DKIM, DMARC); only verified senders can send."},"isDefault":{"type":"boolean"}},"required":["id","shopId","name","email","replyTo","verified","isDefault"]},"TestSendResult":{"type":"object","properties":{"to":{"type":"string"},"sentAt":{"type":"string"}},"required":["to","sentAt"]},"VariantApproveInput":{"type":"object","properties":{"sendAt":{"type":["string","null"],"description":"null = now."},"expectedRecipients":{"type":"object","additionalProperties":{"type":"number"},"description":"The final number per variant id the user confirmed."}},"required":["sendAt","expectedRecipients"]},"VariantPreview":{"type":"object","properties":{"variants":{"type":"array","items":{"$ref":"#/components/schemas/VariantPreviewItem"}},"total":{"type":"number"}},"required":["variants","total"]},"VariantPreviewItem":{"type":"object","properties":{"campaignId":{"type":"string"},"label":{"type":"string"},"shopId":{"type":"string"},"takenByEarlier":{"type":"number"},"final":{"type":"number"},"matched":{"type":"number","description":"Unique contacts in the chosen lists and segments."},"recipients":{"type":"number","description":"Who would receive the campaign now."},"excluded":{"type":"object","properties":{"unconfirmed":{"type":"number"},"not_mailable":{"type":"number"},"weak_consent":{"type":"number"},"exception_expired":{"type":"number"},"no_purpose":{"type":"number"},"excluded_list":{"type":"number"},"excluded_manual":{"type":"number"},"inactive":{"type":"number"}},"required":["unconfirmed","not_mailable","weak_consent","exception_expired","no_purpose","excluded_list","excluded_manual","inactive"]}},"required":["campaignId","label","shopId","takenByEarlier","final","matched","recipients","excluded"],"description":"Counts of one variant before sending: its own audience, the recipients an earlier variant takes, the final number."},"VariantStats":{"type":"object","properties":{"variants":{"type":"array","items":{"type":"object","properties":{"campaignId":{"type":"string"},"label":{"type":"string"},"shopId":{"type":"string"},"stats":{"anyOf":[{"$ref":"#/components/schemas/CampaignStats"},{"type":"null"}]}},"required":["campaignId","label","shopId","stats"]}},"total":{"anyOf":[{"$ref":"#/components/schemas/CampaignStats"},{"type":"null"}],"description":"Sums over the variants (a contact gets one variant, so these are unique contacts); null before sending."}},"required":["variants","total"]}}}}