Webhooks Overview
Set up your first webhook in 5 minutes. Learn how to create endpoints, test locally, and handle events from SnipLink.
- A SnipLink account with an API key
- A server or endpoint that can receive POST requests
- Basic knowledge of API authentication
What You'll Build
By the end of this guide, you'll have a working webhook endpoint that receives real-time notifications when links are created, updated, or deleted in SnipLink.
Step 1: Create a Webhook Endpoint
First, create an HTTP endpoint that can receive POST requests. Here's a simple example using Node.js with Express:
const express = require(039;express039;);
const crypto = require(039;crypto039;);
const app = express();
app.use(express.json());
app.post(039;/webhooks/sniplink039;, (req, res) => {
// Get webhook signature and timestamp from headers
const signature = req.headers[039;x-sniplink-webhook-signature039;];
const timestamp = req.headers[039;x-sniplink-webhook-timestamp039;];
// Get webhook event data
const event = req.body;
// TODO: Verify signature (see security guide)
// Handle the event
console.log(039;Received webhook event:039;, event.type);
console.log(039;Event data:039;, event.data);
// Respond with 200 to acknowledge receipt
res.status(200).json({ received: true });
});
app.listen(3000, () => {
console.log(039;Webhook server listening on port 3000039;);
});Step 2: Register Your Endpoint
Once your endpoint is ready, register it with SnipLink using the Webhooks API:
curl -X POST https://api.sniplink.com/api/v1/webhooks \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"targetUrl": "https://your-domain.com/webhooks/sniplink",
"events": ["link.created", "link.updated", "link.deleted"],
"secret": "your_webhook_secret_key"
}'secret is used to sign webhook payloads. Store this securely and use it to verify webhook signatures. Generate a strong random string (at least 32 characters).Successful response:
{
"id": "wh_abc123",
"targetUrl": "https://your-domain.com/webhooks/sniplink",
"events": ["link.created", "link.updated", "link.deleted"],
"active": true,
"createdAt": "2024-02-06T12:00:00.000Z"
}Step 3: Test Locally with ngrok
To test webhooks during development, use ngrok to expose your local server to the internet:
# Install ngrok (if not already installed)
npm install -g ngrok
# Start your local server
node server.js
# In another terminal, start ngrok
ngrok http 3000
# ngrok will give you a public URL like:
# https://abc123.ngrok.io -> http://localhost:3000
# Use this URL when registering your webhook:
# https://abc123.ngrok.io/webhooks/sniplinkhttp://localhost:4040 where you can inspect all webhook requests in real-time. This is invaluable for debugging!Step 4: Trigger a Test Event
Create a link via the API to trigger a webhook event:
curl -X POST https://api.sniplink.com/api/v1/links \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"slug": "test-webhook"
}'Your webhook endpoint should receive a POST request with this payload:
{
"id": "evt_abc123",
"type": "link.created",
"timestamp": "2024-02-06T12:00:00.000Z",
"workspaceId": "ws_abc123",
"data": {
"link": {
"id": "lnk_123456",
"url": "https://example.com",
"shortUrl": "https://snip.link/test-webhook",
"slug": "test-webhook",
"createdAt": "2024-02-06T12:00:00.000Z"
}
}
}Step 5: Handle Different Event Types
Process events based on their type:
app.post(039;/webhooks/sniplink039;, async (req, res) => {
const event = req.body;
// Verify signature first (see security guide)
try {
switch (event.type) {
case 039;link.created039;:
await handleLinkCreated(event.data.link);
break;
case 039;link.updated039;:
await handleLinkUpdated(event.data.link, event.data.changes);
break;
case 039;link.deleted039;:
await handleLinkDeleted(event.data.link);
break;
default:
console.log(039;Unhandled event type:039;, event.type);
}
res.status(200).json({ received: true });
} catch (error) {
console.error(039;Error processing webhook:039;, error);
// Return 500 to trigger retry
res.status(500).json({ error: 039;Internal server error039; });
}
});
async function handleLinkCreated(link) {
console.log(039;New link created:039;, link.shortUrl);
// Send Slack notification, update database, etc.
}
async function handleLinkUpdated(link, changes) {
console.log(039;Link updated:039;, link.shortUrl);
console.log(039;Changed fields:039;, changes);
// Sync changes to your system
}
async function handleLinkDeleted(link) {
console.log(039;Link deleted:039;, link.shortUrl);
// Remove from your database, analytics, etc.
}Retry Logic
SnipLink automatically retries failed webhook deliveries with exponential backoff:
- Attempt 1: Immediate
- Attempt 2: 2 seconds later
- Attempt 3: 8 seconds later
- Attempt 4: 32 seconds later
- Attempt 5: 128 seconds later (final attempt)
Best Practices
1. Respond Quickly
Acknowledge receipt immediately and process events asynchronously:
app.post(039;/webhooks/sniplink039;, async (req, res) => {
const event = req.body;
// Verify signature
if (!verifySignature(req)) {
return res.status(401).json({ error: 039;Invalid signature039; });
}
// Respond immediately
res.status(200).json({ received: true });
// Process asynchronously
processWebhookEvent(event).catch(error => {
console.error(039;Error processing webhook:039;, error);
});
});2. Handle Idempotency
Use the event id to prevent processing the same event twice:
const processedEvents = new Set();
async function processWebhookEvent(event) {
// Check if already processed
if (processedEvents.has(event.id)) {
console.log(039;Event already processed:039;, event.id);
return;
}
// Process event
await handleEvent(event);
// Mark as processed
processedEvents.add(event.id);
// In production, store in Redis/database with TTL
}3. Monitor Webhook Health
Track webhook delivery success rates:
- Log all incoming webhooks
- Monitor response times
- Alert on consecutive failures
- Check webhook status via API
Production Checklist
Before deploying to production:
- ✅ Verify webhook signatures
- ✅ Implement idempotency checking
- ✅ Add proper error handling and logging
- ✅ Set up monitoring and alerts
- ✅ Use HTTPS endpoint (required)
- ✅ Respond within 30 seconds
- ✅ Handle all event types gracefully
- ✅ Test with high event volumes
Common Issues
Webhooks Not Received
- Check that your endpoint is publicly accessible via HTTPS
- Verify firewall rules allow inbound POST requests
- Ensure webhook is registered and active in SnipLink
- Check webhook status via API
Signature Verification Failing
- Ensure you're using the correct webhook secret
- Verify you're reading the raw request body (before JSON parsing)
- Check timestamp is within ±30 seconds (prevent replay attacks)
- See Security Guide for details
Events Being Retried
- Your endpoint must return 2xx status code
- Check response time is under 30 seconds
- Review server logs for errors or timeouts
What's Next?
Event Types Reference →
Complete reference for all webhook event types and payload structures
Security Guide →
Learn how to verify webhook signatures and prevent replay attacks
Make.com Integration →
Use webhooks for instant triggers in Make.com automation workflows
API Reference →
Interactive API documentation for webhook management endpoints