Webhooks
Receive real-time notifications about system events and integrate with your existing workflows.
Overview
Webhooks provide a way for your applications to receive real-time notifications when specific events occur in Sapphire Legal AI. This enables seamless integration with external systems and automated workflows.
Core concepts
How webhooks work
- You register a webhook endpoint URL with Sapphire Legal AI
- When an event occurs, we send an HTTP POST request to your endpoint
- Your endpoint processes the webhook payload and takes appropriate action
- You return a 2xx status code to acknowledge receipt
Event types
Webhooks are triggered by various system events:
- Case events: Case created, updated, status changed, assigned
- Document events: Document uploaded, processed, updated, deleted
- User events: User login, logout, permission changes
- System events: Backup completed, maintenance scheduled, errors
- AI events: AI processing started, completed, failed
Webhook configuration
Creating a webhook
POST /api/v1/admin/webhooks Authorization: Bearer <admin_jwt_token> Content-Type: application/json { "name": "Case Notifications", "url": "https://your-app.com/webhooks/sapphire", "events": ["case.created", "case.updated", "case.status_changed"], "secret": "your_webhook_secret", "active": true, "retry_policy": { "max_attempts": 5, "backoff_multiplier": 2, "initial_delay": 60 } }
Webhook settings
Setting | Type | Description | Required |
---|---|---|---|
name | string | Human-readable name for the webhook | Yes |
url | string | HTTPS endpoint to receive webhooks | Yes |
events | array | List of events to subscribe to | Yes |
secret | string | Secret for signature verification | Yes |
active | boolean | Whether webhook is active | No |
Webhook payloads
Standard payload format
{ "id": "webhook_1234567890abcdef", "event": "case.created", "timestamp": "2025-01-20T10:30:00Z", "data": { "case_id": "case_1234567890abcdef", "title": "Smith v. Johnson", "case_number": "CV-2025-001", "status": "active", "created_by": "user_1234567890abcdef" }, "metadata": { "webhook_id": "webhook_1234567890abcdef", "attempt": 1, "delivery_id": "delivery_1234567890abcdef" } }
Case created event
{ "id": "webhook_1234567890abcdef", "event": "case.created", "timestamp": "2025-01-20T10:30:00Z", "data": { "case_id": "case_1234567890abcdef", "title": "Smith v. Johnson", "case_number": "CV-2025-001", "case_type": "litigation", "jurisdiction": "federal", "client_name": "John Smith", "status": "active", "priority": "high", "created_by": "user_1234567890abcdef", "created_at": "2025-01-20T10:30:00Z" } }
Document uploaded event
{ "id": "webhook_1234567890abcdef", "event": "document.uploaded", "timestamp": "2025-01-20T10:30:00Z", "data": { "document_id": "doc_1234567890abcdef", "case_id": "case_1234567890abcdef", "title": "Complaint", "document_type": "pleading", "file_size": 1048576, "file_type": "application/pdf", "uploaded_by": "user_1234567890abcdef", "uploaded_at": "2025-01-20T10:30:00Z" } }
Security and verification
Signature verification
Each webhook includes a signature header that you can use to verify the request authenticity:
X-Sapphire-Signature: t=1234567890,v1=abc123def456... X-Sapphire-Timestamp: 1234567890
Verification process
- Extract the timestamp and signature from headers
- Concatenate the timestamp and request body
- Create HMAC SHA256 using your webhook secret
- Compare the computed signature with the received signature
Example verification (Node.js)
const crypto = require('crypto'); function verifyWebhookSignature(payload, signature, timestamp, secret) { const expectedSignature = crypto .createHmac('sha256', secret) .update(timestamp + '.' + payload) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) ); }
Retry policy
Automatic retries
If your webhook endpoint fails to respond or returns an error, we automatically retry delivery:
- Retry attempts: Up to 5 attempts by default
- Backoff strategy: Exponential backoff with jitter
- Initial delay: 60 seconds
- Maximum delay: 1 hour
- Total timeout: 24 hours
Retry conditions
Webhooks are retried when your endpoint:
- Returns a 4xx or 5xx HTTP status code
- Doesn't respond within 30 seconds
- Returns a malformed response
- Is unreachable (network errors)
Dead letter queue
After all retry attempts are exhausted, failed webhooks are moved to a dead letter queue for manual investigation and processing.
Best practices
Webhook endpoint design
- Idempotency: Handle duplicate webhooks gracefully
- Quick response: Return 2xx status immediately, process asynchronously
- Error handling: Log errors and return appropriate status codes
- Security: Always verify webhook signatures
- Monitoring: Track webhook delivery success and failures
Performance considerations
- Process webhooks asynchronously when possible
- Use connection pooling for database operations
- Implement proper timeout handling
- Monitor endpoint response times
- Scale your webhook endpoint as needed
Testing webhooks
Test endpoint
Use our test endpoint to verify your webhook configuration:
POST /api/v1/admin/webhooks/{webhook_id}/test Authorization: Bearer <admin_jwt_token> Content-Type: application/json { "event_type": "case.created", "test_data": { "case_id": "test_case_123", "title": "Test Case" } }
Local testing
For local development, use tools like ngrok to expose your local endpoint:
# Install ngrok npm install -g ngrok # Expose local endpoint ngrok http 3000 # Use the ngrok URL as your webhook endpoint https://abc123.ngrok.io/webhooks/sapphire
What's next
- SDKs & Libraries - Use official client libraries
- System Configuration - Configure webhook settings
- API Endpoints - Explore other API capabilities