[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fwebhooks":3},{"_path":4,"title":5,"description":6,"navigation":7,"image":12,"head":17,"body":36},"\u002Fdocs\u002Fwebhooks","Webhooks · Waitlister Documentation","Learn how to set up webhooks to receive real-time notifications for waitlist events and integrate with external systems.",{"title":8,"group":9,"description":10,"order":11},"Webhooks","Features","Receive real-time HTTP notifications for waitlist events including sign-ups, referrals, and milestones to automate workflows.",11,{"src":13,"width":14,"height":15,"alt":16},"https:\u002F\u002Ffirebasestorage.googleapis.com\u002Fv0\u002Fb\u002Fwaitinglist-app-c24fc.appspot.com\u002Fo\u002Fresources%2Ffeatures%2Ffeature-webhooks.webp?alt=media&token=72244cd3-17f1-4cc5-a55e-b094c92f581c",400,300,"Waitlister Webhooks Documentation",{"meta":18,"og":31,"twitter":33},[19,22,25,28],{"name":20,"content":21},"keywords","webhooks, http callbacks, real-time notifications, integrations, automation, webhook security, hmac verification, developer tools",{"name":23,"content":24},"robots","index, follow",{"name":26,"content":27},"author","Waitlister",{"name":29,"content":30},"copyright","© 2026 Waitlister",{"title":5,"description":6,"type":32,"image":13},"article",{"card":34,"title":35,"description":6,"image":13},"summary_large_image","Webhooks with Waitlister",{"type":37,"children":38,"toc":1110},"root",[39,52,58,66,71,79,86,91,147,153,158,165,175,180,186,195,200,206,215,220,226,235,240,246,255,260,266,272,277,315,321,326,380,386,391,434,440,461,467,480,486,495,501,510,516,525,531,540,546,552,557,564,572,578,586,598,609,617,628,636,647,653,659,664,707,713,718,741,747,752,775,781,786,809,815,836,864,870,876,884,907,915,933,941,959,967,990,996,1001,1034,1040,1046,1051,1074,1080,1085],{"type":40,"tag":41,"props":42,"children":43},"element","p",{},[44],{"type":40,"tag":45,"props":46,"children":49},"span",{"className":47},[48],"secondary-heading",[50],{"type":51,"value":9},"text",{"type":40,"tag":53,"props":54,"children":56},"h1",{"id":55},"webhooks",[57],{"type":51,"value":8},{"type":40,"tag":41,"props":59,"children":60},{},[61],{"type":40,"tag":62,"props":63,"children":65},"img",{"alt":64,"src":13},"Webhooks overview",[],{"type":40,"tag":41,"props":67,"children":68},{},[69],{"type":51,"value":70},"Webhooks allow you to receive real-time HTTP notifications for various waitlist events. This enables you to automate workflows, update external systems, and create custom integrations with your favorite tools.",{"type":40,"tag":72,"props":73,"children":76},"div",{"className":74},[75],"note",[77],{"type":51,"value":78},"Webhooks are available on the Growth plan and above.",{"type":40,"tag":80,"props":81,"children":83},"h2",{"id":82},"benefits-of-webhooks",[84],{"type":51,"value":85},"Benefits of Webhooks",{"type":40,"tag":41,"props":87,"children":88},{},[89],{"type":51,"value":90},"Using webhooks with your waitlist provides powerful automation capabilities.",{"type":40,"tag":92,"props":93,"children":94},"ol",{},[95,107,117,127,137],{"type":40,"tag":96,"props":97,"children":98},"li",{},[99,105],{"type":40,"tag":100,"props":101,"children":102},"strong",{},[103],{"type":51,"value":104},"Real-time Integration",{"type":51,"value":106},": Instantly sync new subscribers to your CRM, email platform, or analytics tools",{"type":40,"tag":96,"props":108,"children":109},{},[110,115],{"type":40,"tag":100,"props":111,"children":112},{},[113],{"type":51,"value":114},"Multiple Event Types",{"type":51,"value":116},": Receive notifications for sign-ups, referrals, and milestone achievements",{"type":40,"tag":96,"props":118,"children":119},{},[120,125],{"type":40,"tag":100,"props":121,"children":122},{},[123],{"type":51,"value":124},"Custom Workflows",{"type":51,"value":126},": Trigger automated processes like Slack notifications, database updates, or custom logic",{"type":40,"tag":96,"props":128,"children":129},{},[130,135],{"type":40,"tag":100,"props":131,"children":132},{},[133],{"type":51,"value":134},"Reliable Delivery",{"type":51,"value":136},": Secure HTTPS delivery with HMAC verification and automatic retry logic",{"type":40,"tag":96,"props":138,"children":139},{},[140,145],{"type":40,"tag":100,"props":141,"children":142},{},[143],{"type":51,"value":144},"Complete Data",{"type":51,"value":146},": Receive subscriber information including metadata and referral details",{"type":40,"tag":80,"props":148,"children":150},{"id":149},"webhook-events",[151],{"type":51,"value":152},"Webhook Events",{"type":40,"tag":41,"props":154,"children":155},{},[156],{"type":51,"value":157},"Waitlister supports three webhook event types that you can enable or disable individually.",{"type":40,"tag":159,"props":160,"children":162},"h3",{"id":161},"new-sign-ups",[163],{"type":51,"value":164},"New Sign-ups",{"type":40,"tag":41,"props":166,"children":167},{},[168],{"type":40,"tag":169,"props":170,"children":172},"code",{"className":171},[],[173],{"type":51,"value":174},"waitlist.signup_created",{"type":40,"tag":41,"props":176,"children":177},{},[178],{"type":51,"value":179},"Triggered when someone joins your waitlist. Use this to sync subscribers to your CRM, send custom welcome emails, or update analytics.",{"type":40,"tag":159,"props":181,"children":183},{"id":182},"referrals-completed",[184],{"type":51,"value":185},"Referrals Completed",{"type":40,"tag":41,"props":187,"children":188},{},[189],{"type":40,"tag":169,"props":190,"children":192},{"className":191},[],[193],{"type":51,"value":194},"waitlist.referral_completed",{"type":40,"tag":41,"props":196,"children":197},{},[198],{"type":51,"value":199},"Triggered when a subscriber successfully refers someone new. Use this to reward top referrers, send thank-you messages, or track viral growth.",{"type":40,"tag":159,"props":201,"children":203},{"id":202},"milestones-reached",[204],{"type":51,"value":205},"Milestones Reached",{"type":40,"tag":41,"props":207,"children":208},{},[209],{"type":40,"tag":169,"props":210,"children":212},{"className":211},[],[213],{"type":51,"value":214},"waitlist.milestone_reached",{"type":40,"tag":41,"props":216,"children":217},{},[218],{"type":51,"value":219},"Triggered when a subscriber reaches a configurable points threshold. Use this to unlock rewards, grant early access, or celebrate achievements with your community.",{"type":40,"tag":159,"props":221,"children":223},{"id":222},"subscriber-unsubscribed",[224],{"type":51,"value":225},"Subscriber Unsubscribed",{"type":40,"tag":41,"props":227,"children":228},{},[229],{"type":40,"tag":169,"props":230,"children":232},{"className":231},[],[233],{"type":51,"value":234},"waitlist.subscriber_unsubscribed",{"type":40,"tag":41,"props":236,"children":237},{},[238],{"type":51,"value":239},"Triggered when a subscriber unsubscribes from your waitlist. Use this to update your CRM, remove users from email sequences, or track churn.",{"type":40,"tag":159,"props":241,"children":243},{"id":242},"subscriber-pending-expired",[244],{"type":51,"value":245},"Subscriber Pending Expired",{"type":40,"tag":41,"props":247,"children":248},{},[249],{"type":40,"tag":169,"props":250,"children":252},{"className":251},[],[253],{"type":51,"value":254},"waitlist.subscriber_pending_expired",{"type":40,"tag":41,"props":256,"children":257},{},[258],{"type":51,"value":259},"Triggered when a subscriber doesn't confirm their double opt-in email before the expiry window (24, 48, or 72 hours based on your setting). Use this to send re-engagement emails, add unconfirmed leads to a remarketing list, or track opt-in conversion rates.",{"type":40,"tag":80,"props":261,"children":263},{"id":262},"setting-up-webhooks",[264],{"type":51,"value":265},"Setting Up Webhooks",{"type":40,"tag":159,"props":267,"children":269},{"id":268},"configuring-your-webhook",[270],{"type":51,"value":271},"Configuring Your Webhook",{"type":40,"tag":41,"props":273,"children":274},{},[275],{"type":51,"value":276},"To set up a webhook for your waitlist, follow these steps.",{"type":40,"tag":92,"props":278,"children":279},{},[280,285,290,295,300,305,310],{"type":40,"tag":96,"props":281,"children":282},{},[283],{"type":51,"value":284},"Navigate to your waitlist dashboard",{"type":40,"tag":96,"props":286,"children":287},{},[288],{"type":51,"value":289},"Go to \"Integrations\" in the sidebar navigation",{"type":40,"tag":96,"props":291,"children":292},{},[293],{"type":51,"value":294},"Click \"Manage\" on the \"Webhooks\" card",{"type":40,"tag":96,"props":296,"children":297},{},[298],{"type":51,"value":299},"Enter your webhook URL and optional secret",{"type":40,"tag":96,"props":301,"children":302},{},[303],{"type":51,"value":304},"Select which events you want to receive",{"type":40,"tag":96,"props":306,"children":307},{},[308],{"type":51,"value":309},"Configure milestone thresholds (for milestone events)",{"type":40,"tag":96,"props":311,"children":312},{},[313],{"type":51,"value":314},"Test your webhook to make sure it's working correctly",{"type":40,"tag":159,"props":316,"children":318},{"id":317},"event-configuration",[319],{"type":51,"value":320},"Event Configuration",{"type":40,"tag":41,"props":322,"children":323},{},[324],{"type":51,"value":325},"You can enable or disable each event type independently:",{"type":40,"tag":327,"props":328,"children":329},"ul",{},[330,340,350,360,370],{"type":40,"tag":96,"props":331,"children":332},{},[333,338],{"type":40,"tag":100,"props":334,"children":335},{},[336],{"type":51,"value":337},"New sign-ups",{"type":51,"value":339},": Always available and enabled by default",{"type":40,"tag":96,"props":341,"children":342},{},[343,348],{"type":40,"tag":100,"props":344,"children":345},{},[346],{"type":51,"value":347},"Referrals completed",{"type":51,"value":349},": Enable to track when subscribers refer others",{"type":40,"tag":96,"props":351,"children":352},{},[353,358],{"type":40,"tag":100,"props":354,"children":355},{},[356],{"type":51,"value":357},"Milestones reached",{"type":51,"value":359},": Configure point thresholds (default: 100, 200, 300, 500, 1000 points)",{"type":40,"tag":96,"props":361,"children":362},{},[363,368],{"type":40,"tag":100,"props":364,"children":365},{},[366],{"type":51,"value":367},"Subscriber unsubscribed",{"type":51,"value":369},": Enable to track when subscribers leave your waitlist",{"type":40,"tag":96,"props":371,"children":372},{},[373,378],{"type":40,"tag":100,"props":374,"children":375},{},[376],{"type":51,"value":377},"Pending sign-up expired",{"type":51,"value":379},": Enable to get notified when double opt-in confirmations expire (requires double opt-in to be enabled)",{"type":40,"tag":159,"props":381,"children":383},{"id":382},"webhook-url-requirements",[384],{"type":51,"value":385},"Webhook URL Requirements",{"type":40,"tag":41,"props":387,"children":388},{},[389],{"type":51,"value":390},"Your webhook endpoint must meet these requirements:",{"type":40,"tag":327,"props":392,"children":393},{},[394,404,414,424],{"type":40,"tag":96,"props":395,"children":396},{},[397,402],{"type":40,"tag":100,"props":398,"children":399},{},[400],{"type":51,"value":401},"HTTPS only",{"type":51,"value":403},": All webhook URLs must use secure HTTPS connections",{"type":40,"tag":96,"props":405,"children":406},{},[407,412],{"type":40,"tag":100,"props":408,"children":409},{},[410],{"type":51,"value":411},"Fast response",{"type":51,"value":413},": Your endpoint should respond within 15 seconds",{"type":40,"tag":96,"props":415,"children":416},{},[417,422],{"type":40,"tag":100,"props":418,"children":419},{},[420],{"type":51,"value":421},"Return 2xx status",{"type":51,"value":423},": Return any 2xx HTTP status code to indicate successful receipt",{"type":40,"tag":96,"props":425,"children":426},{},[427,432],{"type":40,"tag":100,"props":428,"children":429},{},[430],{"type":51,"value":431},"Handle retries",{"type":51,"value":433},": Be prepared to receive the same webhook multiple times",{"type":40,"tag":80,"props":435,"children":437},{"id":436},"webhook-payloads",[438],{"type":51,"value":439},"Webhook Payloads",{"type":40,"tag":41,"props":441,"children":442},{},[443,445,451,453,459],{"type":51,"value":444},"All payloads include both ",{"type":40,"tag":169,"props":446,"children":448},{"className":447},[],[449],{"type":51,"value":450},"position",{"type":51,"value":452}," (the real internal position) and ",{"type":40,"tag":169,"props":454,"children":456},{"className":455},[],[457],{"type":51,"value":458},"inflated_position",{"type":51,"value":460}," (the public-facing position with any configured position inflation offset applied). When no inflation is configured, both values are identical.",{"type":40,"tag":159,"props":462,"children":464},{"id":463},"new-sign-up-event",[465],{"type":51,"value":466},"New Sign-up Event",{"type":40,"tag":468,"props":469,"children":475},"pre",{"code":470,"language":471,"meta":472,"className":473},"{\n  \"event\": \"waitlist.signup_created\",\n  \"timestamp\": \"2025-01-15T10:30:00Z\",\n  \"data\": {\n    \"id\": \"signup_abc123\",\n    \"email\": \"user@example.com\",\n    \"name\": \"John Doe\",\n    \"phone\": \"+1 123 4567\",\n    \"position\": 42,\n    \"inflated_position\": 42,\n    \"points\": 50,\n    \"referral_code\": \"happy-star-4f3d\",\n    \"referred_by\": \"friend-code-123\",\n    \"signup_token\": \"abc123xyz789token\",\n    \"thank_you_url\": \"https:\u002F\u002Fwaitlister.me\u002Fthank-you\u002Fyour-waitlist-key\u002Fabc123xyz789token\",\n    \"waitlist\": {\n      \"key\": \"your-waitlist-key\"\n    },\n    \"metadata\": {\n      \"referring_domain\": \"google.com\",\n      \"user_agent\": \"Mozilla\u002F5.0...\",\n      \"source\": \"landing-page\",\n      \"origin_url\": \"https:\u002F\u002Fyoursite.com\",\n      \"ip_address\": \"192.168.1.1\", \n      \"city\": \"New York\",\n      \"region\": \"NY\",\n      \"country\": \"US\",\n      \"timezone\": \"America\u002FNew_York\",\n      \"custom_fields\": {},\n      \"signup_date\": 1642248600000\n    }\n  }\n}\n","json","",[474],"language-json",[476],{"type":40,"tag":169,"props":477,"children":478},{"__ignoreMap":472},[479],{"type":51,"value":470},{"type":40,"tag":159,"props":481,"children":483},{"id":482},"referral-completed-event",[484],{"type":51,"value":485},"Referral Completed Event",{"type":40,"tag":468,"props":487,"children":490},{"code":488,"language":471,"meta":472,"className":489},"{\n  \"event\": \"waitlist.referral_completed\",\n  \"timestamp\": \"2025-01-15T11:45:00Z\",\n  \"data\": {\n    \"referrer\": {\n      \"id\": \"signup_abc123\",\n      \"email\": \"referrer@example.com\",\n      \"name\": \"Jane Doe\",\n      \"points\": 80,\n      \"position\": 15,\n      \"inflated_position\": 15,\n      \"total_referrals\": 2,\n      \"referral_code\": \"happy-star-4f3d\",\n      \"signup_token\": \"referrer_token_abc123\"\n    },\n    \"new_signup\": {\n      \"id\": \"signup_xyz789\",\n      \"email\": \"newuser@example.com\",\n      \"name\": \"Bob Smith\",\n      \"referred_by\": \"happy-star-4f3d\",\n      \"signup_token\": \"newsignup_token_xyz789\"\n    },\n    \"points_earned\": 30,\n    \"waitlist\": {\n      \"key\": \"your-waitlist-key\"\n    }\n  }\n}\n",[474],[491],{"type":40,"tag":169,"props":492,"children":493},{"__ignoreMap":472},[494],{"type":51,"value":488},{"type":40,"tag":159,"props":496,"children":498},{"id":497},"milestone-reached-event",[499],{"type":51,"value":500},"Milestone Reached Event",{"type":40,"tag":468,"props":502,"children":505},{"code":503,"language":471,"meta":472,"className":504},"{\n  \"event\": \"waitlist.milestone_reached\",\n  \"timestamp\": \"2025-01-15T12:00:00Z\",\n  \"data\": {\n    \"subscriber\": {\n      \"id\": \"signup_abc123\",\n      \"email\": \"user@example.com\",\n      \"name\": \"John Doe\",\n      \"points\": 100,\n      \"previous_points\": 85,\n      \"position\": 12,\n      \"inflated_position\": 12,\n      \"referral_code\": \"happy-star-4f3d\",\n      \"signup_token\": \"subscriber_token_def456\"\n    },\n    \"milestone\": {\n      \"points\": 100,\n      \"reached_at\": 1642249200000\n    },\n    \"waitlist\": {\n      \"key\": \"your-waitlist-key\"\n    }\n  }\n}\n",[474],[506],{"type":40,"tag":169,"props":507,"children":508},{"__ignoreMap":472},[509],{"type":51,"value":503},{"type":40,"tag":159,"props":511,"children":513},{"id":512},"subscriber-unsubscribed-event",[514],{"type":51,"value":515},"Subscriber Unsubscribed Event",{"type":40,"tag":468,"props":517,"children":520},{"code":518,"language":471,"meta":472,"className":519},"{\n  \"event\": \"waitlist.subscriber_unsubscribed\",\n  \"timestamp\": \"2025-01-15T14:30:00Z\",\n  \"data\": {\n    \"subscriber\": {\n      \"id\": \"signup_abc123\",\n      \"email\": \"user@example.com\",\n      \"name\": \"John Doe\",\n      \"phone\": \"+1 123 4567\",\n      \"position\": 42,\n      \"inflated_position\": 42,\n      \"points\": 80,\n      \"referral_code\": \"happy-star-4f3d\",\n      \"signup_token\": \"abc123xyz789token\",\n      \"signed_up_at\": 1642248600000\n    },\n    \"unsubscribe\": {\n      \"source\": \"manual\",\n      \"unsubscribed_at\": 1642335000000\n    },\n    \"waitlist\": {\n      \"key\": \"your-waitlist-key\"\n    },\n    \"metadata\": {\n      \"ip_address\": \"192.168.1.1\",\n      \"city\": \"New York\",\n      \"region\": \"NY\",\n      \"country\": \"US\",\n      \"custom_fields\": {}\n    }\n  }\n}\n",[474],[521],{"type":40,"tag":169,"props":522,"children":523},{"__ignoreMap":472},[524],{"type":51,"value":518},{"type":40,"tag":159,"props":526,"children":528},{"id":527},"subscriber-pending-expired-event",[529],{"type":51,"value":530},"Subscriber Pending Expired Event",{"type":40,"tag":468,"props":532,"children":535},{"code":533,"language":471,"meta":472,"className":534},"{\n  \"event\": \"waitlist.subscriber_pending_expired\",\n  \"timestamp\": \"2025-01-15T16:00:00Z\",\n  \"data\": {\n    \"id\": \"pending_abc123\",\n    \"email\": \"user@example.com\",\n    \"name\": \"John Doe\",\n    \"phone\": \"+1 123 4567\",\n    \"waitlist\": {\n      \"key\": \"your-waitlist-key\"\n    },\n    \"pending\": {\n      \"created_at\": 1642248600000,\n      \"expired_at\": 1642421400000,\n      \"email_sent\": true\n    },\n    \"metadata\": {\n      \"source\": \"landing-page\",\n      \"origin_url\": \"https:\u002F\u002Fyoursite.com\",\n      \"ip_address\": \"192.168.1.1\",\n      \"city\": \"New York\",\n      \"region\": \"NY\",\n      \"country\": \"US\",\n      \"timezone\": \"America\u002FNew_York\",\n      \"custom_fields\": {}\n    }\n  }\n}\n",[474],[536],{"type":40,"tag":169,"props":537,"children":538},{"__ignoreMap":472},[539],{"type":51,"value":533},{"type":40,"tag":80,"props":541,"children":543},{"id":542},"security-verification",[544],{"type":51,"value":545},"Security & Verification",{"type":40,"tag":159,"props":547,"children":549},{"id":548},"hmac-signature-verification",[550],{"type":51,"value":551},"HMAC Signature Verification",{"type":40,"tag":41,"props":553,"children":554},{},[555],{"type":51,"value":556},"For added security, you can configure a webhook secret. When provided, we'll include an HMAC SHA-256 signature in the request headers.",{"type":40,"tag":558,"props":559,"children":561},"h4",{"id":560},"headers",[562],{"type":51,"value":563},"Headers",{"type":40,"tag":468,"props":565,"children":567},{"code":566},"X-Webhook-Signature: sha256=your-computed-signature\nX-Waitlister-Event: waitlist.signup_created | waitlist.referral_completed | waitlist.milestone_reached | waitlist.subscriber_unsubscribed | waitlist.subscriber_pending_expired\nX-Waitlister-Delivery: unique-delivery-id\nX-Waitlister-Timestamp: 2025-01-15T10:30:00Z\n",[568],{"type":40,"tag":169,"props":569,"children":570},{"__ignoreMap":472},[571],{"type":51,"value":566},{"type":40,"tag":558,"props":573,"children":575},{"id":574},"verification-examples",[576],{"type":51,"value":577},"Verification Examples",{"type":40,"tag":41,"props":579,"children":580},{},[581],{"type":40,"tag":100,"props":582,"children":583},{},[584],{"type":51,"value":585},"Node.js",{"type":40,"tag":41,"props":587,"children":588},{},[589,591,596],{"type":51,"value":590},"The HMAC signature is computed over the ",{"type":40,"tag":100,"props":592,"children":593},{},[594],{"type":51,"value":595},"raw request body",{"type":51,"value":597},", so you must access the unparsed bytes — not a re-serialized object. Configure Express to expose the raw body:",{"type":40,"tag":468,"props":599,"children":604},{"code":600,"language":601,"meta":472,"className":602},"const crypto = require('crypto');\nconst express = require('express');\nconst app = express();\n\n\u002F\u002F Preserve the raw body for webhook signature verification\napp.use(express.json({\n  verify: (req, res, buf) => { req.rawBody = buf; }\n}));\n\nfunction verifyWebhook(rawBody, signature, secret) {\n  const expectedSignature = 'sha256=' +\n    crypto.createHmac('sha256', secret)\n          .update(rawBody)\n          .digest('hex');\n\n  return crypto.timingSafeEqual(\n    Buffer.from(signature),\n    Buffer.from(expectedSignature)\n  );\n}\n\n\u002F\u002F Usage\nconst isValid = verifyWebhook(\n  req.rawBody,\n  req.headers['x-webhook-signature'],\n  'your-secret'\n);\n\n\u002F\u002F Handle different event types\nconst event = req.body.event;\nswitch (event) {\n  case 'waitlist.signup_created':\n    \u002F\u002F Handle new sign-up\n    break;\n  case 'waitlist.referral_completed':\n    \u002F\u002F Handle referral\n    break;\n  case 'waitlist.milestone_reached':\n    \u002F\u002F Handle milestone\n    break;\n  case 'waitlist.subscriber_unsubscribed':\n    \u002F\u002F Handle unsubscribe\n    break;\n  case 'waitlist.subscriber_pending_expired':\n    \u002F\u002F Handle expired pending sign-up\n    break;\n}\n","javascript",[603],"language-javascript",[605],{"type":40,"tag":169,"props":606,"children":607},{"__ignoreMap":472},[608],{"type":51,"value":600},{"type":40,"tag":41,"props":610,"children":611},{},[612],{"type":40,"tag":100,"props":613,"children":614},{},[615],{"type":51,"value":616},"Python",{"type":40,"tag":468,"props":618,"children":623},{"code":619,"language":620,"meta":472,"className":621},"import hmac\nimport hashlib\n\ndef verify_webhook(payload, signature, secret):\n    expected_signature = 'sha256=' + hmac.new(\n        secret.encode('utf-8'),\n        payload.encode('utf-8'),\n        hashlib.sha256\n    ).hexdigest()\n    \n    return hmac.compare_digest(signature, expected_signature)\n\n# Usage\nis_valid = verify_webhook(\n    request.get_data(as_text=True),\n    request.headers.get('X-Webhook-Signature'),\n    'your-secret'\n)\n\n# Handle different event types\nevent = request.json.get('event')\nif event == 'waitlist.signup_created':\n    # Handle new sign-up\n    signup_token = request.json['data']['signup_token']\n    thank_you_url = request.json['data']['thank_you_url']\nelif event == 'waitlist.referral_completed':\n    # Handle referral\n    pass\nelif event == 'waitlist.milestone_reached':\n    # Handle milestone\n    pass\nelif event == 'waitlist.subscriber_unsubscribed':\n    # Handle unsubscribe\n    pass\nelif event == 'waitlist.subscriber_pending_expired':\n    # Handle expired pending sign-up\n    pass\n","python",[622],"language-python",[624],{"type":40,"tag":169,"props":625,"children":626},{"__ignoreMap":472},[627],{"type":51,"value":619},{"type":40,"tag":41,"props":629,"children":630},{},[631],{"type":40,"tag":100,"props":632,"children":633},{},[634],{"type":51,"value":635},"PHP",{"type":40,"tag":468,"props":637,"children":642},{"code":638,"language":639,"meta":472,"className":640},"function verifyWebhook($payload, $signature, $secret) {\n    $expectedSignature = 'sha256=' . hash_hmac(\n        'sha256', \n        $payload, \n        $secret\n    );\n    \n    return hash_equals($signature, $expectedSignature);\n}\n\n\u002F\u002F Usage\n$isValid = verifyWebhook(\n    file_get_contents('php:\u002F\u002Finput'),\n    $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'],\n    'your-secret'\n);\n\n\u002F\u002F Handle different event types\n$event = json_decode($payload)->event;\nswitch ($event) {\n    case 'waitlist.signup_created':\n        \u002F\u002F Handle new sign-up\n        $signupToken = json_decode($payload)->data->signup_token;\n        $thankYouUrl = json_decode($payload)->data->thank_you_url;\n        break;\n    case 'waitlist.referral_completed':\n        \u002F\u002F Handle referral\n        break;\n    case 'waitlist.milestone_reached':\n        \u002F\u002F Handle milestone\n        break;\n    case 'waitlist.subscriber_unsubscribed':\n        \u002F\u002F Handle unsubscribe\n        break;\n    case 'waitlist.subscriber_pending_expired':\n        \u002F\u002F Handle expired pending sign-up\n        break;\n}\n","php",[641],"language-php",[643],{"type":40,"tag":169,"props":644,"children":645},{"__ignoreMap":472},[646],{"type":51,"value":638},{"type":40,"tag":80,"props":648,"children":650},{"id":649},"use-cases",[651],{"type":51,"value":652},"Use Cases",{"type":40,"tag":159,"props":654,"children":656},{"id":655},"reward-system-automation",[657],{"type":51,"value":658},"Reward System Automation",{"type":40,"tag":41,"props":660,"children":661},{},[662],{"type":51,"value":663},"Use milestone webhooks to automatically grant rewards when subscribers reach point thresholds:",{"type":40,"tag":327,"props":665,"children":666},{},[667,677,687,697],{"type":40,"tag":96,"props":668,"children":669},{},[670,675],{"type":40,"tag":100,"props":671,"children":672},{},[673],{"type":51,"value":674},"100 points",{"type":51,"value":676},": Send exclusive content via email",{"type":40,"tag":96,"props":678,"children":679},{},[680,685],{"type":40,"tag":100,"props":681,"children":682},{},[683],{"type":51,"value":684},"200 points",{"type":51,"value":686},": Grant early access tier 1",{"type":40,"tag":96,"props":688,"children":689},{},[690,695],{"type":40,"tag":100,"props":691,"children":692},{},[693],{"type":51,"value":694},"500 points",{"type":51,"value":696},": Unlock beta features",{"type":40,"tag":96,"props":698,"children":699},{},[700,705],{"type":40,"tag":100,"props":701,"children":702},{},[703],{"type":51,"value":704},"1000 points",{"type":51,"value":706},": Award VIP status",{"type":40,"tag":159,"props":708,"children":710},{"id":709},"referral-campaign-tracking",[711],{"type":51,"value":712},"Referral Campaign Tracking",{"type":40,"tag":41,"props":714,"children":715},{},[716],{"type":51,"value":717},"Use referral webhooks to track and incentivize your top advocates:",{"type":40,"tag":327,"props":719,"children":720},{},[721,726,731,736],{"type":40,"tag":96,"props":722,"children":723},{},[724],{"type":51,"value":725},"Send thank-you messages after each successful referral",{"type":40,"tag":96,"props":727,"children":728},{},[729],{"type":51,"value":730},"Award bonus points after 5, 10, or 25 referrals",{"type":40,"tag":96,"props":732,"children":733},{},[734],{"type":51,"value":735},"Identify power users for special outreach",{"type":40,"tag":96,"props":737,"children":738},{},[739],{"type":51,"value":740},"Track referral campaign performance in your analytics",{"type":40,"tag":159,"props":742,"children":744},{"id":743},"multi-platform-sync",[745],{"type":51,"value":746},"Multi-platform Sync",{"type":40,"tag":41,"props":748,"children":749},{},[750],{"type":51,"value":751},"Use sign-up webhooks to keep your systems in sync:",{"type":40,"tag":327,"props":753,"children":754},{},[755,760,765,770],{"type":40,"tag":96,"props":756,"children":757},{},[758],{"type":51,"value":759},"Add subscribers to your email marketing platform",{"type":40,"tag":96,"props":761,"children":762},{},[763],{"type":51,"value":764},"Update your CRM with new leads",{"type":40,"tag":96,"props":766,"children":767},{},[768],{"type":51,"value":769},"Post to Slack when someone joins",{"type":40,"tag":96,"props":771,"children":772},{},[773],{"type":51,"value":774},"Sync to your data warehouse for analytics",{"type":40,"tag":159,"props":776,"children":778},{"id":777},"re-engagement-for-unconfirmed-sign-ups",[779],{"type":51,"value":780},"Re-engagement for Unconfirmed Sign-ups",{"type":40,"tag":41,"props":782,"children":783},{},[784],{"type":51,"value":785},"Use pending expired webhooks to recover subscribers who didn't confirm their double opt-in.",{"type":40,"tag":327,"props":787,"children":788},{},[789,794,799,804],{"type":40,"tag":96,"props":790,"children":791},{},[792],{"type":51,"value":793},"Send a follow-up email via your own email platform reminding them to join",{"type":40,"tag":96,"props":795,"children":796},{},[797],{"type":51,"value":798},"Add unconfirmed leads to a remarketing audience in your ad platform",{"type":40,"tag":96,"props":800,"children":801},{},[802],{"type":51,"value":803},"Track double opt-in conversion rates to optimize your confirmation email",{"type":40,"tag":96,"props":805,"children":806},{},[807],{"type":51,"value":808},"Trigger SMS or push notifications as an alternative confirmation channel",{"type":40,"tag":159,"props":810,"children":812},{"id":811},"thank-you-page-integration",[813],{"type":51,"value":814},"Thank You Page Integration",{"type":40,"tag":41,"props":816,"children":817},{},[818,820,826,828,834],{"type":51,"value":819},"Use the ",{"type":40,"tag":169,"props":821,"children":823},{"className":822},[],[824],{"type":51,"value":825},"thank_you_url",{"type":51,"value":827}," or ",{"type":40,"tag":169,"props":829,"children":831},{"className":830},[],[832],{"type":51,"value":833},"signup_token",{"type":51,"value":835}," from sign-up webhooks to redirect users or create custom confirmation experiences:",{"type":40,"tag":327,"props":837,"children":838},{},[839,844,849,854,859],{"type":40,"tag":96,"props":840,"children":841},{},[842],{"type":51,"value":843},"Redirect users to a custom thank-you page on your domain",{"type":40,"tag":96,"props":845,"children":846},{},[847],{"type":51,"value":848},"Send personalized confirmation emails with their unique link",{"type":40,"tag":96,"props":850,"children":851},{},[852],{"type":51,"value":853},"Track conversions with the token as a URL parameter",{"type":40,"tag":96,"props":855,"children":856},{},[857],{"type":51,"value":858},"Create custom onboarding flows post-signup",{"type":40,"tag":96,"props":860,"children":861},{},[862],{"type":51,"value":863},"Build subscriber-specific dashboards or portals",{"type":40,"tag":80,"props":865,"children":867},{"id":866},"troubleshooting",[868],{"type":51,"value":869},"Troubleshooting",{"type":40,"tag":159,"props":871,"children":873},{"id":872},"common-issues",[874],{"type":51,"value":875},"Common Issues",{"type":40,"tag":41,"props":877,"children":878},{},[879],{"type":40,"tag":100,"props":880,"children":881},{},[882],{"type":51,"value":883},"Webhook not receiving requests",{"type":40,"tag":327,"props":885,"children":886},{},[887,892,897,902],{"type":40,"tag":96,"props":888,"children":889},{},[890],{"type":51,"value":891},"Verify your URL is publicly accessible and uses HTTPS",{"type":40,"tag":96,"props":893,"children":894},{},[895],{"type":51,"value":896},"Check your firewall settings allow incoming requests",{"type":40,"tag":96,"props":898,"children":899},{},[900],{"type":51,"value":901},"Ensure your endpoint returns a 2xx status code",{"type":40,"tag":96,"props":903,"children":904},{},[905],{"type":51,"value":906},"Verify the event type is enabled in your webhook configuration",{"type":40,"tag":41,"props":908,"children":909},{},[910],{"type":40,"tag":100,"props":911,"children":912},{},[913],{"type":51,"value":914},"Intermittent failures",{"type":40,"tag":327,"props":916,"children":917},{},[918,923,928],{"type":40,"tag":96,"props":919,"children":920},{},[921],{"type":51,"value":922},"Check your server's response time (should be under 15 seconds)",{"type":40,"tag":96,"props":924,"children":925},{},[926],{"type":51,"value":927},"Verify your endpoint can handle concurrent requests",{"type":40,"tag":96,"props":929,"children":930},{},[931],{"type":51,"value":932},"Review error logs for specific failure reasons",{"type":40,"tag":41,"props":934,"children":935},{},[936],{"type":40,"tag":100,"props":937,"children":938},{},[939],{"type":51,"value":940},"Signature verification failing",{"type":40,"tag":327,"props":942,"children":943},{},[944,949,954],{"type":40,"tag":96,"props":945,"children":946},{},[947],{"type":51,"value":948},"Ensure you're using the exact secret configured in Waitlister",{"type":40,"tag":96,"props":950,"children":951},{},[952],{"type":51,"value":953},"Verify you're computing the HMAC using the raw request body",{"type":40,"tag":96,"props":955,"children":956},{},[957],{"type":51,"value":958},"Check that your secret doesn't contain extra whitespace",{"type":40,"tag":41,"props":960,"children":961},{},[962],{"type":40,"tag":100,"props":963,"children":964},{},[965],{"type":51,"value":966},"Not receiving specific events",{"type":40,"tag":327,"props":968,"children":969},{},[970,975,980,985],{"type":40,"tag":96,"props":971,"children":972},{},[973],{"type":51,"value":974},"Check that the event type is enabled in your webhook configuration",{"type":40,"tag":96,"props":976,"children":977},{},[978],{"type":51,"value":979},"For milestone events, verify your milestones are configured correctly",{"type":40,"tag":96,"props":981,"children":982},{},[983],{"type":51,"value":984},"For referral events, ensure your referral program is enabled",{"type":40,"tag":96,"props":986,"children":987},{},[988],{"type":51,"value":989},"For pending expired events, ensure double opt-in is enabled on your waitlist",{"type":40,"tag":159,"props":991,"children":993},{"id":992},"webhook-status",[994],{"type":51,"value":995},"Webhook Status",{"type":40,"tag":41,"props":997,"children":998},{},[999],{"type":51,"value":1000},"Webhooks have three possible statuses.",{"type":40,"tag":327,"props":1002,"children":1003},{},[1004,1014,1024],{"type":40,"tag":96,"props":1005,"children":1006},{},[1007,1012],{"type":40,"tag":100,"props":1008,"children":1009},{},[1010],{"type":51,"value":1011},"Active",{"type":51,"value":1013},": Webhook is configured and working correctly",{"type":40,"tag":96,"props":1015,"children":1016},{},[1017,1022],{"type":40,"tag":100,"props":1018,"children":1019},{},[1020],{"type":51,"value":1021},"Inactive",{"type":51,"value":1023},": Webhook failed its last test or delivery",{"type":40,"tag":96,"props":1025,"children":1026},{},[1027,1032],{"type":40,"tag":100,"props":1028,"children":1029},{},[1030],{"type":51,"value":1031},"Disabled",{"type":51,"value":1033},": Webhook was automatically disabled due to repeated failures",{"type":40,"tag":72,"props":1035,"children":1037},{"className":1036},[75],[1038],{"type":51,"value":1039},"Webhooks are automatically disabled after 10 consecutive failures to prevent spam and protect your endpoint.",{"type":40,"tag":159,"props":1041,"children":1043},{"id":1042},"re-enabling-disabled-webhooks",[1044],{"type":51,"value":1045},"Re-enabling Disabled Webhooks",{"type":40,"tag":41,"props":1047,"children":1048},{},[1049],{"type":51,"value":1050},"If your webhook was automatically disabled, follow these steps.",{"type":40,"tag":92,"props":1052,"children":1053},{},[1054,1059,1064,1069],{"type":40,"tag":96,"props":1055,"children":1056},{},[1057],{"type":51,"value":1058},"Fix the issue causing failures (check logs for error details)",{"type":40,"tag":96,"props":1060,"children":1061},{},[1062],{"type":51,"value":1063},"Go to webhook configuration page",{"type":40,"tag":96,"props":1065,"children":1066},{},[1067],{"type":51,"value":1068},"Click \"Re-enable webhook\" in the status warning",{"type":40,"tag":96,"props":1070,"children":1071},{},[1072],{"type":51,"value":1073},"Test the webhook to verify it's working",{"type":40,"tag":80,"props":1075,"children":1077},{"id":1076},"help-and-support",[1078],{"type":51,"value":1079},"Help and Support",{"type":40,"tag":41,"props":1081,"children":1082},{},[1083],{"type":51,"value":1084},"Need assistance with webhooks? We're here to help.",{"type":40,"tag":327,"props":1086,"children":1087},{},[1088,1100,1105],{"type":40,"tag":96,"props":1089,"children":1090},{},[1091,1093],{"type":51,"value":1092},"Contact us via the ",{"type":40,"tag":1094,"props":1095,"children":1097},"a",{"href":1096},"\u002Fcontact",[1098],{"type":51,"value":1099},"public contact form",{"type":40,"tag":96,"props":1101,"children":1102},{},[1103],{"type":51,"value":1104},"Access the \"Help\" page in your account dashboard",{"type":40,"tag":96,"props":1106,"children":1107},{},[1108],{"type":51,"value":1109},"Check the webhook logs for detailed error information",{"title":472,"searchDepth":1111,"depth":1111,"links":1112},3,[1113,1115,1122,1127,1134,1141,1148,1153],{"id":82,"depth":1114,"text":85},2,{"id":149,"depth":1114,"text":152,"children":1116},[1117,1118,1119,1120,1121],{"id":161,"depth":1111,"text":164},{"id":182,"depth":1111,"text":185},{"id":202,"depth":1111,"text":205},{"id":222,"depth":1111,"text":225},{"id":242,"depth":1111,"text":245},{"id":262,"depth":1114,"text":265,"children":1123},[1124,1125,1126],{"id":268,"depth":1111,"text":271},{"id":317,"depth":1111,"text":320},{"id":382,"depth":1111,"text":385},{"id":436,"depth":1114,"text":439,"children":1128},[1129,1130,1131,1132,1133],{"id":463,"depth":1111,"text":466},{"id":482,"depth":1111,"text":485},{"id":497,"depth":1111,"text":500},{"id":512,"depth":1111,"text":515},{"id":527,"depth":1111,"text":530},{"id":542,"depth":1114,"text":545,"children":1135},[1136],{"id":548,"depth":1111,"text":551,"children":1137},[1138,1140],{"id":560,"depth":1139,"text":563},4,{"id":574,"depth":1139,"text":577},{"id":649,"depth":1114,"text":652,"children":1142},[1143,1144,1145,1146,1147],{"id":655,"depth":1111,"text":658},{"id":709,"depth":1111,"text":712},{"id":743,"depth":1111,"text":746},{"id":777,"depth":1111,"text":780},{"id":811,"depth":1111,"text":814},{"id":866,"depth":1114,"text":869,"children":1149},[1150,1151,1152],{"id":872,"depth":1111,"text":875},{"id":992,"depth":1111,"text":995},{"id":1042,"depth":1111,"text":1045},{"id":1076,"depth":1114,"text":1079}]