Overview
Webhooks allow you to receive HTTP callbacks when events occur in your Rotavision account. Instead of polling for status updates, webhooks push data to your server in real-time.
Supported Events
Event Description analysis.completedFairness analysis job finished analysis.failedFairness analysis job failed alert.triggeredGuardian alert threshold exceeded alert.resolvedGuardian alert returned to normal extraction.completedDocument extraction finished extraction.failedDocument extraction failed workflow.completedOrchestrate workflow finished workflow.failedOrchestrate workflow failed
Setting Up Webhooks
Via Dashboard
Go to Settings → Webhooks in your dashboard
Click Add Endpoint
Enter your endpoint URL
Select events to subscribe to
Save and note your signing secret
Via API
curl -X POST https://api.rotavision.com/v1/webhooks \
-H "Authorization: Bearer rv_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/rotavision",
"events": ["analysis.completed", "alert.triggered"],
"description": "Production webhook"
}'
Response:
{
"id" : "wh_abc123" ,
"url" : "https://your-app.com/webhooks/rotavision" ,
"events" : [ "analysis.completed" , "alert.triggered" ],
"secret" : "whsec_xyz789..." ,
"status" : "active" ,
"created_at" : "2026-02-01T10:00:00Z"
}
Store your webhook secret securely. You’ll need it to verify incoming webhooks.
Webhook Payload
All webhooks follow this structure:
{
"id" : "evt_abc123" ,
"type" : "analysis.completed" ,
"created_at" : "2026-02-01T10:30:00Z" ,
"data" : {
"id" : "analysis_xyz789" ,
"model_id" : "loan-approval-v2" ,
"overall_score" : 0.82 ,
"status" : "completed"
}
}
Verifying Signatures
All webhooks are signed using HMAC-SHA256. Verify the signature to ensure the webhook came from Rotavision:
import hmac
import hashlib
def verify_webhook ( payload : bytes , signature : str , secret : str ) -> bool :
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest( f "sha256= { expected } " , signature)
# In your webhook handler
@app.post ( "/webhooks/rotavision" )
def handle_webhook ( request ):
payload = request.body
signature = request.headers.get( "X-Rotavision-Signature" )
if not verify_webhook(payload, signature, WEBHOOK_SECRET ):
return Response( status = 401 )
event = json.loads(payload)
# Process event...
Handling Webhooks
Best Practices
Return a 200 response within 5 seconds. Process the event asynchronously if needed. @app.post ( "/webhooks/rotavision" )
def handle_webhook ( request ):
# Verify and enqueue
event = verify_and_parse(request)
queue.enqueue(process_event, event)
return Response( status = 200 ) # Respond immediately
Webhooks may be delivered multiple times. Use the id field for idempotency. def process_event ( event ):
if redis.sismember( "processed_events" , event[ "id" ]):
return # Already processed
# Process event...
redis.sadd( "processed_events" , event[ "id" ])
redis.expire( "processed_events" , 86400 ) # 24 hour TTL
Always verify the X-Rotavision-Signature header before processing.
Handle failures gracefully
If processing fails, return a non-2xx status. We’ll retry with exponential backoff.
Retry Policy
Failed webhook deliveries are retried with exponential backoff:
Attempt Delay 1 Immediate 2 1 minute 3 5 minutes 4 30 minutes 5 2 hours 6 8 hours 7 24 hours
After 7 failed attempts, the webhook is marked as failed and you’ll receive an email notification.
Testing Webhooks
Using the CLI
rotavision webhooks trigger analysis.completed \
--endpoint wh_abc123 \
--data '{"model_id": "test-model"}'
Using the Dashboard
Go to Settings → Webhooks
Click on your endpoint
Click Send Test Event
Select an event type
Review the delivery log
Event Reference
analysis.completed
{
"id" : "evt_abc123" ,
"type" : "analysis.completed" ,
"created_at" : "2026-02-01T10:30:00Z" ,
"data" : {
"id" : "analysis_xyz789" ,
"model_id" : "loan-approval-v2" ,
"overall_score" : 0.82 ,
"bias_detected" : true ,
"metrics_summary" : {
"demographic_parity" : 0.78 ,
"equalized_odds" : 0.91 ,
"calibration" : 0.85
},
"report_url" : "https://dashboard.rotavision.com/reports/analysis_xyz789"
}
}
alert.triggered
{
"id" : "evt_def456" ,
"type" : "alert.triggered" ,
"created_at" : "2026-02-01T10:30:00Z" ,
"data" : {
"id" : "alert_uvw123" ,
"monitor_id" : "mon_abc789" ,
"model_id" : "recommendation-v3" ,
"metric" : "prediction_drift" ,
"value" : 0.25 ,
"threshold" : 0.1 ,
"severity" : "high" ,
"message" : "Significant prediction drift detected (PSI: 0.25)"
}
}
{
"id" : "evt_ghi789" ,
"type" : "extraction.completed" ,
"created_at" : "2026-02-01T10:30:00Z" ,
"data" : {
"id" : "extract_mno456" ,
"document_type" : "aadhaar" ,
"confidence" : 0.97 ,
"fields" : {
"name" : "राहुल शर्मा" ,
"name_english" : "Rahul Sharma" ,
"dob" : "1990-05-15" ,
"gender" : "Male" ,
"aadhaar_number" : "XXXX-XXXX-1234"
}
}
}