Overview
Webhooks allow you to receive push notifications instead of polling the API. When an event occurs, Decisio sends an HTTP POST request to your configured URL.
Available Events
| Event | Description | Payload |
|---|---|---|
decision.created | New decision generated by an agent | Decision object |
decision.approved | Decision approved by user | Decision object |
decision.rejected | Decision rejected by user | Decision object |
decision.executed | Approved decision executed | Decision + result |
alert.created | New alert from Sentinel | Alert object |
sync.completed | Integration sync finished | Sync summary |
sync.failed | Integration sync failed | Error details |
Setting Up Webhooks
Via Dashboard
- Go to Settings → Webhooks
- Click Add Webhook
- Enter your endpoint URL (must be HTTPS)
- Select events to subscribe to
- Optionally add a description
- Click Create
Via API
POST /v1/webhooks
Content-Type: application/json
Authorization: Bearer <token>
{
"url": "https://yourserver.com/webhooks/decisio",
"events": ["decision.created", "alert.created"],
"description": "Production webhook"
}Webhook Payload
Each webhook delivery includes a JSON payload with the event details:
{
"id": "evt_abc123",
"type": "decision.created",
"created_at": "2025-01-15T10:30:00Z",
"tenant_id": "tenant_xyz",
"data": {
"id": "dec_456",
"agent": "astra",
"type": "price_increase",
"sku": "ELEC-HDMI-001",
"recommendation": {
"current_price": 599,
"new_price": 649,
"expected_impact": "+4500"
},
"confidence": 0.94,
"status": "pending"
}
}Webhook Headers
Each request includes these headers:
| Header | Description |
|---|---|
X-Decisio-Event | Event type (e.g., decision.created) |
X-Decisio-Signature | HMAC-SHA256 signature for verification |
X-Decisio-Timestamp | Unix timestamp of event |
X-Decisio-Delivery | Unique delivery ID for deduplication |
Verifying Signatures
Always verify webhook signatures to ensure requests are from Decisio:
import hmac
import hashlib
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)The signing secret is shown when you create the webhook. Store it securely.
Responding to Webhooks
Your endpoint must:
- Return
2xxstatus code to acknowledge receipt - Respond within 30 seconds
- Handle duplicate deliveries (use delivery ID for deduplication)
Pro Tip
Acknowledge webhooks immediately and process them asynchronously. This prevents timeouts and ensures reliable delivery.
Retry Policy
If your endpoint fails (non-2xx or timeout), Decisio retries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry (final) | 24 hours |
After 5 failed attempts, the delivery is marked as failed. You can manually retry failed deliveries from the webhook logs.
Testing Webhooks
Use the dashboard to test your endpoint:
- Go to Settings → Webhooks
- Click on your webhook
- Click Send Test Event
- Select an event type
- View the request and response
For local development, use a tunnel service like ngrok:
# Start ngrok tunnel ngrok http 3000 # Use the ngrok URL as your webhook endpoint # https://abc123.ngrok.io/webhooks/decisio
Webhook Logs
View delivery history and debug issues:
- Last 7 days of deliveries retained
- See request payload and response
- Filter by event type or status
- Manually retry failed deliveries
Best Practices
- Always verify signatures before processing
- Use idempotency keys to handle duplicates
- Acknowledge quickly, process asynchronously
- Set up monitoring for failed deliveries
- Use separate endpoints for different event types if needed