Best Practices
Follow these recommendations to build reliable, production-ready webhook handlers.
Return Quickly
Your webhook endpoint should return a 200 response as quickly as possible. If you need to do heavy processing, acknowledge the webhook first and process asynchronously:
app.post('/webhooks/lynkwell', async (req, res) => {
// Validate signature first
// ...
// Acknowledge immediately
res.status(200).json({ received: true });
// Process asynchronously
processWebhookAsync(req.body).catch(console.error);
});Handle Duplicates
While rare, webhooks can be delivered more than once. Use the event id to deduplicate:
const processedEvents = new Set<string>();
async function handleWebhook(event: WebhookEvent) {
if (processedEvents.has(event.id)) {
console.log('Duplicate event, skipping:', event.id);
return;
}
processedEvents.add(event.id);
// Process event...
}For production systems, store processed event IDs in a database with a TTL matching the 30-day retention period.
Use HTTPS
Always use HTTPS endpoints for webhooks. Lynkwell will not deliver webhooks to HTTP endpoints in production environments.
Monitor Deliveries
Regularly check your webhook deliveries via the API to catch any failures:
curl 'https://api.lynkwell.com/webhooks/v1/webhook-endpoints/we_abc123/deliveries?limit=10' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'Rotate Secrets
If you suspect your webhook secret has been compromised:
- Create a new webhook endpoint with the same URL and events
- Update your endpoint to accept signatures from both secrets temporarily
- Delete the old webhook endpoint
- Update your endpoint to only accept the new secret
Troubleshooting
Webhook Not Received
- Verify your endpoint is accessible from the internet
- Check that your endpoint returns a
2xxstatus code - Review the delivery attempts via the API for error details
- Ensure your endpoint responds within 30 seconds
Invalid Signature
- Make sure you're using the raw request body (not parsed JSON)
- Verify you're using the correct webhook secret
- Check that the timestamp hasn't expired (default tolerance: 5 minutes)
- Ensure you're comparing the full signature, not truncated
Missed Events
Events and deliveries are retained for 30 days. Use the List Events API to see recent events for your network:
curl 'https://api.lynkwell.com/webhooks/v1/webhook-events?limit=50' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
