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

थ्रेड

मेल पढ़ें और व्यवस्थित करें।

GETapi.openemail.uk/threads

इस पेज की 7 कॉल में से कोई भी आपकी अपनी कुंजी से आपके वर्कस्पेस पर चलाता है।

सूचीबद्ध करना

GET /threads?folder=inbox. query भेजने पर वही स्थानीय इंडेक्स खोजा जाता है। सादे शब्द सभी आने चाहिए, और हर एक ढीले ढंग से मिलता है — केस, उच्चारण-चिह्नों और विभाजकों की अनदेखी करते हुए — इसलिए min "Benjamin" खोज लेता है। उद्धरण में दिया वाक्यांश केस और उच्चारण-चिह्नों को छोड़कर जैसा लिखा है वैसा ही मिलाया जाता है, इसलिए "ben jamin" "Ben-Jamin" नहीं खोजता। the या emails जैसे भराव शब्द सादे शब्दों की सूची से हटा दिए जाते हैं, बशर्ते खोजने को कुछ और बचा हो। from:, to:, subject:, label:, is:unread, has:pdf, after:2026/01/31 और newer_than:7d जैसे ऑपरेटर इसे सँकरा करते हैं, और OR, कोष्ठक तथा आगे लगा - उन्हें जोड़ते हैं। प्राप्तकर्ता बिना भूमिकाओं के एक ही सूची में संग्रहीत होते हैं और उसमें कभी Bcc नहीं होता, इसलिए cc: वही फ़ील्ड पढ़ता है जो to: पढ़ता है और bcc: अपना कुछ नहीं मिलाता। from:me वह मेल है जो आपने भेजी, और to:me वह मेल है जिसके प्राप्तकर्ताओं में, या जिस पते पर वह पहुँचाई गई उसमें, आपका अपना कोई पता हो — उपनाम सहित।

शब्द और from:, to:, cc:, subject: तथा body: ऑपरेटर हर थ्रेड के सबसे नए संदेश को पढ़ते हैं: उसका भेजने वाला, उसके प्राप्तकर्ता, उसका subject और उसकी body के पहले 4,000 अक्षर। filename: और has: पूरी बातचीत के हर अटैचमेंट को पढ़ते हैं, और label:, in: तथा is: पूरी बातचीत को। folder तब तक लागू रहता है जब तक query in: से, या ऐसे is: से जो is:sent जैसा कोई फ़ोल्डर हो, किसी फ़ोल्डर का नाम न ले ले, और in:anywhere हर फ़ोल्डर में खोजता है — अकेले भी और दूसरे शब्दों के साथ भी। drafts की सूची अपवाद है और query चाहे किसी का भी नाम ले, वह drafts में ही रहती है।

जिस मान का उपयोग खोज नहीं कर सकती, उसे सँकरा करने के बजाय अनदेखा कर दिया जाता है, इसलिए मान में टाइपो परिणाम को ख़ाली करने के बजाय चौड़ा कर देता है: category:, larger:, smaller:, size:, messagesize:, list:, rfc822msgid:, received:, sent:, is:promotions जैसे श्रेणी-शब्द, ऐसा has: शब्द जो किसी प्रकार के अटैचमेंट का नाम न हो, high या low के अलावा कोई importance:, न पढ़ी जा सकने वाली तारीख़, और ऐसी अवधि जिसकी इकाई h, d, w, m या y न हो। जिस ऑपरेटर नाम को वह नहीं जानती, जैसे project:, उसे सादे टेक्स्ट की तरह खोजा जाता है। तारीख़ें थ्रेड की सबसे नई गतिविधि को UTC में पढ़ती हैं, जिसमें after: उस दिन को शामिल करता है जिसका नाम वह लेता है और before: उसे छोड़ देता है; इन्हें YYYY/MM/DD, YYYY-MM-DD, YYYYMMDD, सिर्फ़ वर्ष, या epoch सेकंड या मिलीसेकंड के रूप में लिखें।

nextPageToken अपारदर्शी है। आपको जो दिया गया था ठीक वही वापस भेजें; कभी कोई बनाएँ या संपादित न करें। इसका आकार अनुबंध का हिस्सा नहीं है।

प्राप्त करना

GET /threads/{id} थ्रेड का हर संदेश लौटाता है, केवल सबसे नया नहीं, साथ ही उसके labels और यह कि उसमें कुछ अपठित है या नहीं।

एन्क्रिप्टेड आए संदेश

यह API न एन्क्रिप्ट करता है, न डिक्रिप्ट। यह किसी और के एन्क्रिप्ट किए संदेश को नहीं खोल सकता, और एन्क्रिप्टेड संदेश भेज नहीं सकता। एन्क्रिप्शन मार्कर लिए अनुरोध को 422 के साथ अस्वीकार किया जाता है, क्योंकि उसे सेट करने का अधिकार केवल उन्हीं सतहों को है जिनके पास keys हैं, और किसी API क्लाइंट के पास key नहीं होती। यह जो करता है वह है भीतर आते समय सीलबंद लिफ़ाफ़े को पहचानना — केवल शीर्ष-स्तरीय Content-Type से, इससे अधिक कुछ नहीं — और फिर संदेश पर वह बता देना।

OpenEmail के पास अब ख़ुद keys हैं, और यह ठीक-ठीक बताना ज़रूरी है कि कौन-सा आधा और कहाँ। मेलबॉक्स का मालिक अपने ब्राउज़र में एक OpenPGP पहचान बनाता है और सार्वजनिक key को एक डायरेक्ट्री में प्रकाशित करता है जिसे साइन-इन किए दूसरे OpenEmail भेजने वाले हल कर सकते हैं। निजी आधा उसी ब्राउज़र में बनता है, यहाँ कभी नहीं भेजा जाता, और कभी वापस नहीं पाया जा सकता, इसलिए इस API में कुछ भी कुछ भी डिक्रिप्ट नहीं कर सकता, और न कोई सहायता अनुरोध, समन या हमारा कोई बैकअप ऐसी key देता है जो कर सके। वेब ऐप अब PGP/MIME या inline-PGP संदेश खोल सकता है जब key पढ़ने वाले के ब्राउज़र में हो, पर वह डिक्रिप्शन उसी टैब में होता है और उसका प्लेनटेक्स्ट कभी वापस नहीं लिखा जाता: संग्रहीत संदेश ciphertext ही रहता है, और इस API की कोई प्रतिक्रिया कभी खुला हुआ टेक्स्ट नहीं ले जाती। ऐप अब ब्राउज़र में नया संदेश सील करके भेज भी सकता है: कंपोज़र प्राप्तकर्ताओं की प्रकाशित keys के लिए एन्क्रिप्ट करता है और मेल PGP/MIME के रूप में जाती है। यह API अब भी कुछ भी सील नहीं कर सकता, इसलिए नीचे की फ़ील्ड उस मेल का भी वर्णन करती है जिसे किसी और ने एन्क्रिप्ट किया और उसका भी जिसे OpenEmail टैब में सील किया गया।

यह फ़ील्ड इसलिए ज़रूरी है कि विकल्प क्या था। सीलबंद संदेश कोई पठनीय body संग्रहीत नहीं करता, इसलिए decodedBody "" के रूप में लौटता है — वही बाइट जो उस संदेश के होते जिसमें सचमुच कोई सामग्री न हो। encryption वही है जो आपको किसी पर कार्रवाई करने से पहले दोनों में फ़र्क करने देता है, और यह सत्यापन नहीं बल्कि लिफ़ाफ़े के बारे में कथन है: यह देख लेना कि संदेश सीलबंद है, उसे खोल लेने के बराबर नहीं है।

प्रतिक्रिया
{    "object": "thread",    "id": "thread_2f9b…",    "messages": [      {        "id": "msg_7c41…",        "subject": "Q3 numbers",        "decodedBody": "",        "encryption": {          "format": "pgp-mime",          "detectedAt": "2026-08-30T09:14:22.117Z",          "rawRetained": false,          "parts": [            { "index": 0, "attachmentId": "msg_7c41…-0", "role": "version" },            { "index": 1, "attachmentId": "msg_7c41…-1", "role": "ciphertext" }          ]        }      }    ]  }

encryption

format'pgp-mime' | 'pgp-signed' | 'pgp-inline' | 'smime-encrypted' | 'smime-signed'
कौन-सा लिफ़ाफ़ा आया। शीर्ष-स्तरीय `Content-Type` से पढ़ा जाता है (PGP के लिए उसका `protocol` पैरामीटर, S/MIME के लिए उसका `smime-type`) या, `pgp-inline` के लिए, उस body से जो PGP armor हेडर से शुरू होती है। जिस `pkcs7-mime` हिस्से पर कोई `smime-type` ही न हो, उसे `smime-encrypted` पढ़ा जाता है, जो RFC 8551 के अनुसार उसका डिफ़ॉल्ट है।
detectedAtstring
ISO 8601, कि डिटेक्टर कब चला, यानी जब संदेश यहाँ ingest हुआ। यह इस बारे में कुछ नहीं कहता कि संदेश कब, या किसके द्वारा, एन्क्रिप्ट किया गया था।
rawRetainedboolean
क्या मूल RFC822 बाइट रखे गए थे, ताकि संदेश पूरा वापस सौंपा जा सके। आज हर संदेश पर false है, क्योंकि यहाँ अभी कुछ भी कच्ची मेल नहीं रखता। यह अभी से प्रतिक्रिया में है ताकि जिस दिन यह बदले, वही दिन हर संग्रहीत संदेश को दोबारा माइग्रेट करने का दिन न हो।
partsobject[]
इस फ़ॉर्मैट के काम में आने वाले लिफ़ाफ़े के हिस्से। जब भी `encryption` मौजूद हो तब मौजूद, और जब नाम लेने को कुछ न हो तब ख़ाली: `pgp-inline` का कोई अलग हिस्सा होता ही नहीं, क्योंकि उसका armor ही body है और `decodedBody` में आता है।
parts[].indexnumber
मूल संदेश का यह कौन-सा MIME हिस्सा था, जिसे `attachments` पर नहीं बल्कि जैसे हिस्से आए वैसे उन पर गिना जाता है। दोनों सूचियाँ अलग होती हैं, और इसी वजह से यह दर्ज किया जाता है।
parts[].attachmentIdstring
यह हिस्सा `attachments` में जो id रखता है, जहाँ वह वहाँ दिखता ही है: संदेश id के आगे हिस्से का सूचकांक जोड़ा हुआ। `ciphertext` हिस्सा सूचीबद्ध होता है और किसी भी दूसरी फ़ाइल की तरह डाउनलोड होता है; `version` और `signature` सूची से बाहर रखे जाते हैं, इसलिए उनके ids दोनों दृश्यों को जोड़ने भर के काम आते हैं। अटैचमेंट एंडपॉइंट उन्हें नहीं लौटाएगा।
parts[].role'version' | 'ciphertext' | 'signature'
`version` PGP/MIME का नियंत्रण हिस्सा है, `ciphertext` संदेश है, `signature` एक अलग किया हुआ हस्ताक्षर है। लाने लायक केवल `ciphertext` है; बाक़ी दो प्रोटोकॉल का सामान हैं जो पहले कबाड़ अटैचमेंट की तरह दिखते थे और अब नहीं दिखते।
formatक्या आयाबॉडी
pgp-mimeएक PGP/MIME लिफ़ाफ़ा: protocol=application/pgp-encrypted के साथ multipart/encryptedसीलबंद
pgp-inlinearmor body में ही। इसे हमेशा केवल body टेक्स्ट से पढ़ा जाता है, ताकि ऐसा उत्तर जो महज़ किसी armored ब्लॉक को उद्धृत करता हो, ग़लती से सीलबंद न समझ लिया जाए।सीलबंद
smime-encryptedsmime-type=enveloped-data वाला एक S/MIME pkcs7-mime हिस्सा, या ऐसा हिस्सा जिस पर कोई smime-type हो ही नहीं।सीलबंद
pgp-signedसंदेश के साथ एक अलग किया हुआ PGP हस्ताक्षर: protocol=application/pgp-signature के साथ multipart/signedपठनीय
smime-signedएक अलग किया हुआ S/MIME हस्ताक्षर: pkcs7-signature प्रोटोकॉल, या smime-type=signed-dataपठनीय

हस्ताक्षरित होना सीलबंद होना नहीं है, और format के बजाय encryption की मौजूदगी पर शाखा बनाना इसे ठीक उल्टा समझ लेता है। हस्ताक्षर इस बारे में दावा है कि संदेश किसने लिखा, उसके ऊपर लिपटा आवरण नहीं: हस्ताक्षरित संदेश की body खुली होती है और किसी भी दूसरे संदेश जैसी पढ़ी जाती है। pgp-mime, pgp-inline और smime-encrypted को अपठनीय मानें, और दोनों हस्ताक्षरित फ़ॉर्मैट को साधारण मेल।

सीलबंद संदेश पर क्या बदलता है

केवल तीन सीलबंद फ़ॉर्मैट ही कुछ बदलते हैं, और बदलाव इस प्रतिक्रिया में नहीं, ingest के समय होता है। जो कुछ भी body पढ़ता, वह ciphertext पढ़कर ऐसा नतीजा बताने के बजाय जो उसे मिल ही नहीं सकता था, पीछे हट जाता है:

  • body पर खोज। संदेश ख़ाली body snippet के साथ इंडेक्स होता है, इसलिए वह भेजने वाले, subject, पते और label से तब भी मिल जाता है, और उसके भीतर की किसी चीज़ से नहीं।
  • फ़िशिंग स्कोरर का body पास। फ़ैसला तब भी आता है और बताता है कि वह क्या नहीं कर सका: risk.signals में body-encrypted होता है और risk.aiChecked false होता है।
  • AI-लेखकत्व जाँच, जो अनुमान लगाने के बजाय मना कर देती है: aiWritten.level unknown होता है और aiWritten.skipped encrypted
  • नियमों में body की शर्तें। लिफ़ाफ़े और हेडर की शर्तें ठीक पहले जैसी चलती हैं; जिस नियम ने body के बारे में पूछा, उसे मेल न खाने के रूप में गिनने के बजाय अ-मूल्यांकित दर्ज किया जाता है, क्योंकि "मेल नहीं खाया" और "पढ़ा नहीं जा सका" अलग उत्तर हैं।
  • कैलेंडर निमंत्रण का आयात। निमंत्रण ciphertext के भीतर है, और लिफ़ाफ़े से इवेंट बनाना किसी असली कैलेंडर पर ग़लत प्रविष्टि डाल देता।
  • थ्रेड सारांश और embeddings, पूरे थ्रेड के लिए। एक सीलबंद उत्तर ही काफ़ी है। सारांश प्लेनटेक्स्ट का मॉडल-कृत पाठ होता है जो साफ़ मेटाडेटा के रूप में संग्रहीत होता है, और इस पाइपलाइन में यही वह इकलौती जगह है जहाँ body ऐसे भंडार में रिस जाती जिसे कोई body समझता ही नहीं।

जिस किसी को body की ज़रूरत नहीं, वह अछूता है:

  • DMARC, DKIM और SPF। ये Authentication-Results से पढ़े जाते हैं, जिसे ciphertext छिपाता नहीं, इसलिए एन्क्रिप्टेड संदेश को भी कुछ नहीं के बजाय असली प्रमाणीकरण फ़ैसला मिलता है।
  • थ्रेडिंग, spam में डालना और ब्लॉकलिस्ट: सब लिफ़ाफ़े और हेडर का काम।
  • अटैचमेंट। ciphertext हिस्सा attachments में बना रहता है, बिना नाम आने पर encrypted-message.asc नाम से, और नीचे दिए एंडपॉइंट से डाउनलोड होता है। यह ठीक वही है जो वेब ऐप का अपना रीडर लाकर ब्राउज़र में डिक्रिप्ट करता है; API क्लाइंट के लिए, जिसके पास कोई key नहीं है, वह डाउनलोड ही इस मेल को पढ़ने का एकमात्र रास्ता रहता है। इसे ऐसे क्लाइंट में खोलें जिसके पास key हो।
  • हस्ताक्षरित संदेश इसमें से कुछ नहीं खोता। ऊपर की हर जाँच उस पर चलती रहती है, और कुछ भी रोका नहीं जाता, यही वजह है कि सीलबंद सूची तीन फ़ॉर्मैट की है, पाँच की नहीं।

encryption का न होना प्लेनटेक्स्ट का दावा नहीं है। इसका मतलब है कि किसी ने देखा ही नहीं: या तो संदेश डिटेक्शन से पहले का है, या ऐसे रास्ते से मेलबॉक्स तक पहुँचा जो डिटेक्टर नहीं चलाता। कुछ भी इसे पीछे से नहीं भरता, इसलिए जो फ़ील्ड कहती है "हमने जाँचा नहीं", उसे कभी "हमने जाँचा और कुछ नहीं मिला" नहीं पढ़ना चाहिए।

चिह्नित करना और label लगाना

PATCH /threads/{id} read, addLabelIds और removeLabelIds लेता है। यह उत्पाद जिस भी बैकएंड का समर्थन करता है, उस हर एक पर पढ़ने की स्थिति एक label है, इसलिए एक ही कॉल में read सेट करना और labels हिलाना क्रम को निश्चित रखता है।

PATCH
{ "read": true, "addLabelIds": ["USER_INVOICES"] }

TRASH और SNOOZED को यहाँ label_not_directly_settable के साथ अस्वीकार किया जाता है। इनमें से कोई भी स्थिति अकेले अपने label से नहीं बनती (ट्रैश करना फ़ोल्डर labels भी साफ़ करता है, और snooze के लिए उसके साथ जागने का समय संग्रहीत करना पड़ता है), इसलिए इन्हें हाथ से सेट करने पर थ्रेड ऐसी स्थिति में छूट जाता है जो ऐप कभी बनाता ही नहीं और जिससे उबर नहीं सकता। नीचे दिए एंडपॉइंट इस्तेमाल करें।

ट्रैश और snooze

एंडपॉइंटक्या करता है
POST /threads/{id}/trashBin में ले जाता है, और INBOX, SPAM, SNOOZED तथा ARCHIVE को साथ में हटा देता है।
POST /threads/{id}/snoozeBody { "wakeAt": "…" }। इसे छिपाता है और इसकी वापसी निर्धारित करता है।
POST /threads/{id}/unsnoozeइसे अभी वापस लाता है, और निर्धारित वापसी रद्द कर देता है।

Snooze दो चीज़ें लिखता है: वह label जो थ्रेड को छिपाता है, और वह प्रविष्टि जो उसे वापस लाती है। एक को दूसरे के बिना करना ही ठीक वह वजह है कि ये label संपादन नहीं, एंडपॉइंट हैं।

अटैचमेंट

GET /threads/{id}/messages/{messageId}/attachments हर अटैचमेंट को filename, contentType, size और base64 के रूप में content के साथ लौटाता है। जहाँ संग्रहीत बाइट नहीं मिल सके वहाँ content ख़ाली string होती है, इसलिए डिकोड करने से पहले उसकी लंबाई जाँचें।

एन्क्रिप्टेड लिफ़ाफ़ा पूरा यहाँ नहीं होता। ciphertext होता है (वही संदेश है, और उसे डाउनलोड करना ही API क्लाइंट के लिए यह मेल पढ़ने का एकमात्र रास्ता है), पर PGP/MIME का version हिस्सा और कोई भी अलग किया हुआ हस्ताक्षर सूची से बाहर रखा जाता है, क्योंकि वे कबाड़ अटैचमेंट की तरह दिखते थे और कॉलर उनसे कुछ कर नहीं सकता। दोनों अपने ids encryption.parts में रखते हैं, जो दोनों दृश्यों को जोड़ता है; यह एंडपॉइंट उन्हें नहीं लौटाता।