Skip to content

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.

POST /api/v1/alerts/configure

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.

GET /api/v1/alerts

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

curl -X GET "https://api.calcbridge.io/api/v1/alerts?enabled=true&page_size=50" \
  -H "Authorization: Bearer $TOKEN"
import requests

response = requests.get(
    "https://api.calcbridge.io/api/v1/alerts",
    headers={"Authorization": f"Bearer {token}"},
    params={"enabled": True, "page_size": 50}
)
alerts = response.json()
for alert in alerts["items"]:
    print(f"{alert['name']}: {alert['alert_type']}")
const response = await fetch(
  'https://api.calcbridge.io/api/v1/alerts?enabled=true&page_size=50',
  { headers: { 'Authorization': `Bearer ${token}` } }
);
const alerts = await response.json();
alerts.items.forEach(alert => {
  console.log(`${alert.name}: ${alert.alert_type}`);
});

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.

GET /api/v1/alerts/{alert_id}

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

curl -X GET "https://api.calcbridge.io/api/v1/alerts/dd0e8400-e29b-41d4-a716-446655440050?include_history=true" \
  -H "Authorization: Bearer $TOKEN"

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.

PATCH /api/v1/alerts/{alert_id}

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

curl -X PATCH https://api.calcbridge.io/api/v1/alerts/dd0e8400-e29b-41d4-a716-446655440050 \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "conditions": {
      "metric": "ccc_bucket_pct",
      "operator": "gte",
      "value": 6.0
    },
    "cooldown_minutes": 60
  }'
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.

DELETE /api/v1/alerts/{alert_id}

Path Parameters

Parameter Type Description
alert_id string (UUID) Alert identifier

Example Request

curl -X DELETE https://api.calcbridge.io/api/v1/alerts/dd0e8400-e29b-41d4-a716-446655440050 \
  -H "Authorization: Bearer $TOKEN"

Response

Returns 204 No Content on success.


Test Alert

Send a test notification to verify alert configuration.

POST /api/v1/alerts/{alert_id}/test

Path Parameters

Parameter Type Description
alert_id string (UUID) Alert identifier

Example Request

curl -X POST https://api.calcbridge.io/api/v1/alerts/dd0e8400-e29b-41d4-a716-446655440050/test \
  -H "Authorization: Bearer $TOKEN"

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

{
  "type": "in_app",
  "config": {
    "user_ids": ["user-uuid-1", "user-uuid-2"],
    "priority": "high"
  }
}

Best Practices

  1. Set appropriate cooldowns: Avoid alert fatigue with reasonable cooldown periods
  2. Use multiple channels: Configure backup channels for critical alerts
  3. Test configurations: Use the test endpoint before relying on alerts
  4. Monitor alert history: Review trigger patterns to tune thresholds
  5. Enable trend alerts: Catch issues before they become critical
  6. Document alert purposes: Use descriptions to explain alert rationale