Přejít na dokumentaci
API

Odeslání e-mailu

POST /emails: jedna zpráva, hned nebo později.

POSTapi.openemail.uk/emails

Spustí skutečné volání proti vašemu pracovnímu prostoru, s vaším vlastním klíčem.

Požadavek

from je povinné. Na rozdíl od editoru zpráv tu není žádný záložní odesílatel, protože tím záložním je výchozí adresa pracovního prostoru a ta se neviditelně mění, jak adresy přibývají a ubývají.

PolePovinnéPoznámky
fromanoHolá adresa nebo Name <addr>. Musí to být adresa, pod kterou klíč smí odesílat.
toanoDohromady až 50 příjemců napříč to, cc a bcc.
cc, bccnePříjemci v bcc nejsou nikdy uvedeni v datech, která dostane kdokoli jiný.
subjectneVýchozí hodnota je prázdná.
html, textjedno zObojí je v pořádku. Příjemci vidí HTML.
templatejedno z{ id, version?, props?, slots? }. Uložené tělo, podle id nebo podle slug. Spolu s html, text nebo draftId je odmítnuto. Viz Odeslání se šablonou.
replyToneJedna adresa.
headersneX-*, List-*, Reply-To, Precedence, Auto-Submitted, Importance, Priority, Feedback-Id.
attachmentsne{ filename, content, contentType } v base64, celkem 5 MB, nebo { fileId } odkazující na soubor, který už ve workspace je. 20 souborů.
attachmentDeliverynemime, link nebo auto. auto soubory odkazuje, jakmile přesáhnou 2 MB na doméně s aktivní doménou pro soubory. Výchozí je nastavení schránky.
threadIdneOdpověď do existujícího vlákna.
draftIdneOdeslání existujícího konceptu.
scheduledAtneOkamžik nebo doba trvání podle ISO. Viz Plánování.
cancellableForSecondsneOkno pro vrácení zpět, 0 až 900 vteřin, u okamžitého odeslání. Spolu se scheduledAt je odmítnuto – naplánovaná zpráva zůstává zrušitelná až do odeslání. Viz Plánování.
signaturenefalse nechá u této zprávy podpis stranou. Jinak nese podpis adresy, ze které se odesílá, tedy buď její vlastní, nebo ten nastavený pro Všechny adresy.
tagsneAž 10 vlastních štítků. Vrací se zpět, nikdy se neinterpretují.
trackingne{ opens?, clicks? }. Kterékoli z nich u této zprávy přebije nastavení; když pole vynecháte, spadne daná polovina zpět na nastavení adresy, ze které se odesílá, jinak na Všechny adresy, a je zapnutá, pokud ji jedno z nich nevyplo.
translatene{ to, from?, subject?, includeOriginal? }. Odešle zprávu v jazyce příjemce. Vyhodnotí se při přijetí požadavku, spolu s draftId je odmítnuto.

Neznámá pole se odmítají, místo aby se ignorovala, takže překlep v názvu je 422 hned, ne překvapení později. Hlavičky, které by zmařily autorizaci odesílatele (From, Sender, Bcc, Message-ID, Return-Path a další), se odmítnou s reserved_header.

Odpověď

200, když zpráva už odešla, 202, když se s ní ještě něco musí stát. Volající, který se větví podle stavového kódu, má pravdu v obou případech.

200 OK
{  "object": "email",  "id": "msg_c5f21cc6bfec4e848caf905b",  "status": "sent",  "mode": "live",  "from": "[email protected]",  "subject": "Your September invoice",  "messageId": "<2598…@acme.com>",  "transport": "ses",  "sentAt": "2026-08-29T08:19:08.000Z",  "source": "api",  "replayed": false}

id je trvalý identifikátor, který si uchováte, a zároveň ten, na kterém se vrací událost o doručení – webhook o odmítnutí (bounce) jej uvádí jako emailId. messageId je Message-ID podle RFC 5322 a je null, dokud neexistuje MIME. Nepárujte podle něj: odesílací služba tuto hlavičku cestou ven přepisuje, takže se zdejší hodnota neobjeví v žádném bounce ani delivery reportu a shoda podle ní nikdy nenastane.

V jazyce příjemce

translate napíše zprávu v jazyce někoho jiného ještě předtím, než odejde. Tělo, a pokud to nevypnete i předmět, se přeloží ve chvíli, kdy je požadavek PŘIJAT; totéž pravidlo platí pro template a je nosné ze stejných důvodů: naplánovaná zpráva nese slova, která byla schválena, a ne to, co model vyprodukuje v úterý, a překlad, který se nepodařilo vytvořit, odmítne odeslání dřív, než vznikne záznam. Nic se nedoručí v jazyce, který si jeho odesílatel nevybral.

translate

tostringpovinné
Jazyk, ve kterém se má psát: kód BCP-47 (`de`), anglický název („German“) nebo vlastní název jazyka („Deutsch“), 2 až 60 znaků. Všechny tři podoby se ještě před čímkoli dalším normalizují na kód z tabulky, takže jde o jeden a týž požadavek – na tom záleží, protože otisk pro Idempotency-Key se počítá z naparsovaného požadavku. Řeší se i aliasy: `zh-TW` se stane `zh-Hant`. Hodnota, kterou se nepodaří rozřešit, je 422 na `translate.to`.
fromstring
V čem jste ji napsali, v kterékoli z týchž tří podob. Čistě optimalizace. Když ji vynecháte, tělo se přečte a jazyk se určí, což stojí jedno krátké volání modelu. Na cestě s velkým objemem se vyplatí ho uvést a vyplatí se to i tehdy, když tělo tvoří hlavně jména, čísla a odkazy: detekce se raději zdrží, než by hádala, a neurčený zdroj vás nestojí nic než jazyk uvedený v popisku nad vaším originálem. Nejde o `from` na nejvyšší úrovni, což je adresa.
subjectboolean
Přeložit i řádek s předmětem. Výchozí hodnota je true; false odešle předmět přesně tak, jak jste ho napsali.
includeOriginalboolean
Pod překlad umístí to, co jste skutečně napsali, za oddělovač a s popiskem v jazyce příjemce. Výchozí hodnota je true a vyplatí se ji ponechat. Je to jediné, co čtenáři umožní ověřit větu, která zní podivně, místo aby musel věřit modelu, jehož výstup ani jeden z vás nevidí.
curl
curl -X POST "$OE/emails" -H "$AUTH" -H "Content-Type: application/json" \  -d '{    "from": "[email protected]",    "to": ["[email protected]"],    "subject": "Your September invoice",    "html": "<p>Invoice attached. Payment is due on the 14th.</p>",    "translate": { "to": "de" }  }'
200 OK
{  "object": "email",  "id": "msg_c5f21cc6bfec4e848caf905b",  "status": "sent",  "from": "[email protected]",  "subject": "Ihre Rechnung für September",  "translation": {    "language": "de",    "languageName": "German",    "detectedSourceLanguage": "en",    "subject": true,    "includeOriginal": true  }}

translation je aditivní a objeví se jen u zprávy, která byla přeložena: v této odpovědi a v GET /emails/{id}, nikdy v řádku výpisu, protože výpis uložený požadavek nenačítá a jeho mlčení tam neznamená ani jedno. Nese kódy, ne celé řádky jazyků: je to záznam o tom, co se stalo, a endonymum najdete v GET /languages. subject v odpovědi je ten přeložený, takže konzole nikdy neuvede zprávu pod řetězcem, který příjemce nikdy neviděl.

  • Funguje s template a to je ten užitečný případ: překládá se VYRENDEROVANÝ výstup, takže jedno uložené tělo poslouží každému jazyku, ve kterém vaši zákazníci čtou. Šablona, která vyrenderuje celý dokument, se nejprve rozebere: k modelu se dostane jen to, co je uvnitř <body>, a doctype, bloky <style> a pravidla @font-face se kolem odpovědi vrátí zpět. Proto také limit 30 000 znaků měří prózu, a ne dokument: dvouřádková zpráva zabalená do brandovaného stylesheetu je dvouřádková zpráva.
  • Jediná část šablony, která zůstane nepřeložená, je její <title>, který žádný poštovní klient nezobrazuje. <Preview> z react-email se renderuje do těla a překládá se spolu se zbytkem.
  • S draftId je odmítnuto: 422 na translate se zněním „A draft is sent as it was written; translate a body or send a draft, not both“. Koncept napsal člověk a odesílá se tak, jak ho zanechal.
  • Záměrně není součástí otisku pro idempotenci. Hashuje se požadavek, který jste poslali, včetně translate; to, co vyprodukoval model, ne. Opakované odeslání nezodpovězeného požadavku se stejným Idempotency-Key tedy přehraje ten původní. Vrátí se zpráva, která už existuje, bez druhého odeslání a bez druhého překladu. Hashovat místo toho samotnou formulaci by znamenalo, že poctivé opakování dá pokaždé jiný otisk – a přesně takhle odejde tatáž zpráva dvakrát.
  • Přeložená zpráva, která je ve frontě nebo naplánovaná, je proti změnám formulace zmrazená. Přesuňte ji nebo zrušte; změnit to, co říká, znamená zrušit ji a odeslat znovu, před někým, kdo si nová slova přečte.
  • Cíl psaný zprava doleva vznikne zprava doleva: překlad je zabalen do dir="rtl", váš originál pod ním má vlastní orientaci. Atribut přežije odchozí sanitizér, který dir povoluje přesně z tohoto důvodu, takže zpráva na drátě nese tentýž směr, jaký ukázal náhled.
KódStavKdy
`invalid_parameter`422translate.to nebo translate.from uvádí jazyk, který neumíme zařadit. Zpráva říká, které tři podoby jsou přijímány, a odkazuje na GET /languages.
`unknown_language`422Totéž selhání zachycené o krok později, službou místo schématu. Záchytná pojistka, na translate.to.
`translation_too_long`422Přes 30 000 znaků na kterémkoli konci volání modelu. Odmítnutí místo oříznutí: půlka přeložené zprávy nemá žádný šev, který by ukázal, kde skončila, a čtenář jedná podle té poloviny, kterou dostal.
`translation_not_configured`409Workspace nemá klíč k AI a platformní AI je vypnutá. 409 místo 503, protože opakování selže naprosto stejně. Nic se neodeslalo. Pokud jste zprávu chtěli poslat tak, jak je napsaná, odešlete ji bez translate.
`translation_failed`503Poskytovatel neodpověděl, nebo odpověděl něčím nepoužitelným. Nic se neodeslalo; zpráva se jako náhradní řešení nikdy neodešle nepřeložená. Tohle je na naší straně a stojí za to zopakovat.
`unknown_parameter`422Nerozpoznaný klíč uvnitř translate, což je striktní objekt jako zbytek požadavku.

Při odeslání z kódu si překlad nikdo předem nepřečte. POST /emails/translate je tentýž okruh zastavený o krok dřív, aby se člověku dalo ukázat, co se chystá odeslat. Pak odešlete to, co schválil, jako obyčejné html/subject a bez translate v požadavku.