वेबहुक और इवेंट
जब आपके वर्कस्पेस में कुछ होता है (कोई ईमेल डिलीवर होता है, कोई प्राप्तकर्ता बाउंस होता है, कोई WhatsApp संदेश पढ़ा जाता है), तो Bird उस इवेंट प्रकार की सदस्यता वाले हर वेबहुक एंडपॉइंट पर एक हस्ताक्षरित JSON इवेंट POST करता है। Bird हेडर, हस्ताक्षर और पेलोड संरचना के लिए Standard Webhooks विनिर्देश का पालन करता है। इसलिए अगर आप पहले से किसी दूसरे Standard Webhooks प्लेटफ़ॉर्म के वेबहुक सत्यापित करते हैं, तो वही सत्यापन कोड यहाँ बिना बदलाव के काम करता है।
वेबहुक एंडपॉइंट और डिलीवरी के अवलोकन के लिए वेबहुक क्या है? देखें।
एंडपॉइंट बनाएँ
डैशबोर्ड में Developers > Webhooks के अंतर्गत, या टर्मिनल से bird CLI के साथ एंडपॉइंट पंजीकृत करें:
bird webhooks create --url https://example.com/webhooks/bird \
--events email.delivered,email.bounced,email.complained \
--description "Production delivery + bounce notifications"एंडपॉइंट प्रबंधन के लिए webhooks स्कोप चाहिए। डैशबोर्ड सत्र और CLI का लॉगिन इसे आपकी उपयोगकर्ता भूमिका के ज़रिए रखते हैं, और API कुंजियों में भी यह हो सकता है: एंडपॉइंट और डिलीवरी प्रयास देखने के लिए webhooks:read दें, या उन्हें प्रबंधित करने के लिए webhooks:write दें। संबंधित ऑपरेशन POST /v1/webhooks से शुरू होते हैं।

एंडपॉइंट URL HTTPS होने चाहिए, अधिकतम 2048 अक्षरों के, और सार्वजनिक रूप से पहुँच योग्य। जब आप एंडपॉइंट बनाते या अपडेट करते हैं, तो निजी, लूपबैक, लिंक-लोकल या किसी अन्य आंतरिक पते वाले URL 422 के साथ अस्वीकार कर दिए जाते हैं। डिलीवरी आपके नेटवर्क के बाहर Bird के डिलीवरी इन्फ्रास्ट्रक्चर से आती हैं।
events ऐरे में इवेंट कैटलॉग से अधिकतम 100 प्रकार होते हैं। एंडपॉइंट को केवल वही प्रकार मिलते हैं जो उसमें सूचीबद्ध हैं। आगे की डिलीवरी के लिए पूरी सूची बदलने हेतु PATCH /v1/webhooks/{webhook_id} का उपयोग करें। हर इवेंट पाने के लिए हर प्रकार की सदस्यता लें: कैटलॉग से बाहर का प्रकार 422 के साथ अस्वीकार होता है, और इसमें sms.* जैसा वाइल्डकार्ड भी शामिल है। नए प्रकार उपलब्ध होने पर मौजूदा सदस्यताएँ अपने आप नहीं बढ़तीं।
बनाने की प्रतिक्रिया में एंडपॉइंट का साइनिंग secret (whsec_ उपसर्ग के साथ) केवल एक बार आता है। इसे तुरंत अपने सीक्रेट मैनेजर में सहेजें; इसे दोबारा प्राप्त नहीं किया जा सकता, और अगर यह खो जाए तो इसे रोटेट करें।
{
"id": "whk_01ky7q639cfh99xb7ysy2x2gzj",
"url": "https://example.com/webhooks/bird",
"events": ["email.delivered", "email.bounced", "email.complained"],
"description": "Production delivery + bounce notifications",
"status": "active",
"secret": "whsec_c+dgRBsFELJ9mR4tu2cyhK0gTMMkqntv",
"created_at": "2026-07-23T14:48:29.740Z",
"updated_at": "2026-07-23T14:48:29.740Z"
}एंडपॉइंट पूरे CRUD का समर्थन करते हैं: सूची, प्राप्त करना, अपडेट और हटाना। एंडपॉइंट हटाने पर उसकी सभी डिलीवरी रुक जाती हैं, जिसमें पहले विफल हुई डिलीवरी के फिर से प्रयास भी शामिल हैं, और इसे पूर्ववत नहीं किया जा सकता। डिलीवरी को अस्थायी रूप से रोकने के लिए इसके बजाय status को paused पर सेट करें। एक वर्कस्पेस कई एंडपॉइंट रजिस्टर कर सकता है, और हर एंडपॉइंट का अपना URL, इवेंट फ़िल्टर और सीक्रेट होता है।
इवेंट किसी नो-कोड टूल या एजेंट प्लेटफ़ॉर्म पर भेजें
HTTPS POST स्वीकार करने वाला कोई भी रिसीवर सामान्य एंडपॉइंट की तरह काम करता है, जैसे Zapier "Catch Hook", Make कस्टम वेबहुक या n8n Webhook नोड। उस टूल में ट्रिगर बनाएँ, उसका URL कॉपी करें और ऊपर बताए अनुसार उसे रजिस्टर करें। n8n में वर्कफ़्लो का प्रोडक्शन URL इस्तेमाल करें, क्योंकि टेस्ट URL केवल तब सुनता है जब एडिटर किसी टेस्ट इवेंट की प्रतीक्षा कर रहा हो।
अगर आप चाहते हैं कि Claude Managed Agents या Grok Bot आपको मिलने वाले संदेशों का जवाब दें, तो इसके बजाय संदेशों को अपने AI एजेंट तक भेजें देखें। ChatGPT जैसा कोई MCP क्लाइंट MCP Events के ज़रिए खुद इवेंट सब्सक्राइब कर सकता है। किसी एजेंट के कार्रवाई करने से पहले इनबाउंड संदेशों को स्कोर करने के लिए Superagent देखें।
सामान्य एंडपॉइंट बनाने से पहले GET /v1/webhooks को url से फ़िल्टर करें, ताकि किसी पिछले सेटअप में बना एंडपॉइंट मिल सके। दूसरा बनाने के बजाय उसे PATCH /v1/webhooks/{webhook_id} से बदलें। कई एंडपॉइंट एक ही URL साझा कर सकते हैं, इसलिए किसी मेल खाते एंडपॉइंट को बदलने से पहले उसका विवरण और इवेंट जाँच लें। फ़िल्टर केवल मेल खाते एंडपॉइंट ढूँढता है, डुप्लिकेट बनने से नहीं रोकता:
bird webhooks list --url https://hooks.zapier.com/hooks/catch/123/abc/
bird webhooks update whk_01krdgeqcxet5s7t44vh8rt9mg --events sms.received,whatsapp.receivedफिर यह पुष्टि करने के लिए एक टेस्ट इवेंट भेजें कि रिसीवर उसे स्वीकार करता है।
AI एजेंट की मदद से सेट अप करें
bird CLI और MCP सर्वर में एक webhooks.setup प्रक्रिया है, जो एजेंट को इस पूरे क्रम से गुज़ारती है: आपसे क्या पूछना है (रिसीवर URL, इवेंट, कोई क्रेडेंशियल), मौजूदा एंडपॉइंट ढूँढना, नया बनाना, और सफलता बताने से पहले एक टेस्ट इवेंट भेजना। अपने एजेंट से "send Bird's inbound SMS to my Zapier hook" कहें, और वह यही चरण अपनाता है।
सिग्नेचर सत्यापित करें
हर डिलीवरी में तीन हेडर होते हैं:
| हेडर | मान |
|---|---|
webhook-id | इवेंट डिलीवरी की पहचान करता है। इसके फिर से प्रयास और रीप्ले में यही मान दोबारा इस्तेमाल होता है। |
webhook-timestamp | इस डिलीवरी प्रयास का Unix टाइमस्टैम्प (सेकंड में) |
webhook-signature | v1,<base64 HMAC-SHA256>, संभवतः स्पेस से अलग किए गए कई सिग्नेचर |
सिग्नेचर स्ट्रिंग {webhook-id}.{webhook-timestamp}.{raw request body} पर बना HMAC-SHA256 है, जिसकी कुंजी आपके एंडपॉइंट का सीक्रेट है (कुंजी के बाइट पाने के लिए whsec_ प्रीफ़िक्स हटाएँ और बाकी हिस्से को base64-डिकोड करें)। आपके हैंडलर को सिग्नेचर सत्यापित करना चाहिए, जिन डिलीवरी का webhook-timestamp 5 मिनट से पुराना हो उन्हें अस्वीकार करना चाहिए, और webhook-id के आधार पर डुप्लिकेट हटाने चाहिए। Bird कम से कम एक बार डिलीवर करता है, इसलिए एक ही डिलीवरी एक से ज़्यादा बार आ सकती है।
Bird SDK के साथ सिग्नेचर और टाइमस्टैम्प की जाँच एक ही कॉल में होती है। डुप्लिकेट हटाने का काम आपके हैंडलर में ही रहता है:
// Pass the RAW request body; set the secret via new BirdClient({ webhooks: { secret } }).
const event = bird.webhooks.unwrap(rawBody, headers);
console.log(event.type); // discriminated union: narrow on event.type# Pass the RAW request body (bytes) and the request headers.
event = client.webhooks.unwrap(request.body, request.headers)
if event.root.type == "email.delivered":
print(event.root.data.email_id)package main
import (
"fmt"
"io"
"log"
"net/http"
"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")),
option.WithWebhookSecret(os.Getenv("BIRD_WEBHOOK_SECRET")),
)
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/webhooks/bird", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
event, err := client.Webhooks.Unwrap(body, r.Header)
if err != nil {
http.Error(w, "invalid signature", http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusNoContent) // ack fast, then process
payload, _ := event.AsAny()
switch p := payload.(type) {
case bird.EmailDeliveredEvent:
fmt.Println("delivered:", p.Data.EmailId, p.Data.Recipient)
case bird.EmailBouncedEvent:
fmt.Println("bounced:", p.Type)
}
})
}// Pass the raw request body because parsing changes the bytes used to compute
// the signature.
$rawBody = file_get_contents('php://input') ?: '';
try {
$event = $bird->webhooks->unwrap($rawBody, getallheaders());
// $event is the decoded payload as an array; branch on $event['type'].
echo $event['type'];
} catch (WebhookVerificationError) {
http_response_code(400); // bad signature, stale timestamp, or missing/malformed headers
}ऊपर के उदाहरणों की तरह किसी डिलीवरी को 400 के साथ अस्वीकार करने से इवेंट हटता नहीं है: हम नीचे दिए गए शेड्यूल के अनुसार फिर से प्रयास करते हैं। यह जानबूझकर किया गया है, और आपके लिए यही उपयोगी है। सत्यापन विफल होने का आम कारण ऐसा सीक्रेट होता है जो रोटेशन या गलत डिप्लॉय के दौरान अभी आपके हैंडलर के पास नहीं है। इसलिए फिर से प्रयास की अवधि में आप सीक्रेट ठीक करके भी इवेंट पा सकते हैं। 2xx तभी लौटाएँ जब आप डिलीवरी को हमेशा के लिए हटाना चाहते हों।
कोई भी Standard Webhooks रेफ़रेंस लाइब्रेरी भी काम करती है। अगर आप खुद सत्यापन करते हैं, तो तरीका यह है:
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(rawBody: string, headers: Record<string, string>, secret: string): boolean {
const id = headers["webhook-id"];
const timestamp = headers["webhook-timestamp"];
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false; // 5-minute tolerance
const key = Buffer.from(secret.slice("whsec_".length), "base64");
const expected = createHmac("sha256", key)
.update(`${id}.${timestamp}.${rawBody}`)
.digest("base64");
// During secret rotation, the header can contain several signatures. Accept any match.
return headers["webhook-signature"].split(" ").some((part) => {
const sig = Buffer.from(part.replace(/^v1,/, ""), "base64");
return (
sig.length === Buffer.byteLength(expected, "base64") &&
timingSafeEqual(sig, Buffer.from(expected, "base64"))
);
});
}HMAC की गणना हमेशा अनुरोध बॉडी के मूल बाइट पर करें। JSON को पार्स करके दोबारा सीरियलाइज़ करने से व्हाइटस्पेस या कुंजियों का क्रम बदल जाता है और सिग्नेचर मेल नहीं खाता।
डिलीवरी का व्यवहार
हर डिलीवरी में Content-Type: application/json के साथ एक HTTP POST में एक ही इवेंट होता है, कोई बैचिंग नहीं होती। आपके एंडपॉइंट के पास जवाब देने के लिए 15 सेकंड होते हैं। कोई भी 2xx स्टेटस सफलता माना जाता है, और बाकी सब कुछ (3xx रीडायरेक्ट और टाइमआउट सहित) विफलता माना जाता है। हर विफलता पर एक ही फिर से प्रयास शेड्यूल लागू होता है। आप जो स्टेटस लौटाते हैं, उससे डिलीवरी प्रयास लॉग में दिखने वाली जानकारी बदलती है, यह नहीं कि हम फिर से प्रयास करेंगे या नहीं। ऐसा कोई स्टेटस कोड नहीं है जो डिलीवरी को पहले ही रोक दे। जल्दी जवाब दें और प्रोसेसिंग असिंक्रोनस रूप से करें: असली काम करने से पहले इवेंट को कतार में डालें और 200 लौटाएँ।
पहले प्रयास के बाद, विफल डिलीवरी के लिए इस शेड्यूल पर फिर से प्रयास किया जाता है। इसमें ±20% जिटर जोड़ा जाता है ताकि फिर से प्रयास एक साथ न हों:
| फिर से प्रयास | पिछले प्रयास के बाद की देरी |
|---|---|
| 1 | 5 सेकंड |
| 2 | 5 मिनट |
| 3 | 30 मिनट |
| 4 | 2 घंटे |
| 5 | 5 घंटे |
| 6 | 10 घंटे |
| 7 | 10 घंटे |
यानी लगभग 27.5 घंटों में कुल आठ प्रयास। 429 या टाइमआउट होने पर 60 सेकंड से छोटी निर्धारित देरी को बढ़ाकर 60 सेकंड कर दिया जाता है। व्यवहार में इसका असर केवल पहले फिर से प्रयास पर पड़ता है: जिटर के बाद वह 48 से 72 सेकंड बाद आता है। विफल प्रतिक्रिया में Retry-After हेडर अगले इंतज़ार को लंबा कर सकता है। हम यह हेडर देरी के सेकंड या HTTP तारीख के रूप में स्वीकार करते हैं। अनुरोधित देरी निर्धारित देरी से लंबी हो, तो वह उसकी जगह ले लेती है, पर निर्धारित देरी के दोगुने तक ही (60 सेकंड वाली बढ़ोतरी के बाद)। छोटी देरी को अनदेखा किया जाता है, इसलिए यह हेडर फिर से प्रयास को कभी पहले नहीं लाता। जिटर इसके ऊपर लागू होता है। हर फिर से प्रयास में वही webhook-id होता है, और इसी से डुप्लिकेट हटाना संभव होता है। अंतिम फिर से प्रयास के बाद डिलीवरी स्थायी रूप से विफल हो जाती है; रीप्ले से उसे वापस पाया जा सकता है।
डिलीवरी क्रम में नहीं आतीं। एक ही संदेश के लिए email.delivered, email.accepted से पहले आ सकता है, खासकर जब फिर से प्रयास हो रहे हों। इवेंट पेलोड के अंदर मौजूद timestamp फ़ील्ड के आधार पर क्रम तय करें, पहुँचने के क्रम से कभी नहीं।
अपने एंडपॉइंट संचालित करें
टेस्ट भेजना
POST /v1/webhooks/{webhook_id}/test आपके एंडपॉइंट पर एक हस्ताक्षरित सिंथेटिक इवेंट भेजता है और नतीजा तुरंत लौटाता है: आपके एंडपॉइंट ने उसे स्वीकार किया या नहीं, उसने कौन-सा HTTP स्टेटस लौटाया, और आने-जाने का विलंब। टेस्ट बॉडी एक न्यूनतम JSON स्टब है, जिसमें केवल इवेंट type होता है, और उस पर असली डिलीवरी की तरह ही हस्ताक्षर होते हैं; यह असली इवेंट पेलोड जैसा नहीं होता। कैटलॉग से कोई भी प्रकार चुनने के लिए {"event_type": "email.delivered"} भेजें, चाहे वह सब्सक्राइब किया गया हो या नहीं। बॉडी छोड़ देने पर एंडपॉइंट का पहला सब्सक्राइब किया गया इवेंट प्रकार इस्तेमाल होता है।
आपके एंडपॉइंट के पास जवाब देने के लिए 10 सेकंड होते हैं। एंडपॉइंट तक न पहुँच पाने पर प्रतिक्रिया बॉडी में status: failed आता है, जबकि अनुरोध खुद सफल रहता है। कनेक्टिविटी डीबग करने के लिए इस नतीजे का उपयोग करें। टेस्ट सीधे आपके एंडपॉइंट पर जाते हैं: वे रुके हुए एंडपॉइंट पर भी काम करते हैं और डिलीवरी प्रयास लॉग में दर्ज नहीं होते। 412 का मतलब है कि एंडपॉइंट का अभी टेस्ट नहीं हो सकता, क्योंकि उसमें मान्य साइनिंग सीक्रेट या सब्सक्राइब किया गया इवेंट प्रकार नहीं है।
वास्तविक इवेंट प्रवाह के साथ एंड-टू-एंड परीक्षण के लिए सैंडबॉक्स पतों पर भेजें: सैंडबॉक्स भेजने से सामान्य डिलीवरी मार्ग से वास्तविक वेबहुक इवेंट निकलते हैं। लाइव होने से पहले अपने हैंडलर को परखने का यह सबसे अच्छा तरीका है।
विफल डिलीवरी को फिर से चलाना
POST /v1/webhooks/{webhook_id}/replay विफल हुई डिलीवरी को दोबारा डिलीवर करने के लिए कतार में लगाता है। जो इवेंट एंडपॉइंट पहले ही सफलतापूर्वक प्राप्त कर चुका है, उन्हें छोड़ दिया जाता है, इसलिए रीप्ले कभी दोहरी डिलीवरी नहीं करता। दोबारा डिलीवर किया गया इवेंट अपना मूल webhook-id रखता है, इसलिए आपकी डुप्लिकेट जाँच रीप्ले को भी कवर करती है। केवल विफल प्रयास ही दोबारा चलाए जाते हैं: जो इवेंट आपके एंडपॉइंट को कभी भेजा ही नहीं गया, उसका कोई विफल प्रयास नहीं होता, इसलिए रीप्ले उसे वापस नहीं लाता।
विंडो की सीमा तय करने के लिए since/until टाइमस्टैम्प दें (डिफ़ॉल्ट: अनुरोध के समय तक पिछले 24 घंटे)। दोनों सीमाएँ समावेशी हैं। दोनों इस आधार पर चुनती हैं कि डिलीवरी का प्रयास कब हुआ, न कि इवेंट कब हुआ। इसलिए जो फिर से प्रयास अपने इवेंट से एक दिन बाद हुआ, वह अपने प्रयास के घंटे के अनुसार विंडो में आता है। रीप्ले डिलीवरी प्रयास लॉग पढ़ता है, जो तीन दिन का इतिहास रखता है, इसलिए रीप्ले इससे पुराने इतिहास तक नहीं पहुँचता: पहले का since विंडो को चौड़ा करता है, पर इससे पुराना कुछ भी वापस नहीं लाता। एक रीप्ले विंडो के अधिकतम 10,000 सबसे पुराने इवेंट कवर करता है।
अनुरोध 202 लौटाता है और इवेंट एसिंक्रोनस रूप से दोबारा डिलीवर होते हैं। दोबारा डिलीवरी को केवल एक प्रयास मिलता है, ऊपर दिया गया फिर से प्रयास का शेड्यूल नहीं। प्रयास दर्ज होता है और काम पूरा माना जाता है, चाहे आपके एंडपॉइंट ने उसे स्वीकार किया हो या नहीं। इसलिए अभी भी खराब एंडपॉइंट पर रीप्ले करने में प्रति इवेंट आठ के बजाय एक अनुरोध लगता है। एंडपॉइंट ठीक करें और फिर से रीप्ले करें। ये विफलताएँ एंडपॉइंट की हेल्थ को नहीं बदलतीं: रीप्ले किसी एंडपॉइंट को degraded नहीं कर सकता और न ही उसे अपने आप रोक सकता है। आपके एंडपॉइंट द्वारा स्वीकार की गई दोबारा डिलीवरी दोनों स्थितियों को साफ़ कर देती है।
यदि आप किसी paused एंडपॉइंट पर रीप्ले करते हैं, तो अनुरोध फिर भी 202 लौटाता है, पर कुछ भी दोबारा डिलीवर नहीं होता। पहले उसे फिर से सक्षम करें, जैसा अपने आप रोकना और फिर से सक्षम करना में बताया गया है।
रीप्ले प्रति संगठन प्रति UTC दिन 20 तक सीमित हैं। इससे अधिक होने पर अनुरोध 429 (WebhookReplayQuotaExceeded) लौटाता है। प्रतिक्रिया में कोई गिनती या टास्क ID नहीं होती। परिणामों पर नज़र रखने के लिए GET /v1/webhooks/{webhook_id}/attempts का उपयोग करें, जो हाल के डिलीवरी प्रयासों को स्टेटस कोड और विलंब के साथ नए से पुराने क्रम में दिखाता है। हर HTTP अनुरोध की अपनी प्रविष्टि होती है, इसलिए जिस इवेंट के लिए फिर से प्रयास किया गया, वह हर प्रयास के लिए एक बार दिखता है, और दोबारा डिलीवरी एक और प्रविष्टि के रूप में दिखती है।
साइनिंग सीक्रेट बदलना
POST /v1/webhooks/{webhook_id}/rotate-secret एक नया सीक्रेट बनाता है और उसे एक बार लौटाता है। अगले 24 घंटों तक Bird हर डिलीवरी पर दोनों सीक्रेट से हस्ताक्षर करता है। webhook-signature हेडर में स्पेस से अलग किए गए हस्ताक्षर (v1,<old> v1,<new>) होते हैं, जिससे आप इस ओवरलैप के दौरान नया सीक्रेट डिप्लॉय कर सकते हैं। Standard Webhooks लाइब्रेरी सभी हस्ताक्षर अपने आप जाँचती हैं। 24 घंटे बाद पुराना सीक्रेट हस्ताक्षर करना बंद कर देता है। एक एंडपॉइंट में एक साथ अधिकतम 5 मान्य सीक्रेट हो सकते हैं, इसलिए ओवरलैप विंडो के भीतर बार-बार बदलने पर WebhookTooManySecrets त्रुटि मिलती है, जब तक कोई पुराना सीक्रेट समाप्त न हो जाए।
अपने आप रोकना और फिर से सक्षम करना
एंडपॉइंट का status active, degraded या paused होता है। हाल की डिलीवरी विफलताएँ हेल्थ चेतावनी के रूप में एंडपॉइंट को degraded चिह्नित करती हैं; हम डिलीवरी और फिर से प्रयास करना जारी रखते हैं। जो एंडपॉइंट लगभग पाँच दिन लगातार विफल रहता है, वह अपने आप paused हो जाता है और सारी डिलीवरी रुक जाती है। उस अवधि में एक भी सफल डिलीवरी घड़ी को रीसेट कर देती है। रोका गया एंडपॉइंट अपने आप फिर शुरू नहीं होता। उसे PATCH /v1/webhooks/{webhook_id} और {"status": "active"} से (या डैशबोर्ड के Webhooks पेज से) फिर से सक्षम करें, फिर रुकने से पहले विफल हुए प्रयासों को दोबारा डिलीवर करने के लिए रीप्ले करें। पहले फिर से सक्षम करें: एंडपॉइंट रुके रहने के दौरान माँगा गया रीप्ले कुछ भी दोबारा डिलीवर नहीं करता। रुके रहने के दौरान आए इवेंट कभी भेजे ही नहीं गए, इसलिए रीप्ले उन्हें वापस नहीं लाता।
इनमें से कोई भी स्थिति degraded एंडपॉइंट को active पर लौटा देती है:
| इसे क्या हटाता है | क्यों |
|---|---|
| कोई डिलीवरी सफल होती है | एंडपॉइंट ने फिर से कोई इवेंट स्वीकार किया। |
एंडपॉइंट का url बदलना | दर्ज विफलताएँ उस गंतव्य से जुड़ी हैं जिसका आप अब उपयोग नहीं करते। |
किसी paused एंडपॉइंट को फिर से सक्षम करना | यह फिर से सेवा में आ रहा है, इसलिए इसकी पुरानी विफलताएँ अब लागू नहीं होतीं। |
2xx लौटाने वाला टेस्ट सेंड | आपने दिखा दिया है कि एंडपॉइंट तक पहुँचा जा सकता है। |
एंडपॉइंट का विवरण या उसके सब्सक्राइब किए गए इवेंट प्रकार बदलने से पहुँच के बारे में कुछ पता नहीं चलता, इसलिए इससे degraded बना रहता है। विफल होने वाला टेस्ट सेंड भी इसे नहीं हटाता।
जब कोई एंडपॉइंट पहली बार degraded होता है, तो हम संगठन के मालिकों को ईमेल भेजते हैं। यह ईमेल हर विफल डिलीवरी पर नहीं, बल्कि हर घटना-क्रम पर एक बार जाता है। ठीक होने के बाद दोबारा गिरावट आने पर उन्हें फिर ईमेल जाता है, लेकिन 24 घंटे के कूलडाउन के साथ: हम हर एंडपॉइंट के लिए 24 घंटे में अधिकतम एक गिरावट ईमेल भेजते हैं, ताकि active और degraded के बीच बार-बार बदलने वाला एंडपॉइंट उनके इनबॉक्स को न भर दे। एंडपॉइंट का url बदलने से कूलडाउन रीसेट हो जाता है, इसलिए नए URL पर पहली गिरावट पिछले ईमेल के 24 घंटे के भीतर भी ईमेल भेज सकती है।
इवेंट कैटलॉग
इवेंट पेलोड में आपके सिस्टम से मिलान के लिए संक्षिप्त, प्राप्तकर्ता-विशिष्ट तथ्य होते हैं। इनमें पूरा रिसोर्स नहीं होता। अगर आपको अधिक संदर्भ चाहिए, तो रिसोर्स को उसकी ID से प्राप्त करें। इवेंट टाइप resource.action नामकरण का पालन करते हैं और उत्पाद के अनुसार समूहित हैं; हर उत्पाद के इवेंट पेज पर प्रत्येक इवेंट के पेलोड फ़ील्ड दिए गए हैं:
- ईमेल इवेंट: डिलीवरी का जीवनचक्र (
email.acceptedसेemail.deliveredयाemail.bouncedतक), एंगेजमेंट (email.opened,email.clicked), अनसब्सक्राइब और इनबाउंड ईमेल - SMS इवेंट:
sms.acceptedसे लेकर अंतिम स्थिति तक संदेश का जीवनचक्र - WhatsApp वेबहुक:
whatsapp.acceptedसेwhatsapp.delivered,whatsapp.read,whatsapp.failedतक, इनबाउंड संदेश के लिएwhatsapp.rejected,whatsapp.received, जब कोई उपयोगकर्ता आपके किसी संदेश पर प्रतिक्रिया देता है तबwhatsapp.reacted, और जब कोई अनुमोदन वाले समूह में शामिल होने का अनुरोध करता है या अनुरोध वापस लेता है तबwhatsapp.group.join_request_createdऔरwhatsapp.group.join_request_revoked - Verify इवेंट: सत्यापन का जीवनचक्र (
verify.verification.created,verify.verification.verified) और हर सत्यापन कोड प्रयास की डिलीवरी (verify.attempt.sent,verify.attempt.delivered,verify.attempt.undelivered) - प्राथमिकता इवेंट: सभी चैनलों का सहमति रिकॉर्ड:
preference.granted,preference.revokedऔरpreference.deleted
हर डिलीवरी बॉडी Standard Webhooks का नेस्टेड एनवेलप होती है, जिसमें type, timestamp और टाइप-विशिष्ट data ऑब्जेक्ट होते हैं। webhook-id हेडर इवेंट की पहचान बताता है। एनवेलप का timestamp दर्ज करता है कि इवेंट कब हुआ। webhook-timestamp हेडर मौजूदा डिलीवरी प्रयास दर्ज करता है और हर फिर से प्रयास पर बदलता है।
{
"type": "email.delivered",
"timestamp": "2026-06-10T14:30:00Z",
"data": {
"email_id": "em_01krdgeqcxet5s7t44vh8rt9mg",
"recipient_id": "er_01krdgeqcxet5s7t44vh8rt9mg",
"workspace_id": "ws_01krdgeqcxet5s7t44vh8rt9mg",
"recipient": "user@example.com",
"recipient_role": "to",
"tags": [{ "name": "category", "value": "welcome" }],
"metadata": { "order_id": "ord_123" },
"broadcast_id": null
}
}हर ईमेल इवेंट के data में email_id, recipient_id, workspace_id, recipient पता और उसका एनवेलप recipient_role शामिल होते हैं। इसमें भेजने के अनुरोध से tags और metadata भी होते हैं, या न दिए जाने पर null। इसमें broadcast_id भी होता है, जो उस ब्रॉडकास्ट का नाम बताता है जिसके हिस्से के रूप में ईमेल भेजा गया, या कोई ब्रॉडकास्ट न होने पर null। email.unsubscribed और email.list_unsubscribed पर null होने का मतलब यह नहीं कि ब्रॉडकास्ट नहीं था; इसका कारण ईमेल इवेंट में बताया गया है। इवेंट टाइप इस आधार में अपने फ़ील्ड जोड़ते हैं। हर वेरिएंट के फ़ील्ड स्थिर होते हैं: फ़ील्ड डिफ़ॉल्ट रूप से अनिवार्य हैं, और उनकी मौजूदगी केवल इवेंट टाइप पर निर्भर करती है।
इवेंट के नाम कभी बदले नहीं जाते, और उत्पाद जारी होने पर नए टाइप जोड़े जाते हैं, इसलिए अपना हैंडलर ऐसा लिखें कि वह अनजान टाइप को अनदेखा करे।
प्राथमिकता इवेंट
घोषित प्राथमिकताएँ (हर चैनल की गाइड में बताई गई सहमतियाँ और ऑप्ट-आउट: ईमेल, SMS, WhatsApp) कई चैनलों पर लागू होती हैं, इसलिए उनके इवेंट चैनल का नाम टाइप में नहीं, बल्कि पेलोड में बताते हैं। सहमति लागू होने पर preference.granted ट्रिगर होता है, ऑप्ट-आउट लागू होने पर preference.revoked, और जब कोई दर्ज कथन हटाया जाता है और उसकी कुंजी फिर से बिना रिकॉर्ड की हो जाती है, तब preference.deleted। इवेंट का मतलब है कि कुंजी का मौजूदा रिकॉर्ड बदला है: मौजूदा कथन को दोहराने वाला कथन कोई इवेंट ट्रिगर नहीं करता, और क्रम से बाहर होने के कारण अस्वीकार किया गया कथन भी नहीं। एनवेलप का timestamp वह समय है जब कथन लागू हुआ; पिछली तारीख वाले कथन के लिए यह वह समय है जब कथन दिया गया था, न कि जब वह Bird तक पहुँचा।
हर पेलोड में पूरी प्राथमिकता कुंजी होती है: channel, handle, sender_scope और topic_id। जो स्कोपिंग फ़ील्ड कुंजी को सीमित नहीं करते, वे null मान के साथ मौजूद रहते हैं। कुंजी के साथ ये भी आते हैं: कथन का coverage, preference_id, उस इतिहास प्रविष्टि का transition_id जिसे इस लेखन ने जोड़ा, और वह contact_id जिसका हैंडल कथन दर्ज होते समय मेल खाया था, या null:
{
"type": "preference.revoked",
"timestamp": "2026-08-25T14:52:03.192524705Z",
"data": {
"preference_id": "prf_01krdgeqcxet5s7t44vh8rt9mg",
"transition_id": "prt_01krdgeqcxet5s7t44vh8rt9mg",
"channel": "sms",
"handle": "+15550001234",
"sender_scope": null,
"topic_id": null,
"coverage": "non_transactional",
"contact_id": null
}
}अगले कदम
- वेबहुक API संदर्भ: एंडपॉइंट और स्कीमा का पूरा दस्तावेज़ीकरण
- ईमेल इवेंट: हर इवेंट के पेलोड फ़ील्ड
- टेस्टिंग और सैंडबॉक्स: सैंडबॉक्स से भेजे गए संदेश असली वेबहुक डिलीवरी करते हैं, जिससे हैंडलर की टेस्टिंग के लिए ये उपयुक्त हैं
संबंधित संसाधन
इस विषय के लिए दस्तावेज़, गाइड और उदाहरणों के साथ आगे बढ़ें।