E-posta gönderme
POST /emails: tek bir ileti, şimdi ya da sonra.
Gerçek çağrıyı kendi anahtarınızla çalışma alanınıza karşı çalıştırır.
İstek
from zorunludur. Yazma penceresinin aksine yedek bir gönderen yoktur; çünkü o yedek, çalışma alanının varsayılan adresidir ve adresler gelip gittikçe görünmeden değişir.
| Alan | Zorunlu | Notlar |
|---|---|---|
| from | evet | Çıplak bir adres ya da Name <addr>. Anahtarın adına gönderim yapabileceği bir adres olmalı. |
| to | evet | to, cc ve bcc toplamında en çok 50 alıcı. |
| cc, bcc | hayır | Bcc alıcıları, başkalarının aldığı baytlarda asla adlandırılmaz. |
| subject | hayır | Varsayılanı boştur. |
| html, text | biri | İkisi birden de olur. Alıcıların gördüğü HTML'dir. |
| template | biri | { id, version?, props?, slots? }. Saklanmış bir gövde; id ya da slug ile. html, text veya draftId ile birlikte reddedilir. Bkz. Şablonla gönderme. |
| replyTo | hayır | Tek bir adres. |
| headers | hayır | X-*, List-*, Reply-To, Precedence, Auto-Submitted, Importance, Priority, Feedback-Id. |
| attachments | hayır | base64 olarak { filename, content, contentType }, toplamda 5 MB; ya da çalışma alanında zaten bulunan bir dosyayı adlandıran { fileId }. 20 dosya. |
| attachmentDelivery | hayır | mime, link ya da auto. auto, etkin bir dosya alan adı bulunan bir alan adında dosyalar 2 MB'ı aştığında bağlantı kullanır. Varsayılanı posta kutusu ayarıdır. |
| threadId | hayır | Var olan bir konuşmaya yanıt verir. |
| draftId | hayır | Var olan bir taslağı gönderir. |
| scheduledAt | hayır | ISO bir an ya da süre. Bkz. Zamanlama. |
| cancellableForSeconds | hayır | Anında gönderimde 0 ile 900 saniye arasında bir geri alma penceresi. scheduledAt ile birlikte reddedilir; zamanlanmış ileti zaten gönderilene kadar iptal edilebilir kalır. Bkz. Zamanlama. |
| signature | hayır | false, bu iletiye imza eklemez. Aksi hâlde ileti, gönderildiği adresin imzasını taşır; bu da o adresin kendi imzası ya da All addresses için ayarlanmış olandır. |
| tags | hayır | Kendinize ait en çok 10 etiket. Geri yansıtılır, asla yorumlanmaz. |
| tracking | hayır | { opens?, clicks? }. Her biri bu ileti için ayarı geçersiz kılar; bir alanı göndermezseniz o yarı, iletinin gönderildiği adresin ayarına, o da yoksa All addresses ayarına döner ve bunlardan biri kapatmadıkça açıktır. |
| translate | hayır | { to, from?, subject?, includeOriginal? }. İletiyi alıcının dilinde gönderir. İstek kabul edildiğinde çözülür, draftId ile birlikte reddedilir. |
Bilinmeyen alanlar yok sayılmaz, reddedilir; böylece yanlış yazılmış bir ad sonradan sürpriz olmak yerine şimdi 422 verir. Gönderen yetkilendirmesini boşa çıkaracak başlıklar (From, Sender, Bcc, Message-ID, Return-Path ve diğerleri) reserved_header ile reddedilir.
Yanıt
İleti çoktan gittiyse 200, hâlâ olması gereken bir şey varsa 202. Durum koduna göre dallanan bir çağıran ikisinde de haklıdır.
{ "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, saklayacağınız kalıcı tutamaçtır ve bir teslim olayının üzerinden geri geldiği değerdir; bir bounce webhook'u onu emailId olarak adlandırır. messageId ise RFC 5322 Message-ID değeridir ve MIME var olana kadar null'dır. Eşleştirmeyi onun üzerinden yapmayın: gönderim hizmeti çıkışta o başlığı yeniden yazar, yani buradaki değer hiçbir bounce ya da teslim raporunda görünmez ve onun üzerinden yapılan bir eşleşme asla tutmaz.
Alıcının dilinde
translate, iletiyi gitmeden önce başkasının dilinde yazar. Gövde ve (kapatmazsanız) konu, isteğin KABUL EDİLDİĞİ anda çevrilir; bu, template ile aynı kuraldır ve aynı nedenlerle yük taşır: zamanlanmış bir ileti, bir modelin salı günü üreteceği ne varsa onu değil onaylanmış sözcükleri taşır ve üretilemeyen bir çeviri, ortada bir satır oluşmadan gönderimi reddeder. Hiçbir şey, göndereninin seçmediği bir dilde teslim edilmez.
translate
tostringzorunlu- Yazılacak dil: BCP-47 bir kod (`de`), İngilizce bir ad ("German") ya da dilin kendi adı ("Deutsch"); 2 ile 60 karakter arası. Üçü de başka her şeyden önce tablo koduna normalleştirilir, yani tek bir istek oluştururlar; bu da önemlidir, çünkü Idempotency-Key parmak izi ayrıştırılmış istek üzerinden alınır. Takma adlar da çözülür: `zh-TW`, `zh-Hant` olur. Hiçbir şeye çözülmeyen bir değer `translate.to` üzerinde 422 verir.
fromstring- İletiyi hangi dilde yazdığınız, aynı üç biçimden herhangi biriyle. Tamamen bir optimizasyondur. Göndermezseniz gövde okunur ve dil saptanır; bu da kısa bir model çağrısı kadar tutar. Yüksek hacimli bir yolda belirtmeye değer; gövde çoğunlukla adlardan, sayılardan ve bağlantılardan oluşuyorsa da belirtmeye değer: saptama tahmin yürütmek yerine çekimser kalır ve belirlenemeyen bir kaynağın size maliyeti, özgün metninizin üstündeki başlıkta bir dilin anılmamasından ibarettir. Bu, bir adres olan üst düzey `from` alanı değildir.
subjectboolean- Konu satırını da çevirir. Varsayılanı true'dur; false, konuyu tam olarak yazdığınız gibi gönderir.
includeOriginalboolean- Gerçekte yazdığınızı, çevirinin altına, bir ayraçla ve alıcının dilinde bir başlıkla koyar. Varsayılanı true'dur ve açık bırakmaya değer. Okuyan kişinin, tuhaf düşen bir cümleyi, ikinizin de çıktısını göremediği bir modele güvenmeye zorlanmak yerine denetleyebilmesini sağlayan tek şey budur.
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 eklemeli bir alandır ve yalnızca çevrilmiş bir iletide görünür: bu yanıtta ve GET /emails/{id} içinde, asla bir liste satırında değil; çünkü liste saklanan isteği getirmez ve oradaki sessizliği hiçbir yönde bir şey söylemez. Dil satırlarının tamamını değil kodları taşır: yapılanın kaydıdır ve dilin kendi adı GET /languages içinde yaşar. Yanıttaki subject çevrilmiş olanıdır; böylece bir konsol, alıcının hiç görmediği bir metnin altında ileti listelemez.
templateile çalışır ve asıl işe yarayan durum budur: çevrilen şey İŞLENMİŞ çıktıdır, yani saklanan tek bir gövde, müşterilerinizin okuduğu her dile hizmet eder. Bütün bir belge üreten bir şablon önce parçalarına ayrılır: modele yalnızca<body>içindekiler ulaşır; doctype,<style>blokları ve@font-facekuralları ise yanıtın çevresine geri konur. 30.000 karakterlik sınırın belgeyi değil metnin kendisini ölçmesinin nedeni de budur: markalı bir stil sayfasına sarılmış iki satırlık bir ileti, iki satırlık bir iletidir.- Bir şablonun çevrilmeden bırakılan tek parçası, hiçbir posta istemcisinin göstermediği
<title>etiketidir. react-email<Preview>bileşeni gövdeye işlenir ve geri kalanla birlikte çevrilir. draftIdile birlikte reddedilir:translateüzerinde bir 422 ve şu metin: "A draft is sent as it was written; translate a body or send a draft, not both". Taslağı bir insan yazmıştır ve bıraktığı gibi gönderilir.- Bilinçli olarak idempotency parmak izinin parçası değildir. Karması alınan şey,
translatedahil gönderdiğiniz istektir; modelin ürettiği değil. Bu yüzden yanıtsız kalan bir gönderimi aynıIdempotency-Keyile yeniden denemek özgün isteği yeniden oynatır. Zaten var olan ileti geri gelir; ikinci bir gönderim de ikinci bir çeviri de olmaz. Bunun yerine sözcüklerin karmasını almak, dürüst bir yeniden denemenin her seferinde farklı bir parmak izi vermesine yol açardı; aynı iletinin iki kez gitmesi de böyle olur. - Kuyrukta ya da zamanlanmış durumdaki çevrilmiş bir ileti, sözcük değişikliklerine karşı dondurulmuştur. Zamanını değiştirin ya da iptal edin; söylediğini değiştirmek, iptal edip yeni sözcükleri okuyabilen birinin gözü önünde yeniden göndermek demektir.
- Sağdan sola yazılan bir hedef dil, sağdan sola üretilir: çeviri
dir="rtl"içine sarılır, özgün metniniz altta kendi yönünde durur. Bu öznitelik giden posta temizleyicisinden sağ çıkar; temizleyici tam da bu nedenledirözniteliğine izin verir, yani hattaki ileti önizlemenin gösterdiği yönü taşır.
| Kod | Durum | Ne zaman |
|---|---|---|
| `invalid_parameter` | 422 | translate.to ya da translate.from, yerleştirebileceğimiz bir dili adlandırmıyor. Mesaj hangi üç biçimin kabul edildiğini söyler ve GET /languages adresini gösterir. |
| `unknown_language` | 422 | Aynı hatanın bir adım sonra, şema yerine servis tarafından yakalanması. translate.to üzerinde bir emniyet ağı. |
| `translation_too_long` | 422 | Model çağrısının iki ucunda da 30.000 karakterin üzerinde. Kırpma değil ret: çevrilmiş bir iletinin yarısında, nerede kesildiğini gösteren bir dikiş izi olmaz ve okuyan kişi eline geçen yarıya göre davranır. |
| `translation_not_configured` | 409 | Çalışma alanının AI anahtarı yok ve platform AI'ı kapalı. 503 değil 409 verilir, çünkü yeniden deneme aynı şekilde başarısız olur. Hiçbir şey gönderilmedi. İletiyi yazıldığı gibi göndermek istiyorsanız translate olmadan gönderin. |
| `translation_failed` | 503 | Sağlayıcı yanıt vermedi ya da kullanılabilir bir şey döndürmedi. Hiçbir şey gönderilmedi; ileti yedek çözüm olarak asla çevrilmeden yollanmaz. Bu hata bize aittir ve yeniden denemeye değer. |
| `unknown_parameter` | 422 | translate içinde tanınmayan bir anahtar; translate de isteğin geri kalanı gibi katı bir nesnedir. |
Koddan yapılan bir gönderimde çeviriyi önce okuyan kimse olmaz. POST /emails/translate, aynı gidiş dönüşün bir adım önce durdurulmuş hâlidir ve birine, göndermek üzere olduğu şeyi göstermek içindir. Sonra onayladıklarını, istekte hiç translate olmadan, sıradan bir html/subject olarak gönderin.