Webhook Setup Guide
Configure webhooks to receive real-time notifications for link events
Webhook Setup Guide
Webhooks allow you to receive real-time notifications when events occur in your Smartlinks account.
Overview
Smartlinks can send webhook events to your server when:
- A link is clicked
- A new link is created
- A link is updated or deleted
- Analytics milestones are reached
Creating a Webhook
Step 1: Set Up Your Endpoint
Create an endpoint on your server to receive webhook events:
// Express.js example
const express = require('express');
const app = express();
app.post('/webhooks/smartlinks', express.json(), (req, res) => {
const event = req.body;
console.log('Received webhook:', event.type);
console.log('Data:', event.data);
// Process the event
handleWebhookEvent(event);
// Acknowledge receipt
res.status(200).json({ received: true });
});
app.listen(3000, () => {
console.log('Webhook server running on port 3000');
});
Step 2: Register the Webhook
Register your webhook endpoint with Smartlinks:
async function registerWebhook(url, events) {
const response = await fetch('https://api.smartlinks.io/v1/webhooks', {
method: 'POST',
headers: {
'Authorization': `Bearer ${SMARTLINKS_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: url,
events: events,
active: true
})
});
return await response.json();
}
// Register for link.clicked and link.created events
registerWebhook('https://your-domain.com/webhooks/smartlinks', [
'link.clicked',
'link.created',
'link.updated',
'link.deleted'
]);
Webhook Event Types
link.clicked
Triggered when someone clicks a short link:
{
"type": "link.clicked",
"id": "evt_123abc",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"link_id": "link_456def",
"short_url": "https://smrt.lnk/abc123",
"destination_url": "https://example.com/page",
"click": {
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"referer": "https://google.com",
"country": "US",
"city": "New York",
"device_type": "desktop"
}
}
}
link.created
Triggered when a new link is created:
{
"type": "link.created",
"id": "evt_789ghi",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"link_id": "link_456def",
"short_url": "https://smrt.lnk/abc123",
"destination_url": "https://example.com/page",
"created_by": "user_123"
}
}
Handling Webhooks
Complete Event Handler
function handleWebhookEvent(event) {
switch (event.type) {
case 'link.clicked':
handleLinkClick(event.data);
break;
case 'link.created':
handleLinkCreated(event.data);
break;
case 'link.updated':
handleLinkUpdated(event.data);
break;
case 'link.deleted':
handleLinkDeleted(event.data);
break;
default:
console.log('Unhandled event type:', event.type);
}
}
function handleLinkClick(data) {
console.log(`Link ${data.link_id} clicked from ${data.click.country}`);
// Example: Send to analytics
analytics.track('Link Clicked', {
linkId: data.link_id,
country: data.click.country,
device: data.click.device_type
});
}
function handleLinkCreated(data) {
console.log(`New link created: ${data.short_url}`);
// Example: Send notification
sendNotification(`New short link: ${data.short_url}`);
}
Verifying Webhook Signatures
Security: Always verify webhook signatures to ensure requests are from Smartlinks.
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// In your webhook handler
app.post('/webhooks/smartlinks', express.json(), (req, res) => {
const signature = req.headers['x-smartlinks-signature'];
const webhookSecret = process.env.WEBHOOK_SECRET;
if (!verifyWebhookSignature(req.body, signature, webhookSecret)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the event
handleWebhookEvent(req.body);
res.status(200).json({ received: true });
});
Testing Webhooks
Local Testing with ngrok
Use ngrok to expose your local server:
# Install ngrok
npm install -g ngrok
# Expose your local port
ngrok http 3000
# Use the ngrok URL when registering webhooks
# Example: https://abc123.ngrok.io/webhooks/smartlinks
Manual Testing
Test your webhook endpoint manually:
curl -X POST https://your-domain.com/webhooks/smartlinks \
-H "Content-Type: application/json" \
-H "X-Smartlinks-Signature: test_signature" \
-d '{
"type": "link.clicked",
"id": "evt_test",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"link_id": "link_test",
"short_url": "https://smrt.lnk/test"
}
}'
Error Handling & Retries
Smartlinks will retry failed webhook deliveries:
- 3 automatic retries with exponential backoff
- Maximum retry interval: 1 hour
- Webhooks are disabled after 10 consecutive failures
// Ensure your endpoint responds quickly
app.post('/webhooks/smartlinks', express.json(), async (req, res) => {
// Acknowledge receipt immediately
res.status(200).json({ received: true });
// Process asynchronously
processWebhookAsync(req.body).catch(error => {
console.error('Error processing webhook:', error);
});
});
async function processWebhookAsync(event) {
// Your processing logic here
await saveToDatabase(event);
await triggerNotifications(event);
}
Best Practices
- ✅ Respond with 200 status code quickly
- ✅ Process events asynchronously
- ✅ Verify webhook signatures
- ✅ Implement idempotency using event IDs
- ✅ Log all webhook events
- ❌ Don't perform long-running operations synchronously
- ❌ Don't expose your webhook secret