{"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":"Sending","x-displayName":"Sending and deliverability","description":"Senders, sending domains (SPF, DKIM, DMARC), DMARC reports, sending mode."}],"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}/deliverability/dmarc":{"get":{"operationId":"deliverability_dmarc","summary":"DMARC summary","tags":["Sending"],"description":"Contract notes (cs):\n\n`DmarcSummary` za 30 dní: `domains` (`reports`, `messages`, `dmarcPass`, `dkimPass`, `spfPass`, `passRate`, `lastReport`), `sources` (odesílající IP adresy s počtem zpráv a neúspěchů, nejvýš 20), `reports` (posledních 20: `orgName`, `reportId`, `beginAt`, `endAt`, `messages`, `dmarcPass`, `receivedAt`), `complaints` (`total`, `bySource` (`ses`, `fbl`), `recent` nejvýš 20 bez adres: `at`, `source`, `kind`, `campaignId`, `automationId`, `name`). Reporty a stížnosti nahrává administrace platformy (`python -m postarna.admin deliverability-import` nebo `deliverability-fetch`), ne SPA.","parameters":[{"$ref":"#/components/parameters/tenant"}],"x-postarna-permission":{"module":"settings","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DmarcSummary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/deliverability/dmarc/report":{"get":{"operationId":"deliverability_dmarc_report","summary":"DMARC report detail","tags":["Sending"],"description":"SE Statistiky › DMARC: ?from=&to= (calendar days of the tenant, both included; none = the whole history), ?domain= (sending domain id), ?reporter= (the provider's org name).\n\nContract notes (cs):\n\nSE Statistiky › DMARC: `?from=&to=` (kalendářní dny tenanta, oba včetně; bez nich celá historie, 400 `validation` / `from`, `to`), `?domain=` (id odesílací domény), `?reporter=` (org poskytovatele) → `DmarcReport`: `totals` (zprávy, prošlo DMARC, DKIM, SPF, počet reportů), `domains` (podle hlavičky From), `days` (po dnech konce reportu: reporty, zprávy, průchody), `ips` (odesílající servery s průchody a verzí IP), `ipVersions`, `reporters`, `dispositions`, `cases` (nejnovějších 200 záznamů: doména, reportér, datum, IP, DMARC / DKIM / SPF ok, naložení, počet), `reporterChoices`, `domainChoices`. DMARC prošlo = DKIM nebo SPF prošlo podle vyhodnocení poskytovatele. Země serverů zatím ne (chybí GeoIP, QUEUE).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"domain","in":"query","required":false,"schema":{"type":"string"}},{"name":"from","in":"query","required":false,"schema":{"type":"string"},"description":"Start of the period (YYYY-MM-DD local day, or ISO time where noted)."},{"name":"reporter","in":"query","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","required":false,"schema":{"type":"string"},"description":"End of the period (YYYY-MM-DD local day, or ISO time where noted)."}],"x-postarna-permission":{"module":"settings","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DmarcReport"}}}},"400":{"description":"`validation` (message: to)","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}/deliverability/domains":{"get":{"operationId":"deliverability_domains","summary":"List domains with their DNS state","tags":["Sending"],"description":"Contract notes (cs):\n\n`{items: SendingDomain[], suggestions: string[]}`. `SendingDomain` = `id`, `domain`, `dkimSelectors`, `spf {status, record}`, `dkim {status, records: {<selektor>: {cname, record}}}`, `dmarc {status, record}`, `issues`, `checkedAt`, `createdAt`. `suggestions` = domény odesílacích adres, které ještě nemají řádek (ani nadřazenou doménu).","parameters":[{"$ref":"#/components/parameters/tenant"}],"x-postarna-permission":{"module":"settings","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomainList"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"operationId":"deliverability_domain_create","summary":"Add a domain","tags":["Sending"],"description":"Contract notes (cs):\n\nZaložení `{domain, dkimSelectors?}` → 201 (400 `validation` / `domain` nebo `dkimSelectors`, nejvýš 5 selektorů; 409 `conflict` / `domain`). Úprava `{dkimSelectors}` vrátí stav DKIM na `unknown`. Smazání 204 (smaže i DMARC reporty domény, DNS se nemění).","parameters":[{"$ref":"#/components/parameters/tenant"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomainInput"}}},"description":"Required by the server: domain."},"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomain"}}}},"400":{"description":"`validation`","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}/deliverability/domains/{domain_id}":{"delete":{"operationId":"deliverability_domain_delete","summary":"Delete a domain","tags":["Sending"],"description":"Contract notes (cs):\n\nZaložení `{domain, dkimSelectors?}` → 201 (400 `validation` / `domain` nebo `dkimSelectors`, nejvýš 5 selektorů; 409 `conflict` / `domain`). Úprava `{dkimSelectors}` vrátí stav DKIM na `unknown`. Smazání 204 (smaže i DMARC reporty domény, DNS se nemění).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"domain_id","in":"path","required":true,"description":"Id of the domain (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"x-mcp-confirm":"delete","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"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"patch":{"operationId":"deliverability_domain_update","summary":"Update a domain","tags":["Sending"],"description":"Contract notes (cs):\n\nZaložení `{domain, dkimSelectors?}` → 201 (400 `validation` / `domain` nebo `dkimSelectors`, nejvýš 5 selektorů; 409 `conflict` / `domain`). Úprava `{dkimSelectors}` vrátí stav DKIM na `unknown`. Smazání 204 (smaže i DMARC reporty domény, DNS se nemění).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"domain_id","in":"path","required":true,"description":"Id of the domain (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"dkimSelectors":{"type":"array","items":{"type":"string"}}},"required":["dkimSelectors"]}}},"description":"Required by the server: dkimSelectors."},"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomain"}}}},"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}/deliverability/domains/{domain_id}/check":{"post":{"operationId":"deliverability_domain_check","summary":"Check the DNS records of a domain now","tags":["Sending"],"description":"Contract notes (cs):\n\nZkontroluje SPF, DKIM (každý selektor: klíč v TXT přímo nebo přes CNAME) a DMARC (doména, jinak nadřazená doména) přes resolver serveru a vrátí `SendingDomain`. Záznam, který byl `ok` a už není, pošle výstrahu `dns_regression`. Bez resolveru 503 `unavailable` / `dns`.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"domain_id","in":"path","required":true,"description":"Id of the domain (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDomain"}}}},"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: dns)","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}/deliverability/senders":{"get":{"operationId":"deliverability_senders","summary":"Senders with their authentication state","tags":["Sending"],"description":"Contract notes (cs):\n\n`{items: SenderAuth[]}`: `id`, `shopId`, `name`, `email`, `replyTo`, `domain`, `domainId`, `verified`, `isDefault`, `freemail`, `spf`, `dkim`, `dmarc` (stav domény adresy nebo nadřazené domény), `usableAsSender` (ověřená, ne freemail, všechny tři `ok`).","parameters":[{"$ref":"#/components/parameters/tenant"}],"x-postarna-permission":{"module":"settings","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SenderAuth"}}},"required":["items"]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/sending-defaults":{"get":{"operationId":"sending_defaults","summary":"Get the default settings of new campaigns (tracking parameters on or off)","tags":["Sending"],"description":"SE Nastavení › Rozesílky › Výchozí nastavení beyond what other routes keep (senders, test recipients, the default unsubscribe page): {utmDefaultOn} = new campaign drafts start with the tracking parameters on.","parameters":[{"$ref":"#/components/parameters/tenant"}],"x-postarna-permission":{"module":"settings","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDefaults"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}},"put":{"operationId":"sending_defaults_update","summary":"Set whether new campaigns start with tracking parameters","tags":["Sending"],"description":"Body {utmDefaultOn: bool} (SE UTM Parametry Nesledovat / Sledovat). Audited as setting_changed.","parameters":[{"$ref":"#/components/parameters/tenant"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDefaults"}}},"description":"Required by the server: utmDefaultOn."},"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingDefaults"}}}},"400":{"description":"`validation` (message: utmDefaultOn)","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}/sending-mode":{"get":{"operationId":"sending_mode","summary":"Sending mode of the company (switch, limits)","tags":["Sending"],"description":"What leaves Poštárna for this tenant now (core/backends.mode_of): live (everything), test (only test e-mails to the test whitelist, POSTARNA_SES_LIVE=test), folder (development: files, nothing leaves) or off (nothing). testRecipients = how many addresses the test whitelist has. sendingEnabled = the tenant's kill switch (setting sending_enabled, python -m postarna.admin sending-switch): while it is off no sending tick runs, so no campaign goes out and no automation lets anybody in, whatever the mode says (test e-mails still go out). sendingState = the platform's approval of live sending (pending, live, paused, suspended; migration 0170) and sendingHold why a live tenant is held ('', platform, free_limit, unpaid).","parameters":[{"$ref":"#/components/parameters/tenant"}],"x-postarna-permission":{"module":null,"level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingModeInfo"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/tenants/{tenant}/sending/domains":{"post":{"operationId":"sending_domain_add","summary":"Add a sending domain","tags":["Sending"],"description":"Contract notes (cs):\n\nZaložení `{domain}` → 201 `SetupDomain` (znovu stejná doména vrátí existující řádek; 400 `validation` / `domain` s `reason` `freemail`; 409 `conflict` / `domain` s `reason` `taken`, když doménu spravuje jiný účet). Kontrola načte stav identity ze SES a DNS; první ověřená doména tenanta bez nastavení SES mu nastaví `ses` = eu-north-1 / `PLATFORM` (ostré odesílání dál schvaluje platforma). Smazání smaže i identitu v SES (bez přístupu platformy 503 `unavailable` / `domain`).","parameters":[{"$ref":"#/components/parameters/tenant"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"}},"required":["domain"]}}},"description":"Required by the server: domain."},"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupDomain"}}}},"400":{"description":"`validation`","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}/sending/domains/{domain_id}":{"delete":{"operationId":"sending_domain_delete","summary":"Delete a sending domain","tags":["Sending"],"description":"Contract notes (cs):\n\nZaložení `{domain}` → 201 `SetupDomain` (znovu stejná doména vrátí existující řádek; 400 `validation` / `domain` s `reason` `freemail`; 409 `conflict` / `domain` s `reason` `taken`, když doménu spravuje jiný účet). Kontrola načte stav identity ze SES a DNS; první ověřená doména tenanta bez nastavení SES mu nastaví `ses` = eu-north-1 / `PLATFORM` (ostré odesílání dál schvaluje platforma). Smazání smaže i identitu v SES (bez přístupu platformy 503 `unavailable` / `domain`).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"domain_id","in":"path","required":true,"description":"Id of the domain (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"x-mcp-confirm":"delete","responses":{"204":{"description":"No content"},"400":{"description":"`validation`","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}/sending/domains/{domain_id}/check":{"post":{"operationId":"sending_domain_check","summary":"Check a sending domain","tags":["Sending"],"description":"Contract notes (cs):\n\nZaložení `{domain}` → 201 `SetupDomain` (znovu stejná doména vrátí existující řádek; 400 `validation` / `domain` s `reason` `freemail`; 409 `conflict` / `domain` s `reason` `taken`, když doménu spravuje jiný účet). Kontrola načte stav identity ze SES a DNS; první ověřená doména tenanta bez nastavení SES mu nastaví `ses` = eu-north-1 / `PLATFORM` (ostré odesílání dál schvaluje platforma). Smazání smaže i identitu v SES (bez přístupu platformy 503 `unavailable` / `domain`).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"domain_id","in":"path","required":true,"description":"Id of the domain (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupDomain"}}}},"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}/sending/senders":{"post":{"operationId":"sending_sender_add","summary":"Add a sender","tags":["Sending"],"description":"Contract notes (cs):\n\nPřidání `{shopId, email, name?, replyTo?, isDefault?}` jen na ověřené doméně (400 `validation` / `email`, `reason` `domain_not_verified` nebo `freemail`; 409 `conflict` pro stejnou adresu v e-shopu). První adresa e-shopu je výchozí. Adresa, kterou účet dřív odebral, se stejným přidáním vrátí (stejné `id`, nové jméno a `replyTo`).\n• Úprava (PATCH) `{name?, replyTo?, isDefault: true?}` → `SetupSender`. `name` = jméno odesílatele (Od koho), nejvýš 100 znaků bez `< > { } \"` a řádků (400 `validation` / `name`). `replyTo` = adresa pro odpovědi nebo `\"\"` (odpovědi pak přijdou na adresu odesílatele); co není adresa, odmítne 400 `validation` / `replyTo` (nikdy se tiše nevyprázdní). Samotnou adresu `email` změnit nejde (patří k ověřené doméně): jiná hodnota než uložená = 400 `validation` / `email` s `reason` `read_only`.\n• Odebrání (DELETE) 204. Odmítne 409 `conflict` / `id` s `reason` `default` (výchozí adresa e-shopu) nebo `in_use` (adresu používá kampaň ve stavu `scheduled`, `sending` nebo `paused`, nebo krok E-mail automatizace ve stavu `active` nebo `paused`). Koncepty a skončené kampaně odebrání nebrání. Řádek zůstává (`senders.removed_at`, migrace 0096): skončené kampaně a automatizace si odkaz na odesílatele ponechají, ze všech seznamů a výběrů (`GET …/sending/setup`, `GET /tenants/{t}/senders`, výběr v kampani a automatizaci, schválení) adresa zmizí; koncept s odebranou adresou schválení odmítne 400 `validation` / `senderId`. Další PATCH nebo DELETE odebrané adresy = 404 `not_found`.\n• Modul `settings` `full`, změny zapisují audit (`sender_added`, `sender_updated` s názvy polí, `sender_deleted`).","parameters":[{"$ref":"#/components/parameters/tenant"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupSenderInput"}}},"description":"Required by the server: email, shopId."},"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupSender"}}}},"400":{"description":"`validation`","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}/sending/senders/{sender_id}":{"delete":{"operationId":"sending_sender_delete","summary":"Delete a sender","tags":["Sending"],"description":"204; 409 conflict default / in_use; ?replacementId= (SE's Náhradní adresa, DO-03) first moves the shop's default, the unfinished campaigns and the automation e-mail steps to that sender of the same shop.\n\nContract notes (cs):\n\nPřidání `{shopId, email, name?, replyTo?, isDefault?}` jen na ověřené doméně (400 `validation` / `email`, `reason` `domain_not_verified` nebo `freemail`; 409 `conflict` pro stejnou adresu v e-shopu). První adresa e-shopu je výchozí. Adresa, kterou účet dřív odebral, se stejným přidáním vrátí (stejné `id`, nové jméno a `replyTo`).\n• Úprava (PATCH) `{name?, replyTo?, isDefault: true?}` → `SetupSender`. `name` = jméno odesílatele (Od koho), nejvýš 100 znaků bez `< > { } \"` a řádků (400 `validation` / `name`). `replyTo` = adresa pro odpovědi nebo `\"\"` (odpovědi pak přijdou na adresu odesílatele); co není adresa, odmítne 400 `validation` / `replyTo` (nikdy se tiše nevyprázdní). Samotnou adresu `email` změnit nejde (patří k ověřené doméně): jiná hodnota než uložená = 400 `validation` / `email` s `reason` `read_only`.\n• Odebrání (DELETE) 204. Odmítne 409 `conflict` / `id` s `reason` `default` (výchozí adresa e-shopu) nebo `in_use` (adresu používá kampaň ve stavu `scheduled`, `sending` nebo `paused`, nebo krok E-mail automatizace ve stavu `active` nebo `paused`). Koncepty a skončené kampaně odebrání nebrání. Řádek zůstává (`senders.removed_at`, migrace 0096): skončené kampaně a automatizace si odkaz na odesílatele ponechají, ze všech seznamů a výběrů (`GET …/sending/setup`, `GET /tenants/{t}/senders`, výběr v kampani a automatizaci, schválení) adresa zmizí; koncept s odebranou adresou schválení odmítne 400 `validation` / `senderId`. Další PATCH nebo DELETE odebrané adresy = 404 `not_found`.\n• Modul `settings` `full`, změny zapisují audit (`sender_added`, `sender_updated` s názvy polí, `sender_deleted`).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"sender_id","in":"path","required":true,"description":"Id of the sender (string of digits).","schema":{"type":"string"}},{"name":"replacementId","in":"query","required":false,"schema":{"type":"string"}}],"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"x-mcp-confirm":"delete","responses":{"204":{"description":"No content"},"400":{"description":"`validation` (message: replacementId)","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":"sending_sender_update","summary":"Update a sender","tags":["Sending"],"description":"Contract notes (cs):\n\nPřidání `{shopId, email, name?, replyTo?, isDefault?}` jen na ověřené doméně (400 `validation` / `email`, `reason` `domain_not_verified` nebo `freemail`; 409 `conflict` pro stejnou adresu v e-shopu). První adresa e-shopu je výchozí. Adresa, kterou účet dřív odebral, se stejným přidáním vrátí (stejné `id`, nové jméno a `replyTo`).\n• Úprava (PATCH) `{name?, replyTo?, isDefault: true?}` → `SetupSender`. `name` = jméno odesílatele (Od koho), nejvýš 100 znaků bez `< > { } \"` a řádků (400 `validation` / `name`). `replyTo` = adresa pro odpovědi nebo `\"\"` (odpovědi pak přijdou na adresu odesílatele); co není adresa, odmítne 400 `validation` / `replyTo` (nikdy se tiše nevyprázdní). Samotnou adresu `email` změnit nejde (patří k ověřené doméně): jiná hodnota než uložená = 400 `validation` / `email` s `reason` `read_only`.\n• Odebrání (DELETE) 204. Odmítne 409 `conflict` / `id` s `reason` `default` (výchozí adresa e-shopu) nebo `in_use` (adresu používá kampaň ve stavu `scheduled`, `sending` nebo `paused`, nebo krok E-mail automatizace ve stavu `active` nebo `paused`). Koncepty a skončené kampaně odebrání nebrání. Řádek zůstává (`senders.removed_at`, migrace 0096): skončené kampaně a automatizace si odkaz na odesílatele ponechají, ze všech seznamů a výběrů (`GET …/sending/setup`, `GET /tenants/{t}/senders`, výběr v kampani a automatizaci, schválení) adresa zmizí; koncept s odebranou adresou schválení odmítne 400 `validation` / `senderId`. Další PATCH nebo DELETE odebrané adresy = 404 `not_found`.\n• Modul `settings` `full`, změny zapisují audit (`sender_added`, `sender_updated` s názvy polí, `sender_deleted`).","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"sender_id","in":"path","required":true,"description":"Id of the sender (string of digits).","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupSenderPatch"}}}},"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupSender"}}}},"400":{"description":"`validation`","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}/sending/senders/{sender_id}/check":{"post":{"operationId":"sending_sender_check","summary":"Check whether a sender address is confirmed","tags":["Sending"],"description":"Zkontrolovat of an address confirmed through SES (DO-03): reads the state of its identity.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"sender_id","in":"path","required":true,"description":"Id of the sender (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupSender"}}}},"400":{"description":"`validation`","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}/sending/senders/{sender_id}/resend":{"post":{"operationId":"sending_sender_resend","summary":"Send the confirmation e-mail of a sender address again","tags":["Sending"],"description":"Poslat znovu the confirmation e-mail of an address verified by e-mail (DO-03); 409 when it is verified already, 503 unavailable when no e-mail could go out.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"sender_id","in":"path","required":true,"description":"Id of the sender (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"settings","level":"full","keyScope":"full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupSender"}}}},"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: verified)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"`unavailable` (message: email)","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}/sending/senders/{sender_id}/usage":{"get":{"operationId":"sending_sender_usage","summary":"Where a sender is used","tags":["Sending"],"description":"Where a sender is used (SE \"Použití odesílací adresy\" before Smazat adresu): {items: [{type, id, name, status}]}, type default (its shop's default sender), campaign or automation.","parameters":[{"$ref":"#/components/parameters/tenant"},{"name":"sender_id","in":"path","required":true,"description":"Id of the sender (string of digits).","schema":{"type":"string"}}],"x-postarna-permission":{"module":"settings","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SenderUsage"}}},"required":["items"]}}}},"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}/sending/setup":{"get":{"operationId":"sending_setup","summary":"State of the sending setup (domains and senders)","tags":["Sending"],"description":"Contract notes (cs):\n\n`{managed, platformReady, domains: SetupDomain[], suggestions, shops: [{id, displayName, code}], senders: SetupSender[], advanced?}`. `SetupDomain` = `id`, `domain`, `state` (`verified` | `pending` | `failed` | `setup`), `records` (`kind` dkim/spf/dmarc, `type` CNAME/TXT, `host` = název bez domény, `name` = celý název, `value`, `required`, `status` ok/missing/unknown), `checkedAt`, `createdAt`, `advanced?`. `SetupSender` = `id`, `shopId`, `name`, `email`, `replyTo`, `isDefault`, `verified`, `domainVerified`. `advanced` (region, credentialsRef, configurationSet, selektory, stav SES) jen pro administrátory platformy (`PLATFORM_ADMINS`).","parameters":[{"$ref":"#/components/parameters/tenant"}],"x-postarna-permission":{"module":"settings","level":"read","keyScope":"read or full"},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendingSetup"}}}},"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"}}},"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":{"DmarcReport":{"type":"object","properties":{"totals":{"type":"object","properties":{"messages":{"type":"number"},"dmarcPass":{"type":"number"},"dkimPass":{"type":"number"},"spfPass":{"type":"number"},"reports":{"type":"number"}},"required":["messages","dmarcPass","dkimPass","spfPass","reports"]},"domains":{"type":"array","items":{"type":"object","properties":{"messages":{"type":"number"},"dmarcPass":{"type":"number"},"dkimPass":{"type":"number"},"spfPass":{"type":"number"},"domain":{"type":"string"}},"required":["messages","dmarcPass","dkimPass","spfPass","domain"]}},"days":{"type":"array","items":{"type":"object","properties":{"messages":{"type":"number"},"dmarcPass":{"type":"number"},"dkimPass":{"type":"number"},"spfPass":{"type":"number"},"date":{"type":"string"},"reports":{"type":"number"}},"required":["messages","dmarcPass","dkimPass","spfPass","date","reports"]}},"ips":{"type":"array","items":{"type":"object","properties":{"messages":{"type":"number"},"dmarcPass":{"type":"number"},"dkimPass":{"type":"number"},"spfPass":{"type":"number"},"ip":{"type":"string"},"version":{"type":"string","enum":["ipv4","ipv6"]}},"required":["messages","dmarcPass","dkimPass","spfPass","ip","version"]}},"ipVersions":{"type":"object","properties":{"ipv4":{"type":"number"},"ipv6":{"type":"number"}},"required":["ipv4","ipv6"]},"reporters":{"type":"array","items":{"type":"object","properties":{"messages":{"type":"number"},"dmarcPass":{"type":"number"},"dkimPass":{"type":"number"},"spfPass":{"type":"number"},"org":{"type":"string"}},"required":["messages","dmarcPass","dkimPass","spfPass","org"]}},"dispositions":{"type":"array","items":{"type":"object","properties":{"disposition":{"type":"string"},"messages":{"type":"number"}},"required":["disposition","messages"]}},"cases":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"org":{"type":"string"},"at":{"type":"string"},"ip":{"type":"string"},"dkim":{"type":"boolean"},"spf":{"type":"boolean"},"dmarc":{"type":"boolean"},"disposition":{"type":"string"},"messages":{"type":"number"}},"required":["domain","org","at","ip","dkim","spf","dmarc","disposition","messages"]}},"reporterChoices":{"type":"array","items":{"type":"string"}},"domainChoices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"}},"required":["id","domain"]}}},"required":["totals","domains","days","ips","ipVersions","reporters","dispositions","cases","reporterChoices","domainChoices"]},"DmarcSummary":{"type":"object","properties":{"days":{"type":"number"},"domains":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"reports":{"type":"number"},"messages":{"type":"number"},"dmarcPass":{"type":"number"},"dkimPass":{"type":"number"},"spfPass":{"type":"number"},"passRate":{"type":"number"},"lastReport":{"type":["string","null"]}},"required":["id","domain","reports","messages","dmarcPass","dkimPass","spfPass","passRate","lastReport"]}},"sources":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"sourceIp":{"type":"string"},"messages":{"type":"number"},"failed":{"type":"number"}},"required":["domain","sourceIp","messages","failed"]}},"reports":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"orgName":{"type":"string"},"reportId":{"type":"string"},"beginAt":{"type":"string"},"endAt":{"type":"string"},"messages":{"type":"number"},"dmarcPass":{"type":"number"},"receivedAt":{"type":"string"}},"required":["id","domain","orgName","reportId","beginAt","endAt","messages","dmarcPass","receivedAt"]}},"complaints":{"type":"object","properties":{"total":{"type":"number"},"bySource":{"type":"object","additionalProperties":{"type":"number"}},"recent":{"type":"array","items":{"type":"object","properties":{"at":{"type":"string"},"source":{"type":"string"},"kind":{"type":["string","null"],"enum":["campaign","automation",null]},"campaignId":{"type":["string","null"]},"automationId":{"type":["string","null"]},"name":{"type":"string"}},"required":["at","source","kind","campaignId","automationId","name"]}}},"required":["total","bySource","recent"]}},"required":["days","domains","sources","reports","complaints"]},"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}}}]},"SenderAuth":{"type":"object","properties":{"id":{"type":"string"},"shopId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"replyTo":{"type":"string"},"domain":{"type":"string"},"domainId":{"type":["string","null"]},"verified":{"type":"boolean"},"isDefault":{"type":"boolean"},"freemail":{"type":"boolean"},"spf":{"type":"string","enum":["ok","invalid","error","unknown","missing"]},"dkim":{"type":"string","enum":["ok","invalid","error","unknown","missing"]},"dmarc":{"type":"string","enum":["ok","invalid","error","unknown","missing"]},"usableAsSender":{"type":"boolean"}},"required":["id","shopId","name","email","replyTo","domain","domainId","verified","isDefault","freemail","spf","dkim","dmarc","usableAsSender"]},"SenderUsage":{"type":"object","properties":{"type":{"type":"string","enum":["campaign","automation","default"]},"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}},"required":["type","id","name","status"],"description":"One use of a sender (GET /sending/senders/{id}/usage). type default: the default sender of shop `id`."},"SendingDefaults":{"type":"object","properties":{"utmDefaultOn":{"type":"boolean"}},"required":["utmDefaultOn"],"description":"GET/PUT /tenants/{t}/sending-defaults (SE Výchozí nastavení, DO-07): utmDefaultOn = new drafts start with the\ntracking parameters utm_source newsletter and utm_medium email."},"SendingDomain":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"dkimSelectors":{"type":"array","items":{"type":"string"}},"spf":{"type":"object","properties":{"status":{"type":"string","enum":["ok","invalid","error","unknown","missing"]},"record":{"type":"string"}},"required":["status","record"]},"dkim":{"type":"object","properties":{"status":{"type":"string","enum":["ok","invalid","error","unknown","missing"]},"records":{"type":"object","additionalProperties":{"type":"object","properties":{"cname":{"type":"string"},"record":{"type":"string"}},"required":["cname","record"]}}},"required":["status","records"]},"dmarc":{"type":"object","properties":{"status":{"type":"string","enum":["ok","invalid","error","unknown","missing"]},"record":{"type":"string"}},"required":["status","record"]},"issues":{"type":"array","items":{"type":"string"},"description":"Codes, texts in the catalogs (deliverability.issue.<code>)."},"checkedAt":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","domain","dkimSelectors","spf","dkim","dmarc","issues","checkedAt","createdAt"]},"SendingDomainInput":{"type":"object","properties":{"domain":{"type":"string"},"dkimSelectors":{"type":"array","items":{"type":"string"}}},"required":["domain"]},"SendingDomainList":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SendingDomain"}},"suggestions":{"type":"array","items":{"type":"string"},"description":"Domains of sender addresses without a sending domain yet."}},"required":["items","suggestions"]},"SendingMode":{"type":"string","enum":["live","test","folder","off"]},"SendingModeInfo":{"type":"object","properties":{"mode":{"$ref":"#/components/schemas/SendingMode"},"testRecipients":{"type":"number","description":"How many addresses the tenant's test list has."},"sendingEnabled":{"type":"boolean","description":"The tenant's kill switch: off = no campaign goes out and no automation lets anybody in (tests still go out)."},"sendingState":{"type":"string","enum":["suspended","pending","live","paused"],"description":"The platform's approval (B4): anything but live keeps the tenant to test e-mails."},"sendingHold":{"type":"string","enum":["","free_limit","unpaid","platform"],"description":"Why a live tenant is held: the platform switch or billing (free tier used up, unpaid invoice)."}},"required":["mode","testRecipients"]},"SendingSetup":{"type":"object","properties":{"managed":{"type":"boolean","description":"The tenant sends through the platform account (Poštárna creates the identity)."},"platformReady":{"type":"boolean","description":"false = the platform still has to finish its part (no identity credential)."},"domains":{"type":"array","items":{"$ref":"#/components/schemas/SetupDomain"}},"suggestions":{"type":"array","items":{"type":"string"}},"shops":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"displayName":{"type":"string"},"code":{"type":"string"}},"required":["id","displayName","code"]}},"senders":{"type":"array","items":{"$ref":"#/components/schemas/SetupSender"}},"advanced":{"type":"object","properties":{"region":{"type":"string"},"credentialsRef":{"type":"string"},"configurationSet":{"type":"string"},"identityCredential":{"type":"boolean"},"identityRegion":{"type":"string"}},"required":["region","credentialsRef","configurationSet","identityCredential","identityRegion"],"description":"Platform admins only."}},"required":["managed","platformReady","domains","suggestions","shops","senders"]},"SetupDnsRecord":{"type":"object","properties":{"kind":{"type":"string","enum":["dkim","spf","dmarc"]},"type":{"type":"string","enum":["CNAME","TXT"]},"host":{"type":"string","description":"Name without the domain (what most DNS hosts ask for); '@' = the domain itself."},"name":{"type":"string","description":"Full name."},"value":{"type":"string"},"required":{"type":"boolean"},"status":{"$ref":"#/components/schemas/SetupRecordStatus"}},"required":["kind","type","host","name","value","required","status"]},"SetupDomain":{"type":"object","properties":{"id":{"type":"string"},"domain":{"type":"string"},"state":{"$ref":"#/components/schemas/SetupDomainState"},"records":{"type":"array","items":{"$ref":"#/components/schemas/SetupDnsRecord"}},"checkedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"advanced":{"type":"object","properties":{"managed":{"type":"boolean"},"sesStatus":{"type":"string"},"sesRegion":{"type":"string"},"dkimSelectors":{"type":"array","items":{"type":"string"}},"issues":{"type":"array","items":{"type":"string"}},"sesCheckedAt":{"type":["string","null"]}},"required":["managed","sesStatus","sesRegion","dkimSelectors","issues","sesCheckedAt"],"description":"Platform admins only."}},"required":["id","domain","state","records","checkedAt","createdAt"]},"SetupDomainState":{"type":"string","enum":["pending","failed","verified","setup"]},"SetupRecordStatus":{"type":"string","enum":["ok","unknown","missing"]},"SetupSender":{"type":"object","properties":{"id":{"type":"string"},"shopId":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"},"replyTo":{"type":"string"},"isDefault":{"type":"boolean"},"verified":{"type":"boolean"},"domainVerified":{"type":"boolean"},"verifyMethod":{"type":"string","enum":["domain","email"],"description":"DO-03: domain = verified by the DKIM of its domain, email = confirmed (or waiting for) a confirmation e-mail."},"verificationSentAt":{"type":["string","null"],"description":"When the last confirmation e-mail went out; null = none could be sent."},"freemail":{"type":"boolean","description":"An address of a free mailbox service (its provider's DMARC fails for e-mails sent through Poštárna)."}},"required":["id","shopId","name","email","replyTo","isDefault","verified","domainVerified"]},"SetupSenderInput":{"type":"object","properties":{"shopId":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"replyTo":{"type":"string"},"isDefault":{"type":"boolean"}},"required":["shopId","email"]},"SetupSenderPatch":{"type":"object","properties":{"name":{"type":"string","description":"From name, at most 100 characters without < > { } \" and line breaks."},"replyTo":{"type":"string","description":"Address for replies, '' = replies go to the sender address."},"isDefault":{"type":"boolean","const":true}},"description":"Edit of an existing sender. The address itself never changes (it belongs to a verified domain; server 400\nvalidation email, reason read_only)."}}}}