Brevo API: डेवलपर के लिए एक व्यावहारिक गाइड
डेवलपर्स के लिए Brevo API गाइड: ऑथेंटिकेशन, बेस URL, कॉन्टैक्ट, ट्रांज़ैक्शनल ईमेल, कैम्पेन, CRM ऑब्जेक्ट, वेबहुक, रेट लिमिट और असल व्यावहारिक सीमाएं.
Brevo एक ही REST API देता है जो ट्रांज़ैक्शनल मैसेजिंग, मार्केटिंग कैम्पेन, कॉन्टैक्ट डेटा और CRM रिकॉर्ड तक फैली है. पहली रिक्वेस्ट से 201 पाने में लगभग दो मिनट लगते हैं. ऐसा प्रोडक्शन इंटीग्रेशन बनाने में कहीं ज़्यादा समय लगता है जो चुपचाप डेटा न खोए, क्योंकि जो बंदिशें सबसे ज़्यादा मायने रखती हैं उनमें से कई या तो दस्तावेज़ों में हैं ही नहीं, या API अपने बारे में जो बताता है उसके उलट हैं.
यह गाइड दोनों हिस्से कवर करती है: वे एंडपॉइंट, SDK और ऑथेंटिकेशन जो पहले दिन चाहिए, और वे प्लेटफ़ॉर्म सीमाएं जिन्हें ध्यान में रखकर आपको शिप करने से पहले डिज़ाइन करना होगा.
Brevo API क्या कवर करता है
सब कुछ एक ही होस्ट और एक ही वर्ज़न पाथ के नीचे रहता है. डेवलपर डॉक्युमेंटेशन इस सतह को चार प्रोडक्ट क्षेत्रों में बांटता है:
- मैसेजिंग: ट्रांज़ैक्शनल ईमेल, SMS और WhatsApp, जिसमें बैच सेंड, शेड्यूलिंग और मैसेज एक्टिविटी शामिल हैं.
- मार्केटिंग प्लेटफ़ॉर्म: कॉन्टैक्ट, लिस्ट, सेगमेंट और ईमेल कैम्पेन.
- ई-कॉमर्स: प्रोडक्ट, ऑर्डर और ग्राहक इवेंट ट्रैकिंग.
- कन्वर्सेशन: चैट विजेट और प्रोग्रामैटिक कन्वर्सेशन प्रबंधन.
ये सभी क्षेत्र एक अकाउंट, एक कॉन्टैक्ट डेटाबेस और एक API की साझा करते हैं. यह सुविधाजनक है और कभी-कभी ख़तरनाक भी: डेटा के किसी स्टेजिंग वाले अंदाज़े के लिए लिखी गई स्क्रिप्ट उन्हीं कॉन्टैक्ट से बात कर रही है जिन्हें आपके कैम्पेन भेजे जाते हैं.
ट्रांज़ैक्शनल बनाम मार्केटिंग
ये दोनों परिवार इतने अलग बर्ताव करते हैं कि इन्हें आपस में गड्डमड्ड कर देना सबसे आम डिज़ाइन ग़लती है.
| ट्रांज़ैक्शनल | मार्केटिंग | |
|---|---|---|
| मुख्य एंडपॉइंट | POST /v3/smtp/email | POST /v3/emailCampaigns |
| पता तय करना | रिक्वेस्ट में स्पष्ट प्राप्तकर्ता | listIds या segmentIds |
| ट्रिगर | आपका ऐप्लिकेशन, रियल टाइम में | शेड्यूल किया गया या मांग पर भेजा गया |
| सामान्य वॉल्यूम आकार | लगातार, एक बार में एक मैसेज | झटकेदार, एक बड़ा सेंड |
| रेट लिमिट की स्थिति | बहुत ऊंची, स्टैंडर्ड प्लान पर 1,000 रिक्वेस्ट प्रति सेकंड | कम, कैम्पेन एंडपॉइंट सामान्य कैप के दायरे में आते हैं |
अगर आप अब भी यह तय कर रहे हैं कि Brevo सही प्लेटफ़ॉर्म है भी या नहीं, तो प्लेटफ़ॉर्म का परिचय उस पहलू को कवर करता है.
ऑथेंटिकेशन और की प्रबंधन
Brevo एक कस्टम हेडर में सादी API की इस्तेमाल करता है. हेडर का नाम api-key है, Authorization नहीं, और कोई Bearer प्रीफ़िक्स नहीं होता. जिन लोगों ने पहले कोई दूसरा मैसेजिंग API इस्तेमाल किया है, वे लगभग हमेशा यहीं चूकते हैं.
curl https://api.brevo.com/v3/account \ -H "api-key: $BREVO_API_KEY"की Brevo ऐप में अकाउंट सेटिंग्स के भीतर, SMTP and API सेक्शन में, API keys टैब पर बनती हैं. हर की को उस सिस्टम से जुड़ा हुआ स्पष्ट नाम दें जो उसे इस्तेमाल करता है. की की वैल्यू बनते समय ठीक एक बार दिखाई जाती है, इसलिए अगर वह खो जाए तो पुरानी वापस पाने के बजाय आप नई बनाते हैं.
कुछ व्यावहारिक नियम:
- हर डिप्लॉयमेंट टारगेट और हर सर्विस के लिए अलग की जारी करें. किसी लीक हुई की को रद्द करने से तीन असंबंधित सिस्टम कभी बंद नहीं होने चाहिए.
- स्टैंडर्ड API की पूरे अकाउंट के लिए होती हैं. किसी भी की को कॉन्टैक्ट, सेंडिंग और CRM डेटा तक पूरी पहुंच मानें.
- Brevo उन ऐप्लिकेशन के लिए OAuth 2.0 भी सपोर्ट करता है जो दूसरे Brevo अकाउंट की ओर से काम करते हैं, जिसका वर्णन की फ़्लो के साथ ही authentication schemes में है.
- AI असिस्टेंट जो MCP सर्वर इस्तेमाल करते हैं, वह अलग टोकन लेता है और बियरर हेडर ही इस्तेमाल करता है. वह टोकन उसी API keys स्क्रीन में बनता है, लेकिन REST की के साथ अदला-बदली नहीं किया जा सकता.
बेस URL, वर्ज़निंग और आपकी पहली राइट
बेस URL https://api.brevo.com/v3/ है. वर्ज़न हेडर में नहीं, पाथ में है, और v3 मौजूदा जनरेशन है. इस गाइड का हर पाथ उसी बेस के सापेक्ष है.
पहली राइट पहली रीड से ज़्यादा जानकारी देती है, क्योंकि वह अकाउंट के उन हिस्सों को आज़माती है जो आम तौर पर ग़लत कॉन्फ़िगर होते हैं (ख़ासकर वेरिफ़ाइड सेंडर):
curl -X POST https://api.brevo.com/v3/smtp/email \ -H "api-key: $BREVO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "sender": { "name": "Ops", "email": "[email protected]" }, "to": [{ "email": "[email protected]", "name": "Dev" }], "subject": "First transactional send", "htmlContent": "<html><body><p>It works.</p></body></html>", "tags": ["smoke-test"] }'सफल सेंड messageId के साथ 201 लौटाता है. शेड्यूल किया गया सेंड 202 लौटाता है.
वे एंडपॉइंट जो आप असल में इस्तेमाल करेंगे
कॉन्टैक्ट
POST /v3/contacts एक कॉन्टैक्ट बनाता है. बॉडी में email, कस्टम फ़ील्ड के लिए attributes मैप, listIds, आपकी अपनी बाहरी की के लिए ext_id, और वे दो फ़्लैग आते हैं जो व्यवहार में सबसे ज़्यादा मायने रखते हैं: updateEnabled, जो कॉल को अपसर्ट बना देता है, और getId, जिससे रिस्पॉन्स में कॉन्टैक्ट आईडी लौटती है.
रीड GET /v3/contacts से होती हैं, जो limit (डिफ़ॉल्ट 50, अधिकतम 1000) और offset के साथ पेजिंग करता है, और UTC में modifiedSince तथा createdSince सपोर्ट करता है. इन्क्रीमेंटल सिंक को पूरी लिस्ट टहलने के बजाय modifiedSince पर टिकना चाहिए. ध्यान रखें कि filter पैरामीटर सिर्फ़ बराबरी वाला ऑपरेटर सपोर्ट करता है, इसलिए इससे ज़्यादा अभिव्यक्तिपूर्ण कुछ भी सेगमेंट में होना चाहिए.
बल्क लोडिंग के लिए POST /v3/contacts/import fileUrl, fileBody या jsonBody स्वीकार करता है, listIds को टारगेट करता है, और असिंक्रोनस चलता है, processId लौटाते हुए. Brevo अधिकतम 10 MB बॉडी दस्तावेज़ करता है और 8 MB के आसपास रहने की सलाह देता है, क्योंकि पार्सिंग पेलोड को फुला देती है. notifyUrl दें ताकि पोलिंग करने के बजाय आपको नतीजा पता चल जाए.
ट्रांज़ैक्शनल ईमेल
POST /v3/smtp/email असली मेहनत करने वाला एंडपॉइंट है. sender, to, subject और htmlContent के अलावा जानने लायक फ़ील्ड ये हैं:
templateIdके साथparams, जो इनलाइन कॉन्टेंट की जगह Brevo टेम्पलेट और उसके वेरिएबल प्रतिस्थापन रख देता है. अलग-अलग वर्ज़न params 100 KB पर और कुल params 1000 KB पर सीमित हैं.messageVersions, जो एक ही कॉल में व्यक्तिगत बनाए गए वेरिएंट भेजता है, प्रति वर्ज़न 99 प्राप्तकर्ता तक.tags, जिन्हें आपको हमेशा सेट करना चाहिए. टैग वेबहुक इवेंट पर वापस आते हैं, और किसी डिलीवरी इवेंट को उस कोड पाथ से जोड़ने का यही एकमात्र सस्ता तरीक़ा है जिसने उसे पैदा किया.scheduledAtके साथbatchId, उन भविष्य के सेंड के लिए जिन्हें आप समूह के रूप में कैंसल करना चाह सकते हैं.headers, Title-Case में, कस्टम SMTP हेडर के लिए.
एक रिक्वेस्ट अधिकतम 2,000 प्राप्तकर्ता स्वीकार करती है. इस एंडपॉइंट और कैम्पेन सेंडिंग के बीच फ़र्क़ के लिए, ट्रांज़ैक्शनल ईमेल गाइड में मैसेजिंग रणनीति वाला नज़रिया मिलेगा.
ईमेल कैम्पेन
POST /v3/emailCampaigns को name और sender चाहिए, साथ ही ठीक एक कॉन्टेंट स्रोत: htmlContent (न्यूनतम 10 अक्षर, 1 MB से कम), htmlUrl, या templateId. ऑडियंस recipients में listIds या segmentIds के रूप में जाती है, और scheduledAt YYYY-MM-DDTHH:mm:ss.SSSZ UTC फ़ॉर्मैट इस्तेमाल करता है. साथी रूट तुरंत भेजने, टेस्ट भेजने, स्टेटस अपडेट करने और कैम्पेन रिपोर्ट खींचने को कवर करते हैं.
कंपनियां, डील और ऑब्जेक्ट
Brevo के CRM में दो ओवरलैप करने वाले राइट पाथ हैं, और सही चुनाव मायने रखता है.
CRM रूट हैं POST /v3/companies, PATCH /v3/companies/{id}, DELETE /v3/companies/{id}, और डील के लिए इसी के समकक्ष सेट. ये सिंक्रोनस हैं. बदलाव लागू होते ही PATCH 204 लौटाता है.
ऑब्जेक्ट API बल्क पाथ है: POST /v3/objects/{object_type}/batch/upsert प्रति रिक्वेस्ट 1000 रिकॉर्ड और 1 MB तक लेता है, प्रति रिकॉर्ड 500 एट्रिब्यूट तक, और प्रति रिकॉर्ड प्रति ऑब्जेक्ट टाइप 10 एसोसिएशन रिकॉर्ड तक. यह processId के साथ 202 लौटाता है, यानी लागू हो गया नहीं, स्वीकार कर लिया गया.
curl -X POST https://api.brevo.com/v3/objects/company/batch/upsert \ -H "api-key: $BREVO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "records": [ { "identifiers": { "id": 12345 }, "attributes": { "domain": "acme.example", "industry": "retail" } } ] }'Brevo CRM गाइड ऑब्जेक्ट मॉडल को ऑपरेटर के नज़रिए से कवर करती है.
आधिकारिक SDK
Brevo getbrevo GitHub संगठन के तहत क्लाइंट मेंटेन करता है:
| भाषा | रिपॉज़िटरी |
|---|---|
| Node.js | github.com/getbrevo/brevo-node |
| Python | github.com/getbrevo/brevo-python |
| PHP | github.com/getbrevo/brevo-php |
| Java | github.com/getbrevo/brevo-java |
| C# | github.com/getbrevo/brevo-csharp |
| Go | github.com/getbrevo/brevo-go |
| Ruby | github.com/getbrevo/brevo-ruby |
Node क्लाइंट @getbrevo/brevo के रूप में इंस्टॉल होता है:
npm install @getbrevo/brevoimport { BrevoClient } from "@getbrevo/brevo";
const brevo = new BrevoClient({ apiKey: process.env.BREVO_API_KEY });
const result = await brevo.transactionalEmails.sendTransacEmail({ subject: "Order confirmed", htmlContent: "<html><body><p>Thanks for your order.</p></body></html>", tags: ["order-confirmation"],});
console.log("Message ID:", result.messageId);Python क्लाइंट pip install brevo-python से इंस्टॉल होता है. अगर आप दो एंडपॉइंट के लिए SDK निर्भरता नहीं ढोना चाहते, तो कच्ची HTTP सतह इतनी छोटी है कि उसे सीधे कॉल किया जा सकता है, जो आपको SDK वर्ज़न की उठापटक से भी बचाए रखता है:
import osimport requests
BASE = "https://api.brevo.com/v3"HEADERS = { "api-key": os.environ["BREVO_API_KEY"], "Content-Type": "application/json",}
def upsert_contact(email, attributes, list_ids): response = requests.post( f"{BASE}/contacts", headers=HEADERS, json={ "email": email, "attributes": attributes, "listIds": list_ids, "updateEnabled": True, }, timeout=30, ) response.raise_for_status() return responseAI असिस्टेंट के लिए https://mcp.brevo.com/v1/brevo/mcp पर एक MCP सर्वर भी है, जो उसी सेटिंग्स स्क्रीन में बने बियरर टोकन से ऑथेंटिकेट होता है. यह खोजबीन और अकाउंट से जुड़े सवालों के लिए उपयोगी है, प्रोडक्शन डेटा पाथ के लिए नहीं.
वेबहुक
सेंड के बाद क्या हुआ, यह जानने का ज़रिया वेबहुक हैं. POST /v3/webhooks एक वेबहुक बनाता है, जिसमें url, events, type, और वैकल्पिक रूप से channel (email या sms), batched, कस्टम headers और एक auth ऑब्जेक्ट होते हैं.
तीन वेबहुक टाइप हैं, जिनकी इवेंट शब्दावली अलग-अलग है:
- ट्रांज़ैक्शनल:
sent,request,delivered,hardBounce,softBounce,blocked,spam,invalid,deferred,click,opened,uniqueOpened,unsubscribed. - मार्केटिंग:
spam,opened,click,hardBounce,softBounce,unsubscribed,listAddition,delivered,contactUpdated,contactDeleted. - इनबाउंड:
inboundEmailProcessedऔरreply, जिनके लिए अतिरिक्त रूप से एकdomainभी चाहिए.
curl -X POST https://api.brevo.com/v3/webhooks \ -H "api-key: $BREVO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://yourapp.example/hooks/brevo", "type": "transactional", "events": ["delivered", "hardBounce", "spam", "unsubscribed"], "description": "Deliverability signals" }'तीन बातें ठीक रखनी हैं. पहली, एक अकाउंट सभी टाइप मिलाकर अधिकतम 40 वेबहुक रख सकता है, इसलिए हर इवेंट के लिए अलग एंडपॉइंट रजिस्टर करने के बजाय अपने हैंडलर के भीतर इवेंट के हिसाब से रूट करें. दूसरी, जब वॉल्यूम की उम्मीद हो तो batched फ़्लैग इस्तेमाल करें, क्योंकि कई इवेंट ढोने वाली एक रिक्वेस्ट को प्रोसेस करना कई रिक्वेस्ट के मुक़ाबले कहीं सस्ता है. तीसरी, रिसीवर की सुरक्षा करें: Brevo अपनी सेंडिंग IP रेंज प्रकाशित करता है, और अपने एंडपॉइंट को उन्हीं रेंज तक सीमित करना दस्तावेज़ में बताया गया तरीक़ा है. दूसरी परत के रूप में headers फ़ील्ड के ज़रिए अपना साझा सीक्रेट भी जोड़ें.
हैंडलर आइडेम्पोटेंट होने चाहिए. मैसेज आईडी, इवेंट टाइप और टाइमस्टैम्प को मिलाकर डीडुप्लिकेशन की मानें.
रेट लिमिट और एरर हैंडलिंग
Brevo की रेट लिमिट हर एंडपॉइंट और हर प्लान टियर के हिसाब से हैं, और एंडपॉइंट के बीच का फ़ासला बहुत बड़ा है.
| एंडपॉइंट | Standard | Professional और Enterprise |
|---|---|---|
POST /v3/smtp/email | 1,000 RPS | 2,000 RPS |
POST /v3/transactionalSMS/send | 150 RPS | 200 RPS |
/v3/contacts/... | 10 RPS, 36,000 RPH | 20 RPS, 72,000 RPH |
POST /v3/events | 10 RPS, 36,000 RPH | Enterprise पर ज़्यादा |
GET /v3/smtp/emails | 2 RPS, 7,200 RPH | 3 RPS, 10,800 RPH |
| बाकी सब कुछ | 100 RPH | 200 RPH |
आख़िरी पंक्ति ही चोट पहुंचाती है. सेंडिंग व्यावहारिक रूप से बिना मीटर के है, जबकि कैम्पेन प्रबंधन, CRM रीड और ज़्यादातर प्रशासनिक कॉल स्टैंडर्ड प्लान पर 100 रिक्वेस्ट प्रति घंटे का बजट आपस में बांटते हैं. हर राइट से पहले कंपनी रिकॉर्ड पढ़ने वाला भोला-भाला बैकफ़िल दो मिनट से भी कम में एक घंटे का कोटा ख़त्म कर देगा.
हर रिस्पॉन्स x-sib-ratelimit-limit, x-sib-ratelimit-remaining और x-sib-ratelimit-reset लेकर आता है. इन्हें सिर्फ़ विफलता पर नहीं, सफलता पर भी पढ़ें. लिमिट पार होने पर 429 मिलता है, और सही प्रतिक्रिया यह है कि रीसेट हेडर में दिए गए अंतराल तक रुकें और फिर जिटर के साथ एक्सपोनेंशियल बैकऑफ़ लगाएं.
async function callBrevo(path, init, attempt = 0) { const response = await fetch(`https://api.brevo.com/v3${path}`, { ...init, headers: { "api-key": process.env.BREVO_API_KEY, "Content-Type": "application/json", ...init.headers }, });
if (response.status === 429 && attempt < 5) { const reset = Number(response.headers.get("x-sib-ratelimit-reset") || 1); const backoff = Math.pow(2, attempt) * 250 + Math.random() * 250; await new Promise((r) => setTimeout(r, reset * 1000 + backoff)); return callBrevo(path, init, attempt + 1); }
return response;}429 और 5xx को दोबारा आज़माएं. 400 या 409 को आंख मूंदकर कभी दोबारा न आज़माएं, क्योंकि दोनों का मतलब आम तौर पर यह होता है कि रिक्वेस्ट जल्दी नहीं, बल्कि ग़लत है, और ख़ासकर 409 के लिए दोहराव नहीं, कोई दूसरी कार्रवाई चाहिए.
मेल भेजे बिना टेस्ट करना
ट्रांज़ैक्शनल सेंड में X-Sib-Sandbox हेडर को drop वैल्यू के साथ जोड़ें. Brevo रिक्वेस्ट वैलिडेट करता है, messageId के साथ 201 लौटाता है, कुछ भी डिलीवर नहीं करता और कोई ईमेल लॉग नहीं लिखता.
curl -X POST https://api.brevo.com/v3/smtp/email \ -H "api-key: $BREVO_API_KEY" \ -H "X-Sib-Sandbox: drop" \ -H "Content-Type: application/json" \ -d '{ "sender": { "email": "[email protected]" }, "to": [{ "email": "[email protected]" }], "subject": "Sandbox", "htmlContent": "<p>hi</p>" }'समझ लें कि यह क्या साबित करता है और क्या नहीं. सैंडबॉक्स मोड सिर्फ़ रिक्वेस्ट का फ़ॉर्मैट वैलिडेट करता है. यह सेंडर ऑथेंटिकेशन, टेम्पलेट रेंडरिंग या डिलिवरेबिलिटी के बारे में कुछ नहीं कहता. कॉन्टैक्ट या CRM डेटा को छूने वाली किसी भी चीज़ के इंटीग्रेशन टेस्टिंग के लिए अलग Brevo अकाउंट रखें, क्योंकि सैंडबॉक्स मोड सेंडिंग को कवर करता है, बाक़ी API को नहीं.
वे सीमाएं जो आपके इंटीग्रेशन का डिज़ाइन तय करती हैं
ये वे बंदिशें हैं जो तभी सामने आती हैं जब इंटीग्रेशन असली अकाउंट पर वॉल्यूम के साथ चलता है. इनमें से कई API के अपने ही दावों का खंडन करती हैं. इनमें से कोई भी बातचीत के दायरे में नहीं है, इसलिए एकमात्र समझदार प्रतिक्रिया यही है कि इन्हें ध्यान में रखकर डिज़ाइन किया जाए.
कंपनियों के लिए डोमेन ज़रूरी है, और प्रति डोमेन एक ही कंपनी
GET /v3/crm/attributes/companies हर एट्रिब्यूट को ग़ैर-ज़रूरी बताता है, और create-a-company संदर्भ सिर्फ़ name को अनिवार्य बताता है. व्यवहार में, ख़ाली न होने वाले domain एट्रिब्यूट के बिना POST /v3/companies अनुपस्थित अनिवार्य डिफ़ॉल्ट एट्रिब्यूट के संदेश के साथ 400 लौटाता है. ख़ाली स्ट्रिंग उसी तरह विफल होती है जैसे उसे छोड़ देना.
इससे भी बुरा, डोमेन की विशिष्टता लागू होती है. पहले से इस्तेमाल में मौजूद डोमेन पर दूसरी कंपनी 409 लौटाती है. B2B कॉमर्स के लिए यह ढांचागत समस्या है: जो सहायक कंपनियां एक ही ख़रीदार ईमेल डोमेन साझा करती हैं, वे Brevo में अलग-अलग कंपनियों के रूप में मौजूद नहीं रह सकतीं. किसी कॉन्टैक्ट को सिंक करना भी उस कॉन्टैक्ट के ईमेल डोमेन पर कंपनी प्रकट कर देने के लिए काफ़ी है, इसलिए क्रिएट ऐसी कंपनी से टकरा सकता है जिसे किसी ने स्पष्ट रूप से बनाया ही नहीं था. सही हैंडलर 409 पर विफल होने या दोबारा कोशिश करने के बजाय मौजूदा कंपनी को अपना लेता है.
बिना घोषित एट्रिब्यूट चुपचाप हटा दिए जाते हैं
यह प्लेटफ़ॉर्म का सबसे ख़तरनाक व्यवहार है, और Brevo इसे साफ़ शब्दों में दस्तावेज़ करता है: अगर कोई एट्रिब्यूट रिक्वेस्ट में आता है लेकिन पहले ऑब्जेक्ट स्कीमा में परिभाषित नहीं था, तो कुछ नहीं होता. न एरर, न एट्रिब्यूट का निर्माण, न कोई चेतावनी.
इसलिए 2xx रिस्पॉन्स इस बात का सबूत नहीं है कि आपका डेटा पहुंच गया. लिखने से पहले स्कीमा पढ़ें, अपने क्लाइंट में ही बिना घोषित हर चीज़ हटा दें, और उस सिंक को चलाने से इनकार कर दें जिसके एट्रिब्यूट मौजूद नहीं हैं, बजाय इसके कि किसी को पता चलने से पहले एक महीने तक आधा रिकॉर्ड लिखा जाता रहे.
एट्रिब्यूट फ़िल्टर स्वीकार होते हैं और नज़रअंदाज़ कर दिए जाते हैं
GET /v3/companies?filters[attributes.domain]=... 200 लौटाता है और फ़िल्टर को नज़रअंदाज़ कर देता है. दो बिल्कुल अलग फ़िल्टर वही रिकॉर्ड लौटाते हैं. उस रूट से एट्रिब्यूट के आधार पर कंपनी खोजने का कोई कारगर तरीक़ा नहीं है.
इस तथ्य के साथ मिलाकर देखें कि बड़े अकाउंट पर बिना फ़िल्टर वाली लिस्ट किसी भी पेज साइज़ पर 504 के साथ टाइमआउट हो जाती है, तो दस्तावेज़ में बताए गए रास्ते से कोई मौजूदा कंपनी सचमुच खोजी ही नहीं जा सकती. उपाय यह है कि GET /v3/objects/company/records को sort=desc के साथ स्कैन किया जाए, जो तेज़ है, पेजिनेटेड है और एट्रिब्यूट लौटाता है, और उसे पेजों की एक समझदार संख्या तक सीमित रखा जाए. जिस कंपनी ने अभी-अभी 409 ट्रिगर किया, वह लगभग हमेशा कुछ ही पल पहले बनी होती है, इसलिए नए से पुराने क्रम में स्कैन करना उसे जल्दी ढूंढ लेता है.
प्रति ऑब्जेक्ट टाइप दस लाख रिकॉर्ड, और कोई बल्क डिलीट नहीं
किसी ऑब्जेक्ट टाइप में दस लाख रिकॉर्ड हो जाने के बाद POST /v3/objects/{type}/batch/upsert 400 लौटाता है. यह क्रिएट के साथ-साथ अपडेट भी रोक देता है: किसी मौजूदा रिकॉर्ड को उसकी अपनी संख्यात्मक आईडी से संबोधित करना भी उसी तरह विफल होता है. पूरा ऑब्जेक्ट राइट पाथ एक साथ बंद हो जाता है.
सीमा से नीचे वापस आना धीमा है, क्योंकि company जैसे Brevo स्टैंडर्ड ऑब्जेक्ट टाइप के लिए POST /v3/objects/{type}/batch/delete 403 लौटाता है. एकमात्र रास्ता DELETE /v3/companies/{id} है, लगभग 156 ms पर एक कॉल में एक रिकॉर्ड. इस तरह 1,24,000 रिकॉर्ड साफ़ करने में 20 समानांतर वर्कर के साथ घंटों लगे. किसी विफल सिंक से सीमा का पता चलने के बजाय रिकॉर्ड गिनती की निगरानी नियमित रूप से करें, और ज़्यादा वॉल्यूम वाले अपडेट PATCH /v3/companies/{id} से रूट करें, जिस पर ऐसी कोई सीमा नहीं है.
ext_id Brevo की आईडी है, आपकी नहीं
ऑब्जेक्ट रिकॉर्ड पर identifiers.ext_id में Brevo की अपनी CRM कंपनी आईडी होती है, एक Mongo शैली की स्ट्रिंग. यह कोई खुली बाहरी की नहीं है. ext_id को अपने प्लेटफ़ॉर्म के पहचानकर्ता पर सेट करके अपसर्ट करना मिलान करने के बजाय डुप्लिकेट बनाता है. आपकी बाहरी आईडी अपने ही एक घोषित एट्रिब्यूट में होनी चाहिए.
ऑब्जेक्ट अपसर्ट असिंक्रोनस हैं, CRM राइट नहीं
batch/upsert 202 और एक processId लौटाता है, फिर बाद में लागू होता है. कोई ग़ैर-मौजूद आईडी असिंक्रोनस रूप से विफल होती है और आपके कॉलर को फिर भी 202 ही लौटाती है. PATCH /v3/companies/{id} 204 लौटाता है और सिंक्रोनस रूप से लागू होता है. अगर आपका सिंक सफलता की सूचना देता है, तो बिना किसी अनुवर्ती रीड के यह शब्द सिर्फ़ सिंक्रोनस पाथ ही कमाता है.
एक छोटी इंटीग्रेशन चेकलिस्ट
- हर सर्विस और हर एनवायरनमेंट के लिए अलग API की, जो स्टाफ़ बदलने पर घुमाई जाएं.
- सभी राइट एक ही क्लाइंट से गुज़रें जो रेट लिमिट हेडर पढ़ता है और 429 पर बैकऑफ़ करता है.
- एट्रिब्यूट स्कीमा स्टार्टअप पर सत्यापित हो, और एट्रिब्यूट ग़ायब होने पर सिंक चलने से इनकार कर दे.
- कंपनी क्रिएट पर 409 का मतलब है अपनाना, दोबारा कोशिश करना नहीं.
- बल्क पाथ थ्रूपुट के लिए ऑब्जेक्ट API इस्तेमाल करें, और जिसकी पुष्टि ज़रूरी हो उसके लिए CRM रूट.
- वेबहुक आइडेम्पोटेंट, बैच किए हुए, IP से सीमित हों और साझा सीक्रेट हेडर लेकर चलें.
- इन्क्रीमेंटल कॉन्टैक्ट सिंक पूरी लिस्ट टहलने के बजाय
modifiedSinceइस्तेमाल करें.
इस परत को बनाना और बनाए रखना असली इंजीनियरिंग काम है: स्कीमा सत्यापन, बैकऑफ़, अडॉप्शन लॉजिक, रीकंसिलिएशन. Tajo इसी को अपने ऊपर लेने के लिए मौजूद है, जो Shopify और कॉमर्स डेटा को Brevo के कॉन्टैक्ट, कंपनियों और इवेंट के साथ सिंक में रखता है, बिना किसी को रीट्राई और डीडुप लॉजिक हाथ से लिखे. अगर आप इसे ख़ुद जोड़ रहे हैं, तो Brevo इंटीग्रेशन गाइड उन डेटा मॉडल विकल्पों से गुज़रती है जो कोड से पहले आते हैं.
मुख्य बातें
- API
https://api.brevo.com/v3/पर एक ही REST सतह है, जो बियरर टोकन के बजायapi-keyहेडर से ऑथेंटिकेट होती है. - रेट लिमिट बेहद असमान हैं: सेंडिंग व्यावहारिक रूप से बिना मीटर की है, जबकि बाक़ी ज़्यादातर एंडपॉइंट स्टैंडर्ड प्लान पर 100 रिक्वेस्ट प्रति घंटे आपस में बांटते हैं.
- सात भाषाओं के लिए आधिकारिक SDK मौजूद हैं, लेकिन जब आपको सिर्फ़ कुछ एंडपॉइंट चाहिए तो HTTP सतह इतनी सरल है कि उसे सीधे कॉल किया जा सकता है.
- सैंडबॉक्स मोड सिर्फ़ रिक्वेस्ट का फ़ॉर्मैट वैलिडेट करता है, इसलिए सेंड से आगे किसी भी चीज़ की टेस्टिंग के लिए अलग अकाउंट रखें.
- 2xx रिस्पॉन्स यह साबित नहीं करता कि राइट लागू हुई. बिना घोषित एट्रिब्यूट चुपचाप हटा दिए जाते हैं, और ऑब्जेक्ट अपसर्ट असिंक्रोनस होते हैं.
- तय सीमाओं को ध्यान में रखकर डिज़ाइन करें: प्रति डोमेन एक कंपनी, प्रति ऑब्जेक्ट टाइप दस लाख रिकॉर्ड, स्टैंडर्ड ऑब्जेक्ट के लिए कोई बल्क डिलीट नहीं, और ऐसे एट्रिब्यूट फ़िल्टर जो चुपचाप कुछ नहीं करते.