ईमेल भेजना
POST /v1/email/messages एक ईमेल भेजता है। JSON पेलोड में sender, recipients और content दें। API एक message ID के साथ 202 Accepted लौटाता है, फिर ईमेल को asynchronously डिलीवर करता है। पूरे schemas के लिए API रेफ़रेंस देखें।
न्यूनतम send
सबसे छोटा मान्य पेलोड एक from, कम से कम एक to recipient, एक subject, और एक body (html, text, या दोनों) है। from पता इस वर्कस्पेस में आपके verified डोमेन पर या onboarding डोमेन पर होना चाहिए।
const msg = await bird.email.send({
from: { email: "onboarding@messagebird.dev", name: "Bird" },
to: ["delivered@messagebird.dev"],
subject: "Hello from Bird",
html: "<p>My first Bird email.</p>",
});
console.log(msg.id, msg.status); // "em_…", "accepted"msg = client.email.send(
from_={"email": "onboarding@messagebird.dev", "name": "Bird"},
to=["delivered@messagebird.dev"],
subject="Hello from Bird",
html="<p>My first Bird email.</p>",
)
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{"delivered@messagebird.dev"},
Subject: "Hello from Bird",
HTML: "<p>My first Bird email.</p>",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}$message = $bird->email->send(
from: 'Bird <onboarding@messagebird.dev>',
to: ['delivered@messagebird.dev'],
subject: 'Hello from Bird',
html: '<p>My first Bird email.</p>',
);
echo $message->getId(), ' ', $message->getStatus();bird email send \
--from hello@yourdomain.com \
--html '<p>It works.</p>' \
--subject 'Hello from Bird' \
--to delivered@messagebird.devcurl -X POST https://us1.platform.bird.com/v1/email/messages \
-H "Authorization: Bearer bk_us1_..." \
-H "Content-Type: application/json" \
-d '{
"from": "hello@yourdomain.com",
"to": ["delivered@messagebird.dev"],
"subject": "Hello from Bird",
"html": "<p>It works.</p>"
}'अपने regional host (https://us1.platform.bird.com या https://eu1.platform.bird.com) का उपयोग मिलती-जुलती bk_{region}_... key के साथ करें।
send उदाहरण delivered@messagebird.dev का उपयोग करता है, जो एक sandbox पता है और हमेशा मेल स्वीकार करता है। API placeholder डोमेन को 422 के साथ अस्वीकार करता है: example.com, example.net, example.org, example.edu, test.com, और reserved .test, .example, .invalid, या .localhost TLDs के अंतर्गत कुछ भी। इन डोमेन पर भेजा गया ईमेल केवल bounce हो सकता है, जिससे आपकी sender reputation प्रभावित होती है।
डोमेन verify करने से पहले भेजना
onboarding के दौरान आप हमारे shared onboarding डोमेन onboarding@messagebird.dev से भेज सकते हैं। ये sends डोमेन जाँच को छोड़ देते हैं, लेकिन केवल आपके वर्कस्पेस के verified सदस्यों और sandbox पतों तक पहुँचते हैं, एक दैनिक recipient सीमा के अंतर्गत। quickstart में सटीक नियम और सीमाएँ दी गई हैं।
पेलोड बनाना
Recipients
to, cc, और bcc प्रत्येक 50 पतों तक स्वीकार करते हैं, और to में कम से कम एक होना ज़रूरी है। प्रत्येक entry एक सामान्य email string, एक RFC 5322 mailbox string (Jane <jane@acme.com>), या एक optional display name वाला object हो सकती है।
वर्कस्पेस suppression list पर मौजूद recipients से request fail नहीं होती। यह फिर भी 202 लौटाती है, और प्रत्येक suppressed recipient read endpoints पर status: rejected के रूप में recipient_suppressed reason के साथ दिखता है, भले ही send पर सभी recipients suppressed हों।
Content
inline sends के लिए subject आवश्यक है, अधिकतम 998 characters। html, text, या दोनों दें, प्रत्येक अधिकतम 524,288 characters। जहाँ संभव हो दोनों भेजें: जो client HTML render नहीं कर सकता वह text part पर fallback करता है।
inline content को पर्सनलाइज़ करने के लिए, subject या body में {{ variable }} टोकन रखें और उनके values parameters में दें, अधिकतम 16 KB serialized। values का एक सेट send के हर recipient पर लागू होता है, और बिना matching key वाला टोकन खाली render होता है। बार-बार उपयोग होने वाले content के लिए, इसके बजाय template भेजें।
subject और body को Liquid के रूप में process करने के लिए parameters शामिल करें, भले ही empty object ({}) के रूप में। इसे हटा दें तो {{ animal }} जैसे टोकन जैसे लिखे हैं वैसे ही भेजे जाएँगे। प्रत्येक parameter name एक अकेला शब्द होता है, जैसे first_name; dotted names और reserved name bird अस्वीकार किए जाते हैं। अमान्य Liquid syntax और असमर्थित tags या filters 422 लौटाते हैं।
HTML में डाले गए values escape किए जाते हैं ताकि वे आसपास के markup को बदल न सकें। पूर्ण link या image URL के लिए, url_encode के बिना {{ link }} का उपयोग करें। URL query के अंदर किसी value के लिए, उस value को स्पष्ट रूप से encode करें, उदाहरण के लिए https://example.com/search?q={{ query | url_encode }}।
Reply-to और कस्टम हेडर
reply_to 1 से 25 पते स्वीकार करता है, recipients के समान formats में। हर recipient की reply उन सभी को जाती है, इसलिए एक या दो सामान्य है।
headers आपके अपने हेडर के लिए एक string-to-string object है, उदाहरण के लिए {"X-Campaign": "spring-2026"}, अधिकतम 25 हेडर जिनके values 998 characters तक हो सकते हैं। तीन प्रकार के हेडर 422 के रूप में लौटाए जाते हैं:
- Addressing और platform हेडर। message की addressing समर्पित fields (from, to, cc, bcc, reply_to, subject) के माध्यम से सेट करें। वे names, और हमारे द्वारा generate किए गए हेडर (Content-Type, Content-Transfer-Encoding, DKIM-Signature, Received, Return-Path), यहाँ सेट नहीं किए जा सकते।
- List-Unsubscribe और List-Unsubscribe-Post marketing सेंड पर। हम उन पर स्वयं एक अनुपालन-योग्य वन-क्लिक अनसब्सक्राइब हेडर सेट करते हैं। transactional सेंड पर हम आपके हेडर ठीक वैसे ही छोड़ देते हैं जैसे आपने सेट किए।
- carriage return या line feed वाला कोई भी value।
ट्रैकिंग
track_opens और track_clicks दोनों का default true है। इस send पर open-pixel injection या link rewriting छोड़ने के लिए किसी को भी false सेट करें। ट्रैकिंग और मेट्रिक्स बताता है कि प्रत्येक message में क्या बदलता है।
Category और IP pool
category content को classify करता है और suppression policy सेट करता है: marketing हर suppression reason और किसी भी opt-out पर delivery रोकता है, और transactional complaint suppression या marketing-only opt-out के बावजूद deliver करता है (सभी messages के लिए recorded opt-out इसे भी रोकता है)। यह template send पर template की category और अन्यथा marketing पर default होता है, इसलिए receipts, password resets, और अन्य operational mail के लिए transactional स्पष्ट रूप से सेट करें। Categories इस चुनाव को कवर करता है। SMTP के ज़रिए submit किया गया mail अपनी category key के SMTP configuration से लेता है।
ip_pool_id sending pool चुनता है: एक pool ID (ipp_...), या shared pool से स्पष्ट रूप से route करने के लिए ipp_shared। अपने organization के default pool के लिए इसे छोड़ दें। अज्ञात pool, या जिसमें भेजने के लिए कोई dedicated IP उपलब्ध नहीं है, 422 के साथ अस्वीकार किया जाता है।
फ़ील्ड रेफ़रेंस
| फ़ील्ड | टाइप | आवश्यक | सीमाएँ और नोट्स |
|---|---|---|---|
| from | address | हाँ | verified डोमेन या onboarding डोमेन पर होना चाहिए |
| to | address[] | हाँ | 1 से 50 |
| cc, bcc | address[] | नहीं | प्रत्येक अधिकतम 50 |
| subject | string | inline sends | अधिकतम 998 characters; template sends पर छोड़ दें |
| html, text | string | कम से कम एक | प्रत्येक अधिकतम 524,288 characters; template sends पर छोड़ दें |
| reply_to | address[] | नहीं | 1 से 25; replies सूचीबद्ध हर पते पर जाती हैं |
| headers | object (string → string) | नहीं | अधिकतम 25; reserved names अस्वीकार (कस्टम हेडर देखें) |
| parameters | object | नहीं | inline content में {{ tokens }} के लिए values; अधिकतम 16 KB serialized; सभी recipients में साझा |
| tags | {name, value}[] | नहीं | अधिकतम 20; name ≤ 32 chars, value ≤ 64 chars; केवल [A-Za-z0-9_-]; प्रति send names अद्वितीय |
| metadata | object | नहीं | arbitrary JSON, अधिकतम 2 KB serialized |
| track_opens | boolean | नहीं | Default true |
| track_clicks | boolean | नहीं | Default true |
| category | string | नहीं | marketing या transactional; template send पर template की category, अन्यथा marketing default |
| ip_pool_id | string | नहीं | ipp_... या ipp_shared; अपने organization के default pool के लिए छोड़ दें |
| template | object | नहीं | id या slug से published template भेजें, इसके variables के लिए parameters और एक optional language के साथ |
| attachments | object[] | नहीं | अधिकतम 20; attachments देखें |
| scheduled_at | RFC 3339 timestamp | नहीं | इनलाइन कॉन्टेंट या template को शेड्यूल करें; देखें शेड्यूल किया गया भेजना |
template के साथ भेजना
inline content के बजाय, एक published template भेजें: template को एक object सेट करें जो इसे id (emt_...) या slug से name करे, दोनों में से ठीक एक, और इसके variable values template.parameters में दें। subject, html, और text छोड़ दें, क्योंकि template में ये पहले से होते हैं।
const msg = await bird.email.send({
from: { email: "onboarding@messagebird.dev", name: "Bird" },
to: ["delivered@messagebird.dev"],
category: "transactional",
template: {
slug: "welcome-email",
parameters: { first_name: "Jane" },
},
});
console.log(msg.id, msg.status);msg = client.email.send(
from_={"email": "onboarding@messagebird.dev", "name": "Bird"},
to=["delivered@messagebird.dev"],
category="transactional",
template="welcome-email",
parameters={"first_name": "Jane"},
)
print(msg.id, msg.status)msg, err := client.Email.Send(context.Background(), bird.EmailSendParams{
From: "onboarding@messagebird.dev",
To: []string{"delivered@messagebird.dev"},
Category: "transactional",
Template: "welcome-email",
Parameters: map[string]any{"first_name": "Jane"},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)$message = $bird->email->send(
from: 'Bird <onboarding@messagebird.dev>',
to: ['delivered@messagebird.dev'],
category: 'transactional',
template: (new EmailMessageSendRequestTemplate())
->setSlug('welcome-email')
->setParameters(['first_name' => 'Jane']),
);
echo $message->getId(), ' ', $message->getStatus();bird email send \
--category transactional \
--from hello@yourdomain.com \
--parameters '{"first_name":"Jane"}' \
--template welcome-email \
--to delivered@messagebird.devcurl -X POST https://us1.platform.bird.com/v1/email/messages \
-H "Authorization: Bearer bk_us1_..." \
-H "Content-Type: application/json" \
-d '{
"from": "hello@yourdomain.com",
"to": ["delivered@messagebird.dev"],
"category": "transactional",
"template": {
"slug": "welcome-email",
"parameters": { "first_name": "Jane" }
}
}'template का content Liquid है, इसलिए सामान्य {{ variable }} substitution के अलावा यह filters, {% if %} conditionals, और {% for %} loops का उपयोग कर सकता है। variables से पर्सनलाइज़ करना उन कुछ constructs को सूचीबद्ध करता है जिन्हें publish अस्वीकार करता है। template.parameters वह जगह है जहाँ आप template के अपने parameters के values, name के अनुसार keyed, रखते हैं। कोई एक छोड़ दें तो send उसका नाम बताते हुए 422 के साथ अस्वीकार हो जाता है। send के बारे में बाकी सब कुछ inline की तरह ही काम करता है, जिसमें recipients, tags, metadata, tracking, और attachments शामिल हैं। template send के लिए विशिष्ट बातें:
- inline या templated, दोनों कभी नहीं। subject, html, या text के साथ template भेजना 422 के साथ अस्वीकार किया जाता है। API top-level parameters field में variable values को भी अस्वीकार करता है; template send पर ये template.parameters में होने चाहिए।
- bird एकमात्र reserved name है। bird. से शुरू होने वाला placeholder path हमारे अपने data को name करता है, जैसे unsubscribe link या recipient का contact record, इसलिए template.parameters key का नाम bird नहीं हो सकता। बाकी हर key आप define कर सकते हैं, और प्रत्येक एक flat single word है: {"order_number": "A-1043"} {{ order_number }} को fill करता है।
- टेम्पलेट अभी या बाद में भेजा जा सकता है। भेजना शेड्यूल करने के लिए scheduled_at जोड़ें। हम स्वीकृति के समय प्रकाशित संस्करण, चयनित भाषा और पैरामीटर वैल्यू को पिन कर लेते हैं। अगर आप भेजने के समय से पहले टेम्पलेट हटा देते हैं, तो मैसेज generation_failure के साथ अस्वीकृत हो जाता है।
- send template के published version का उपयोग करता है। drafts कभी नहीं भेजे जाते। अज्ञात template 404 के साथ अस्वीकार होता है, और बिना published version वाला template 422 के साथ।
- language template की किसी एक language को चुनता है। template की default language भेजने के लिए इसे छोड़ दें। जो template के पास नहीं है वह माँगें, तो उसकी on_missing_language setting तय करती है कि निकटतम match भेजा जाए या send अस्वीकार हो। language_source_required सेट करने वाला template ऐसे send को अस्वीकार करता है जो कोई language नाम ही नहीं देता।
- template की category एक default है, और आपकी उसे override करती है। category छोड़ दें तो send template की category inherit करता है, इसलिए transactional template को हर call पर इसे दोहराने की ज़रूरत नहीं।
Email templates authoring, publishing, और template में उपलब्ध constructs को कवर करता है।
Tags बनाम metadata
दोनों आपके अपने data को send से जोड़ते हैं, और इनमें अंतर यह है कि बाद में आप इसे कैसे query करते हैं:
- tags structured {name, value} pairs हैं: प्रति send अधिकतम 20, name अधिकतम 32 characters, value अधिकतम 64, केवल ASCII letters, digits, underscore, और hyphen, और send के भीतर names अद्वितीय। Tags filter dimensions हैं, इसलिए आप tag के अनुसार message list filter कर सकते हैं और analytics तथा dashboard rollups को tag से slice कर सकते हैं। इन्हें campaign, experiment_variant, या source जैसे low-cardinality labels के लिए उपयोग करें।
- metadata एक arbitrary JSON object है, अधिकतम 2 KB serialized। हम इसे store करते हैं, API reads पर लौटाते हैं, और हर webhook event पर echo करते हैं, इसलिए यह उस context के लिए उपयुक्त है जो आप वापस चाहते हैं: internal IDs, foreign keys, structured पेलोड।
हर webhook event में दोनों correlation IDs (email_id, recipient_id) के साथ शामिल होते हैं, ताकि आप दूसरे lookup के बिना अपने records से reconcile कर सकें। __bird से शुरू होने वाले tag names और top-level metadata keys अस्वीकार किए जाते हैं। आपको device, geography, mailbox provider, bounce type, या recipient domain को किसी भी field में encode करने की ज़रूरत नहीं है, क्योंकि हम इनमें से प्रत्येक को पहले से एक analytics dimension के रूप में capture करते हैं।
कोड उदाहरण
{
"tags": [{ "name": "campaign", "value": "onboarding" }],
"metadata": { "user_id": "usr_12345", "order_id": "ord_98765" }
}Attachments
attachments प्रति message अधिकतम 20 files स्वीकार करता है, inline base64-encoded bytes के रूप में। हम ऐसे send को अस्वीकार करते हैं जिसका अनुमानित generated message size base64 encoding के बाद 20 MB से अधिक हो, इसलिए headroom के लिए raw attachment content 15 MB या उससे कम रखें। Attachments में field contract, inline images, blocked file types, और attachment वापस download करने का तरीका है।
202 का क्या मतलब है
सफल send em_-prefixed message ID और status: accepted के साथ 202 Accepted लौटाता है:
कोड उदाहरण
{
"id": "em_01ky7ma8y2es1s2akzk53tmjn0",
"status": "accepted",
"category": "marketing",
"from": { "email": "hello@yourdomain.com" },
"to": [{ "email": "delivered@messagebird.dev" }],
"subject": "Hello from Bird",
"accepted_count": 1,
"processed_count": 0,
"delivered_count": 0,
"deferred_count": 0,
"bounced_count": 0,
"complained_count": 0,
"rejected_count": 0,
"open_count": 0,
"click_count": 0,
"track_opens": true,
"track_clicks": true,
"created_at": "2026-07-23T13:58:20.866Z"
}202 का मतलब है कि हमने send को durably स्वीकार कर लिया है। जो विफलताएँ आप ठीक कर सकते हैं वे request पर ही 422 के रूप में लौटती हैं: unverified sender domain, या ऐसा field जो validate नहीं होता। प्रति-recipient परिणाम (delivered, bounced, deferred, complained) बाद में webhooks और message read endpoints के माध्यम से आते हैं।
इससे दो बातें निकलती हैं:
- reads body के बिना state लौटाते हैं। GET /v1/email/messages/{message_id} message और recipient state लौटाता है, कभी html या text body नहीं। जब वर्कस्पेस के लिए content storage enabled हो, तो stored bodies GET /v1/email/messages/{message_id}/content से 30 दिनों तक उपलब्ध रहती हैं।
- read, send से थोड़ा पीछे रह सकता है। 202 के तुरंत बाद read endpoints पर 404 का मतलब है कि message अभी दिखाई नहीं दे रहा, इसलिए कुछ देर बाद फिर से प्रयास करें।
सुरक्षित रूप से फिर से प्रयास करना
प्रति logical send एक unique value के साथ Idempotency-Key हेडर भेजें। अगर request सफल हुई लेकिन आपने response नहीं देखा, तो उसी key के साथ इसे replay करें। API दूसरा ईमेल भेजने के बजाय मूल result लौटाता है और एक Idempotency-Replay हेडर शामिल करता है। Idempotency में key format और retention दिया गया है।
Batch sending
API requests कम करने के लिए, POST /v1/email/batches अधिकतम 100 independent messages स्वीकार करता है और उन्हें एक unit के रूप में validate करता है। single-send endpoint को loop में call करना भी समर्थित है। एक batch item इस page का पेलोड उपयोग करता है, scheduled_at सहित, इसलिए एक batch immediate और scheduled messages मिला सकता है।
बिलिंग
email sends आपकी plan की monthly allowance के विरुद्ध प्रति recipient meter होते हैं, इसलिए तीन recipients को भेजा गया message तीन sends consume करता है। Billing and usage metering model और live usage read को कवर करता है।
अगले कदम
- Email templates: यहाँ भेजे जाने वाले templates author और publish करें
- Categories: marketing और transactional suppression behavior को कैसे बदलते हैं
- Suppressions: हम किसे deliver नहीं करते, और क्यों
- Scheduled sending: scheduled_at के साथ भविष्य के समय पर deliver करें
- Testing sandbox: sandbox recipients और pre-verification sending
- API रेफ़रेंस: पूर्ण request और response schemas
संबंधित संसाधन
इस विषय के लिए डॉक्यूमेंटेशन, गाइड और उदाहरणों के साथ आगे बढ़ें। संसाधन अंग्रेज़ी में हैं।
गाइड देखेंOrder confirmation emailsक्षमता जानेंOrder confirmation emailsलर्निंग पाथ फ़ॉलो करेंBuild your first integration
अभ्यास करें और इम्प्लीमेंटेशन ब्रीफ़ पाएँ