Ranked shifts against each service's own baseline
Precomputed anomalies: worsening regime shifts (BOCPD changepoints, threshold-free) detected continuously over persisted 5-minute series of every signal — error_rate and latency_p95 per operation, log_volume, error_log_rate and profile_cost (the service's total profiled cost) per service (the operation field holds the entity) — and persisted to the sigiro_anomalies table. Ordered by the unit-free shift magnitude (after - before) / (after + before) descending (1.0 = appeared from a zero baseline, 1/3 = doubled), so the most significant shifts lead regardless of the signal's units — nothing is filtered out; judge significance from before/after (raw signal units: %, µs, logs, profile cost). Optionally filter by service and a from_ts/to_ts window (microseconds since the Unix epoch) over the shift time. Each row carries a ready-to-run drill_down_sql for POST /v1/query. Rows whose shifts fall in the same or adjacent 5-minute detection bucket on the same service share an incident_id — one incident across signals, not N independent anomalies (the correlation window is the detection pass's own bucket resolution, never a tuned threshold); incident_id is null for uncorrelated rows.
Request
curl -X GET "https://api.sigiro.com/v1/anomalies" \
-H "Authorization: Bearer $SIGIRO_KEY"- Auth
- Authorization: Bearer <key> — a tenant key. Self-hosted servers in open mode accept any value.
Parameters
| Name | Type | Description |
|---|---|---|
| service | string | Filter to one service. |
| from_ts | integer (int64) | Only shifts at or after this time (microseconds since the Unix epoch). |
| to_ts | integer (int64) | Only shifts at or before this time (microseconds since the Unix epoch). |
Responses
200Anomaly rows, biggest shift first
{
"anomalies": [
{
"after": 0.1,
"before": 0.1,
"detected_at": "string",
"direction": "string",
"drill_down_sql": "string",
"incident_id": "string",
"kind": "string",
"operation": "string",
"service_name": "string",
"signal": "string",
"ts_shift": "string",
"ts_shift_us": 0
}
]
}401Missing or invalid bearer token
Every field and constraint is in /openapi.json, which is the document this page is generated from.
List services seen, with time bounds
Every service that has reported telemetry, with the first and last timestamp seen for each (microseconds since the Unix epoch). The entry point of an agent loop: pick a service here, then investigate it.
Diagnose a service: ranked findings with runnable SQL
Root-cause an incident for one or more services over a time window. Returns a triage summary — NOT raw telemetry: a ranked findings array (read this first), per-operation anomaly flags, and bounded samples of spans/logs. Every lead carries a ready-to-run SQL string (drill_down_sql on findings, operations, spans, and log patterns; drill_all_sql on the spans/logs sections) that you paste VERBATIM into POST /v1/query to fetch the underlying rows and go deeper. Typical agent loop: GET /v1/services → POST /v1/investigate → for any finding or anomalous operation, run its drill_down_sql via /v1/query. Timestamps are microseconds since the Unix epoch. The response is a map {results: {service: block}, errors: {service: message}} — partial results survive a single failing service.