The Metrics API enables programmatic management of data quality metrics. Use it to track trends in your data over time, detect anomalies, and integrate quality monitoring into your pipelines.
Endpoints
| Method | Endpoint | Description |
|---|
| GET | /api/v1/sdk/metrics/{asset_id}/summary | Get metrics summary for an asset |
| GET | /api/v1/sdk/metrics/{asset_id} | List metrics for an asset |
| GET | /api/v1/sdk/metrics/{asset_id}/{metric_id} | Get metric details |
| POST | /api/v1/sdk/metrics/{asset_id} | Create a new metric |
| PATCH | /api/v1/sdk/metrics/{asset_id}/{metric_id} | Update a metric |
| DELETE | /api/v1/sdk/metrics/{asset_id}/{metric_id} | Delete a metric |
| POST | /api/v1/sdk/metrics/{asset_id}/{metric_id}/capture | Trigger metric capture |
| GET | /api/v1/sdk/metrics/{asset_id}/{metric_id}/snapshots | List metric snapshots |
Metric Types
| Type | Description | Requires Column |
|---|
row_count | Total row count of the table | No |
null_percent | Percentage of null values | Yes |
distinct_count | Count of distinct values | Yes |
duplicate_count | Count of duplicate values | Yes |
min_value | Minimum numeric value | Yes |
max_value | Maximum numeric value | Yes |
avg_value | Average numeric value | Yes |
percentile | Percentile value (requires percentile_value) | Yes |
Get Metrics Summary
GET /api/v1/sdk/metrics/{asset_id}/summary
Returns aggregate metrics statistics for an asset.
curl -H "Authorization: Bearer aa_live_xxx" \
"https://api.anomalyarmor.ai/api/v1/sdk/metrics/550e8400-e29b-41d4-a716-446655440000/summary"
Response
{
"data": {
"total_metrics": 15,
"active_metrics": 12,
"total_checks": 8,
"passing": 6,
"failing": 1,
"warning": 1,
"error": 0,
"health_percentage": 87.5
}
}
List Metrics
GET /api/v1/sdk/metrics/{asset_id}
Query Parameters
| Parameter | Type | Default | Description |
|---|
metric_type | string | - | Filter by type (e.g., row_count, null_percent) |
is_active | boolean | - | Filter by active status |
limit | integer | 50 | Max results (max: 100) |
offset | integer | 0 | Results to skip |
curl -H "Authorization: Bearer aa_live_xxx" \
"https://api.anomalyarmor.ai/api/v1/sdk/metrics/550e8400-e29b-41d4-a716-446655440000?metric_type=null_percent&limit=10"
Response
{
"data": {
"items": [
{
"id": "m_550e8400-e29b-41d4-a716-446655440001",
"internal_id": 123,
"asset_id": 456,
"table_path": "snowflake.prod.warehouse.orders",
"column_name": "customer_email",
"metric_type": "null_percent",
"capture_interval": "daily",
"sensitivity": 3,
"is_active": true,
"created_at": "2026-01-01T10:00:00Z"
}
]
},
"pagination": {
"total": 15,
"limit": 50,
"offset": 0,
"has_more": false
}
}
Get Metric Details
GET /api/v1/sdk/metrics/{asset_id}/{metric_id}
Query Parameters
| Parameter | Type | Default | Description |
|---|
include_snapshots | boolean | true | Include recent snapshots |
snapshot_limit | integer | 30 | Max snapshots to include |
curl -H "Authorization: Bearer aa_live_xxx" \
"https://api.anomalyarmor.ai/api/v1/sdk/metrics/550e8400-e29b-41d4-a716-446655440000/m_550e8400-e29b-41d4-a716-446655440001?include_snapshots=true&snapshot_limit=10"
Response
{
"data": {
"id": "m_550e8400-e29b-41d4-a716-446655440001",
"internal_id": 123,
"asset_id": 456,
"table_path": "snowflake.prod.warehouse.orders",
"column_name": "customer_email",
"metric_type": "null_percent",
"capture_interval": "daily",
"sensitivity": 3,
"is_active": true,
"created_at": "2026-01-01T10:00:00Z"
}
}
Create Metric
POST /api/v1/sdk/metrics/{asset_id}
Requires read-write or admin scope.
Request Body
| Field | Type | Required | Description |
|---|
metric_type | string | Yes | Metric type (see table above) |
table_path | string | Yes | Full table path (catalog.schema.table) |
column_name | string | For column metrics | Column name |
capture_interval | string | No | hourly, daily, weekly (default: daily) |
sensitivity | float | No | Anomaly detection sensitivity (default: 1.0) |
group_by_columns | array | No | Columns to group by |
percentile_value | float | No | Percentile value (for percentile type) |
curl -X POST -H "Authorization: Bearer aa_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"metric_type": "null_percent",
"table_path": "snowflake.prod.warehouse.orders",
"column_name": "customer_email",
"capture_interval": "daily"
}' \
"https://api.anomalyarmor.ai/api/v1/sdk/metrics/550e8400-e29b-41d4-a716-446655440000"
Response
{
"data": {
"id": "m_550e8400-e29b-41d4-a716-446655440001",
"internal_id": 123,
"asset_id": 456,
"table_path": "snowflake.prod.warehouse.orders",
"column_name": "customer_email",
"metric_type": "null_percent",
"capture_interval": "daily",
"sensitivity": 1.0,
"is_active": true,
"created_at": "2026-01-04T10:30:00Z"
}
}
Update Metric
PATCH /api/v1/sdk/metrics/{asset_id}/{metric_id}
Requires read-write or admin scope.
Request Body
| Field | Type | Description |
|---|
is_active | boolean | Whether metric is active |
capture_interval | string | Capture interval |
sensitivity | float | Anomaly detection sensitivity |
curl -X PATCH -H "Authorization: Bearer aa_live_xxx" \
-H "Content-Type: application/json" \
-d '{"is_active": false}' \
"https://api.anomalyarmor.ai/api/v1/sdk/metrics/550e8400-e29b-41d4-a716-446655440000/m_550e8400-e29b-41d4-a716-446655440001"
Delete Metric
DELETE /api/v1/sdk/metrics/{asset_id}/{metric_id}
Requires read-write or admin scope.
curl -X DELETE -H "Authorization: Bearer aa_live_xxx" \
"https://api.anomalyarmor.ai/api/v1/sdk/metrics/550e8400-e29b-41d4-a716-446655440000/m_550e8400-e29b-41d4-a716-446655440001"
Response
{
"data": {
"success": true,
"message": "Metric deleted"
}
}
Trigger Metric Capture
POST /api/v1/sdk/metrics/{asset_id}/{metric_id}/capture
Requires read-write or admin scope.
Triggers an immediate capture of the metric value.
curl -X POST -H "Authorization: Bearer aa_live_xxx" \
"https://api.anomalyarmor.ai/api/v1/sdk/metrics/550e8400-e29b-41d4-a716-446655440000/m_550e8400-e29b-41d4-a716-446655440001/capture"
Response
{
"data": {
"snapshot_count": 1,
"snapshots": [
{
"id": 789,
"value": 2.5,
"captured_at": "2026-01-04T10:35:00Z",
"is_anomaly": false,
"status": "PASS"
}
]
}
}
List Metric Snapshots
GET /api/v1/sdk/metrics/{asset_id}/{metric_id}/snapshots
Query Parameters
| Parameter | Type | Default | Description |
|---|
limit | integer | 100 | Max results |
offset | integer | 0 | Results to skip |
curl -H "Authorization: Bearer aa_live_xxx" \
"https://api.anomalyarmor.ai/api/v1/sdk/metrics/550e8400-e29b-41d4-a716-446655440000/m_550e8400-e29b-41d4-a716-446655440001/snapshots?limit=30"
Response
{
"data": {
"items": [
{
"id": 789,
"metric_definition_id": 123,
"value": 2.5,
"captured_at": "2026-01-04T10:35:00Z",
"is_anomaly": false,
"z_score": 0.3,
"status": "PASS"
},
{
"id": 788,
"metric_definition_id": 123,
"value": 15.2,
"captured_at": "2026-01-03T10:35:00Z",
"is_anomaly": true,
"z_score": 4.2,
"status": "FAIL"
}
]
},
"pagination": {
"total": 90,
"limit": 30,
"offset": 0,
"has_more": true
}
}
Use Case: Monitor Row Count Trends
Track daily row counts to detect unexpected data volume changes:
from anomalyarmor import Client
client = Client()
asset_id = "550e8400-e29b-41d4-a716-446655440000"
# Create row count metric
metric = client.metrics.create(
asset_id,
metric_type="row_count",
table_path="snowflake.prod.warehouse.orders",
capture_interval="daily",
sensitivity=2.0, # Alert on 2+ standard deviations
)
# Trigger initial capture
result = client.metrics.capture(asset_id, metric.id)
print(f"Initial row count: {result['snapshots'][0]['value']}")
# Later: check for anomalies
snapshots = client.metrics.snapshots(asset_id, metric.id, limit=7)
anomalies = [s for s in snapshots if s.is_anomaly]
if anomalies:
print(f"Found {len(anomalies)} anomalies in the last 7 captures")
Error Responses
Metric Not Found (404)
{
"error": {
"code": "METRIC_NOT_FOUND",
"message": "Metric not found",
"details": {"metric_id": "m_invalid-uuid"}
}
}
Validation Error (400)
{
"error": {
"code": "VALIDATION_ERROR",
"message": "column_name is required for null_percent metrics",
"details": {"field": "column_name", "metric_type": "null_percent"}
}
}
Forbidden (403)
{
"error": {
"code": "FORBIDDEN",
"message": "Insufficient permissions. Required scope: read-write",
"details": {"current_scope": "read-only", "required_scope": "read-write"}
}
}