नया गाइड: प्रतिष्ठा को नुकसान पहुँचाए बिना डेडिकेटेड IP को वार्म-अप कैसे करें। अभी पढ़ें →
MigoSMTP
SMTP और APIअपडेट किया गया 16 अक्तू॰ 2026

प्रोडक्शन में Email API इंटीग्रेशन: Idempotency, Retries और Bulk Sending पैटर्न

HTTP API से एक ईमेल भेजना आसान है। असली चुनौती लाखों ईमेल को बिना डबल सेंड, बिना खोए संदेशों और बिना retry storm के भेजना है। इस गाइड में idempotency और आपकी अपनी dedupe टेबल, outbox पैटर्न, queue और workers, batching, 4xx, 5xx और नेटवर्क एरर के लिए retry वर्गीकरण, message ID सहेजना, rate-limit की जानकारी, graceful degradation और टेस्टिंग शामिल हैं।

MO
लेखक Mateus Oliveira
Senior SMTP and MTA Engineer
समीक्षक Tomasz Kowalski
  • प्रकाशित29 सित॰ 2026
  • पढ़ने का समय4 मिनट
  • लंबाई688 शब्द
इस गाइड को साझा करें

एक भरोसेमंद email api integration ज़्यादातर इस बात पर निर्भर करता है कि कुछ गलत होने पर क्या होता है। सामान्य स्थिति में बस एक HTTP रिक्वेस्ट होती है। कठिन स्थितियां हैं: ऐसा timeout जहां आपको पता नहीं कि संदेश स्वीकार हुआ या नहीं, batch के बीच में क्रैश होने वाला worker, और ऐसा retry लूप जो छोटे आउटेज को बाढ़ में बदल देता है। यह गाइड हमें पैटर्न का एक सेट देती है, जो हर ईमेल को ठीक एक बार, या कम से कम अनुमानित रूप से एक बार, भेजना सुनिश्चित करता है, चाहे आप किसी भी प्रोवाइडर endpoint को कॉल करें।

हम इन पैटर्न को सामान्य रूप में बताते हैं ताकि ये MigoSMTP सहित किसी भी HTTP email API के साथ काम करें। जहां कोई विशेष फ़ीचर मायने रखता है, जैसे idempotency header, batch endpoint या rate limit, वहां मान लेने के बजाय सटीक विवरण के लिए अपना MigoSMTP अकाउंट या API डॉक्यूमेंटेशन देखें। अगर आप अभी प्रोटोकॉल चुन रहे हैं, तो पहले SMTP या API: कैसे चुनें पढ़ें।

1हर इच्छित ईमेल के लिए dedupe key, किसी भी API कॉल से पहले बनाई गई
3सेंड प्रयास के परिणाम: accepted, rejected, unknown
2सुरक्षित करने की जगहें: request पाथ और retry पाथ
04xx validation एरर पर अंधाधुंध retry

ईमेल सेंड उन तरीकों से क्यों फ़ेल होते हैं जिनसे अन्य API कॉल नहीं होते

ज़्यादातर API कॉल बिना नुकसान दोहराई जा सकती हैं। ईमेल नहीं। यूज़र बनाने की दूसरी कॉल आमतौर पर conflict के साथ फ़ेल होती है, लेकिन रसीद भेजने की दूसरी कॉल आराम से दूसरी रसीद भेज देती है। ग्राहक को दो संदेश दिखते हैं, सपोर्ट को शिकायत मिलती है, और दो बार भेजा गया पासवर्ड रीसेट उस कोड को अमान्य कर सकता है जिसे व्यक्ति पढ़ रहा है।

मूल समस्या अज्ञात परिणाम है। आपका क्लाइंट रिक्वेस्ट भेजता है, सर्वर उसे स्वीकार करता है, और जवाब नेटवर्क ड्रॉप या timeout में खो जाता है। आपकी ओर से यह उस रिक्वेस्ट जैसा दिखता है जो कभी पहुंची ही नहीं। अगर आप retry करते हैं, तो डुप्लिकेट हो सकता है। अगर नहीं करते, तो संदेश खो सकता है। नीचे का हर पैटर्न इसी अस्पष्टता को सुलझाने के लिए है।

फ़ेल्योरआपको क्या पता हैसीधे-सादे तरीके से संभालने पर जोखिम
Connection refused या DNS फ़ेल्योररिक्वेस्ट API तक कभी पहुंची ही नहींretry सुरक्षित है; जोखिम केवल retry storm का है
रिक्वेस्ट भेजने के बाद read timeoutस्वीकार होने के बारे में कुछ नहींdedupe key के बिना retry से डबल सेंड हो सकता है
429 Too Many RequestsAPI ने गति नियंत्रण के कारण कॉल अस्वीकार कीतुरंत retry करने से दबाव और बढ़ता है
API या gateway से 5xxआमतौर पर स्वीकार नहीं हुआ, पर गारंटी नहींकुछ मामलों में timeout जैसी ही अस्पष्टता
400 या 422 validation एरररिक्वेस्ट ही गलत हैहमेशा retry करने से क्षमता बर्बाद होती है और बग छिप जाता है
API कॉल के बाद worker क्रैशस्वीकार हो गया, पर आपने रिकॉर्ड नहीं कियाजॉब दोबारा डिलीवर होती है और ईमेल फिर से भेजा जाता है

Idempotency keys और डुप्लिकेट-सेंड की रोकथाम

एक idempotent ऑपरेशन चाहे जितनी बार करें, वही परिणाम देता है। कई HTTP API आपको idempotency key देने देते हैं, आमतौर पर header में, ताकि उसी key वाली दोहराई गई रिक्वेस्ट नया रिसोर्स बनाने के बजाय मूल परिणाम लौटाए। IETF के पास Idempotency-Key header field के मानक के लिए एक सक्रिय ड्राफ़्ट है, जो दिखाता है कि यह विचार कितना व्यापक है। MigoSMTP ऐसे header को सपोर्ट करता है या नहीं, और key कितनी देर याद रखी जाती है, इसकी पुष्टि MigoSMTP API डॉक्यूमेंटेशन में करनी होगी। हम यहां इसे मानकर नहीं चलते।

अच्छी बात यह है कि आपको सर्वर सपोर्ट का इंतज़ार नहीं करना है। आप dedupe टेबल से अपनी ओर वही गारंटी बना सकते हैं। मुख्य विचार यह है कि आपकी एप्लिकेशन नेटवर्क से बात करने से पहले ही ईमेल की पहचान तय कर लेती है।

निर्धारक dedupe key चुनें

अच्छी key बिज़नेस इवेंट से बनती है, सेंड के समय जनरेट नहीं होती। order-1042-shipped या user-77-password-reset-2026-10-15T09:14 जैसा कुछ इस्तेमाल करें। worker के अंदर बनाया गया रैंडम UUID मदद नहीं करता, क्योंकि दोबारा डिलीवर हुई जॉब नया UUID बना देगी। संदेश का प्रकार शामिल करें ताकि एक ही ऑर्डर की रसीद और शिपिंग सूचना आपस में न टकराएं, और समय-बकेट या काउंटर केवल तब जोड़ें जब बार-बार भेजना वैध हो, जैसे दैनिक digest।

इसे unique constraint से लागू करें

"पहले देखो, फिर डालो" जैसी एप्लिकेशन जांचें race condition वाली होती हैं। key पर unique index लगाएं और टकराव का फ़ैसला डेटाबेस को करने दें। पहला लिखने वाला जीतता है और send रिकॉर्ड बनाता है। बाद का कोई भी प्रयास या तो constraint एरर पाता है या मौजूदा पंक्ति ढूंढकर उसकी स्थिति पढ़ता है।

CREATE TABLE email_sends (
  id            BIGINT PRIMARY KEY AUTO_INCREMENT,
  dedupe_key    VARCHAR(190) NOT NULL,
  to_address    VARCHAR(320) NOT NULL,
  template      VARCHAR(80)  NOT NULL,
  payload_json  JSON         NOT NULL,
  status        VARCHAR(20)  NOT NULL DEFAULT 'pending',
  attempts      INT          NOT NULL DEFAULT 0,
  next_try_at   DATETIME     NULL,
  message_id    VARCHAR(255) NULL,
  last_error    TEXT         NULL,
  created_at    DATETIME     NOT NULL,
  updated_at    DATETIME     NOT NULL,
  UNIQUE KEY uq_dedupe (dedupe_key)
);

हम जो स्थितियां इस्तेमाल करते हैं वे हैं pending, sending, accepted, failed और unknown। Accepted का मतलब है कि API ने सफलता लौटाई और आपने message ID सहेज ली। Unknown का मतलब है कि कॉल की गई थी और परिणाम निश्चित नहीं है, जिसे हम retry अनुभाग में देखेंगे। अगर API idempotency key सपोर्ट करता है, तो वही dedupe key वहां भी भेजें, ताकि दोनों परतें सहमत रहें। सर्वर-साइड सपोर्ट को दूसरा सुरक्षा जाल मानें, विकल्प नहीं।

Outbox पैटर्न: केवल वही भेजें जो कमिट हुआ हो

क्लासिक बग ऐसा दिखता है: आपका कोड ऑर्डर सहेजता है, फिर ईमेल API को कॉल करता है, फिर लौट जाता है। अगर API कॉल फ़ेल हो जाए, तो ऑर्डर मौजूद है पर ईमेल नहीं गया। अगर आप पहले API कॉल करें और डेटाबेस कमिट फ़ेल हो जाए, तो ग्राहक को ऐसे ऑर्डर की पुष्टि मिल जाती है जो मौजूद ही नहीं है। दो सिस्टम एक ट्रांज़ैक्शन में अपडेट नहीं हो सकते, इसलिए हम समस्या को ही बदल देते हैं।

Outbox पैटर्न में ईमेल रिक्वेस्ट बस एक और पंक्ति होती है जो बिज़नेस बदलाव वाले ट्रांज़ैक्शन में ही लिखी जाती है। या तो दोनों कमिट होते हैं या कोई नहीं। फिर एक अलग प्रोसेस outbox पंक्तियों को API तक पहुंचाती है। डिलीवरी एक retry योग्य बैकग्राउंड जॉब बन जाती है, और डेटाबेस इस बात का एकमात्र स्रोत बन जाता है कि क्या भेजा जाना है।

  1. ट्रांज़ैक्शन: ऑर्डर और email_sends पंक्ति को एक साथ, pending स्थिति के साथ डालें।
  2. कमिट: कमिट के बाद ही कुछ भी सेंडर प्रोसेस को दिखाई देता है।
  3. Claim: एक worker वे pending पंक्तियां चुनता है जिनका समय आ गया है और row locking का उपयोग करके उन्हें sending चिह्नित करता है, ताकि दो workers कभी एक ही पंक्ति न लें।
  4. API कॉल करें: रिक्वेस्ट भेजें, फिर परिणाम और message ID पंक्ति पर दर्ज करें।
  5. Reconcile: एक आवधिक जॉब sending या unknown में अटकी पंक्तियों को ढूंढकर सुलझाती है।

आप worker को हर कुछ सेकंड में टेबल poll करके फ़ीड कर सकते हैं, या कमिट के बाद queue में पब्लिश करके। Polling सरल है और इसमें कम हिस्से होते हैं। ज़्यादा वॉल्यूम पर queue मदद करती है, लेकिन टेबल को सच्चाई का रिकॉर्ड बनाए रखें, क्योंकि queues संदेश दोबारा डिलीवर या ड्रॉप कर सकती हैं और टेबल आपको पूछने देती है कि इस ईमेल का क्या हुआ।

आपके ऐप में Queueing: workers, concurrency और क्रम

जब तक कोई मज़बूत कारण न हो, वेब रिक्वेस्ट के अंदर ईमेल API को कॉल न करें। तब किसी भी थर्ड पार्टी का धीमा जवाब आपके धीमे चेकआउट में बदल जाता है, और साइन-अप में उछाल खुले कनेक्शनों में उछाल बन जाता है। outbox पंक्ति कमिट होते ही यूज़र को लौटा दें, और डिलीवरी बैकग्राउंड workers पर छोड़ दें।

  • Concurrency सीमित रखें। तय संख्या के workers, हर एक के पास छोटा HTTP connection pool, प्रति सेकंड रिक्वेस्ट की अनुमानित ऊपरी सीमा देते हैं। असीमित parallelism ही वह तरीका है जिससे ऐप अनजाने में API सीमा तक पहुंच जाता है।
  • Queues को urgency के अनुसार अलग करें। पासवर्ड रीसेट और one-time codes को कभी न्यूज़लेटर के पीछे इंतज़ार नहीं करना चाहिए। अलग queues या प्राथमिकताएं इस्तेमाल करें, जैसा ट्रांज़ैक्शनल और मार्केटिंग स्ट्रीम को अलग करने में बताया गया है।
  • जॉब्स को idempotent बनाएं। मानकर चलें कि हर जॉब दो बार डिलीवर हो सकती है। जॉब का पहला कदम पंक्ति लोड करना है, और अगर स्थिति पहले से accepted है तो बाहर निकल जाना है।
  • क्रम पर भरोसा न करें। Retries और parallel workers संदेशों का क्रम बदल देते हैं। अगर क्रम मायने रखता है, जैसे welcome से पहले verification, तो उसे queue के क्रम में नहीं, अपने डेटा में dependency के रूप में मॉडल करें।
  • पुराने मेल को expire करें। बीस मिनट बाद पहुंचा लॉगिन कोड न होने से भी बुरा है। समय-संवेदनशील पंक्तियों को expiry दें और भेजने के बजाय उन्हें expired चिह्नित करें।

Payload छोटे रखें। टेम्पलेट का नाम और वेरिएबल, या अंतिम रेंडर किया हुआ कंटेंट सहेजें, लेकिन queue संदेशों के अंदर बड़े attachments नहीं। सहेजी गई फ़ाइलों को ID से संदर्भित करें, जैसा हमारी size limits और MIME गाइड में बताई सीमाओं के अनुरूप हो।

Timeouts और retry वर्गीकरण

हर HTTP कॉल को स्पष्ट timeouts चाहिए। बिना timeout वाला क्लाइंट किसी इंसान की परवाह से कहीं ज़्यादा देर इंतज़ार करेगा, और पूरे समय worker स्लॉट को रोके रखेगा। छोटा connect timeout रखें, अक्सर एक या दो सेकंड, और ऐसा कुल timeout जो सामान्य जवाब के लिए पर्याप्त लंबा हो पर जल्दी फ़ेल होने के लिए पर्याप्त छोटा। मान अपनी मापी हुई latency और अपने MigoSMTP API डॉक्यूमेंटेशन के मार्गदर्शन से चुनें, किसी ब्लॉग पोस्ट की संख्या से नहीं।

कॉल खत्म होने पर परिणाम को तीन बकेट में से एक में रखें। यह वर्गीकरण इंटीग्रेशन का मूल है।

परिणामउदाहरणकार्रवाई
स्वीकृतmessage ID के साथ 2xxID सहेजें, accepted चिह्नित करें, रुक जाएं
निश्चित रूप से अस्वीकृत, retry न करें400, 401, 403, 404, 422, आपकी रिक्वेस्ट का वर्णन करने वाले अन्य 4xxfailed चिह्नित करें, एरर body दर्ज करें, दोहराव पर अलर्ट दें; कोड, क्रेडेंशियल या डेटा ठीक करें
बाद में retry करें, वही dedupe key429, 500, 502, 503, 504, connect एरर, DNS एररBack off करके retry करें; Retry-After का पालन करें
अज्ञात परिणामRead timeout, भेजने के बाद connection resetकेवल उसी dedupe key के साथ retry करें, या पहले reconcile करें

इन कोड के लिए HTTP semantics, जिनमें Retry-After header भी शामिल है, RFC 9110 में परिभाषित हैं, और RFC 6585 429 को परिभाषित करता है। SMTP से अंतर पर ध्यान दें। SMTP में 4xx उत्तर अस्थायी और 5xx स्थायी होते हैं, जिसे हम SMTP bounce codes की अपनी गाइड में बताते हैं। HTTP API में भूमिकाएं अलग हैं: 5xx का मतलब सर्विस में समस्या थी और 4xx का मतलब आपकी रिक्वेस्ट में समस्या थी। दोनों मॉडल को न मिलाएं। HTTP 400 कभी अस्थायी मेल फ़ेल्योर नहीं होता।

Jitter के साथ Backoff

Retry की देरी exponential रूप से बढ़नी चाहिए और उसमें यादृच्छिकता होनी चाहिए, ताकि एक साथ फ़ेल हुए हज़ार workers एक साथ वापस न आएं। एक सामान्य तरीका है आधार देरी को हर प्रयास पर दोगुना करना, अधिकतम सीमा तक, और उस पर एक रैंडम अंश लगाना। अगर response में Retry-After हो, तो उसे न्यूनतम मानें। प्रयासों की अधिकतम संख्या या अधिकतम उम्र तय करें, जिसके बाद पंक्ति failed में चली जाए और अलर्ट उठाए। रणनीति पर और गहराई से जानने के लिए हमारी rate limits, retries और backoff गाइड देखें।

import random, time

RETRY_STATUS = {429, 500, 502, 503, 504}

def next_delay(attempt, retry_after=None, base=2.0, cap=300.0):
    delay = min(cap, base * (2 ** attempt))
    delay = random.uniform(delay / 2, delay)
    if retry_after is not None:
        delay = max(delay, float(retry_after))
    return delay

def deliver(row, client):
    try:
        resp = client.post("/send", json=row.payload,
                           headers={"X-Dedupe-Key": row.dedupe_key},
                           timeout=(2, 15))
    except (ConnectionError, TimeoutError):
        return ("retry", next_delay(row.attempts))
    if 200 <= resp.status_code < 300:
        return ("accepted", resp.json().get("id"))
    if resp.status_code in RETRY_STATUS:
        ra = resp.headers.get("Retry-After")
        return ("retry", next_delay(row.attempts, ra))
    return ("failed", resp.text[:500])

इस उदाहरण में header का नाम समझाने के लिए गढ़ा गया है। MigoSMTP API डॉक्यूमेंटेशन में जो बताया गया है वही इस्तेमाल करें, या अगर ऐसा कोई header नहीं है तो केवल अपनी टेबल पर निर्भर रहें।

Response हैंडलिंग और message ID सहेजना

सफलता का response कहानी का अंत नहीं, ट्रैकिंग की शुरुआत है। response से मिली message ID को तुरंत अपने send रिकॉर्ड पर सहेजें, उसी कदम में जिसमें पंक्ति को accepted चिह्नित करते हैं। तब delivery, bounce और complaint के webhook इवेंट उससे जोड़े जा सकते हैं। उस दूसरे हिस्से की विश्वसनीयता ईमेल webhooks को भरोसेमंद ढंग से संभालने में बताई गई है।

  • कच्चे API response body को थोड़े समय तक रखें। डिबगिंग में यह अमूल्य है।
  • created, पहला प्रयास, accepted और आखिरी इवेंट के timestamps दर्ज करें। इनके बीच के अंतर बताते हैं कि देरी कहां होती है।
  • समझें कि accepted का क्या मतलब है। ईमेल API से 2xx response का आमतौर पर मतलब होता है कि सर्विस ने संदेश को डिलीवरी के लिए queue में रखा, यह नहीं कि प्राप्तकर्ता के सर्वर ने उसे स्वीकार किया। अंतिम डिलीवरी बाद में इवेंट से बताई जाती है।
  • एरर संदेशों को लॉजिक की तरह parse न करें। स्टेटस कोड और किसी भी डॉक्यूमेंटेड एरर कोड का उपयोग करें, और फ्री टेक्स्ट को इंसानों के लिए जानकारी मानें।
  • message ID कॉलम को index करें ताकि सपोर्ट लॉग की ID से एक ही क्वेरी में ग्राहक रिकॉर्ड तक पहुंच सके।

लॉग में secrets और व्यक्तिगत डेटा को redact करें। dedupe key, send ID, स्थिति और message ID लॉग करें, लेकिन API keys या पूरे संदेश body नहीं। Keys को API key security में बताए अनुसार सहेजें और rotate करें।

Batching और bulk sends

कई प्राप्तकर्ताओं को भेजना एक रसीद भेजने से अलग वर्कलोड है। अब आप throughput, मेमोरी और अन्य ट्रैफ़िक के प्रति निष्पक्षता संभाल रहे हैं। कुछ ईमेल API एक batch endpoint देते हैं जो एक रिक्वेस्ट में कई संदेश लेता है, जबकि अन्य प्रति रिक्वेस्ट एक संदेश चाहते हैं और कई concurrent कॉल की अपेक्षा रखते हैं। किसी एक पर डिज़ाइन बनाने से पहले, क्या उपलब्ध है और प्रति-रिक्वेस्ट प्राप्तकर्ता सीमाएं क्या हैं, इसके लिए अपना MigoSMTP अकाउंट या API डॉक्यूमेंटेशन देखें।

  • ऑडियंस को chunks में बांटें। प्राप्तकर्ताओं को डेटाबेस से पेजों में पढ़ें, मेमोरी में एक विशाल सूची के रूप में नहीं। प्रति प्राप्तकर्ता send पंक्तियां बनाएं, फिर workers को उन्हें प्रोसेस करने दें।
  • प्रति प्राप्तकर्ता वैयक्तिकरण करें। To या Cc में कई प्राप्तकर्ता रखने से बचें। हर व्यक्ति को अपना संदेश मिलना चाहिए, अपने unsubscribe लिंक और ट्रैकिंग डेटा के साथ।
  • सेंड की गति नियंत्रित करें। बड़े कैंपेन को सब कुछ एक साथ छोड़ने के बजाय एक समय-खिड़की में फैलाएं। गति नियंत्रण आपकी प्रतिष्ठा की भी रक्षा करता है, खासकर नए डोमेन पर, जैसा warm-up गाइड में बताया गया है।
  • कैंपेन को फिर से शुरू करने योग्य बनाएं। क्योंकि हर प्राप्तकर्ता की एक पंक्ति होती है जिसकी unique dedupe key होती है, जैसे campaign-318-user-9001, आप किसी भी बिंदु पर सेंड को रोककर दोबारा शुरू कर सकते हैं और डबल सेंड नहीं होगा।
  • आंशिक विफलता संभालें। अगर batch कॉल कुछ संदेशों के लिए सफल और अन्य के लिए विफल हो सकती है, तो प्रति-संदेश परिणाम सहेजें। एक स्टेटस कोड के आधार पर पूरे batch को accepted या failed कभी चिह्नित न करें, जब तक डॉक्यूमेंटेशन न कहे कि यह ऐसे ही काम करता है।

सूची की बुनियादी बातें न छोड़ें: API से bulk sending सहमति, suppression और unsubscribe के नियम नहीं बदलती। हमारी suppression list गाइड के तरीके से, send पंक्तियां बनाने से पहले suppressed पते फ़िल्टर करें।

उदाहरण: एक आउटेज, दो डिज़ाइन

यहां गोल संख्याओं वाला एक काल्पनिक उदाहरण है। एक ऑनलाइन दुकान हर ऑर्डर के लिए ऑर्डर पुष्टि भेजती है। एक व्यस्त दोपहर में वह एक घंटे में 6,000 ऑर्डर बनाती है, और ईमेल API में 4 मिनट तक धीमे जवाब और बीच-बीच में 503 एरर आते हैं।

चरणसीधा-सादा डिज़ाइनdedupe key के साथ Outbox
ऑर्डर बनारिक्वेस्ट सीधे API को कॉल करती हैरिक्वेस्ट ऑर्डर और send पंक्ति लिखती है, तुरंत लौट जाती है
4 मिनट तक धीमा APIचेकआउट लंबे timeout पर इंतज़ार करता है, कुछ ग्राहकों को एरर दिखते हैं और वे फिर Pay पर क्लिक करते हैंचेकआउट अप्रभावित; पंक्तियां pending में इंतज़ार करती हैं
150 कॉल पर timeoutकोड तुरंत retry करता है; उनमें से कई संदेश पहले ही स्वीकार हो चुके थेपंक्तियां unknown चिह्नित; बाद में उसी dedupe key से retry
परिणाम150 ऑर्डर पर लगभग 2-2 पुष्टि, साथ में डबल क्लिक से डुप्लिकेट ऑर्डरलगभग 150 संदेश कुछ मिनट देर से; शून्य डुप्लिकेट
सपोर्ट पर असरदर्जनों टिकट कि कौन सा ईमेल सही हैकोई नहीं; queue age अलर्ट बजा और शांत हो गया

घंटे में 6,000 ऑर्डर के साथ औसत 100 प्रति मिनट है, इसलिए 4 मिनट की सुस्ती लगभग 400 पंक्तियों का बैकलॉग छोड़ती है। अगर API ठीक होने पर workers 300 प्रति मिनट भेज सकते हैं, तो बैकलॉग लगभग 2 मिनट में साफ़ हो जाता है (400 पंक्तियां भाग 200 प्रति मिनट, जो नए आगमन के 100 प्रति मिनट के ऊपर की अतिरिक्त क्षमता है)। यह गणित अपने सिस्टम के लिए करना सार्थक है: आपके workers की अतिरिक्त क्षमता तय करती है कि आप कितनी जल्दी उबरते हैं, और concurrency की सीमा तय करती है कि रिकवरी आपके अकाउंट की सीमाओं के भीतर रहती है या नहीं।

Rate-limit की जानकारी

Rate limits कई रूपों में आती हैं, जैसे प्रति सेकंड रिक्वेस्ट, प्रति दिन संदेश, concurrent कनेक्शन और प्रति रिक्वेस्ट प्राप्तकर्ता। आपके अकाउंट पर कौन सी लागू हैं और उनके सटीक मान क्या हैं, यह आपके MigoSMTP अकाउंट या API डॉक्यूमेंटेशन में है। अंदाज़ा न लगाएं। अपना क्लाइंट ऐसे बनाएं कि ये संख्याएं कॉन्फ़िगरेशन हों, कोड में स्थिरांक नहीं।

  • हर worker में token bucket या रिक्वेस्ट के बीच तय देरी का उपयोग करें, और सभी workers पर एक ग्लोबल सीमा रखें।
  • 429 पर, उस worker से Retry-After अवधि तक सेंडिंग रोकें, या अगर कोई न दी गई हो तो backoff देरी तक। वही कॉल बस दोबारा न करें।
  • धीमी सफलता पर नज़र रखें। बढ़ती latency अक्सर एरर से पहले आती है, और यह concurrency घटाने का संकेत है।
  • circuit breaker इस्तेमाल करें। लगातार विफलताओं के बाद थोड़ी देर कॉल रोकें, फिर पूरी गति पर लौटने से पहले एक रिक्वेस्ट से जांचें।
  • प्राप्त करने वाले पक्ष की सीमाओं का ध्यान रखें। प्रोवाइडर द्वारा स्वीकार करना केवल पहला पड़ाव है। मेलबॉक्स प्रोवाइडर अपनी सीमाएं लगाते हैं, जो हमारी bulk sender requirements गाइड में बताई गई हैं।

API बंद होने पर Graceful degradation

कोई भी बाहरी सर्विस कभी न कभी अनुपलब्ध होगी। पहले से तय करें कि आपका प्रोडक्ट क्या करेगा, ताकि जवाब आउटेज के दौरान तुक्के से न बने।

ईमेल का प्रकारआउटेज के दौरान सुझाया गया व्यवहार
पासवर्ड रीसेट, one-time codeछोटी expiry के साथ queue करें; स्क्रीन पर दिखाएं कि संदेश में देरी हो सकती है और cool-down के बाद दोबारा भेजने का विकल्प दें
ऑर्डर या भुगतान पुष्टिQueue करें और देर से डिलीवर करें; पुष्टि ऑर्डर पेज पर भी दिखाएं
अकाउंट सूचनाएंQueue करें और देर से डिलीवर करें; कई को एक में मिलाने पर विचार करें
न्यूज़लेटर और कैंपेनकैंपेन रोकें और बाद में दोबारा शुरू करें; पकड़ने की जल्दी कभी न करें
इंटरनल अलर्टचैट या दूसरे प्रोवाइडर जैसे किसी अन्य चैनल पर fallback करें

केवल एरर काउंट पर नहीं, queue depth और सबसे पुरानी pending पंक्ति की उम्र पर अलर्ट लगाएं। बिना एरर के बढ़ती queue का भी मतलब है कि ग्राहक इंतज़ार कर रहे हैं। queue पर एक सीमा रखें ताकि मेमोरी और स्टोरेज असीमित न बढ़ें, और तय करें कि सीमा पर पहुंचने पर पहले क्या छोड़ा जाएगा। अगर आप fallback के रूप में दूसरा प्रोवाइडर डिज़ाइन करते हैं, तो दूसरे पाथ को warm up और authenticate करने का काम याद रखें, जैसा हमारी migration गाइड में बताया गया है।

इंटीग्रेशन की टेस्टिंग

जो टेस्ट केवल 200 response जांचते हैं, वे आपकी रक्षा नहीं करेंगे। असली महत्व इसका है कि फ़ेल्योर पर क्या होता है, इसलिए फ़ेल्योर पैदा करना आसान बनाएं। अपने क्लाइंट को ऐसे mock सर्वर या sandbox के विरुद्ध चलाएं जिसे धीरे जवाब देने, Retry-After के साथ 429 लौटाने, 503 लौटाने, रिक्वेस्ट पढ़ने के बाद कनेक्शन गिराने या विकृत body लौटाने को कहा जा सके। कंटेंट जांच के लिए mail catcher का उपयोग करें, हमारी staging environment गाइड के अनुसार।

  • डुप्लिकेट जॉब टेस्ट: वही जॉब दो बार enqueue करें और पुष्टि करें कि mock API तक केवल एक रिक्वेस्ट पहुंची।
  • क्रैश टेस्ट: API कॉल के बाद और डेटाबेस अपडेट से पहले worker को kill करें, फिर पुष्टि करें कि reconciler दूसरा सेंड किए बिना पंक्ति को सुलझा देता है।
  • Timeout टेस्ट: mock से रिक्वेस्ट स्वीकार करवाएं और फिर रुकवाएं, और जांचें कि पंक्ति ठीक एक बार accepted के रूप में खत्म होती है।
  • Poison message टेस्ट: ऐसा payload भेजें जो 422 लौटाए और पुष्टि करें कि वह एक प्रयास के बाद, एरर सहेजकर, failed में चला जाता है।
  • Load टेस्ट: staging पर यथार्थवादी burst चलाएं और पुष्टि करें कि concurrency सीमाएं और backoff डिज़ाइन के अनुसार काम करते हैं।

लॉन्च-पूर्व चेकलिस्ट

  • हर ईमेल की एक निर्धारक dedupe key है और unique index उसे लागू करता है।
  • Send पंक्तियां बिज़नेस इवेंट वाले ही ट्रांज़ैक्शन में लिखी जाती हैं (outbox)।
  • Idempotency header सपोर्ट की पुष्टि MigoSMTP API डॉक्यूमेंटेशन में हो चुकी है, और हमारी अपनी टेबल फिर भी इस्तेमाल होती है।
  • API को वेब रिक्वेस्ट नहीं, workers कॉल करते हैं, सीमित concurrency के साथ।
  • हर कॉल पर connect और कुल timeouts सेट हैं।
  • Responses वर्गीकृत हैं: accepted, retry, failed, unknown। अन्य 4xx responses पर कभी अंधाधुंध retry नहीं होता।
  • Backoff में jitter, सीमा और अधिकतम प्रयास संख्या है और वह Retry-After का पालन करता है।
  • Message IDs send पंक्तियों पर सहेजी गई हैं और index की गई हैं।
  • Bulk sends chunked, गति-नियंत्रित और फिर से शुरू करने योग्य हैं, और पंक्तियां बनाने से पहले suppression फ़िल्टरिंग होती है।
  • Rate limits कॉन्फ़िगरेशन हैं, जो आपके अकाउंट या API डॉक्यूमेंटेशन से ली गई हैं।
  • सबसे पुरानी pending पंक्ति की उम्र, failed संख्या और 429 दर पर अलर्ट मौजूद हैं।
  • डुप्लिकेट, क्रैश, timeouts और 429 के लिए फ़ेल्योर टेस्ट staging में पास होते हैं।

अपने सेंडिंग डिज़ाइन पर दूसरी नज़र चाहिए? हमें बताएं कि आपकी एप्लिकेशन आज ईमेल कैसे भेजती है और retries या डुप्लिकेट को लेकर आपको कहां चिंता है, और हम एक सुरक्षित इंटीग्रेशन की योजना बनाने में आपकी मदद करेंगे।

सपोर्ट से संपर्क करें

आगे पढ़ें और स्रोत

अक्सर पूछे जाने वाले प्रश्न

Email API के लिए idempotency key क्या है?

यह एक यूनिक वैल्यू है जिसे आप रिक्वेस्ट के साथ जोड़ते हैं, ताकि सर्वर उसी रिक्वेस्ट के दोहराव को पहचान सके और काम को दो बार न करे। ईमेल के मामले में इसका मतलब है कि timeout के बाद किया गया retry संदेश की दूसरी कॉपी नहीं बनाता। MigoSMTP idempotency header को सपोर्ट करता है या नहीं, और कैसे, यह MigoSMTP API डॉक्यूमेंटेशन में पुष्टि करना ज़रूरी है। किसी भी स्थिति में, आप अपनी dedupe टेबल से वही सुरक्षा पा सकते हैं।

अगर API idempotency सपोर्ट करता है, तो क्या फिर भी मुझे अपनी dedupe टेबल चाहिए?

हां, हम इसकी सलाह देते हैं। सर्वर-साइड idempotency आमतौर पर सीमित अवधि और केवल उन रिक्वेस्ट को कवर करती है जो API तक पहुंचती हैं। आपकी अपनी टेबल डुप्लिकेट जॉब, डुप्लिकेट webhook ट्रिगर और अपस्ट्रीम में डबल क्लिक को भी रोकती है, और यह भी रिकॉर्ड देती है कि आपने क्या भेजने का इरादा किया था।

क्या timeout के बाद retry करना सुरक्षित है?

केवल तभी जब आपके पास dedupe रणनीति हो। timeout का मतलब है कि आपको पता नहीं कि API ने संदेश स्वीकार किया या नहीं। idempotency key या अपने रेफ़रेंस से लुकअप के बिना, retry से ईमेल दो बार जा सकता है। इनके साथ retry सुरक्षित है।

कौन से HTTP स्टेटस कोड पर retry करना चाहिए?

नेटवर्क फ़ेल्योर, timeout, 429 Too Many Requests और 5xx सर्वर एरर पर retry करें, exponential backoff और jitter के साथ और किसी भी Retry-After header का सम्मान करते हुए। 400, 401, 403 या 422 जैसे अन्य 4xx एरर पर retry न करें, क्योंकि जब तक आप कुछ बदलते नहीं, वही रिक्वेस्ट उसी तरह फ़ेल होगी।

Outbox पैटर्न क्या है?

आप ईमेल रिक्वेस्ट को उसी डेटाबेस ट्रांज़ैक्शन में एक टेबल में लिखते हैं जिसमें बिज़नेस बदलाव होता है, फिर एक अलग प्रोसेस न भेजी गई पंक्तियों को पढ़कर API को कॉल करता है। इससे वह अंतर खत्म हो जाता है जिसमें डेटाबेस कमिट सफल हो जाता है पर ईमेल कॉल फ़ेल हो जाती है, या इसका उल्टा।

क्या मुझे वेब रिक्वेस्ट से ईमेल भेजना चाहिए या queue से?

लगभग हर चीज़ के लिए queue से। queue यूज़र-फेसिंग latency की रक्षा करती है, सुरक्षित retry देती है और आपको रेट कंट्रोल करने देती है। अपवाद एक बहुत सरल इंटरनल टूल है जहां फ़ेल हुए सेंड को सीधे ट्रिगर करने वाले व्यक्ति को दिखाया जा सकता है।

मैं API से बड़ा कैंपेन कैसे भेजूं?

प्राप्तकर्ताओं को batches में बांटें, concurrency सीमित रखें, डॉक्यूमेंटेड सीमाओं और Retry-After का पालन करें, और सेंडिंग को समय में फैलाएं। सटीक सीमाओं और batch endpoint है या नहीं, इसके लिए अपना MigoSMTP अकाउंट या API डॉक्यूमेंटेशन देखें। नए डोमेन या IP के लिए warm-up प्लान भी अपनाएं।

API द्वारा लौटाया गया message ID क्यों सहेजना चाहिए?

यह आपके सेंड रिकॉर्ड और बाद के इवेंट, जैसे delivery, bounce और complaint webhooks, के बीच जोड़ने वाली कुंजी है। इसके बिना, "क्या इस ग्राहक को रसीद मिली" जैसे सपोर्ट सवाल अंदाज़े का खेल बन जाते हैं।

असली मेल भेजे बिना ईमेल इंटीग्रेशन को कैसे टेस्ट करूं?

API क्लाइंट को ऐसे mock सर्वर या sandbox के विरुद्ध चलाएं जो मांग पर धीमे जवाब, 429 और 5xx लौटा सके, और कंटेंट जांच के लिए mail catcher का उपयोग करें। केवल HTTP कॉल पर नहीं, अपनी send टेबल पर assert करें। हमारी staging गाइड में सुरक्षित सेटअप बताए गए हैं।

टॉपिक#email api#idempotency#outbox pattern#retries#backoff#bulk sending#batching#queue#message id#rate limits#timeouts#डुप्लिकेट ईमेल#ट्रांजैक्शनल ईमेल#इंटीग्रेशन टेस्टिंग
क्या यह गाइड उपयोगी थी?आपका उत्तर हमें हमारे डॉक्यूमेंटेशन को बेहतर बनाने में मदद करता है।

आगे पढ़ें

SMTP और APIAPI कुंजी सुरक्षा: अनुमतियां, स्टोरेज, रोटेशन और लीक पर प्रतिक्रियालीक हुई ईमेल API कुंजी या SMTP क्रेडेंशियल से मिनटों में आपके नाम पर स्पैम भेजा जा सकता है, जिससे आपके डोमेन और IP की प्रतिष्ठा को नुकसान पहुंचता है। यह गाइड दिखाती है कि हर कुंजी को केवल उतनी ही अनुमतियां कैसे दें जितनी उसे चाहिए, उसे कहां स्टोर करें, बिना डाउनटाइम के रोटेट कैसे करें और लीक के बाद पहले घंटे में क्या करें।गाइड पढ़ें →डिलीवरेबिलिटीईमेल डिलीवरेबिलिटी इंसिडेंट रनबुक: अचानक गिरावट पर कैसे प्रतिक्रिया देंजब डिलीवरी अचानक गिर जाती है, तो पहला घंटा तय करता है कि नुकसान कितना होगा। यह रनबुक हमें 30 मिनट की ट्रायाज योजना, लक्षण से कारण तक की निर्णय तालिका, जुटाए जाने वाले साक्ष्य, नियंत्रण और रिकवरी के चरण, हितधारकों और सपोर्ट के लिए संदेश टेम्पलेट, पोस्ट-इंसिडेंट रिव्यू का प्रारूप, और आपके अपने ट्रैफ़िक के अनुसार ट्यून करने के लिए उदाहरण गार्डरेल और अलर्ट थ्रेशोल्ड देता है।गाइड पढ़ें →डोमेन और DNSईमेल के लिए DNS रिकॉर्ड ट्रबलशूटिंग: TXT की लंबाई, TTL, प्रोपेगेशन और रजिस्ट्रार की खामियाँईमेल ऑथेंटिकेशन की ज़्यादातर विफलताएँ उस रिकॉर्ड की गलती नहीं होतीं जिसे आप प्रकाशित करना चाहते थे। वे इस बात की बारीकियाँ होती हैं कि DNS पैनल उसे कैसे स्टोर करता है: लंबी DKIM कुंजी जो विभाजित नहीं की गई, डोमेन नाम का दो बार जुड़ जाना, वैल्यू में चिपके हुए कोट्स, दूसरा SPF रिकॉर्ड, चालू किया हुआ प्रॉक्सी, या कैश में पड़ा पुराना उत्तर। यह गाइड बताती है कि इनमें से हर समस्या को कैसे पहचानें और ठीक करें।गाइड पढ़ें →

मिनटों में भेजना शुरू करें।

खाता बनाएँ, अपना डोमेन जोड़ें और पहला ईमेल भेजें।

मुफ़्त शुरू करें सेल्स से बात करें