डेवलपर दस्तावेज़

Webhooks

Webhooks साइन की हुई सूचनाएं हैं जो बताती हैं कि नोट बदला है। नया कंटेंट REST API से प्राप्त करें।

Webhook इवेंट्स

इवेंटकब ट्रिगर होता है
note.endedरिकॉर्डिंग सेशन पूरा हुआ और उसका फ़ाइनल ट्रांसक्रिप्ट लाया जा सकता है। हर रिकॉर्डिंग सेशन पर एक बार ट्रिगर होता है — कई सेशन वाले नोट में यह कई बार आता है।
note.summary.generatedसारांश बन चुका है और उसे लाया जा सकता है।
note.updatedनोट खत्म होने के बाद बाहर दिखने वाले फ़ील्ड (title, content) बदले। यह debounced है — जल्दी-जल्दी किए गए एडिट एक ही इवेंट में सिमट जाते हैं।
note.deletedनोट डिलीट हुआ (data.reason: "deleted") या आपके credential की visibility scope से बाहर चला गया (data.reason: "access_lost")।

दो सर्विस इवेंट भी हैं: endpoint.verification (endpoint बनाते समय और URL बदलने पर भेजा जाता है; 2xx से जवाब देने पर endpoint एक्टिव हो जाता है) और endpoint.test (जब आप कंसोल में "Send test" दबाते हैं या test API कॉल करते हैं)।

Request body

Webhooks हल्की सूचनाएं हैं: इनमें सिर्फ़ identifier और status होते हैं, ट्रांसक्रिप्ट या सारांश का कंटेंट कभी नहीं। कंटेंट note_id के ज़रिए REST API से लाएं।

JSON
{
  "event_id": "5f8c0a5e-...",
  "event_type": "note.ended",
  "occurred_at": "2026-08-12T05:20:00Z",
  "data": {
    "note_id": "note_abc123",
    "recording_session_id": "rec_456",
    "revision": 7,
    "transcript_status": "ready",
    "summary_status": "pending"
  }
}

सिग्नेचर जांचें

हर delivery, endpoint बनाते समय जारी हुए whsec_... secret से Standard Webhooks स्पेसिफ़िकेशन के अनुसार साइन की जाती है:

HTTP
POST /webhooks/alt HTTP/1.1
Content-Type: application/json
webhook-id: 5f8c0a5e-...
webhook-timestamp: 1765515600
webhook-signature: v1,K5oZfzN95Z9UVu1EsPQmSmZQGGVfCM0jaZ0lPI4dvLU=
signature
signed_content = "{webhook-id}.{webhook-timestamp}.{raw request body}"
signature     = base64( HMAC-SHA256( base64url_decode(secret_after_whsec_), signed_content ) )
  • वेरिफ़िकेशन raw request body पर करें — JSON को दोबारा serialize न करें।
  • सिग्नेचर की तुलना constant-time comparison से करें।
  • replay attack रोकने के लिए पुराने timestamp अस्वीकार करें (हम ±5 मिनट की सहनशीलता सुझाते हैं)।
  • जिन अनुरोधों का सिग्नेचर मेल न खाए, उन्हें 4xx के साथ अस्वीकार करें। चालू रिसीवर कोड यहाँ है: क्विकस्टार्ट का चरण 4

Delivery failures और retries

  • 10 सेकंड के भीतर 2xx से जवाब दें। बाकी सब कुछ failure माना जाता है। पहले ack करें, प्रोसेसिंग asynchronously करें।
  • विफल deliveries को बढ़ते backoff के साथ दोबारा भेजा जाता है (30s → 5m → 30m → 2h → 12h → 12h, कुल अधिकतम 7 प्रयास)।
  • लगातार कई deliveries में विफल रहने वाला endpoint अपने आप disable कर दिया जाता है।
  • Redirect फ़ॉलो नहीं किए जाते; webhook URL को HTTPS पर सीधे जवाब देना होगा।

डुप्लिकेट इवेंट संभालें

Delivery at-least-once है: एक ही इवेंट एक से ज़्यादा बार आ सकता है (retries, कंसोल से replay)। प्रोसेस किए गए event_id का थोड़े समय का रिकॉर्ड रखें और डुप्लिकेट छोड़ दें।

गलत क्रम में आए इवेंट संभालें

इवेंट क्रम से बाहर भी आ सकते हैं (retries, समानांतर deliveries)। यह न मानें कि सबसे बाद में आया इवेंट ही नवीनतम स्थिति है। बाहर दिखने वाला हर बदलाव नोट के revision को बढ़ाता है (सर्वर द्वारा दिया गया, monotonic): हर नोट के लिए आपने जो revision लागू किया है उसे सेव रखें, और उससे बराबर या कम revision वाली हर चीज़ अनदेखा करें। संदेह हो तो नोट को REST API से दोबारा fetch करें — यह हमेशा मौजूदा revision लौटाता है।

छूटे बदलाव जांचें

  • Webhooks छूट भी सकते हैं (retry window से लंबा downtime, disable हो चुके endpoints)। समय-समय पर GET /v1/notes?updated_after=<last sync> कॉल करके छूटा हुआ डेटा भर लें।
  • reason: "access_lost" के साथ आया note.deleted का मतलब है कि नोट आपके credential की scope से बाहर चला गया (जैसे कोई पर्सनल नोट teamspace में चला गया)। इसे बिल्कुल डिलीशन की तरह ही संभालें: अपनी सेव की हुई कॉपी हटा दें या उस तक पहुँच बंद कर दें।
  • सिर्फ़ incremental polling से डिलीशन या scope से बाहर जाना पता नहीं चलता। समय-समय पर सभी नोट्स लिस्ट करें (include_deleted=true लगाने पर tombstone भी दिखते हैं): आपके पास मौजूद कोई भी note ID जो अब लिस्ट में नहीं है, या तो डिलीट हो चुका है या आपकी scope से बाहर चला गया है।