Investigation API

Send an alert, your service map and the events around an incident. You get back the most likely root cause, the evidence for it, the failure path, what was ruled out and a next step, as JSON. Nothing is stored.

Request

POST https://api.boxai.dev/api/investigate
Content-Type: application/json

{ "incident": { ... } }      your own incident
{ "sample": "login-5xx" }     or one of the built-in samples
FieldMeaning
incidentThe alert, services and events. Format below.
samplecheckout-latency, login-5xx or transfer-backlog. List them with GET /api/investigate/samples.
narrateOptional. false skips the model-written incident update. The investigation itself never uses a model.

Incident format

{
  "alert": { "service": "checkout", "signal": "p95 latency 4.8s", "at": "2026-11-03T10:04:00Z" },
  "services": [
    { "name": "checkout", "dependsOn": ["payments-api"] },
    { "name": "payments-api", "aliases": ["pay-svc.prod"] }
  ],
  "events": [
    { "ts": "2026-11-03T09:58:30Z", "service": "payments-api", "kind": "config",
      "message": "DB_POOL_MAX changed 50 -> 5" },
    { "ts": "2026-11-03T10:02:00Z", "service": "checkout", "kind": "log", "level": "error",
      "message": "timeout calling payments-api after 3000ms" },
    { "ts": "2026-11-03T10:03:10Z", "service": "checkout", "kind": "metric",
      "message": "p95 latency", "value": 4800, "baseline": 420, "unit": "ms" }
  ]
}
FieldMeaning
alert.service, signal, atWhich service alerted, what fired, and when (ISO 8601).
services[].nameLetters, digits, ., _, -. Unique.
services[].dependsOnThe services it calls. Every name must be in services.
services[].aliasesOptional. Up to 5 other names logs use for it, such as hostnames. At least 3 characters.
services[].kindOptional label shown on the map, such as database.
events[].kindlog, metric, deploy, config or k8s.
events[].levelinfo, warn or error. Used for logs and Kubernetes events.
events[].value, baseline, unitFor metrics: the observed value and what is normal.
events[].version, previousVersionFor deploys. The previous version goes into the rollback step.

How it decides

Response

FieldMeaning
investigation.rootCauseService, score, confidence, the evidence for each check met, and what was missing. null if nothing upstream is anomalous.
investigation.hypothesesEvery suspect tested, best first.
investigation.chainThe failure path from root cause to the alerting service. confirmed means the caller's errors name the next hop.
investigation.ruledOut, impactSuspects ruled out with the reason, and affected callers.
investigation.actionNext step: roll back, revert a config change, or page the owner.
investigation.caveatsReasons to double-check the result. Empty when there are none.
investigation.timeline, graph, statsEvery event with its flags, the service map with each node's status, and counts.
narrativeThe incident update. source is model or template; a template comes with a reason.
engine, engineMs, totalMsEngine version and timings.

Errors and limits

StatusErrorWhen
400invalid_json, missing_incident, invalid_alert, invalid_services, unknown_dependency, invalid_event and othersThe body or incident is wrong. detail says what to fix.
404unknown_sampleNo sample with that id.
413too_largeBody over 64 KB.
429rate_limitedToo many requests from your address. Wait a minute.

Up to 60 services, 600 events and 400 characters per message. The model-written update shares a daily budget; when it is used up, you get the template and the investigation is unchanged.