Webhook Integration Guide
Send real-time lead data to external services when someone joins your waitlist
Webhooks let you receive an instant notification whenever someone signs up for your waitlist. When a new lead subscribes, Waitlistly sends a POST request to a URL you specify, containing the lead's details. This lets you connect your waitlist to tools like Zapier, Make, Slack, n8n, or your own backend API.
What You Can Do With Webhooks
- Add new leads to your CRM or email marketing tool automatically
- Send a Slack or Discord notification when someone joins
- Trigger a welcome email sequence via Zapier or Make
- Sync lead data to a Google Sheet or Airtable
- Run custom logic on your own server
1Go to Your Project Settings
Open your Dashboard, select your project, and navigate to the Webhook tab (or find the "Webhook Integration" section in your project settings).
2Enter Your Webhook URL
Paste the URL where you want to receive lead data. This is typically a URL provided by your automation tool or your own API endpoint.
Where to get your webhook URL:
- Zapier: Create a Zap with "Webhooks by Zapier" trigger → "Catch Hook" → copy the URL
- Make: Add a "Custom webhook" module → copy the generated URL
- n8n: Add a "Webhook" node set to POST → copy the test or production URL
- Slack: Create an "Incoming Webhook" app in Slack → copy the webhook URL
- Your own API: Use any URL that accepts POST requests with JSON body
3Set a Secret Key (Optional)
If you want to verify that webhook requests are genuinely from Waitlistly, add a secret key. This enables HMAC-SHA256 signature verification. You can use any random string — the longer, the better.
Tip: If you're sending to Zapier, Make, or Slack, you can skip this step — those services don't validate signatures. A secret key is most useful when sending to your own backend.
4Enable and Test
Toggle the webhook on, save your settings, then click "Test Webhook" to send a sample request to your URL. The test payload uses dummy data (email: test@example.com) so you can verify everything works.
Testing tip: Use webhook.site to get a temporary URL that shows you exactly what Waitlistly sends — the headers, payload, and timing. Great for debugging.
You're All Set!
Every time someone joins your waitlist, their data will be sent to your webhook URL in real time. The webhook fires in the background and won't slow down the signup experience.
Payload Reference
Every webhook request is a POST with a JSON body. Here's the full structure:
{
"event": "lead.created",
"timestamp": "2026-01-28T14:30:00.000Z",
"data": {
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"phone": "+1234567890",
"customAnswer": "Referral",
"referralCode": "abc12345",
"referredBy": "xyz67890",
"queuePosition": 5,
"source": "landing_page"
},
"project": {
"id": "project-uuid",
"name": "My Startup",
"subdomain": "mystartup",
"url": "https://mystartup.waitlistly.live"
}
}| Field | Description |
|---|---|
| event | lead.created for real signups, lead.test for test webhooks |
| timestamp | ISO 8601 timestamp of when the event occurred |
| data.email | Lead's email address (always present) |
| data.firstName / lastName | Name fields (present if your form collects them) |
| data.phone | Phone number (present if your form collects it) |
| data.customAnswer | Response to your custom question (if configured) |
| data.referralCode | This lead's unique referral code |
| data.referredBy | Referral code of who referred this lead (if applicable) |
| data.queuePosition | Lead's position in the waitlist queue |
| project.url | Uses your custom domain if connected, otherwise the Waitlistly subdomain |
HTTP Headers
The following headers are included with every webhook request:
| Header | Description |
|---|---|
| Content-Type | application/json |
| X-Waitlistly-Event | Event type: lead.created or lead.test |
| X-Webhook-Signature | HMAC-SHA256 signature (only sent if you configured a secret key). Format: sha256=<hex> |
Verifying Webhook Signatures
If you set a secret key, every request includes an X-Webhook-Signature header. To verify a request is genuinely from Waitlistly, compute the HMAC-SHA256 of the raw request body using your secret and compare it to the header value.
Node.js
const crypto = require('crypto');
function verifySignature(rawBody, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your Express route handler:
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const isValid = verifySignature(
JSON.stringify(req.body),
signature,
'your-secret-key'
);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process the lead data
const { event, data } = req.body;
console.log('New lead:', data.email);
res.status(200).send('OK');
});Python
import hmac
import hashlib
def verify_signature(raw_body: str, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(),
raw_body.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)Integration Examples
Zapier
- Create a new Zap
- Choose "Webhooks by Zapier" as the trigger app
- Select "Catch Hook" as the trigger event
- Copy the generated webhook URL and paste it into Waitlistly
- Click "Test Webhook" in Waitlistly to send sample data
- Set up your action (e.g., add row to Google Sheet, send email via Mailchimp)
Make (formerly Integromat)
- Create a new Scenario
- Search for and add the "Custom webhook" module as the trigger
- Click "Add" to generate a new webhook URL
- Copy the URL and paste it into Waitlistly
- Click "Test Webhook" in Waitlistly, then "Redetermine data structure" in Make
- Add your downstream modules (e.g., Google Sheets, HubSpot, Email)
Slack
- Go to api.slack.com/apps and create a new app (or use an existing one)
- Enable "Incoming Webhooks" and add a new webhook to your workspace
- Choose the channel where you want notifications
- Copy the webhook URL and paste it into Waitlistly
Note: Slack expects a specific payload format. For best results, use Zapier or Make as a middleman to transform the Waitlistly payload into a Slack message format.
n8n
- Add a "Webhook" node as the trigger
- Set HTTP Method to POST
- Copy the test or production webhook URL
- Paste it into Waitlistly and send a test webhook
- Connect downstream nodes to process the lead data
Troubleshooting
Test webhook works but real signups don't trigger it
- Make sure the webhook toggle is enabled (on) and you clicked Save
- Check that your landing page is deployed and using the latest settings
- Webhooks fire in the background — check your endpoint logs for incoming requests
Webhook request is failing (no data received)
- Verify the URL is correct and publicly accessible (not behind a firewall or VPN)
- Make sure the endpoint accepts POST requests with a JSON body
- Test with webhook.site to confirm Waitlistly is sending correctly
- If using Zapier/Make, ensure the Zap/Scenario is turned on
Some fields are missing from the payload
Fields like firstName, lastName, phone, and customAnswer are only included if your landing page form collects them. The email field is always present. Configure your form fields in the page editor to collect additional data.
Does Waitlistly retry failed webhooks?
Currently, webhooks are sent once (fire-and-forget). If your endpoint is temporarily down, the webhook won't be retried. The lead is still saved in your Waitlistly CRM regardless of webhook success or failure. We recommend using a reliable endpoint or a service like Zapier that handles availability for you.
Need More Help?
Contact us at hello@waitlistly.live