Odeslání e-mailu
POST /emails: jedna zpráva, hned nebo později.
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í.
| Pole | Povinné | Poznámky |
|---|---|---|
| from | ano | Holá adresa nebo Name <addr>. Musí to být adresa, pod kterou klíč smí odesílat. |
| to | ano | Dohromady až 50 příjemců napříč to, cc a bcc. |
| cc, bcc | ne | Příjemci v bcc nejsou nikdy uvedeni v datech, která dostane kdokoli jiný. |
| subject | ne | Výchozí hodnota je prázdná. |
| html, text | jedno z | Obojí je v pořádku. Příjemci vidí HTML. |
| template | jedno 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. |
| replyTo | ne | Jedna adresa. |
| headers | ne | X-*, List-*, Reply-To, Precedence, Auto-Submitted, Importance, Priority, Feedback-Id. |
| attachments | ne | { filename, content, contentType } v base64, celkem 5 MB, nebo { fileId } odkazující na soubor, který už ve workspace je. 20 souborů. |
| attachmentDelivery | ne | mime, 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. |
| threadId | ne | Odpověď do existujícího vlákna. |
| draftId | ne | Odeslání existujícího konceptu. |
| scheduledAt | ne | Okamžik nebo doba trvání podle ISO. Viz Plánování. |
| cancellableForSeconds | ne | Okno 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í. |
| signature | ne | false 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. |
| tags | ne | Až 10 vlastních štítků. Vrací se zpět, nikdy se neinterpretují. |
| tracking | ne | { 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. |
| translate | ne | { 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.
{ "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 -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" } }'{ "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
templatea 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-facese 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
draftIdje odmítnuto: 422 natranslatese 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ýmIdempotency-Keytedy 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ýdirpovoluje přesně z tohoto důvodu, takže zpráva na drátě nese tentýž směr, jaký ukázal náhled.
| Kód | Stav | Kdy |
|---|---|---|
| `invalid_parameter` | 422 | translate.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` | 422 | Totéž selhání zachycené o krok později, službou místo schématu. Záchytná pojistka, na translate.to. |
| `translation_too_long` | 422 | Př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` | 409 | Workspace 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` | 503 | Poskytovatel 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` | 422 | Nerozpoznaný 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.