Webhooks
Webhooks allow your application to receive real-time notifications when events occur in Semaswift.
Overview
Instead of polling the API for changes, webhooks push events to your server as they happen.
sequenceDiagram
participant Semaswift
participant Your Server
Note over Semaswift: Event occurs
Semaswift->>Your Server: POST /your-webhook-url
Your Server-->>Semaswift: 200 OK
Setting Up Webhooks
1. Create a Webhook Endpoint
POST /api/v1/webhooks
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
{
"url": "https://your-server.com/webhooks/semaswift",
"events": ["ticket.created", "call.completed"],
"secret": "your-webhook-secret"
}
2. Handle Webhook Events
const crypto = require('crypto');
const express = require('express');
app.post('/webhooks/semaswift', express.raw({type: 'application/json'}), (req, res) => {
// Verify signature
const signature = req.headers['x-semaswift-signature'];
const expectedSig = crypto
.createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (signature !== `sha256=${expectedSig}`) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
// Handle event
switch (event.type) {
case 'ticket.created':
handleTicketCreated(event.data);
break;
case 'call.completed':
handleCallCompleted(event.data);
break;
}
res.status(200).send('OK');
});
Webhook Payload
{
"id": "evt_123456",
"type": "ticket.created",
"created_at": "2024-01-15T10:30:00Z",
"organization_id": "org_789",
"data": {
"ticket": {
"id": "tkt_abc123",
"subject": "Help needed",
"status": "open",
"priority": "high"
}
}
}
Available Events
Ticket Events
| Event | Description |
|---|---|
ticket.created | New ticket created |
ticket.updated | Ticket was updated |
ticket.resolved | Ticket was resolved |
ticket.assigned | Ticket assigned to agent |
ticket.comment.added | Comment added to ticket |
Call Events
| Event | Description |
|---|---|
call.started | Call initiated |
call.answered | Call was answered |
call.completed | Call ended |
call.transferred | Call was transferred |
recording.ready | Call recording available |
Agent Events
| Event | Description |
|---|---|
agent.status_changed | Agent status changed |
agent.logged_in | Agent logged in |
agent.logged_out | Agent logged out |
User Events
| Event | Description |
|---|---|
user.created | New user created |
user.updated | User profile updated |
user.deleted | User was deleted |
Signature Verification
Always verify webhook signatures:
import hmac
import hashlib
def verify_signature(payload, signature, secret):
expected = 'sha256=' + hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# In your webhook handler
@app.route('/webhooks/semaswift', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-Semaswift-Signature')
if not verify_signature(request.data, signature, WEBHOOK_SECRET):
return 'Invalid signature', 401
event = request.json
# Process event...
return 'OK', 200
Retry Policy
Failed webhook deliveries are retried:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
| 6 | 8 hours |
After 6 failures, the webhook is disabled.
Best Practices
- Respond quickly - Return 200 within 30 seconds
- Process async - Queue events for background processing
- Verify signatures - Always validate webhook authenticity
- Handle duplicates - Events may be delivered multiple times
- Monitor failures - Set up alerting for webhook errors
- Use HTTPS - Webhook URLs must use HTTPS
Testing Webhooks
Use the API to send test events:
POST /api/v1/webhooks/{webhook_id}/test
Authorization: Bearer YOUR_TOKEN
{
"event_type": "ticket.created"
}
Webhook Logs
View delivery attempts and responses:
GET /api/v1/webhooks/{webhook_id}/deliveries
Authorization: Bearer YOUR_TOKEN
{
"deliveries": [
{
"id": "dlv_123",
"event_id": "evt_456",
"status": "success",
"response_code": 200,
"response_time_ms": 150,
"delivered_at": "2024-01-15T10:30:05Z"
}
]
}