API — Agents & Chat
POST /agents/ — create an agent
Body (AgentCreate):
| Field | Type | Required | Default |
|---|---|---|---|
name | string | ✅ | |
type | string | ✅ | |
description | string | null | null | |
system_prompt | string | ✅ | |
language | string | "English" | |
tone | string | "Professional" | |
enabled_tools | string (comma-separated tool IDs) | "" |
curl -X POST http://localhost:8001/agents/ -H "Content-Type: application/json" -d '{
"name": "Ops Assistant", "type": "Email Ops",
"system_prompt": "You are a precise operations assistant.",
"enabled_tools": "email_analyzer,task_creator"
}'200 → AgentResponse (adds id, created_at). 422 on missing required fields. No name-uniqueness constraint.
GET /agents/ — list agents
200 → AgentResponse[], newest first. No pagination.
GET /agents/{id} — fetch one agent
200 → AgentResponse · 404 {"detail": "Agent not found"}
POST /agents/{id}/chat — chat exchange
Body: {"message": "string"}
{
"agent_id": 1,
"user_message": "Introduce yourself.",
"assistant_response": "I am Ops Assistant...",
"run_id": 42,
"latency_ms": 913
}On an OpenAI failure, assistant_response is the fallback string "Sorry, I could not generate a response right now." and the run is recorded with status="failed" — check GET /agents/{id}/runs for the real error. Semantics: Error Handling.
Side effects per call: two Message rows + one AgentRun.
GET /agents/{id}/runs — chat run history
200 → AgentRunResponse[], newest first:
[{
"id": 42, "agent_id": 1,
"input_text": "Introduce yourself.",
"output_text": "I am Ops Assistant...",
"latency_ms": 913, "status": "success",
"error_message": null, "created_at": "2026-07-16T10:00:00"
}]GET /agents/{id}/messages — chat messages (paginated)
Query params: limit (default 50) · offset (default 0). Ordered newest-first by created_at.
200 → MessageResponse[] (id, agent_id, role, content, created_at).
GET /agents/{id}/tool-calls — tool-call log
200 → ToolCallResponse[], newest first. Fields include tool_name, tool_input/tool_output (JSON strings), success ("true"/"false" strings), latency_ms, and — on costed workflow stages — model_name, estimated_tokens, estimated_cost. Tool-name meanings: Observability.
GET /agents/{id}/dashboard — aggregated metrics
200 → AgentDashboardResponse:
{
"agent_id": 1, "agent_name": "Ops Assistant",
"total_tasks": 12, "open_tasks": 4, "in_progress_tasks": 2, "completed_tasks": 6,
"total_tool_calls": 58, "successful_tool_calls": 55, "failed_tool_calls": 3,
"total_workflow_runs": 9, "successful_workflow_runs": 8, "failed_workflow_runs": 1,
"average_latency_ms": 1240.5,
"estimated_total_tokens": 48210,
"estimated_total_cost": "0.014210",
"average_quality_score": 0.87
}Nullable: average_latency_ms, average_quality_score (null when no data). Cost/token caveats: Cost Monitoring.
GET /agents/{id}/stats — ⚠️ do not use
Declared as a stats read but implemented as a (broken) forced delete — it references a nonexistent column and fails with 500 on any call. Documented for completeness in Known Issues. There is currently no supported agent update or delete endpoint.
Related pages
- Routers: Agents — implementation
- API: Tasks & Email · API: Workflows