Agent Endpoints
Agent execution endpoints, served by the orchestration engine and proxied through the API gateway at http://localhost:8000 under the /api/v1 prefix.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/execute | Execute an agent pipeline synchronously |
POST | /api/v1/agents/{agent_id}/execute | Agent-scoped alias for /execute |
GET | /api/v1/conversations/{id}/stream | Stream an agent turn via SSE |
Both execute routes land on the orchestration /execute handler. The
agent_id in the scoped alias is informational — the agent is selected by the
agent_type field in the body.
POST /api/v1/execute
Execute a full agent pipeline synchronously. The agent runs the LangGraph
StateGraph: system prompt → memory → resume guard → LLM call → tool loop
(including R36 skill selection via pull_routers / select_skill) → approval →
output formatting.
Request:
curl -X POST http://localhost:8000/api/v1/execute \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"conversation_id": "conv-abc123",
"agent_type": "rule_37",
"message": "I need a spacing exception for well API 42-383-12345 on the Smith Ranch lease"
}'| Field | Type | Required | Description |
|---|---|---|---|
conversation_id | string | Yes | Conversation to append this turn to (pre-register via POST /api/v1/conversations) |
message | string | Yes | The user’s input message |
agent_type | string | No | Free-form agent key slug (R41 B6), resolved against agent_definitions.agent_key at runtime — e.g. general (default; domain-agnostic, recruits skills itself via the router manifest + pull_routers / select_skill), creator, rule_37, rule_32. An unresolvable key degrades to core tools; a malformed slug 422s |
agent_id | string | No | Owning agent id (defaults to "default") |
tenant_id | string | No | Canonical tenant UUID; defaults to the single dev tenant |
model | string | No | Per-request model override (else the tenant/env default) |
system_prompt | string | No | Per-request system prompt override |
max_tokens / max_cost_usd | int / float | No | Per-execution budget overrides (clamped by the tenant ceiling) |
thinking_mode | string | No | "adaptive" or "disabled"; clamped to the tenant ceiling, never rejected |
attachment_ids | string[] | No | Ids of previously uploaded conversation_attachments to splice into this turn |
metadata | object | No | Free-form metadata |
Response (200):
{
"execution_id": "a1b2c3d4-...",
"conversation_id": "conv-abc123",
"status": "completed",
"messages": [
{"role": "assistant", "content": "Based on the spacing analysis for well 42-383-12345...", "tool_calls": null}
],
"tokens_used": 6000,
"cost_usd": 0.12,
"skills_injected": ["rrc_rule37"],
"thinking_mode": "adaptive",
"referenced_entities": [{"entity_id": "well-001", "name": "Smith Ranch #1", "entity_type": "Well"}],
"hitl_approval_id": null,
"hitl_checkpoint_type": null,
"error": null
}| Field | Type | Description |
|---|---|---|
execution_id | string | Turn identity (the R40a verdict-capture key) |
status | string | completed, awaiting_hitl, or error |
messages | object[] | Assistant/tool messages produced this turn (role, content, tool_calls) |
tokens_used / cost_usd | int / float | Actual usage for the turn |
skills_injected | string[] | Skill keys loaded during the turn |
thinking_mode | string | null | The effective post-clamp mode (may differ from the request) |
referenced_entities | object[] | Entities resolved/created this turn (entity_id, name, entity_type) |
hitl_approval_id / hitl_checkpoint_type | string | null | The pause identity when status is awaiting_hitl; both null otherwise |
error | string | null | Error detail when status is error |
The SSE stream is the recommended way to run agents interactively — it is
rejoinable and emits node-by-node progress. /execute is best for tests and
batch operations. Daily budget caps are checked before the turn starts:
/execute returns 429 when the tenant (or per-user) daily cap is exhausted.
GET /api/v1/conversations/{conversation_id}/stream
Stream an agent turn in real time via Server-Sent Events. Pass message (and
optional attachment_ids, thinking_mode) as query parameters to start a
turn; omit message to attach as a reader to an in-flight or completed turn.
See the SSE Events page for the full event reference.
Request:
curl -N -H "Authorization: Bearer $TOKEN" \
"http://localhost:8000/api/v1/conversations/conv-abc123/stream?message=Assess%20flaring%20risk"Response: text/event-stream. Each frame is a named event whose data
is a JSON StreamEvent (event, node, data):
event: node_end
data: {"event": "node_end", "node": "initial_llm_call", "data": {"status": "running", "tokens_used": 1892, "message": {"role": "assistant", "content": "Based on the analysis..."}}}
event: done
data: {"event": "done", "node": null, "data": {"execution_id": "a1b2c3d4-...", "status": "completed", "tokens_used": 4210, "cost_usd": 0.031, "skills_injected": ["flaring_watch"], "thinking_mode": "adaptive", "referenced_entities": [], "hitl_approval_id": null, "hitl_checkpoint_type": null}}Because the server emits named events (event: node_end, event: done,
…), a browser EventSource must use addEventListener('node_end', …) etc.;
the default onmessage handler only fires for unnamed events.