Alerts API¶
The Alerts API provides endpoints for configuring, managing, and monitoring compliance and threshold alerts.
Overview¶
CalcBridge's alerting system enables:
- Threshold Alerts: Trigger when metrics cross defined thresholds
- Compliance Alerts: Notify on test failures or warnings
- Trend Alerts: Detect concerning patterns over time
- Multiple Channels: Email, webhook, Slack, and in-app notifications
Endpoints¶
Configure Alert¶
Create a new alert configuration.
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Alert name (1-200 chars) |
description | string | No | Alert description |
alert_type | string | Yes | Type: threshold, compliance, trend, schedule |
conditions | object | Yes | Alert trigger conditions |
channels | array[Channel] | Yes | Notification channels |
workbook_id | string (UUID) | No | Specific workbook (or tenant-wide) |
enabled | boolean | No | Enable alert (default: true) |
cooldown_minutes | integer | No | Minimum time between alerts (default: 60) |
Conditions Object (Threshold Alert)¶
| Field | Type | Required | Description |
|---|---|---|---|
metric | string | Yes | Metric to monitor |
operator | string | Yes | Comparison: gt, gte, lt, lte, eq, ne |
value | number | Yes | Threshold value |
duration_minutes | integer | No | Must exceed for N minutes |
Conditions Object (Compliance Alert)¶
| Field | Type | Required | Description |
|---|---|---|---|
test_ids | array[string] | No | Specific tests (or all if omitted) |
status | array[string] | Yes | Trigger on: fail, warning, pass |
cushion_threshold | number | No | Alert when cushion below value |
Channel Object¶
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Channel: email, webhook, slack, in_app |
config | object | Yes | Channel-specific configuration |
Example Request¶
curl -X POST https://api.calcbridge.io/api/v1/alerts/configure \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "CCC Bucket Warning",
"description": "Alert when CCC rated assets approach limit",
"alert_type": "threshold",
"conditions": {
"metric": "ccc_bucket_pct",
"operator": "gte",
"value": 6.5
},
"channels": [
{
"type": "email",
"config": {
"recipients": ["portfolio@example.com", "risk@example.com"]
}
},
{
"type": "slack",
"config": {
"webhook_url": "https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX",
"channel": "#compliance-alerts"
}
}
],
"workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"cooldown_minutes": 120
}'
import requests
response = requests.post(
"https://api.calcbridge.io/api/v1/alerts/configure",
headers={"Authorization": f"Bearer {token}"},
json={
"name": "CCC Bucket Warning",
"description": "Alert when CCC rated assets approach limit",
"alert_type": "threshold",
"conditions": {
"metric": "ccc_bucket_pct",
"operator": "gte",
"value": 6.5
},
"channels": [
{
"type": "email",
"config": {
"recipients": ["portfolio@example.com", "risk@example.com"]
}
},
{
"type": "webhook",
"config": {
"url": "https://api.example.com/webhooks/calcbridge",
"headers": {"X-Custom-Header": "value"}
}
}
],
"workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"cooldown_minutes": 120
}
)
alert = response.json()
print(f"Alert created: {alert['id']}")
const response = await fetch('https://api.calcbridge.io/api/v1/alerts/configure', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'CCC Bucket Warning',
description: 'Alert when CCC rated assets approach limit',
alert_type: 'threshold',
conditions: {
metric: 'ccc_bucket_pct',
operator: 'gte',
value: 6.5
},
channels: [
{
type: 'email',
config: {
recipients: ['portfolio@example.com', 'risk@example.com']
}
}
],
workbook_id: '550e8400-e29b-41d4-a716-446655440000',
cooldown_minutes: 120
})
});
const alert = await response.json();
console.log('Alert created:', alert.id);
Response¶
{
"id": "dd0e8400-e29b-41d4-a716-446655440050",
"name": "CCC Bucket Warning",
"description": "Alert when CCC rated assets approach limit",
"alert_type": "threshold",
"conditions": {
"metric": "ccc_bucket_pct",
"operator": "gte",
"value": 6.5
},
"channels": [
{
"type": "email",
"config": {
"recipients": ["portfolio@example.com", "risk@example.com"]
}
},
{
"type": "slack",
"config": {
"webhook_url": "https://hooks.slack.com/services/...",
"channel": "#compliance-alerts"
}
}
],
"workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"enabled": true,
"cooldown_minutes": 120,
"created_by": "user@example.com",
"created_at": "2026-01-25T10:30:00Z",
"updated_at": "2026-01-25T10:30:00Z"
}
Error Responses¶
| Status | Error | Description |
|---|---|---|
400 | Invalid alert type | Unknown alert_type value |
400 | Invalid channel type | Unknown channel type |
400 | Invalid conditions | Conditions don't match alert type |
422 | Channel configuration error | Missing required channel config |
List Alerts¶
Get all alert configurations for the current tenant.
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
page_size | integer | 20 | Items per page |
workbook_id | string (UUID) | - | Filter by workbook |
alert_type | string | - | Filter by type |
enabled | boolean | - | Filter by enabled status |
Example Request¶
Response¶
{
"items": [
{
"id": "dd0e8400-e29b-41d4-a716-446655440050",
"name": "CCC Bucket Warning",
"description": "Alert when CCC rated assets approach limit",
"alert_type": "threshold",
"enabled": true,
"workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"last_triggered": "2026-01-24T15:30:00Z",
"trigger_count": 3,
"created_at": "2026-01-20T10:00:00Z"
},
{
"id": "dd0e8400-e29b-41d4-a716-446655440051",
"name": "Compliance Test Failure",
"description": "Alert on any compliance test failure",
"alert_type": "compliance",
"enabled": true,
"workbook_id": null,
"last_triggered": "2026-01-25T09:00:00Z",
"trigger_count": 7,
"created_at": "2026-01-15T10:00:00Z"
}
],
"total": 12,
"page": 1,
"page_size": 50,
"total_pages": 1
}
Get Alert¶
Retrieve a specific alert configuration with history.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
alert_id | string (UUID) | Alert identifier |
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
include_history | boolean | false | Include trigger history |
history_limit | integer | 10 | Number of history entries |
Example Request¶
Response¶
{
"id": "dd0e8400-e29b-41d4-a716-446655440050",
"name": "CCC Bucket Warning",
"description": "Alert when CCC rated assets approach limit",
"alert_type": "threshold",
"conditions": {
"metric": "ccc_bucket_pct",
"operator": "gte",
"value": 6.5
},
"channels": [
{
"type": "email",
"config": {
"recipients": ["portfolio@example.com", "risk@example.com"]
}
}
],
"workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"enabled": true,
"cooldown_minutes": 120,
"last_triggered": "2026-01-24T15:30:00Z",
"trigger_count": 3,
"history": [
{
"triggered_at": "2026-01-24T15:30:00Z",
"metric_value": 6.8,
"notifications_sent": 2,
"channels_notified": ["email", "slack"]
},
{
"triggered_at": "2026-01-22T10:15:00Z",
"metric_value": 7.1,
"notifications_sent": 2,
"channels_notified": ["email", "slack"]
},
{
"triggered_at": "2026-01-20T14:45:00Z",
"metric_value": 6.5,
"notifications_sent": 2,
"channels_notified": ["email", "slack"]
}
],
"created_by": "user@example.com",
"created_at": "2026-01-20T10:00:00Z",
"updated_at": "2026-01-24T15:30:00Z"
}
Update Alert¶
Update an existing alert configuration.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
alert_id | string (UUID) | Alert identifier |
Request Body¶
All fields are optional. Only provided fields are updated.
| Field | Type | Description |
|---|---|---|
name | string | Alert name |
description | string | Alert description |
conditions | object | Alert conditions |
channels | array[Channel] | Notification channels |
enabled | boolean | Enable/disable alert |
cooldown_minutes | integer | Cooldown period |
Example Request¶
import requests
response = requests.patch(
f"https://api.calcbridge.io/api/v1/alerts/{alert_id}",
headers={"Authorization": f"Bearer {token}"},
json={
"conditions": {
"metric": "ccc_bucket_pct",
"operator": "gte",
"value": 6.0
},
"cooldown_minutes": 60
}
)
alert = response.json()
print(f"Updated threshold to: {alert['conditions']['value']}")
const response = await fetch(
`https://api.calcbridge.io/api/v1/alerts/${alertId}`,
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
conditions: {
metric: 'ccc_bucket_pct',
operator: 'gte',
value: 6.0
},
cooldown_minutes: 60
})
}
);
const alert = await response.json();
console.log('Updated threshold to:', alert.conditions.value);
Response¶
{
"id": "dd0e8400-e29b-41d4-a716-446655440050",
"name": "CCC Bucket Warning",
"description": "Alert when CCC rated assets approach limit",
"alert_type": "threshold",
"conditions": {
"metric": "ccc_bucket_pct",
"operator": "gte",
"value": 6.0
},
"channels": [
{
"type": "email",
"config": {
"recipients": ["portfolio@example.com", "risk@example.com"]
}
}
],
"workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"enabled": true,
"cooldown_minutes": 60,
"created_by": "user@example.com",
"created_at": "2026-01-20T10:00:00Z",
"updated_at": "2026-01-25T11:00:00Z"
}
Delete Alert¶
Delete an alert configuration.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
alert_id | string (UUID) | Alert identifier |
Example Request¶
Response¶
Returns 204 No Content on success.
Test Alert¶
Send a test notification to verify alert configuration.
Path Parameters¶
| Parameter | Type | Description |
|---|---|---|
alert_id | string (UUID) | Alert identifier |
Example Request¶
Response¶
{
"test_id": "ee0e8400-e29b-41d4-a716-446655440060",
"alert_id": "dd0e8400-e29b-41d4-a716-446655440050",
"results": [
{
"channel": "email",
"status": "success",
"message": "Test email sent to 2 recipients"
},
{
"channel": "slack",
"status": "success",
"message": "Test message posted to #compliance-alerts"
}
],
"tested_at": "2026-01-25T11:00:00Z"
}
Alert Types¶
Threshold Alert¶
Triggered when a metric crosses a defined threshold.
{
"alert_type": "threshold",
"conditions": {
"metric": "single_obligor_concentration",
"operator": "gte",
"value": 4.5,
"duration_minutes": 0
}
}
Available Metrics:
| Metric | Description |
|---|---|
single_obligor_concentration | Maximum single obligor exposure % |
top_5_concentration | Top 5 obligors combined % |
industry_concentration | Maximum industry exposure % |
ccc_bucket_pct | CCC rated assets % |
average_rating_factor | Portfolio average rating factor |
oc_ratio | Overcollateralization ratio |
ic_ratio | Interest coverage ratio |
wal | Weighted average life |
was | Weighted average spread |
Compliance Alert¶
Triggered on compliance test status changes.
{
"alert_type": "compliance",
"conditions": {
"test_ids": ["concentration_single_obligor", "rating_ccc_bucket"],
"status": ["fail", "warning"],
"cushion_threshold": 1.0
}
}
Trend Alert¶
Triggered when metrics show concerning trends.
{
"alert_type": "trend",
"conditions": {
"metric": "ccc_bucket_pct",
"direction": "increasing",
"change_threshold": 0.5,
"lookback_days": 7
}
}
Schedule Alert¶
Triggered on a schedule (e.g., daily compliance summary).
{
"alert_type": "schedule",
"conditions": {
"schedule": "0 9 * * 1-5",
"report_type": "compliance_summary"
}
}
Notification Channels¶
Email¶
{
"type": "email",
"config": {
"recipients": ["user@example.com"],
"cc": ["manager@example.com"],
"subject_prefix": "[ALERT]",
"include_details": true
}
}
Webhook¶
{
"type": "webhook",
"config": {
"url": "https://api.example.com/webhooks/alerts",
"method": "POST",
"headers": {
"Authorization": "Bearer webhook-token",
"X-Custom-Header": "value"
},
"retry_count": 3
}
}
Webhook Payload¶
{
"alert_id": "dd0e8400-e29b-41d4-a716-446655440050",
"alert_name": "CCC Bucket Warning",
"alert_type": "threshold",
"triggered_at": "2026-01-25T10:30:00Z",
"workbook_id": "550e8400-e29b-41d4-a716-446655440000",
"workbook_name": "CLO Portfolio Q1 2026",
"details": {
"metric": "ccc_bucket_pct",
"current_value": 6.8,
"threshold_value": 6.5,
"operator": "gte"
}
}
Slack¶
{
"type": "slack",
"config": {
"webhook_url": "https://hooks.slack.com/services/...",
"channel": "#compliance-alerts",
"username": "CalcBridge Bot",
"icon_emoji": ":warning:",
"mention_users": ["U12345678"]
}
}
In-App¶
Best Practices¶
- Set appropriate cooldowns: Avoid alert fatigue with reasonable cooldown periods
- Use multiple channels: Configure backup channels for critical alerts
- Test configurations: Use the test endpoint before relying on alerts
- Monitor alert history: Review trigger patterns to tune thresholds
- Enable trend alerts: Catch issues before they become critical
- Document alert purposes: Use descriptions to explain alert rationale