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.
Request
curl -X POST "https://api.sigiro.com/v1/investigate" \
-H "Authorization: Bearer $SIGIRO_KEY" \
-H "Content-Type: application/json" \
-d '{
"from_ts": 1780000000000000,
"service": "checkout",
"services": [
"checkout",
"cart"
],
"to_ts": 1780001800000000
}'- Auth
- Authorization: Bearer <key> — a tenant key. Self-hosted servers in open mode accept any value.
- Body
- application/json — InvestigateRequest
Responses
200Per-service investigation blocks
{
"errors": {
"property1": "string",
"property2": "string"
},
"results": {
"property1": {
"context": {
"dependencies": [
{
"error_count": 0,
"error_rate": 0.1,
"service_name": "string",
"span_count": 0
}
],
"dependents": [
{
"error_count": 0,
"error_rate": 0.1,
"service_name": "string",
"span_count": 0
}
],
"deployment": "string",
"first_seen": "string",
"has_instance_id": true,
"last_seen": "string",
"namespace": "string",
"pod_count": 0,
"service_name": "string"
},
"coverage": {
"has_logs": true,
"has_metrics": true,
"has_profiles": true,
"has_spans": true,
"log_template_count": 0,
"metric_series_count": 0,
"profile_sample_count": 0,
"signals": [
{
"available": true,
"reason": "string",
"severity": "string",
"signal_type": "string"
}
],
"span_count": 0
},
"error_traces_total": 0,
"events": [
{
"description": "string",
"detected_at": "string",
"detected_at_us": 0,
"event_type": "string"
}
],
"findings": [
{
"drill_down_sql": "string",
"incident": {},
"kind": "string",
"severity": "string",
"summary": "string"
}
],
"gen_ai": [
{
"call_count": 0,
"duration_p95_us": 0.1,
"error_pct": 0.1,
"finish_reasons": [
{
"count": 0,
"reason": "string"
}
],
"input_tokens": 0,
"model": "string",
"operations": [
"string"
],
"output_tokens": 0,
"system": "string"
}
],
"log_counters": [
{
"avg_value": 0.1,
"label": "string",
"max_value": 0.1,
"min_value": 0.1,
"pattern": "string",
"pinned_zero": true,
"samples": 0
}
],
"log_patterns": [
{
"count": 0,
"drill_down_sql": "string",
"error_count": 0,
"example_body": "string",
"first_seen": "string",
"last_seen": "string",
"pattern": "string",
"sample_values": {},
"severity_text": "string",
"template_id": 0
}
],
"logs": {
"drill_all_sql": "string",
"sample": [
{
"attributes": {},
"body": "string",
"severity_text": "string",
"span_id": "string",
"timestamp": 0,
"timestamp_iso": "string",
"trace_id": "string"
}
],
"sampled_by": "string",
"total": 0
},
"metrics": [
{
"avg": 0.1,
"bucket": "string",
"count": 0,
"metric_name": "string",
"p95": 0.1
}
],
"operation_summaries": [
{
"anomaly_reason": "string",
"baseline_count": 0,
"baseline_error_pct": 0,
"baseline_p95_us": 0,
"count": 0,
"drill_down_sql": "string",
"duration_p50_us": 0.1,
"duration_p95_us": 0.1,
"duration_p99_us": 0.1,
"error_breakdown": [
{
"count": 0,
"error_type": "string"
}
],
"error_count": 0,
"error_pct": 0.1,
"exemplar_error_trace_id": "string",
"is_anomalous": true,
"operation": "string",
"span_name": "string"
}
],
"profiles": [
{
"function": "string",
"profile_type": "string",
"sample_count": 0,
"total_value": 0,
"unit": "string"
}
],
"service": "string",
"spans": {
"drill_all_sql": "string",
"sample": [
{
"drill_down_sql": "string",
"duration_us": 0,
"end_ts": 0,
"events": {},
"is_error": true,
"parent_span_id": "string",
"span_attributes": {},
"span_id": "string",
"span_kind": 0,
"span_name": "string",
"start_iso": "string",
"start_ts": 0,
"status_code": 0,
"status_message": "string",
"trace_id": "string"
}
],
"sampled_by": "string",
"total": 0
},
"window": {
"from_iso": "string",
"from_ts": 0,
"to_iso": "string",
"to_ts": 0
}
},
"property2": {
"context": {
"dependencies": [
{
"error_count": 0,
"error_rate": 0.1,
"service_name": "string",
"span_count": 0
}
],
"dependents": [
{
"error_count": 0,
"error_rate": 0.1,
"service_name": "string",
"span_count": 0
}
],
"deployment": "string",
"first_seen": "string",
"has_instance_id": true,
"last_seen": "string",
"namespace": "string",
"pod_count": 0,
"service_name": "string"
},
"coverage": {
"has_logs": true,
"has_metrics": true,
"has_profiles": true,
"has_spans": true,
"log_template_count": 0,
"metric_series_count": 0,
"profile_sample_count": 0,
"signals": [
{
"available": true,
"reason": "string",
"severity": "string",
"signal_type": "string"
}
],
"span_count": 0
},
"error_traces_total": 0,
"events": [
{
"description": "string",
"detected_at": "string",
"detected_at_us": 0,
"event_type": "string"
}
],
"findings": [
{
"drill_down_sql": "string",
"incident": {},
"kind": "string",
"severity": "string",
"summary": "string"
}
],
"gen_ai": [
{
"call_count": 0,
"duration_p95_us": 0.1,
"error_pct": 0.1,
"finish_reasons": [
{
"count": 0,
"reason": "string"
}
],
"input_tokens": 0,
"model": "string",
"operations": [
"string"
],
"output_tokens": 0,
"system": "string"
}
],
"log_counters": [
{
"avg_value": 0.1,
"label": "string",
"max_value": 0.1,
"min_value": 0.1,
"pattern": "string",
"pinned_zero": true,
"samples": 0
}
],
"log_patterns": [
{
"count": 0,
"drill_down_sql": "string",
"error_count": 0,
"example_body": "string",
"first_seen": "string",
"last_seen": "string",
"pattern": "string",
"sample_values": {},
"severity_text": "string",
"template_id": 0
}
],
"logs": {
"drill_all_sql": "string",
"sample": [
{
"attributes": {},
"body": "string",
"severity_text": "string",
"span_id": "string",
"timestamp": 0,
"timestamp_iso": "string",
"trace_id": "string"
}
],
"sampled_by": "string",
"total": 0
},
"metrics": [
{
"avg": 0.1,
"bucket": "string",
"count": 0,
"metric_name": "string",
"p95": 0.1
}
],
"operation_summaries": [
{
"anomaly_reason": "string",
"baseline_count": 0,
"baseline_error_pct": 0,
"baseline_p95_us": 0,
"count": 0,
"drill_down_sql": "string",
"duration_p50_us": 0.1,
"duration_p95_us": 0.1,
"duration_p99_us": 0.1,
"error_breakdown": [
{
"count": 0,
"error_type": "string"
}
],
"error_count": 0,
"error_pct": 0.1,
"exemplar_error_trace_id": "string",
"is_anomalous": true,
"operation": "string",
"span_name": "string"
}
],
"profiles": [
{
"function": "string",
"profile_type": "string",
"sample_count": 0,
"total_value": 0,
"unit": "string"
}
],
"service": "string",
"spans": {
"drill_all_sql": "string",
"sample": [
{
"drill_down_sql": "string",
"duration_us": 0,
"end_ts": 0,
"events": {},
"is_error": true,
"parent_span_id": "string",
"span_attributes": {},
"span_id": "string",
"span_kind": 0,
"span_name": "string",
"start_iso": "string",
"start_ts": 0,
"status_code": 0,
"status_message": "string",
"trace_id": "string"
}
],
"sampled_by": "string",
"total": 0
},
"window": {
"from_iso": "string",
"from_ts": 0,
"to_iso": "string",
"to_ts": 0
}
}
}
}400Invalid request (e.g. timestamps not in microseconds, or to_ts <= from_ts)
401Missing or invalid bearer token
Every field and constraint is in /openapi.json, which is the document this page is generated from.
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.
Run SQL over your telemetry
Accepts exactly one SELECT statement as the raw request body. Allowed tables: sigiro_spans, sigiro_logs, sigiro_log_templates, sigiro_metrics_gauge, sigiro_metrics_sum, sigiro_metrics_histogram, sigiro_metrics_exp_histogram, sigiro_profiles, sigiro_anomalies (optionally qualified as lake.* or main.*). WITH/CTE clauses are not supported — rewrite as derived-table subqueries. Scalar functions are allowlisted (aggregates, json extraction, date/time, string, math, conditional helpers); file/network readers are blocked. Every drill_down_sql returned by /v1/investigate can be pasted here verbatim.