दस्तावेज़ पर जाएँ
API

ईमेल भेजें

POST /emails: एक संदेश, अभी या बाद में।

POSTapi.openemail.uk/emails

असली कॉल आपकी अपनी कुंजी से आपके वर्कस्पेस पर चलाता है।

अनुरोध

from आवश्यक है। composer के विपरीत यहाँ कोई फ़ॉलबैक भेजने वाला नहीं है, क्योंकि वह फ़ॉलबैक वर्कस्पेस का डिफ़ॉल्ट पता होता है और पतों के आने-जाने के साथ वह अदृश्य रूप से बदलता रहता है।

फ़ील्डआवश्यकटिप्पणियाँ
fromहाँसादा पता या Name <addr>। ऐसा होना चाहिए जिसके रूप में कुंजी भेज सके।
toहाँto, cc और bcc मिलाकर अधिकतम 50 प्राप्तकर्ता।
cc, bccनहींBcc प्राप्तकर्ताओं का नाम उन बाइट्स में कभी नहीं होता जो किसी और को मिलती हैं।
subjectनहींडिफ़ॉल्ट रूप से खाली।
html, textइनमें से एकदोनों भी ठीक हैं। प्राप्तकर्ता HTML ही देखते हैं।
templateइनमें से एक{ id, version?, props?, slots? }। एक संग्रहीत बॉडी, id या slug से। html, text या draftId के साथ अस्वीकार। template के साथ भेजें देखें।
replyToनहींएक अकेला पता।
headersनहींX-*, List-*, Reply-To, Precedence, Auto-Submitted, Importance, Priority, Feedback-Id।
attachmentsनहीं{ filename, content, contentType } base64 के रूप में, कुल 5 MB, या { fileId } जो वर्कस्पेस में पहले से मौजूद किसी फ़ाइल का नाम लेता है। 20 फ़ाइलें।
attachmentDeliveryनहींmime, link या auto। सक्रिय files डोमेन वाले डोमेन पर फ़ाइलें 2 MB पार करते ही auto उन्हें लिंक कर देता है। डिफ़ॉल्ट रूप से मेलबॉक्स सेटिंग।
threadIdनहींकिसी मौजूदा thread में उत्तर दें।
draftIdनहींकोई मौजूदा draft भेजें।
scheduledAtनहींISO क्षण या अवधि। शेड्यूलिंग देखें।
cancellableForSecondsनहींतत्काल भेजाव पर 0 से 900 सेकंड की undo विंडो। scheduledAt के साथ अस्वीकार, जो भेजे जाने तक वैसे भी रद्द किया जा सकता है। शेड्यूलिंग देखें।
signatureनहींfalse इस संदेश पर हस्ताक्षर नहीं लगाता। अन्यथा उस पते का हस्ताक्षर लगता है जिससे यह भेजा गया है, यानी उस पते का अपना, वरना All addresses के लिए सेट किया गया।
tagsनहींआपके अपने अधिकतम 10 लेबल। वापस लौटाए जाते हैं, कभी व्याख्यायित नहीं होते।
trackingनहीं{ opens?, clicks? }। इनमें से कोई भी इस संदेश के लिए सेटिंग को ओवरराइड करता है; कोई फ़ील्ड छोड़ दें तो वह आधा हिस्सा उस पते की सेटिंग पर लौटता है जिससे यह भेजा गया है, वरना All addresses पर, और जब तक इनमें से किसी ने उसे बंद न किया हो यह चालू रहता है।
translateनहीं{ to, from?, subject?, includeOriginal? }। इसे प्राप्तकर्ता की भाषा में भेजता है। अनुरोध स्वीकार होते समय तय होता है, draftId के साथ अस्वीकार।

अनजान फ़ील्ड नज़रअंदाज़ करने के बजाय अस्वीकार किए जाते हैं, इसलिए ग़लत वर्तनी वाला नाम बाद के किसी आश्चर्य के बजाय अभी 422 बनता है। जो हेडर भेजने वाले के प्राधिकार को विफल कर देते (From, Sender, Bcc, Message-ID, Return-Path और अन्य) वे reserved_header के साथ अस्वीकार होते हैं।

प्रतिक्रिया

200 तब जब संदेश जा चुका है, 202 तब जब उसके साथ कुछ होना अभी बाकी है। स्टेटस कोड पर शाखा बनाने वाला कॉलर दोनों के बारे में सही रहता है।

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 वह टिकाऊ हैंडल है जिसे आप रखते हैं, और डिलीवरी इवेंट भी उसी पर लौटता है, क्योंकि bounce webhook उसे emailId के रूप में नाम देता है। messageId RFC 5322 वाला Message-ID है और MIME बनने तक null रहता है। उस पर मिलान न करें: भेजने वाली सेवा बाहर जाते समय उस हेडर को फिर से लिखती है, इसलिए यहाँ दिखने वाला मान किसी bounce या delivery रिपोर्ट में नहीं आता और उस पर मिलान कभी नहीं चलता।

प्राप्तकर्ता की भाषा में

translate संदेश को भेजने से पहले किसी और की भाषा में लिखता है। बॉडी, और विषय भी जब तक आप उसे बंद न करें, तब अनूदित होते हैं जब अनुरोध स्वीकार किया जाता है — वही नियम जिसका template पालन करता है और उन्हीं कारणों से यह निर्णायक है: शेड्यूल किया गया संदेश वही शब्द ले जाता है जो स्वीकृत हुए थे, न कि जो कोई मॉडल मंगलवार को गढ़ दे, और जो अनुवाद बन ही न सके वह पंक्ति बनने से पहले भेजाव को अस्वीकार कर देता है। किसी भी संदेश की डिलीवरी उस भाषा में नहीं होती जिसे उसके भेजने वाले ने नहीं चुना।

translate

tostringआवश्यक
जिस भाषा में लिखना है: एक BCP-47 कोड (`de`), एक अंग्रेज़ी नाम ("German") या भाषा का अपना नाम ("Deutsch"), 2 से 60 अक्षर। बाकी कुछ भी होने से पहले तीनों को तालिका के कोड में सामान्यीकृत किया जाता है, इसलिए वे एक ही अनुरोध हैं — और यह मायने रखता है क्योंकि Idempotency-Key का फ़िंगरप्रिंट पार्स किए गए अनुरोध पर लिया जाता है। उपनाम भी हल होते हैं: `zh-TW` `zh-Hant` बन जाता है। जो कुछ भी हल न हो वह `translate.to` पर 422 है।
fromstring
आपने इसे जिस भाषा में लिखा, उन्हीं तीन रूपों में से किसी एक में। यह विशुद्ध रूप से एक अनुकूलन है। छोड़ देने पर बॉडी पढ़ी जाती है और भाषा का पता लगाया जाता है, जिसकी लागत एक छोटी मॉडल कॉल है। अधिक मात्रा वाले पथ पर इसे बताना सार्थक है, और तब भी जब बॉडी में ज़्यादातर नाम, संख्याएँ और लिंक हों: पहचान अनुमान लगाने के बजाय चुप रह जाती है, और अनिर्धारित स्रोत की कीमत आपको सिर्फ़ यह पड़ती है कि आपके मूल पाठ के ऊपर वाले कैप्शन में भाषा का नाम नहीं आता। यह शीर्ष-स्तर का `from` नहीं है, जो एक पता है।
subjectboolean
विषय पंक्ति का भी अनुवाद करें। डिफ़ॉल्ट true; false होने पर विषय ठीक वैसे ही भेजा जाता है जैसे आपने लिखा।
includeOriginalboolean
आपने वास्तव में जो लिखा उसे अनुवाद के नीचे रखें, एक विभाजक के पीछे और प्राप्तकर्ता की भाषा में कैप्शन के साथ। डिफ़ॉल्ट true, और इसे चालू रखना ही ठीक है। यही एकमात्र चीज़ है जो पढ़ने वाले को किसी अटपटे वाक्य की जाँच करने देती है, बजाय इसके कि उससे ऐसे मॉडल पर भरोसा करने को कहा जाए जिसका आउटपुट आप दोनों में से कोई नहीं देख सकता।
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 अतिरिक्त है और केवल उसी संदेश पर दिखता है जिसका अनुवाद हुआ: इस प्रतिक्रिया पर और GET /emails/{id} पर, कभी किसी सूची पंक्ति पर नहीं, क्योंकि सूची संग्रहीत अनुरोध नहीं लाती और वहाँ उसकी चुप्पी किसी भी दिशा में कुछ नहीं कहती। यह पूरी भाषा पंक्तियों के बजाय कोड रखता है: यह इस बात का रिकॉर्ड है कि क्या किया गया, और endonym GET /languages में रहता है। प्रतिक्रिया पर subject अनूदित वाला होता है, इसलिए कोई कंसोल संदेश को ऐसी स्ट्रिंग के नीचे सूचीबद्ध नहीं करता जो प्राप्तकर्ता ने कभी देखी ही नहीं।

  • यह template के साथ काम करता है, और यही उपयोगी स्थिति है: अनुवाद रेंडर किए गए आउटपुट का होता है, इसलिए एक संग्रहीत बॉडी आपके ग्राहकों की हर पढ़ी जाने वाली भाषा के काम आती है। जो template पूरा दस्तावेज़ रेंडर करता है उसे पहले खोला जाता है: केवल <body> के भीतर का हिस्सा मॉडल तक पहुँचता है, और doctype, <style> ब्लॉक तथा @font-face नियम उत्तर के चारों ओर वापस लगा दिए जाते हैं। इसीलिए 30,000 अक्षरों की सीमा गद्य को नापती है, दस्तावेज़ को नहीं: किसी ब्रांडेड स्टाइलशीट में लिपटा दो-पंक्ति का संदेश दो-पंक्ति का ही संदेश है।
  • template का एकमात्र हिस्सा जो अनूदित नहीं होता वह उसका <title> है, जिसे कोई मेल क्लाइंट नहीं दिखाता। react-email का <Preview> बॉडी में रेंडर होता है और बाकी के साथ अनूदित होता है।
  • draftId के साथ अस्वीकार: translate पर एक 422, जिसमें लिखा होता है "A draft is sent as it was written; translate a body or send a draft, not both"। draft किसी व्यक्ति ने लिखा है और वैसा ही भेजा जाता है जैसा उसने छोड़ा।
  • यह जानबूझकर idempotency फ़िंगरप्रिंट का हिस्सा नहीं है। hash उस अनुरोध का होता है जो आपने भेजा, translate सहित; मॉडल ने जो बनाया वह नहीं। इसलिए बिना उत्तर वाले भेजाव को उसी Idempotency-Key के साथ दोहराने पर मूल वाला ही दोबारा चलता है। जो संदेश पहले से मौजूद है वही वापस आता है, बिना दूसरे भेजाव और बिना दूसरे अनुवाद के। इसके बजाय शब्दावली का hash लेने पर एक ईमानदार पुनः प्रयास हर बार अलग फ़िंगरप्रिंट बनाता, और इसी तरह एक ही संदेश दो बार जाता है।
  • जो अनूदित संदेश queued या scheduled है वह शब्दावली में बदलाव के विरुद्ध जमा दिया जाता है। उसे खिसकाएँ या रद्द करें; उसकी बात बदलने का मतलब है उसे रद्द करना और किसी ऐसे व्यक्ति के सामने दोबारा भेजना जो नए शब्द पढ़ सके।
  • दाएँ-से-बाएँ लक्ष्य के लिए आउटपुट दाएँ से बाएँ बनता है: अनुवाद dir="rtl" में लिपटा, और आपका मूल पाठ उसके नीचे अपनी ही दिशा में। यह गुण बाहर जाने वाले sanitiser से बच जाता है, जो ठीक इसी कारण dir की अनुमति देता है, इसलिए तार पर जाने वाला संदेश वही दिशा ले जाता है जो पूर्वावलोकन में दिखी थी।
कोडस्थितिकब
`invalid_parameter`422translate.to या translate.from ऐसी किसी भाषा का नाम लेता है जिसे हम पहचान नहीं सकते। संदेश बताता है कि कौन-से तीन रूप स्वीकार हैं और GET /languages की ओर इशारा करता है।
`unknown_language`422वही विफलता, एक कदम बाद पकड़ी गई, schema के बजाय सेवा द्वारा। एक बैकस्टॉप, translate.to पर।
`translation_too_long`422मॉडल कॉल के किसी भी छोर पर 30,000 अक्षरों से ऊपर। काट देने के बजाय अस्वीकृति: आधे अनूदित संदेश में ऐसी कोई सीवन नहीं होती जो बताए कि वह कहाँ रुका, और पढ़ने वाला उसी आधे पर कार्रवाई कर देता है जो उसे मिला।
`translation_not_configured`409वर्कस्पेस के पास कोई AI कुंजी नहीं है और प्लेटफ़ॉर्म AI बंद है। 503 के बजाय 409, क्योंकि पुनः प्रयास ठीक वैसे ही विफल होगा। कुछ भी नहीं भेजा गया। अगर आपका इरादा उसे जैसा लिखा था वैसा भेजने का था, तो translate के बिना भेजें।
`translation_failed`503प्रदाता ने उत्तर नहीं दिया, या ऐसा उत्तर दिया जो काम का नहीं था। कुछ भी नहीं भेजा गया; संदेश कभी फ़ॉलबैक के तौर पर बिना अनुवाद के पोस्ट नहीं होता। यह हमारी तरफ़ का है और इसे दोबारा आज़माना सार्थक है।
`unknown_parameter`422translate के भीतर कोई अपरिचित कुंजी, जो बाकी अनुरोध की तरह एक सख़्त ऑब्जेक्ट है।

कोड से भेजे गए मेल में अनुवाद पहले कोई नहीं पढ़ता। POST /emails/translate वही चक्कर है जो एक कदम पहले रोक दिया गया हो, ताकि किसी व्यक्ति को दिखाया जा सके कि वह क्या भेजने वाला है। फिर जो उसने स्वीकृत किया उसे साधारण html/subject के रूप में भेजें, अनुरोध पर translate बिल्कुल न रखते हुए।