Belgelere geç
API

E-posta gönderme

POST /emails: tek bir ileti, şimdi ya da sonra.

POSTapi.openemail.uk/emails

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.

AlanZorunluNotlar
fromevetÇıplak bir adres ya da Name <addr>. Anahtarın adına gönderim yapabileceği bir adres olmalı.
toevetto, cc ve bcc toplamında en çok 50 alıcı.
cc, bcchayırBcc alıcıları, başkalarının aldığı baytlarda asla adlandırılmaz.
subjecthayırVarsayılanı boştur.
html, textbiriİkisi birden de olur. Alıcıların gördüğü HTML'dir.
templatebiri{ id, version?, props?, slots? }. Saklanmış bir gövde; id ya da slug ile. html, text veya draftId ile birlikte reddedilir. Bkz. Şablonla gönderme.
replyTohayırTek bir adres.
headershayırX-*, List-*, Reply-To, Precedence, Auto-Submitted, Importance, Priority, Feedback-Id.
attachmentshayırbase64 olarak { filename, content, contentType }, toplamda 5 MB; ya da çalışma alanında zaten bulunan bir dosyayı adlandıran { fileId }. 20 dosya.
attachmentDeliveryhayırmime, 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.
threadIdhayırVar olan bir konuşmaya yanıt verir.
draftIdhayırVar olan bir taslağı gönderir.
scheduledAthayırISO bir an ya da süre. Bkz. Zamanlama.
cancellableForSecondshayırAnı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.
signaturehayırfalse, 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.
tagshayırKendinize ait en çok 10 etiket. Geri yansıtılır, asla yorumlanmaz.
trackinghayı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.
translatehayı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.

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, 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
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 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.

  • template ile ç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-face kuralları 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.
  • draftId ile 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, translate dahil gönderdiğiniz istektir; modelin ürettiği değil. Bu yüzden yanıtsız kalan bir gönderimi aynı Idempotency-Key ile 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 nedenle dir özniteliğine izin verir, yani hattaki ileti önizlemenin gösterdiği yönü taşır.
KodDurumNe zaman
`invalid_parameter`422translate.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`422Aynı hatanın bir adım sonra, şema yerine servis tarafından yakalanması. translate.to üzerinde bir emniyet ağı.
`translation_too_long`422Model ç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`503Sağ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`422translate 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.