Version: 0.1.0
Base URL:http://localhost:8000/api/v1
Interactive docs:http://localhost:8000/docs(Swagger UI)
Every ARIA agent exposes a REST API. This serves two purposes:
- Testing & debugging — call any agent individually and inspect its JSON output without running the full pipeline.
- API mode — agents call each other via HTTP instead of in-process LangGraph calls, enabling microservice-style deployments where each agent runs as a separate service.
All responses are JSON. All error responses use the same envelope as success responses — you will never receive an HTML error page.
| Mode | Set via | Agent communication | Use case |
|---|---|---|---|
workflow (default) |
ARIA_MODE=workflow |
In-process LangGraph | Single-server deployment |
api |
ARIA_MODE=api |
HTTP calls between agents | Distributed / microservice |
In API mode each agent's URL is configurable:
ARIA_AGENT1_URL=http://agent1-service:8000
ARIA_AGENT2_URL=http://agent2-service:8000
ARIA_AGENT3_URL=http://agent3-service:8000
ARIA_AGENT4_URL=http://agent4-service:8000
# Install API dependencies
pip install fastapi uvicorn
# Start the server (development)
uvicorn api.main:app --reload
# Start the server (production)
uvicorn api.main:app --host 0.0.0.0 --port 8000 --workers 4Required env vars must be set before starting (see .env.example).
Every response — success or error — uses this structure:
{
"status": "success | error",
"agent": "agent1 | agent2 | agent3 | agent4 | pipeline",
"incident_number": "INC0010001",
"duration_ms": 843,
"data": { ... },
"error": null
}On error, data is null and error contains the message. HTTP status codes are used conventionally:
| HTTP code | Meaning |
|---|---|
| 200 | Agent ran successfully |
| 404 | Incident not found in ServiceNow |
| 502 | Upstream auth failure (ServiceNow credentials rejected) |
| 503 | Upstream unavailable (ServiceNow unreachable, env vars missing) |
| 500 | Unexpected internal error |
Returns the API version and per-agent readiness status.
Response 200
{
"status": "ok",
"version": "0.1.0",
"agents": {
"agent1": "ready",
"agent2": "not_implemented",
"agent3": "not_implemented",
"agent4": "not_implemented"
}
}Status: ✅ Implemented
Source:api/routers/agent1.py
Fetches an incident from ServiceNow and enriches missing fields using LLM extraction.
Request
{
"incident_number": "INC0010001"
}Response 200 — success, ITSM fields complete (no LLM needed)
{
"status": "success",
"agent": "agent1",
"incident_number": "INC0010001",
"duration_ms": 312,
"data": {
"incident_number": "INC0010001",
"short_description": "Hive service KO on cdp-worker-03",
"long_description": "Monitoring probe detected Hive metastore unreachable...",
"priority": "P2",
"state": "In Progress",
"affected_ci": "cdp-worker-03",
"assigned_group": "Data Platform OPS",
"caller": "monitoring-probe",
"opened_at": "2026-04-21T08:34:00",
"llm_extraction": null
},
"error": null
}Response 200 — success, LLM enrichment ran (cmdb_ci was blank)
{
"status": "success",
"agent": "agent1",
"incident_number": "INC0010001",
"duration_ms": 843,
"data": {
"incident_number": "INC0010001",
"short_description": "Daily quota for dataflow X not reached",
"long_description": "The daily ingestion quota for dataflow X on the CDP cluster was not reached...",
"priority": "P3",
"state": "New",
"affected_ci": "cdp-cluster-prod-01",
"assigned_group": "Data Platform OPS",
"caller": "john.doe",
"opened_at": "2026-04-21T07:00:00",
"llm_extraction": {
"affected_ci": "cdp-cluster-prod-01",
"platform_tag": "cdp",
"confidence": "medium"
}
},
"error": null
}Response 404 — incident not found
{
"status": "error",
"agent": "agent1",
"incident_number": "INC9999999",
"duration_ms": 201,
"data": null,
"error": "Incident INC9999999 not found in ServiceNow"
}Fields
| Field | Type | Description |
|---|---|---|
incident_number |
string | ServiceNow incident ID |
short_description |
string | One-line summary from the ticket |
long_description |
string | Full description body |
priority |
string | P1 | P2 | P3 | P4 |
state |
string | ServiceNow state (display value) |
affected_ci |
string | null | Affected resource — from ITSM field or LLM extraction |
assigned_group |
string | null | Assignment group |
caller |
string | null | Who opened the ticket |
opened_at |
ISO 8601 | Ticket creation timestamp |
llm_extraction |
object | null | Present only when LLM ran; null if ITSM fields were complete |
llm_extraction.affected_ci |
string | null | CI extracted by LLM |
llm_extraction.platform_tag |
string | cdp | databricks | oracle | gcp | aws | azure | unknown |
llm_extraction.confidence |
string | high | medium | low |
Checks whether Agent 1's dependencies (ServiceNow env vars, LLM model) are configured. Does not make any network calls.
Response 200
{
"agent": "agent1",
"status": "ready",
"llm_model": "claude-sonnet-4-6",
"connector": "servicenow"
}status is ready when all env vars are set, degraded when any are missing.
Status: 🔜 M3 (ARI-62)
Extracts relevant log lines for the incident. Uses a two-tier strategy: log aggregator (Tier 1) if configured, KB-guided SSH fallback (Tier 2) otherwise.
Request — option A (incident number only, Agent 2 calls Agent 1 internally)
{
"incident_number": "INC0010001"
}Request — option B (pass Agent 1 output directly, avoids a second ServiceNow call)
{
"incident_number": "INC0010001",
"incident_metadata": {
"incident_number": "INC0010001",
"affected_ci": "cdp-cluster-prod-01",
"priority": "P2",
...
}
}Response 200
{
"status": "success",
"agent": "agent2",
"incident_number": "INC0010001",
"duration_ms": 2341,
"data": {
"log_lines": [
{
"timestamp": "2026-04-21T06:58:12",
"level": "ERROR",
"message": "Container killed by YARN due to exceeding memory limits",
"source": "cdp-worker-03:/var/log/hadoop/yarn/userlogs/app_001/container_001/syslog"
}
],
"query_executed": "grep -i 'ERROR\\|WARN\\|Exception' /var/log/hadoop/yarn/*.log | tail -500",
"total_scanned": 14230,
"confidence": "high",
"tier_used": "kb_fallback",
"kb_hint_used": true
},
"error": null
}tier_used: "aggregator" when a log aggregator was queried directly, "kb_fallback" when KB-guided SSH was used.
Status: ✅ Implemented (S7 — ARI-18, ARI-19, ARI-63)
Classifies the incident root cause using LLM reasoning over the extracted log lines.
Request
{
"incident_number": "INC0010001",
"incident_metadata": { ... },
"log_result": { ... }
}Response 200
{
"status": "success",
"agent": "agent3",
"incident_number": "INC0010001",
"duration_ms": 1520,
"data": {
"error_class": "resource",
"error_label": "OOM — YARN container killed",
"confidence": 0.87,
"confidence_band": "high",
"supporting_evidence": [
"Container killed by YARN due to exceeding memory limits",
"GC overhead limit exceeded in ApplicationMaster"
],
"recommended_actions": [
"Increase YARN container memory limit for this job",
"Check for memory leak in the Spark job's UDFs"
]
},
"error": null
}Error classes: oom | cpu | disk | network | auth | db_lock | pipeline | unknown
Confidence bands: high (≥0.7) | medium (0.5–0.69) | low (<0.5)
Status: 🔜 M5 (ARI-64)
Formats and sends findings to Slack / MS Teams.
Request
{
"incident_number": "INC0010001",
"incident_metadata": { ... },
"classification": { ... }
}Response 200
{
"status": "success",
"agent": "agent4",
"incident_number": "INC0010001",
"duration_ms": 312,
"data": {
"notification_sent": true,
"channels": ["slack"],
"slack_message_ts": "1745280011.123456",
"slack_channel": "#aria-alerts"
},
"error": null
}Status: ✅ Implemented (M6)
Runs all four agents in sequence and returns the complete pipeline state as JSON.
Request
{
"incident_number": "INC0010001"
}Response 200
{
"status": "success",
"agent": "pipeline",
"incident_number": "INC0010001",
"duration_ms": 8432,
"data": {
"incident_metadata": { ... },
"log_result": { ... },
"classification": { ... },
"notification_sent": true,
"error": null
},
"error": null
}Run history and live status for every pipeline run. The same endpoints feed the built-in dashboard (P1.5 S2) and any external ops tooling.
Paginated run history, newest first. All filtering is server-side.
Query parameters
| Param | Type | Default | Purpose |
|---|---|---|---|
from |
ISO 8601 datetime | — | Only runs with start_time >= |
to |
ISO 8601 datetime | — | Only runs with start_time <= |
status |
string | — | Exact match: success | partial | failed |
error_class |
string | — | Exact match on classified error class |
limit |
int (1–500) | 50 | Page size |
offset |
int | 0 | Records to skip |
Response 200
{
"runs": [
{
"run_id": "9b1c6c2e-...",
"incident_number": "INC0010001",
"status": "success",
"error_class": "oom",
"confidence": 0.88,
"confidence_band": "high",
"duration_ms": 8432,
"start_time": "2026-06-12T09:14:02Z"
}
],
"total": 1
}total counts all matching records across pages — use it to drive pagination.
Full after-action record for one run. 404 if the run_id is unknown.
Response 200
{
"run_id": "9b1c6c2e-...",
"incident_number": "INC0010001",
"start_time": "2026-06-12T09:14:02Z",
"end_time": "2026-06-12T09:14:10Z",
"status": "success",
"current_agent": null,
"per_agent_durations": { "agent1": 1200, "agent2": 3400, "agent3": 900, "agent4": 300 },
"total_tokens_in": 1500,
"total_tokens_out": 400,
"confidence": 0.88,
"confidence_band": "high",
"error_class": "oom",
"react_loop_iterations": 1,
"outcome": null
}outcome is always null in Phase 1 — it is populated by the Phase 2
Approve/Reject gate.
Lightweight live polling for an in-flight run — designed for 1-second polling. Reads only the in-memory live state store.
Response 200 (run in flight)
{
"current_agent": "agent2",
"elapsed_ms": 4210,
"status": "running"
}Response 404 — the run is not in flight. Completed runs move to the run
history store; a 404 here is the client's signal to stop polling and fetch
GET /api/v1/runs/{run_id} instead.
The pipeline checks ARIA_OPERATING_MODE (or runtime.operating_mode in
conf.yaml) before every run:
| Mode | Behaviour |
|---|---|
inform (default) |
Normal notify-only pipeline run |
hitm |
NotImplementedError — ships in Phase 2 |
autonomous |
NotImplementedError — ships in Phase 3 |
When called through POST /api/v1/pipeline/run, an unimplemented mode surfaces
as the standard JSON error envelope from the global exception handler.