# Logos ADK HTTP API Reference

Complete reference for Logos ADK HTTP server endpoints.

## Base Endpoints

### Health Check
```
GET /health
```

Returns server health status.

**Response:**
```json
{
  "status": "ok",
  "version": "0.3.0",
  "agents": ["bot", "assistant"]
}
```

### Observability Summary
```
GET /observability/summary
```

Returns metrics and tracing summary.

**Response:**
```json
{
  "totals": {
    "requests": 100,
    "tokens": 50000,
    "spans": 250
  },
  "by_agent": {
    "bot": {"requests": 60, "tokens": 30000}
  }
}
```

---

## Agent Endpoints

Each agent gets its own route prefix: `/{agent_name}/...`

### Run (Sync)
```
POST /{agent}/run
```

Execute agent synchronously.

**Request Body:**
```json
{
  "prompt": "Hello, how are you?",
  "session_id": "optional-session-id",
  "workspace_id": "optional-workspace",
  "trace_id": "optional-trace-id",
  "task_run": {
    "id": "task-run-1",
    "sessionId": "session-123",
    "agentName": "bot",
    "profileId": "bot",
    "profileTitle": "Bot",
    "profileBadge": "Test",
    "prompt": "Hello",
    "fieldValues": {},
    "startedAt": "2026-03-20T00:00:00+00:00",
    "status": "running"
  }
}
```

**Response:**
```json
{
  "content": "Hello! I'm doing well...",
  "run_id": "run-abc123",
  "session_id": "session-123",
  "trace_id": "trace-xyz",
  "usage": {"input_tokens": 10, "output_tokens": 20}
}
```

### Stream
```
POST /{agent}/stream
```

Execute agent with streaming response (SSE).

**Request Body:** Same as `/run`

**Response:** Server-Sent Events stream
```
data: {"type": "text", "delta": "Hello", "terminal": false}
data: {"type": "text", "delta": "!", "terminal": false}
data: {"type": "done", "terminal": true, "task_run_status": "completed"}
```

### Stream-UI
```
POST /{agent}/stream-ui
```

Execute agent with streaming UI events (supports pause/resume).

**Request Body:** Same as `/run`

**Response:** Server-Sent Events stream
```
data: {"event": "text", "delta": "Hello", "terminal": false}
data: {"event": "pause", "reason": "approval_required", "terminal": false}
data: {"event": "graph_completed", "status": "completed", "terminal": true}
```

### Stream-UI Continue
```
POST /{agent}/stream-ui/continue
```

Continue a paused session.

**Request Body:**
```json
{
  "session_id": "session-123",
  "user_input": "approved",
  "continue_correlation_id": "corr-123",
  "continue_from_node": "review"
}
```

**Response:**
```json
{
  "status": "continued",
  "session_id": "session-123"
}
```

---

## Session Endpoints

### Global Routes (All Agents)
```
GET /sessions
POST /sessions
GET /sessions/{session_id}
PUT /sessions/{session_id}
DELETE /sessions/{session_id}
```

- Shows ALL sessions across all agents
- No ownership validation
- Error message: `"Session not found"`

### Agent Routes (Specific Agent)
```
GET /{agent}/sessions
POST /{agent}/sessions
GET /{agent}/sessions/{session_id}
PUT /{agent}/sessions/{session_id}
DELETE /{agent}/sessions/{session_id}
```

- Shows only sessions owned by that agent
- Validates session ownership
- Error message: `"session_not_found"`

#### Create Session
```
POST /{agent}/sessions
```

**Request Body:**
```json
{
  "name": "My Session",
  "metadata": {"key": "value"}
}
```

**Response:**
```json
{
  "id": "session-abc123",
  "name": "My Session",
  "agent_name": "bot",
  "messages": [],
  "task_runs": [],
  "created_at": "2026-03-26T12:00:00Z"
}
```

#### List Sessions
```
GET /{agent}/sessions?agent_name_filter=bot&limit=10
```

**Query Parameters:**
- `agent_name_filter` — Filter by agent name
- `limit` — Max results (default: 100)

**Response:**
```json
{
  "items": [
    {
      "id": "session-abc123",
      "name": "My Session",
      "agent_name": "bot",
      "created_at": "2026-03-26T12:00:00Z"
    }
  ],
  "next_cursor": null
}
```

---

## Task Run Endpoints

### Cancel Task Run
```
POST /{agent}/sessions/{session_id}/task-runs/{task_run_id}/cancel
```

Cancel an active task run.

**Response:**
```json
{
  "status": "cancel_requested",
  "session_id": "session-123",
  "task_run_id": "task-run-1",
  "task_run_status": "paused"
}
```

---

## Feedback Endpoints

### Submit Feedback
```
POST /{agent}/feedback
```

**Request Body:**
```json
{
  "run_id": "run-abc123",
  "kind": "thumbs_down",
  "failure_types": ["bad_retrieval", "incorrect"],
  "corrected_output": "The correct answer is...",
  "metadata": {"rejected_contexts": ["doc1", "doc2"]}
}
```

**Response:**
```json
{
  "id": "feedback-xyz",
  "run_id": "run-abc123",
  "kind": "thumbs_down",
  "created_at": "2026-03-26T12:00:00Z"
}
```

---

## Quality Endpoints

### Run Quality Suite
```
POST /quality/run
```

**Request Body:**
```json
{
  "kind": "regression",
  "suite": {
    "examples": [
      {"name": "test-1", "prompt": "hello", "expected": "hi"},
      {"name": "test-fail", "prompt": "bad", "expected": "good"}
    ]
  }
}
```

Or for load testing:
```json
{
  "kind": "load-test",
  "suite": {
    "prompts": ["ping", "pong"],
    "iterations": 3
  },
  "background": true
}
```

**Response (sync):**
```json
{
  "status": "completed",
  "run_id": "run-quality-123",
  "summary": {"passed": 10, "failed": 2, "requests": 12},
  "reports": {"html": "/quality/runs/run-quality-123/report.html"}
}
```

**Response (background):**
```json
{
  "status": "queued",
  "run_id": "run-quality-123",
  "message": "Run queued"
}
```
Returns HTTP 202 for background runs.

### List Quality Runs
```
GET /quality/runs?kind=regression&limit=10
```

**Response:**
```json
{
  "items": [
    {
      "run_id": "run-quality-123",
      "status": "completed",
      "kind": "regression",
      "created_at": "2026-03-26T12:00:00Z"
    }
  ]
}
```

### Get Quality Run Details
```
GET /quality/runs/{run_id}
```

**Response:**
```json
{
  "run_id": "run-quality-123",
  "status": "completed",
  "kind": "regression",
  "summary": {"passed": 10, "failed": 2, "requests": 12},
  "reports": {"html": "/quality/runs/run-quality-123/report.html"}
}
```

### Compare Runs
```
GET /quality/compare?run_id_a=run-1&run_id_b=run-2
```

**Response:**
```json
{
  "summary_diff": {
    "passed": {"a": 10, "b": 12}
  },
  "row_count_diff": {
    "a": 12,
    "b": 12
  }
}
```

---

## Artifact Endpoints

### Upload Artifact
```
POST /artifacts
```

**Request Body (multipart/form-data):**
- `file` — File to upload
- `agent_name` — Associated agent
- `session_id` — Associated session (optional)
- `purpose` — Purpose (input/output/log/etc)

**Response:**
```json
{
  "artifact_id": "artifact-123",
  "filename": "document.pdf",
  "size": 1024,
  "purpose": "input"
}
```

### Get Artifact
```
GET /artifacts/{artifact_id}
```

Returns the file content.

### List Artifacts
```
GET /artifacts?agent_name=bot&session_id=session-123
```

---

## Campaign Endpoints

### List Campaigns
```
GET /campaigns
```

**Response:**
```json
{
  "items": [
    {
      "id": "campaign-123",
      "name": "Q1 Outreach",
      "status": "active",
      "event_count": 100
    }
  ]
}
```

### Get Campaign
```
GET /campaigns/{campaign_id}
```

### Create Campaign Event
```
POST /campaigns/{campaign_id}/events
```

**Request Body:**
```json
{
  "user_id": "user-123",
  "prompt": "Hello",
  "response": "Hi there!"
}
```

---

## Error Responses

### 400 Bad Request
```json
{
  "error": "validation",
  "message": "Invalid request body"
}
```

### 404 Not Found
```json
{"detail": {"error": "session_not_found"}}
```
or
```json
{"detail": "Session not found"}
```

### 422 Unprocessable Entity
```json
{
  "error": "validation",
  "message": "[{'type': 'missing', 'loc': ('body', 'prompt'), 'msg': 'Field required'}]"
}
```

### 500 Internal Server Error
```json
{
  "error": "internal",
  "message": "internal: <error details>"
}
```

---

## SSE Event Formats

### /stream endpoint
```json
{
  "type": "text|tool_start|tool_end|error|done|final",
  "task_run_id": "task-123",
  "task_run_status": "running|completed|failed",
  "terminal": true|false,
  "delta": "text chunk",
  "error": "error message",
  "resume_required": false,
  "retryable": false
}
```

### /stream-ui endpoint
```json
{
  "type": "text|tool_start|tool_end|pause|graph_completed|done|error",
  "event": "text|tool_start|...",
  "task_run_id": "task-123",
  "task_run_status": "...",
  "terminal": true|false,
  "delta": "text chunk",
  "reason": "approval_required",
  "status": "completed",
  "output": "result"
}
```