Alerts API
The Alerts API manages threshold-based alert rules that monitor gateway metrics over sliding time windows. When a rule’s condition is met, an alert history record is written and a webhook notification is delivered. All endpoints require admin authentication (Authorization: Bearer $ARBITEX_API_KEY).
Base URL: https://gateway.arbitex.ai
For notification channel setup (Slack, PagerDuty, email), see the Alert configuration admin guide.
Endpoints summary
Section titled “Endpoints summary”| Method | Path | Description |
|---|---|---|
GET | /api/alerts | List all alert rules |
POST | /api/alerts | Create an alert rule |
GET | /api/alerts/{rule_id} | Get a single alert rule |
PUT | /api/alerts/{rule_id} | Update alert rule (partial) |
DELETE | /api/alerts/{rule_id} | Delete alert rule |
GET | /api/alerts/{rule_id}/history | Get trigger history for a rule |
POST | /api/alerts/evaluate | Manually trigger evaluation of all rules |
AlertRule object
Section titled “AlertRule object”| Field | Type | Description |
|---|---|---|
id | UUID | Alert rule UUID |
name | string | Human-readable rule name |
metric_type | MetricType | Metric to evaluate (see table below) |
threshold | float | Numeric threshold value |
comparison | ComparisonOp | How to compare the metric against the threshold |
window_minutes | int | Sliding evaluation window in minutes (1–10080) |
webhook_url | string | null | URL to POST when the rule triggers; null to disable notifications |
enabled | bool | Whether the rule participates in scheduled evaluation |
cooldown_minutes | int | Minimum minutes between consecutive firings (1–10080, default 60) |
last_triggered_at | datetime | null | Timestamp of the most recent trigger, or null if never triggered |
created_at | datetime | ISO 8601 creation timestamp |
updated_at | datetime | ISO 8601 last-modified timestamp |
tenant_id | UUID | Owning tenant UUID |
MetricType values
Section titled “MetricType values”| Value | Unit | Description |
|---|---|---|
cost | USD | Total AI spend in the evaluation window |
error_rate | Percent (0–100) | Percentage of requests returning errors in the window |
latency_p95 | Milliseconds | 95th-percentile request latency in the window |
dlp_trigger_count | Count | Number of DLP trigger events in the window |
blocked_request_count | Count | Number of blocked requests in the window |
ComparisonOp values
Section titled “ComparisonOp values”| Value | Meaning |
|---|---|
gt | Metric is greater than threshold |
lt | Metric is less than threshold |
gte | Metric is greater than or equal to threshold |
lte | Metric is less than or equal to threshold |
List alert rules
Section titled “List alert rules”GET /api/alertsReturns all alert rules for the tenant, ordered by created_at descending (newest first).
Request
curl -s https://gateway.arbitex.ai/api/alerts \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK
[ { "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "name": "Hourly cost spike", "metric_type": "cost", "threshold": 50.00, "comparison": "gt", "window_minutes": 60, "webhook_url": "https://hooks.slack.com/services/T00/B00/XXXX", "enabled": true, "cooldown_minutes": 30, "last_triggered_at": "2026-03-12T08:15:00Z", "created_at": "2026-02-10T12:00:00Z", "updated_at": "2026-03-01T09:30:00Z", "tenant_id": "9c0e1d2f-3b4a-5c6d-7e8f-9a0b1c2d3e4f" }, { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "DLP trigger rate — 15 min", "metric_type": "dlp_trigger_count", "threshold": 100, "comparison": "gte", "window_minutes": 15, "webhook_url": "https://my-ops-gateway.example.com/webhook", "enabled": true, "cooldown_minutes": 15, "last_triggered_at": null, "created_at": "2026-01-20T14:00:00Z", "updated_at": "2026-01-20T14:00:00Z", "tenant_id": "9c0e1d2f-3b4a-5c6d-7e8f-9a0b1c2d3e4f" }]Create alert rule
Section titled “Create alert rule”POST /api/alertsCreates a new alert rule. The rule enters the evaluation schedule immediately if enabled is true (the default).
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Human-readable rule name |
metric_type | string | yes | One of the MetricType values |
threshold | float | yes | Trigger threshold |
comparison | string | yes | One of the ComparisonOp values |
window_minutes | int | yes | Evaluation window in minutes (1–10080) |
webhook_url | string | null | no | Notification endpoint |
enabled | bool | no | Default true |
cooldown_minutes | int | no | Default 60 (1–10080) |
Request — cost spike alert
curl -s -X POST https://gateway.arbitex.ai/api/alerts \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Hourly cost spike", "metric_type": "cost", "threshold": 50.00, "comparison": "gt", "window_minutes": 60, "webhook_url": "https://hooks.slack.com/services/T00/B00/XXXX", "cooldown_minutes": 30 }'Request — high error rate alert
curl -s -X POST https://gateway.arbitex.ai/api/alerts \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Provider error rate > 5%", "metric_type": "error_rate", "threshold": 5.0, "comparison": "gte", "window_minutes": 15, "webhook_url": "https://my-ops-gateway.example.com/webhook", "cooldown_minutes": 10 }'Request — p95 latency alert
curl -s -X POST https://gateway.arbitex.ai/api/alerts \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "p95 latency > 3s", "metric_type": "latency_p95", "threshold": 3000, "comparison": "gt", "window_minutes": 10, "webhook_url": "https://events.pagerduty.com/v2/enqueue", "cooldown_minutes": 5 }'Response 201 Created
{ "id": "7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e", "name": "Hourly cost spike", "metric_type": "cost", "threshold": 50.00, "comparison": "gt", "window_minutes": 60, "webhook_url": "https://hooks.slack.com/services/T00/B00/XXXX", "enabled": true, "cooldown_minutes": 30, "last_triggered_at": null, "created_at": "2026-03-12T15:00:00Z", "updated_at": "2026-03-12T15:00:00Z", "tenant_id": "9c0e1d2f-3b4a-5c6d-7e8f-9a0b1c2d3e4f"}Get alert rule
Section titled “Get alert rule”GET /api/alerts/{rule_id}Returns a single alert rule.
Path parameters
| Parameter | Type | Description |
|---|---|---|
rule_id | UUID | The alert rule UUID |
Request
curl -s https://gateway.arbitex.ai/api/alerts/7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK — the AlertRule object.
Response 404 Not Found — rule ID does not exist within the tenant.
Update alert rule
Section titled “Update alert rule”PUT /api/alerts/{rule_id}Partial update — only the fields included in the request body are modified.
Path parameters
| Parameter | Type | Description |
|---|---|---|
rule_id | UUID | The alert rule UUID |
Request — raise threshold and increase cooldown
curl -s -X PUT \ https://gateway.arbitex.ai/api/alerts/7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "threshold": 75.00, "cooldown_minutes": 60 }'Request — disable during maintenance
curl -s -X PUT \ https://gateway.arbitex.ai/api/alerts/7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e \ -H "Authorization: Bearer $ARBITEX_API_KEY" \ -H "Content-Type: application/json" \ -d '{"enabled": false}'Response 200 OK — the updated AlertRule object.
Response 404 Not Found — rule ID does not exist within the tenant.
Delete alert rule
Section titled “Delete alert rule”DELETE /api/alerts/{rule_id}Permanently deletes the rule and all associated history records.
Path parameters
| Parameter | Type | Description |
|---|---|---|
rule_id | UUID | The alert rule UUID |
Request
curl -s -X DELETE \ https://gateway.arbitex.ai/api/alerts/7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 204 No Content
Get trigger history
Section titled “Get trigger history”GET /api/alerts/{rule_id}/historyReturns the trigger history for a single rule, newest first.
Path parameters
| Parameter | Type | Description |
|---|---|---|
rule_id | UUID | The alert rule UUID |
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | int | 50 | Maximum number of records to return |
offset | int | 0 | Number of records to skip (for pagination) |
Request
curl -s \ "https://gateway.arbitex.ai/api/alerts/7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e/history?limit=10&offset=0" \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK
{ "history": [ { "id": "hist-a1b2c3d4-...", "rule_id": "7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e", "rule_name": "Hourly cost spike", "metric_value": 67.42, "threshold": 50.00, "triggered_at": "2026-03-12T08:15:00Z", "webhook_delivered": true }, { "id": "hist-b2c3d4e5-...", "rule_id": "7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e", "rule_name": "Hourly cost spike", "metric_value": 53.18, "threshold": 50.00, "triggered_at": "2026-03-11T14:47:00Z", "webhook_delivered": false } ], "total": 2}AlertHistory object fields
Section titled “AlertHistory object fields”| Field | Type | Description |
|---|---|---|
id | UUID | History record UUID |
rule_id | UUID | Parent alert rule UUID |
rule_name | string | Name of the rule at the time of trigger |
metric_value | float | Observed metric value that caused the trigger |
threshold | float | Threshold value at the time of trigger |
triggered_at | datetime | ISO 8601 trigger timestamp |
webhook_delivered | bool | true if the webhook POST returned a 2xx response |
Response 404 Not Found — rule ID does not exist within the tenant.
Manually evaluate all rules
Section titled “Manually evaluate all rules”POST /api/alerts/evaluateImmediately evaluates all enabled alert rules against current metric values, outside the normal evaluation schedule. Rules that trigger create history records and attempt webhook delivery as normal.
Use this to:
- Test a newly created rule against live data before the next scheduled evaluation
- Validate that threshold values are correctly calibrated
- Diagnose missing notifications after a known event
Request
curl -s -X POST https://gateway.arbitex.ai/api/alerts/evaluate \ -H "Authorization: Bearer $ARBITEX_API_KEY"Response 200 OK
{ "rules_evaluated": 5, "rules_triggered": 1, "triggered": [ { "rule_id": "7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e", "rule_name": "Hourly cost spike", "metric_value": 67.42 } ]}| Field | Type | Description |
|---|---|---|
rules_evaluated | int | Total number of enabled rules evaluated |
rules_triggered | int | Number of rules whose threshold condition was met |
triggered | list | Summary of each triggered rule — rule_id, rule_name, and observed metric_value |
Rules in cooldown are still evaluated but do not produce history records or webhook deliveries. They are counted in rules_evaluated but not in rules_triggered.
Webhook notification payload
Section titled “Webhook notification payload”When a rule triggers, Arbitex POSTs the following JSON to the rule’s webhook_url:
{ "alert_rule_id": "7b8c9d0e-1f2a-3b4c-5d6e-7f8a9b0c1d2e", "alert_name": "Hourly cost spike", "metric_type": "cost", "metric_value": 67.42, "threshold": 50.00, "comparison": "gt", "triggered_at": "2026-03-12T08:15:00Z"}The webhook_delivered flag on the history record is set to true only if the POST returns a 2xx response. Failed deliveries are not retried automatically. To detect missed notifications, review the trigger history and check webhook_delivered.
Error codes
Section titled “Error codes”| Status | Condition |
|---|---|
400 Bad Request | Invalid request body, unsupported metric_type or comparison, or window_minutes / cooldown_minutes out of range |
403 Forbidden | Caller is not an admin |
404 Not Found | Rule ID does not exist within the tenant |
See also
Section titled “See also”- Alert configuration admin guide — notification channel setup (Slack, PagerDuty, email), threshold tuning, and operational guidelines
- Webhooks API — outbound webhooks for event-driven integrations
- Quotas API — configure the limits monitored by
quota_exceededevents - DLP Rules API — rules that produce
dlp_trigger_countmetric data