Sign inGet started

WhatsApp इवेंट

Bird इनबाउंड और आउटबाउंड WhatsApp संदेशों के लिए इवेंट रिकॉर्ड करता है। आउटबाउंड टाइमलाइन दिखाती है कि संदेश भेजने के अनुरोध पर 202 मिलने के बाद क्या हुआ: स्वीकृति, WhatsApp को हैंडऑफ़, डिलीवरी, पढ़ना, या विफलता। इनबाउंड टाइमलाइन रिकॉर्ड करती है कि Bird ने संदेश कब प्राप्त किया।

इवेंट एन्वेलप

WhatsApp delivery, incoming-message, और reaction इवेंट मानक webhook एन्वेलप का उपयोग करते हैं: एक type, एक timestamp, और एक type-विशिष्ट data ऑब्जेक्ट।
कोड उदाहरण
{
  "data": {
    "direction": "outbound",
    "from": { "phone_number": "+13124495569" },
    "metadata": { "session_id": "sess_4821" },
    "tags": [{ "name": "flow", "value": "login-otp" }],
    "to": { "phone_number": "+14155550100" },
    "whatsapp_id": "wam_01ky7qbvswf3fvyaw3az90391c",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b"
  },
  "timestamp": "2026-07-23T14:51:39.913Z",
  "type": "whatsapp.delivered"
}
किसी संदेश के लिए प्रत्येक सार्वजनिक WhatsApp webhook पेलोड में whatsapp_id, workspace_id, direction, from, to, tags, और metadata होता है। whatsapp.reacted अपवाद है, क्योंकि रिएक्शन एक संदेश पर एनोटेशन है, अपने आप में एक संदेश नहीं; नीचे रिएक्शन इसका स्वरूप बताता है। किसी पते में E.164 phone_number, bsuid में Meta business-scoped user ID, या दोनों शामिल हो सकते हैं। WhatsApp उपयोगकर्ता से प्राप्त संदेश में उनकी प्रकाशित प्रोफ़ाइल भी होती है, username और display_name में। भेजने के अनुरोध में tags और metadata के मान न दिए गए हों, तो वे null होते हैं। रिप्लाई में भेजा गया संदेश अपनी टाइमलाइन के हर आउटबाउंड इवेंट पर in_reply_to_message_id भी रखता है, whatsapp.accepted से लेकर whatsapp.read, whatsapp.failed, या whatsapp.rejected तक, जो बताता है कि वह किस संदेश का उत्तर है।
इवेंट API हल्के टाइमलाइन रिकॉर्ड लौटाता है जिनमें id, type, और occurred_at टाइमस्टैम्प होता है। मैसेज ID पहले से अनुरोध URL में होती है।

लाइफ़साइकल इवेंट

इवेंट कालक्रम के अनुसार दिखाई देते हैं। एक आउटबाउंड संदेश whatsapp.failed या whatsapp.rejected पर रुक सकता है, और इसका whatsapp.read इवेंट तभी दिखता है जब प्राप्तकर्ता संदेश खोलता है। एक इनबाउंड टाइमलाइन whatsapp.received से शुरू होती है और आपका वर्कस्पेस संदेश को पढ़ा हुआ चिह्नित करने के बाद whatsapp.read रिकॉर्ड कर सकती है।
इवेंटअर्थ
whatsapp.acceptedBird ने संदेश भेजने का अनुरोध स्वीकार किया। यही वह है जो 202 ने रिपोर्ट किया।
whatsapp.sentBird ने संदेश WhatsApp नेटवर्क को सौंपा।
whatsapp.deliveredWhatsApp ने प्राप्तकर्ता के डिवाइस पर डिलीवरी की पुष्टि की।
whatsapp.readप्राप्तकर्ता ने संदेश खोला।
whatsapp.failedसंदेश डिलीवर नहीं हुआ। error.code बताता है कि किस कारण रुका।
whatsapp.rejectedBird ने संदेश भेजने से पहले अस्वीकार कर दिया। इसका शुल्क नहीं लगा।
whatsapp.receivedBird ने किसी संपर्क से इनबाउंड संदेश प्राप्त किया।
लागू delivered या read कॉलबैक कीमत में Meta के हिस्से का शुल्क लागू कर सकते हैं। WhatsApp इवेंट पेलोड में लागत की जानकारी नहीं होती। संदेश की लागत देखने के लिए उसे GET /v1/whatsapp/messages/{message_id} से वापस पढ़ें। लागत और बिलिंग देखें।
इनबाउंड संदेश को पढ़ा हुआ चिह्नित करना इसकी टाइमलाइन में whatsapp.read रिकॉर्ड करता है लेकिन कोई read acknowledgement webhook emit नहीं करता। इनबाउंड संदेश अपनी received स्थिति बनाए रखता है और WhatsApp द्वारा acknowledgement स्वीकार करने के बाद read_at रिकॉर्ड करता है।
whatsapp.read संदेश status को नहीं बदलता। एक delivered संदेश delivered बना रहता है; संदेश read को read_at में भी रिकॉर्ड करता है।
whatsapp.delivered पूरी तरह skip हो सकता है। जब प्राप्तकर्ता का चैट उनके डिवाइस पर पहले से खुला हो, तो Meta बिना delivery रिपोर्ट किए सीधे read रिपोर्ट करता है, इसलिए टाइमलाइन whatsapp.acceptedwhatsapp.sentwhatsapp.read पढ़ती है और बीच में कोई whatsapp.delivered नहीं होता। read को delivery का प्रमाण मानें: जो consumer संदेश पहुँचा मानने से पहले delivered का इंतज़ार करता है, वह ठीक उन्हीं प्राप्तकर्ताओं पर अटकेगा जिन्होंने संदेश सबसे तेज़ देखा, और जो केवल delivered से delivery rate गिनता है वह इसे कम रिपोर्ट करता है। इस स्थिति में संदेश status sent बना रहता है, क्योंकि केवल delivery receipt ही इसे आगे बढ़ाती है।
एक read-only callback भी लागू Meta शुल्क ट्रिगर कर सकता है। Bird delivered और read दोनों paths में एक ही fee identity का उपयोग करता है; missing delivery event का अर्थ मुफ़्त Meta component नहीं है। देखें Cost and billing
इवेंट type की सूची खुली है: समय के साथ नए type जोड़े जा सकते हैं, इसलिए किसी अपरिचित value को त्रुटि के बजाय भविष्य का इवेंट मानें।

विफलता इवेंट

whatsapp.failed और whatsapp.rejected अंतिम (terminal) हैं। rejection का अर्थ है कि Bird ने संदेश को WhatsApp को भेजने से पहले रोक दिया, इसलिए इसका शुल्क नहीं लगा। कारणों में suppressed या opted-out प्राप्तकर्ता, अपर्याप्त wallet balance, या बिना configured price वाला destination शामिल हैं। failure का अर्थ है कि संदेश delivered नहीं हुआ, और error.code बताता है कि यह किसने तय किया। अधिकांश codes WhatsApp का निर्णय carry करते हैं, जो इसके रिपोर्ट किए गए code से mapped होता है। internal_error अपवाद है: यह एक missing usable sender credential या exhausted processing retries रिकॉर्ड करता है। एक अनिश्चित transport प्रयास यह साबित नहीं करता कि Meta ने कभी request प्राप्त नहीं किया। meta_error_code में उपलब्ध होने पर WhatsApp का code होता है, और एक internal_error failure में स्वाभाविक रूप से कोई code नहीं होता।
दोनों इवेंट में एक error ऑब्जेक्ट होता है जिसमें एक स्थिर Bird code, एक मानव-पठनीय description, एक वैकल्पिक meta_error_code, और occurred_at होता है। यह ऑब्जेक्ट API रिकॉर्ड और webhook पेलोड में केवल इन्हीं event types के लिए दिखाई देता है।

रिएक्शन इवेंट

एक emoji रिएक्शन किसी मौजूदा संदेश पर annotation करता है। यह कोई whatsapp.received संदेश नहीं बनाता। Bird तब whatsapp.reacted emit करता है जब कोई contact रिएक्शन जोड़ता, बदलता या हटाता है, जैसा कि Reactions में वर्णित है। आपके business number द्वारा भेजे गए रिएक्शन वह webhook emit नहीं करते। अपना रिएक्शन जोड़ने, बदलने या हटाने के लिए Sending reactions देखें, और webhook तथा REST API उदाहरणों के लिए Receiving reactions देखें। Contact रिएक्शन customer service window नहीं खोलते।
जिस संदेश पर react किया गया उसका reaction log contact और आपके business number दोनों द्वारा किए गए बदलाव रिकॉर्ड करता है: additions, replacements और removals।
एक मामला कहीं भी रिकॉर्ड नहीं होता। Bird एक provider ID के ज़रिए रिएक्शन को उसके संदेश से मिलाता है जिसे वह 15 दिन तक रखता है, जबकि WhatsApp 30 दिन पुराने संदेश तक रिएक्शन स्वीकार करता है, इसलिए उससे पुराने संदेश पर रखा गया रिएक्शन match नहीं हो पाता और न तो log में पहुँचता है न reactions में। इसलिए बिना किसी entry वाला संदेश इस बात का प्रमाण नहीं है कि किसी ने उस पर react नहीं किया।
उस log को GET /v1/whatsapp/messages/{message_id}/reaction-events से पढ़ें, नवीनतम पहले। एक entry emoji, बदलाव करने वाला, और received, sent, failed, या rejected का एक status बताती है; एक failed या rejected entry कारण error पर carry करती है। प्रत्येक entry में एक reaction ID (war_…) और एक occurred_at timestamp होता है। removal में emoji: null होता है। pending बदलावों की entry तब तक नहीं होती जब तक उनका परिणाम ज्ञात न हो। रिएक्शन पर कभी शुल्क नहीं लगता, इसलिए वहाँ कोई failure billing वाला नहीं है। बदलावों के इतिहास के बजाय संदेश पर वर्तमान में क्या है, इसके लिए इसके reactions को GET /v1/whatsapp/messages/{message_id} से पढ़ें, जो log को प्रति sender एक entry में समेट देता है।

Suppression इवेंट

प्रति-संदेश lifecycle के अलावा, एक इवेंट वर्कस्पेस की suppression list में बदलाव की रिपोर्ट करता है: whatsapp_suppression.created तब fire होता है जब कोई suppression खुलता है। पेलोड suppression_id, E.164 फ़ॉर्मेट में suppressed address, जिस waba तक block सीमित है (null जब यह पूरे वर्कस्पेस को cover करता है, चाहे कोई भी account भेजे), reason, और workspace_id carry करता है, ताकि आपका अपना सिस्टम बिना polling के नए blocks देख सके। केवल openings इवेंट fire करती हैं: suppression समाप्त करना अभी fire नहीं करता, इसलिए किसी mirrored block को अभी भी चालू मानने से पहले list दोबारा पढ़ें:
कोड उदाहरण
{
  "type": "whatsapp_suppression.created",
  "timestamp": "2026-08-25T14:52:03.192524705Z",
  "data": {
    "suppression_id": "was_01krdgeqcxet5s7t44vh8rt9mg",
    "address": "+14155550100",
    "waba": null,
    "reason": "manual",
    "workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf"
  }
}
प्राप्तकर्ता द्वारा स्वयं बताया गया opt-out suppression के बजाय एक preference है, और इसके बदले preference.revoked fire करता है।

API से इवेंट पढ़ना

GET /v1/whatsapp/messages/{message_id}/events टाइमलाइन कालक्रम के अनुसार लौटाता है। bounded list paginated नहीं है। इवेंट पढ़ने के लिए whatsapp:read वाली एक API key आवश्यक है:
const { data } = await bird.whatsapp.listEvents("wa_abc123");
for (const event of data) console.log(event.type, event.occurred_at);
एक संदेश जो accepted, sent, delivered और read हुआ, चार इवेंट लौटाता है:
कोड उदाहरण
{
  "data": [
    {
      "id": "ev_01ky7q6a1fejfbvs0myn41hj41",
      "occurred_at": "2026-07-23T14:48:34.71Z",
      "type": "whatsapp.accepted"
    },
    {
      "id": "ev_01ky7q6a2denvtd6jg1vqwmg13",
      "occurred_at": "2026-07-23T14:48:35.671Z",
      "type": "whatsapp.sent"
    },
    {
      "id": "ev_01ky7q6a2zff9r2qm74mmg1g6z",
      "occurred_at": "2026-07-23T14:48:36.642Z",
      "type": "whatsapp.delivered"
    },
    {
      "id": "ev_01ky7q6c21frssf0vj8h50qysw",
      "occurred_at": "2026-07-23T14:48:38.65Z",
      "type": "whatsapp.read"
    }
  ]
}
एक exact public event type लौटाने के लिए type पास करें, जैसे ?type=whatsapp.failed या ?type=whatsapp.read। पूरी टाइमलाइन के लिए इसे छोड़ दें।
यही टाइमलाइन WhatsApp log पेज तब रेंडर करता है जब आप कोई संदेश खोलते हैं।
Bird डैशबोर्ड में WhatsApp संदेश विवरण शीट, एक delivered bird_order_confirmation संदेश के लिए खोली गई: Events टैब प्रति-संदेश lifecycle टाइमलाइन दिखा रहा है, Accepted, Sent, Delivered, और Read, प्रत्येक अपने timestamp के साथ, धुँधली संदेश सूची के ऊपर

Webhooks

Webhooks पेज या webhooks API से whatsapp.accepted, whatsapp.sent, whatsapp.delivered, whatsapp.read, whatsapp.failed, whatsapp.rejected, whatsapp.received, और whatsapp.reacted की सदस्यता लें। Webhooks guide में endpoints, signatures, और retries शामिल हैं।
whatsapp.received ऊपर दिए गए एन्वेलप के साथ संदेश का content carry करता है, ताकि कोई endpoint इनबाउंड संदेश को वापस पढ़े बिना उस पर कार्रवाई कर सके। किसी interactive संदेश पर टैप interactive_reply के रूप में आता है, और in_reply_to_message_id उस संदेश को नाम देता है जिसका यह उत्तर है:
कोड उदाहरण
{
  "data": {
    "direction": "inbound",
    "from": {
      "display_name": "Alex Rivera",
      "phone_number": "+14155550100",
      "username": "alexr"
    },
    "in_reply_to_message_id": "wam_01ky7qbvswf3fvyaw3az90391c",
    "interactive_reply": {
      "list": {
        "description": "Next day to 2 days",
        "slug": "priority_express",
        "text": "Priority Mail Express"
      },
      "type": "list"
    },
    "metadata": null,
    "tags": null,
    "to": { "phone_number": "+13124495569" },
    "whatsapp_id": "wam_01ky8b3xq4gd7pmzn2ka51f7te",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b"
  },
  "timestamp": "2026-07-23T14:52:04.118Z",
  "type": "whatsapp.received"
}
अन्य content arms उसी one-of-these आकार का पालन करते हैं: text, image, video, audio, sticker, document, location, contact_cards, और unsupported उस kind के लिए जिसे API model नहीं करता। GET /v1/whatsapp/messages/{message_id} प्रत्येक को document करता है।

Reactions

whatsapp.reacted तब fire होता है जब कोई WhatsApp उपयोगकर्ता आपके किसी संदेश पर react करता है। यह एकमात्र WhatsApp इवेंट है जो किसी संदेश की delivery टाइमलाइन का हिस्सा नहीं है: यह GET /v1/whatsapp/messages/{message_id}/events में दिखाई नहीं देता, और वहाँ इसे filter करने का कोई तरीक़ा नहीं है।
whatsapp_id उस संदेश को नाम देता है जिस पर react किया गया, रिएक्शन को नहीं, और emoji उपयोगकर्ता द्वारा किया गया बदलाव है। कोई उपयोगकर्ता जो react करता है, अपना emoji बदलता है, फिर रिएक्शन वापस लेता है, उस एक संदेश पर तीन इवेंट उत्पन्न करता है। WhatsApp पहले दोनों के बीच कोई removal नहीं भेजता, इसलिए बदलाव नया emoji carry करने वाले एक ही इवेंट के रूप में आता है।
कोड उदाहरण
{
  "data": {
    "emoji": "👍",
    "from": { "phone_number": "+14155550100" },
    "to": { "phone_number": "+13124495569" },
    "whatsapp_id": "wam_01ky8b3xq4gd7pmzn2ka51f7te",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b"
  },
  "timestamp": "2026-07-23T14:52:11.000Z",
  "type": "whatsapp.reacted"
}
WhatsApp रिएक्शन समय को सेकंड तक रिपोर्ट करता है, इसलिए उन तीन इवेंट में से दो एक ही timestamp साझा कर सकते हैं। उनके अनुसार sort करने से उनका क्रम तय नहीं होगा, और न ही delivery क्रम से, जिसे retries अविश्वसनीय बनाते हैं। प्रत्येक इवेंट जो रिएक्शन carry करता है उस पर कार्रवाई करें, जो बदलाव वह बताता है उसी रूप में। इवेंट से अनुक्रम पुनर्निर्माण न करें या अंतिम आने वाले को संदेश का स्थायी रिएक्शन न मानें, क्योंकि न timestamps और न ही arrival क्रम इसका समर्थन करता है। मौजूद रिएक्शन के लिए संदेश वापस पढ़ें: GET /v1/whatsapp/messages/{message_id} reactions में प्रति sender एक entry लौटाता है, और संदेश के reaction log में हर बदलाव है।
emoji मौजूद होता है और null होता है जब उपयोगकर्ता ने अपना रिएक्शन वापस लिया, इसलिए null स्वयं removal है न कि कोई missing value। emoji ठीक वैसे ही deliver होता है जैसे WhatsApp ने भेजा और यह normalized नहीं होता, इसलिए और ❤️ आपके पास अलग-अलग strings के रूप में पहुँचते हैं।

अगले कदम

  • Receiving reactions: contact reaction webhooks हैंडल करें और मौजूदा reactions पढ़ें
  • Sending reactions: अपना रिएक्शन जोड़ें, बदलें, या हटाएँ
  • Mark message as read: इनबाउंड संदेश acknowledge करें और typing दिखाएँ
  • WhatsApp log: प्रति-संदेश व्यू जो इस टाइमलाइन को रेंडर करता है
  • WhatsApp संदेश भेजना: जहाँ संदेश का lifecycle शुरू होता है
  • Webhooks guide: endpoints, signatures, retries, और पूरा event catalog