Webhook Best Practices
Recommendations for building reliable webhook integrations.
Respond Quickly
Return a 2xx response within 30 seconds. Process events asynchronously:
@app.route('/webhooks/scribesight', methods=['POST'])
def webhook():
event = request.json
# Queue for background processing
task_queue.enqueue(process_event, event)
# Acknowledge immediately
return '', 200
Handle Duplicates
Events may be delivered more than once. Use the event ID for idempotency:
def process_event(event):
event_id = event['id']
# Check if already processed
if redis.sismember('processed_events', event_id):
return
# Process the event
handle_event(event)
# Mark as processed (with TTL)
redis.sadd('processed_events', event_id)
redis.expire('processed_events', 86400 * 7) # 7 days
Verify Signatures
Always verify the webhook signature before processing:
if not verify_signature(request.data, signature_header):
abort(401)
See Signature Verification for implementation details.
Handle All Event Types
Include a default handler for unknown events:
def handle_event(event):
event_type = event['event']
handlers = {
'transcription.completed': handle_transcription_completed,
'content_analysis.completed': handle_analysis_completed,
}
handler = handlers.get(event_type, handle_unknown_event)
handler(event)
def handle_unknown_event(event):
# Log and ignore unknown events
logger.info(f"Unknown event type: {event['event']}")
Use HTTPS
Webhook URLs must use HTTPS. We won't deliver to HTTP endpoints.
Monitor Deliveries
Check the webhook dashboard for delivery status:
- Go to Settings → Webhooks
- Click on your webhook endpoint
- View recent deliveries and any failures
You can also fetch deliveries via API:
curl https://scribesight.com/api/v1/webhooks/wh_xxx/deliveries \
-H "Authorization: Bearer sk_live_xxx"
Handle Failures Gracefully
If your endpoint is down:
- We'll retry with exponential backoff (up to 5 attempts)
- After exhausting retries, you'll receive a notification
- Events are stored for 30 days for replay
To replay missed events:
# Get the event from the deliveries log
curl https://scribesight.com/api/v1/webhooks/wh_xxx/deliveries \
-H "Authorization: Bearer sk_live_xxx"
# Manually trigger a test delivery
curl -X POST https://scribesight.com/api/v1/webhooks/wh_xxx/test \
-H "Authorization: Bearer sk_live_xxx"
Use Project Filtering
Only receive events from relevant projects:
curl -X POST https://scribesight.com/api/v1/webhooks \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhooks/scribesight",
"events": ["transcription.completed"],
"project_ids": ["proj_xxx", "proj_yyy"]
}'
Rotate Secrets Regularly
Rotate webhook secrets periodically:
curl -X POST https://scribesight.com/api/v1/webhooks/wh_xxx/rotate-secret \
-H "Authorization: Bearer sk_live_xxx"
The old secret remains valid for 24 hours during rotation.
Test Before Production
Use the test endpoint to verify your integration:
curl -X POST https://scribesight.com/api/v1/webhooks/wh_xxx/test \
-H "Authorization: Bearer sk_live_xxx"
This sends a webhook.test event to your endpoint.