> ## Documentation Index
> Fetch the complete documentation index at: https://witchking.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# API Reference

> All REST endpoints exposed by the TI Agent backend.

All endpoints run on `http://localhost:3001`.

| Method | Path | Description |
| - | - | - |
| `GET` | `/health` | Server health check, returns DB path |
| `POST` | `/api/fetch-feeds` | Fetch and parse RSS/Atom feeds for a date window |
| `POST` | `/api/analyze` | Proxy to Anthropic `/v1/messages` (API key auth) |
| `POST` | `/api/analyze-cli` | Proxy to local Claude Code CLI (subscription auth) — same response shape as `/api/analyze` |
| `GET` | `/api/config` | Load all saved config |
| `PUT` | `/api/config` | Save config (API key always excluded) |
| `GET` | `/api/config/export` | Download full config + custom feeds as JSON |
| `POST` | `/api/config/import` | Restore config from exported JSON |
| `GET` | `/api/feeds/custom` | List custom feeds |
| `POST` | `/api/feeds/custom` | Add a custom feed |
| `PUT` | `/api/feeds/custom/:id` | Rename or re-point an existing custom feed |
| `DELETE` | `/api/feeds/custom/:id` | Remove a custom feed |
| `GET` | `/api/reports` | List all reports (no body field) |
| `GET` | `/api/reports/:id` | Get a single report with body |
| `POST` | `/api/reports` | Save a generated report |
| `DELETE` | `/api/reports/:id` | Delete a report (cascades to its hypotheses) |
| `GET` | `/api/costs` | Get cost ledger rows |
| `GET` | `/api/reports/:id/export?format=` | Export report (`md` / `html` / `pdf` / `docx`) |
| `POST` | `/api/reports/:id/hypotheses` | Replace a report's stored hypotheses |
| `GET` | `/api/reports/:id/hypotheses` | List a report's stored hypotheses |
| `GET` | `/api/hypotheses/counts` | `{ [report_id]: count }` for every report in one query |
| `GET` | `/api/hypotheses/consolidated?reportIds=&theme=` | Consolidated hunting-hypotheses HTML (`theme` = `light` \| `dark`, default `light`) |

## `POST /api/fetch-feeds`

**Request body:**

```json theme={null}
{
  "feeds": [
    {
      "id": "talos",
      "name": "Cisco Talos",
      "xmlUrl": "https://blog.talosintelligence.com/feed",
      "url": "https://blog.talosintelligence.com"
    }
  ],
  "dateFrom": "2025-01-01",
  "dateTo": "2025-01-07"
}
```

**Response:**

```json theme={null}
{
  "articles": [
    {
      "title": "Article title",
      "url": "https://...",
      "date": "2025-01-03",
      "summary": "First 800 chars of article text...",
      "feedName": "Cisco Talos",
      "feedIndex": 1
    }
  ],
  "errors": [
    { "feed": "Some Feed", "error": "Timeout" }
  ]
}
```

**Feed fetcher behaviour:**

* All feeds fetched in parallel with `Promise.allSettled`
* 8-second timeout per feed via `AbortController`
* Capped at 15 articles per feed
* Articles outside the date window are filtered out
* Failed feeds appear in `errors[]` and are noted in the report


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.