ईमेल डिलीवरी टेस्ट करें (mail sandbox)
Mail sandbox बिना किसी असली इनबॉक्स पर भेजे webhook हैंडलर, suppression लॉजिक और डिलीवरी परिणामों को टेस्ट करता है। सामान्य API के ज़रिए messagebird.dev पर किसी पते पर भेजें। Local part परिणाम तय करता है: bounce@messagebird.dev बाउंस करता है और delivered@messagebird.dev डिलीवर करता है।
Sandbox सेंड सामान्य acceptance, event और webhook पथों का उपयोग करता है। यह वही 202 रिस्पॉन्स लौटाता है और प्रति-प्राप्तकर्ता वही event पेलोड आकार उत्पन्न करता है जो प्रोडक्शन सेंड करता है। पेलोड में कोई test flag नहीं होता। संदेश बाहरी डिलीवरी इन्फ्रास्ट्रक्चर या किसी असली इनबॉक्स तक नहीं पहुँचता। सिम्युलेटेड बाउंस और complaints भेजने की प्रतिष्ठा को प्रभावित नहीं करते और न ही suppression list में लिखते हैं, इसलिए आप पतों का दोबारा उपयोग कर सकते हैं।
Sandbox को किसी सेटअप की ज़रूरत नहीं: कोई टॉगल नहीं, कोई test mode नहीं, कोई विशेष API key नहीं। यह पूरी तरह प्राप्तकर्ता पते पर ट्रिगर होता है, सामान्य send endpoints (POST /v1/email/messages और POST /v1/email/batches) पर और एक broadcast पर: ऑडियंस में जिस contact का पता sandbox पता है, उसे भेजने की बजाय सिम्युलेट किया जाता है, इसी तरह आप बिना किसी को मेल भेजे कैम्पेन का रिहर्सल करते हैं। सिम्युलेटेड प्राप्तकर्ता आपके send allowance में गिना जाता है, इसलिए रिहर्सल उसी कोटा का उपयोग करता है जो असली सेंड करता।
Magic addresses
सभी पते @messagebird.dev पर हैं। Local-part परिणाम चुनता है:
| पता | सिम्युलेटेड परिणाम | Webhook अनुक्रम | नोट्स |
|---|---|---|---|
| delivered@ | प्राप्तकर्ता मेल सर्वर संदेश स्वीकार करता है | email.accepted → email.processed → email.delivered | सामान्य सफल पथ |
| bounce@ / hardbounce@ | Hard bounce: SMTP 550, 5.1.1 Unknown User, bounce class 10 | email.accepted → email.processed → email.bounced with bounce_type: "hard" | Suppression list में कोई write नहीं, इसलिए पता दोबारा उपयोग योग्य रहता है |
| softbounce@ | Soft bounce: SMTP 451, 4.3.0 Temporary failure, please retry, class 20 | email.accepted → email.processed → email.bounced with bounce_type: "soft" | Soft bounces कभी suppress नहीं करते, असली हों या सिम्युलेटेड |
| deferred@ / delay@ | Deferral: SMTP 451, 4.2.1 Mailbox temporarily unavailable, will retry, class 21 | email.accepted → email.processed → email.deferred | सिम्युलेटेड deferral अंतिम है: कोई retry नहीं होता, इसलिए प्राप्तकर्ता deferred रहता है |
| complaint@ / spam@ | प्राप्तकर्ता संदेश को स्पैम रिपोर्ट करता है (feedback_type: "abuse") | email.accepted → email.processed → email.complained | कोई suppression write नहीं; दोबारा उपयोग योग्य |
| suppressed@ | प्राप्तकर्ता को आपकी suppression list में पहले से मौजूद माना जाता है | email.accepted → email.rejected with rejection_reason: "recipient_suppressed" | प्रोसेसिंग के दौरान ठीक वैसे ही शॉर्ट-सर्किट होता है जैसे असली suppressed प्राप्तकर्ता: कोई email.processed नहीं, कोई delivery events नहीं |
| reject@ | किसी भी delivery प्रयास से पहले संदेश अस्वीकार कर दिया जाता है | email.accepted → email.rejected with rejection_reason: "transmission_failed" | इसके बाद कोई email.processed या delivery events नहीं आते |
ऊपर दिए गए अनुक्रम वे webhooks हैं जो एक अकेला send उत्पन्न करता है। Broadcast पर, शुरुआती email.accepted हटा दें: broadcast प्राप्तकर्ता अपने आप स्वीकार होता है, लेकिन हम उस event को बिना webhook भेजे रिकॉर्ड करते हैं, इसलिए प्रत्येक अनुक्रम उसके बाद जो आता है वहाँ से शुरू होता है, delivery पथों पर email.processed और suppressed@ तथा reject@ के लिए email.rejected। उसके बाद सब कुछ समान है, और event reference इस नियम को पूरी तरह कवर करता है।
एक send में sandbox और असली प्राप्तकर्ताओं का मिश्रण हो सकता है। प्रत्येक प्राप्तकर्ता का अपना lifecycle होता है: असली प्राप्तकर्ता सामान्य रूप से डिलीवर होते हैं, sandbox प्राप्तकर्ता सिम्युलेट किए जाते हैं।
वही events संदेश की timeline पर email log में और events API में भी दिखते हैं, इसलिए आप बिना webhook endpoint के sandbox चला सकते हैं और परिणाम वापस पढ़ सकते हैं।
पता-संबंधी नियम
- डिटेक्शन केवल local-part से होता है, और केवल messagebird.dev डोमेन पर। bounce@yourdomain.com एक सामान्य पता है।
- केवल magic addresses तालिका में दिए गए local parts ही magic हैं। messagebird.dev पर कोई भी अन्य पता सामान्य प्राप्तकर्ता है। जब आप shared onboarding domain से भेजते हैं, तो वह पता किसी verified वर्कस्पेस सदस्य का होना चाहिए।
- मैचिंग case-insensitive है: Bounce@messagebird.dev और bounce@messagebird.dev समान व्यवहार करते हैं।
- +label subaddressing मैचिंग से पहले हटा दी जाती है: bounce+signup-flow@messagebird.dev फिर भी बाउंस करता है। टेस्ट केस को सहसंबंधित करने के लिए लेबल का उपयोग करें; पूरा पता, लेबल सहित, आपके events और webhooks में दिखता है, इसलिए प्रत्येक टेस्ट रन अपने प्राप्तकर्ताओं को टैग कर सकता है।
वॉकथ्रू: एक bounce सिम्युलेट करें, शुरू से अंत तक
आपको verified sending domain की ज़रूरत नहीं। onboarding@messagebird.dev से भेजें, जैसा अपना पहला ईमेल भेजें में बताया गया है। मान्यता-प्राप्त sandbox पते onboarding domain की verified-member प्रतिबंध से छूट प्राप्त हैं, लेकिन फिर भी इसके दैनिक कोटा में गिने जाते हैं।
सुनिश्चित करें कि आपके पास email events के लिए सब्सक्राइब किया हुआ webhook endpoint है (देखें Webhooks), फिर भेजें:
const msg = await bird.email.send({
from: { email: "onboarding@messagebird.dev", name: "Bird" },
to: ["bounce+signup-flow@messagebird.dev"],
subject: "Sandbox bounce test",
html: "<p>This message will hard-bounce.</p>",
tags: [{ name: "flow", value: "signup" }],
metadata: { test_run: "docs-capture-1" },
});
console.log(msg.id, msg.status); // "em_…", "accepted"msg = client.email.send(
from_={"email": "onboarding@messagebird.dev", "name": "Bird"},
to=["bounce+signup-flow@messagebird.dev"],
subject="Sandbox bounce test",
html="<p>This message will hard-bounce.</p>",
tags=[{"name": "flow", "value": "signup"}],
metadata={"test_run": "docs-capture-1"},
)
print(msg.id, msg.status)package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
msg, err := client.Email.Send(context.Background(), bird.EmailSendParams{
From: "onboarding@messagebird.dev",
To: []string{"bounce+signup-flow@messagebird.dev"},
Subject: "Sandbox bounce test",
HTML: "<p>This message will hard-bounce.</p>",
Tags: []bird.Tag{{Name: "flow", Value: "signup"}},
Metadata: map[string]any{"test_run": "docs-capture-1"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}$message = $bird->email->send(
from: 'Bird <onboarding@messagebird.dev>',
to: ['bounce+signup-flow@messagebird.dev'],
subject: 'Sandbox bounce test',
html: '<p>This message will hard-bounce.</p>',
);
echo $message->getId(), ' ', $message->getStatus();bird email send \
--from onboarding@messagebird.dev \
--html '<p>This message will hard-bounce.</p>' \
--metadata '{"test_run":"docs-capture-1"}' \
--subject 'Sandbox bounce test' \
--tag flow=signup \
--to bounce+signup-flow@messagebird.devcurl -X POST "https://us1.platform.bird.com/v1/email/messages" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "onboarding@messagebird.dev",
"to": ["bounce+signup-flow@messagebird.dev"],
"subject": "Sandbox bounce test",
"html": "<p>This message will hard-bounce.</p>",
"tags": [{ "name": "flow", "value": "signup" }],
"metadata": { "test_run": "docs-capture-1" }
}'यदि आपकी key bk_eu1_ से शुरू होती है, तो इसके बजाय https://eu1.platform.bird.com कॉल करें।
API एक em_* message ID के साथ 202 Accepted रिस्पॉन्स देता है, जो प्रोडक्शन send से अलग नहीं पहचाना जा सकता। यही मुख्य बात है: जो code path आप टेस्ट कर रहे हैं वह आपका असली path है। इसके बाद आपका webhook endpoint email.accepted, email.processed, और अंत में email.bounced प्राप्त करता है। हर event send के tags और metadata (null जब send में कोई नहीं था) को echo करता है, और email.bounced पेलोड में पूरा bounce classification होता है:
कोड उदाहरण
{
"type": "email.bounced",
"timestamp": "2026-07-23T14:51:00.362Z",
"data": {
"email_id": "em_01ky7qanhrejer0bn34v38hrxh",
"recipient_id": "er_01ky7qanhrejds4decpk83q5qq",
"workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf",
"recipient": "bounce+signup-flow@messagebird.dev",
"recipient_role": "to",
"bounce_type": "hard",
"bounce_class": 10,
"bounce_code": "550",
"bounce_description": "5.1.1 Unknown User",
"sending_ip": null,
"tags": [{ "name": "flow", "value": "signup" }],
"metadata": { "test_run": "docs-capture-1" },
"broadcast_id": null
}
}फ़ील्ड के अर्थ events reference में हैं। पेलोड में कहीं भी कोई simulator flag नहीं दिखता: event type और आकार ठीक वही है जो एक असली hard bounce उत्पन्न करता है। इसे सिम्युलेटेड के रूप में पहचानने वाली एकमात्र चीज़ प्राप्तकर्ता पता ही है, इसलिए यदि आपके handler को test traffic को अलग से संभालना है, तो messagebird.dev प्राप्तकर्ता डोमेन पर key करें।
यह सत्यापित करने के लिए कि पहले से suppressed प्राप्तकर्ता को कभी नहीं भेजा जाता, suppressed@messagebird.dev के साथ send दोहराएँ। Assert करें कि आपको email.accepted मिलता है, फिर rejection_reason: "recipient_suppressed" के साथ email.rejected। आपको कोई email.processed या delivery events नहीं मिलने चाहिए। यह एक असली suppressed प्राप्तकर्ता का बिल्कुल सटीक प्रतिबिंब है: संदेश स्वीकार होता है, फिर किसी भी send से पहले प्रोसेसिंग के दौरान शॉर्ट-सर्किट हो जाता है।
Sandbox क्या करता है और क्या नहीं करता
- Suppression list में कोई write नहीं। सिम्युलेटेड hard bounces और complaints प्राप्तकर्ता को आपकी suppression list में नहीं जोड़ते; यही वह बात है जो पतों को दोबारा उपयोग योग्य बनाती है। आपका webhook फिर भी फ़ायर होता है (email.bounced, email.complained), इसलिए आपका अपना suppression लॉजिक पूरी तरह अभ्यासित होता है। पहले से suppressed rejection path टेस्ट करने के लिए, समर्पित suppressed@ पते का उपयोग करें।
- कभी कोई असली डिलीवरी नहीं। Sandbox प्राप्तकर्ताओं को संदेश के delivery infrastructure तक पहुँचने से पहले इंटरसेप्ट कर लिया जाता है। कुछ भी ट्रांसमिट नहीं होता, कोई इनबॉक्स शामिल नहीं, और आपकी भेजने की प्रतिष्ठा अप्रभावित रहती है।
- Request validation फिर भी लागू होता है। Sandbox send सामान्य endpoints का उपयोग करता है, इसलिए schema checks, size caps और हेडर नियम किसी अमान्य request को हमेशा की तरह अस्वीकार करते हैं। Sandbox जो छोड़ता है वह handoff के बाद का सब कुछ है: उस बिंदु के बाद rendering और delivery व्यवहार अभ्यासित नहीं होते।
- Opens और clicks सिम्युलेट नहीं होते। Magic address ट्रांसमिशन परिणाम सिम्युलेट करता है, और कोई संदेश नहीं खोलता, इसलिए email.opened और email.clicked केवल असली मेल से आते हैं।
- Stats में sandbox ट्रैफ़िक शामिल होता है। Sandbox sends आपके वर्कस्पेस के समग्र stats और bounce तथा complaint दरों में गिने जाते हैं। भारी sandbox bouncing आपके dashboards को विषम करता है जबकि आपकी प्रतिष्ठा अपरिवर्तित रहती है।
अगले कदम
- Events: पूर्ण event शब्दावली और प्रति-प्राप्तकर्ता lifecycle
- Webhooks: सब्सक्राइब करना, signature verification, और retries
- अपना पहला ईमेल भेजें: onboarding-domain quickstart जिस पर यह वॉकथ्रू बना है
- Suppressions: असली suppression list कैसे काम करती है
- बिना किसी को स्पैम किए ईमेल टेस्ट करना: एक वीडियो जो sandbox पतों और हर एक द्वारा उत्पन्न events को दिखाता है
संबंधित संसाधन
इस विषय के लिए डॉक्यूमेंटेशन, गाइड और उदाहरणों के साथ आगे बढ़ें। संसाधन अंग्रेज़ी में हैं।