Documentation Index
Fetch the complete documentation index at: https://docs.urtentic.com/llms.txt
Use this file to discover all available pages before exploring further.
Setting Up Webhooks
Access Webhook Settings
Log into your Urtentic Dashboard, navigate to Integrations, and click Webhooks
Configure Endpoint
- Endpoint URL: Your HTTPS endpoint (e.g.,
https://api.yourapp.com/webhooks/urtentic)
- Secret Key: Auto-generated or custom webhook secret
- IP Whitelist: Optional IP address restrictions
Test Connection
Click Test Endpoint, review the test payload, verify your endpoint responds with HTTP 200, and check signature verification
Implementing Webhook Endpoints
const express = require('express');
const crypto = require('crypto');
const app = express();
app.use('/webhooks/urtentic', express.raw({ type: 'application/json' }));
app.post('/webhooks/urtentic', (req, res) => {
const signature = req.headers['x-urtentic-signature'];
const timestamp = req.headers['x-urtentic-timestamp'];
const payload = req.body;
try {
verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET, timestamp);
const event = JSON.parse(payload);
handleWebhookEvent(event);
res.status(200).json({ received: true });
} catch (error) {
console.error('Webhook verification failed:', error.message);
res.status(400).json({ error: 'Webhook verification failed' });
}
});
function verifyWebhookSignature(payload, signature, secret, timestamp) {
const currentTime = Math.floor(Date.now() / 1000);
if (Math.abs(currentTime - timestamp) > 300) {
throw new Error('Webhook timestamp too old');
}
const secretBytes = Buffer.from(secret, 'base64');
const expectedSignature = crypto
.createHmac('sha256', secretBytes)
.update(payload, 'utf8')
.digest('hex');
if (signature.startsWith('sha256=')) signature = signature.substring(7);
if (!crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
)) {
throw new Error('Invalid signature');
}
}
function handleWebhookEvent(event) {
switch (event.eventName) {
case 'verification_completed':
console.log(`Verification completed: ${event.flowId}`);
break;
case 'verification_abandoned':
console.log(`Verification abandoned: ${event.flowId}`);
break;
case 'step_completed':
console.log(`Step completed: ${event.step.stepId}`);
break;
default:
console.log(`Unhandled event: ${event.eventName}`);
}
}
app.listen(3000, () => console.log('Webhook server listening on port 3000'));
Monitoring & Maintenance
Webhook Health Monitoring
Monitor your webhook endpoint health:
- Response Times: Track webhook processing performance
- Success Rates: Monitor delivery success percentages
- Error Patterns: Identify common failure modes
- Retry Frequency: Track how often retries are needed
Logging Best Practices
function handleWebhookEvent(event) {
const startTime = Date.now();
try {
console.log(`Processing webhook: ${event.eventName}`);
processEvent(event);
const duration = Date.now() - startTime;
console.log(`Webhook processed successfully (${duration}ms)`);
} catch (error) {
console.error(`Webhook processing failed:`, error.message);
throw error;
}
}
Scaling Considerations
Queue Processing
Use message queues (RabbitMQ, SQS) for webhook processing
Load Balancing
Distribute webhook traffic across multiple servers
Database Optimization
Optimize queries for webhook handlers
Caching
Cache frequently accessed data to improve performance