# HTTP API

Base URL: `http://localhost:3000`

All JSON. `Content-Type: application/json`.

## `GET /health`

```json
{ "ok": true, "chunks": 512, "model": "gpt-4o-mini" }
```

`chunks` from vector store count. `503` if store missing (ingest not run).

## `POST /v1/query`

Body:

```json
{
  "question": "For mortgage SI, what is typical if cancer treatment ended 3 years ago?",
  "k": 8,
  "filters": {
    "module": "cancer",
    "knowledge_layer": "synthesis_2026"
  }
}
```

| Field | Required | Notes |
|-------|----------|--------|
| `question` | yes | 1–4000 chars |
| `k` | no | 1–20, default 8 |
| `filters.module` | no | See data-sources disease slugs, plus `bmi`, `mortgage_process`, `mortgage_dataset` |
| `filters.doc_type` | no | |
| `filters.knowledge_layer` | no | `synthesis_2026` \| `legacy_2022_dump` |

Success `200`:

```json
{
  "answer": "...markdown...",
  "citations": [
    {
      "id": "abc...",
      "source_path": "html/diseases/disease-cancer.html",
      "title": "Typical decision patterns",
      "score": 0.81
    }
  ],
  "model": "gpt-4o-mini",
  "retrieved": 6,
  "insufficient_context": false
}
```

Errors:

| Code | When |
|------|------|
| 400 | Invalid body (zod) |
| 503 | Store empty |
| 502 | OpenAI error |
| 429 | Optional rate limit later |

## `POST /v1/ingest`

Protected in v1 by header `X-Ingest-Token` matching `INGEST_TOKEN` env (optional; if unset, disable this route and use CLI only).

Triggers the same pipeline as `npm run ingest`. Long-running: return `202` `{ "job": "started" }` or run sync for this small corpus (`200` with counts).

**Recommendation:** CLI ingest only in v1; omit this route until needed.

## `GET /v1/sources`

Lists ingested `source_path` + chunk counts. Useful to confirm corpus coverage.

## Environment

Copy `.env.example`:

```
OPENAI_API_KEY=sk-...
OPENAI_CHAT_MODEL=gpt-4o-mini
OPENAI_EMBED_MODEL=text-embedding-3-small
CORPUS_DIR=./html
VECTOR_DIR=./data/lancedb
PORT=3000
RETRIEVE_K=8
MIN_RELEVANCE=0.25
LOG_QUERIES=false
INGEST_TOKEN=
VECTOR_DIR=./data/lancedb
CHUNKS_PATH=./data/chunks/chunks.jsonl
LEARNING_DIR=./data/learning
```

Learning data locations: [learning-model.md](./learning-model.md).

## `POST /v1/feedback`

Appends a rating to `data/learning/feedback.jsonl` (does not retrain GPT-4o-mini).

## Example

```bash
curl -s http://localhost:3000/v1/query \
  -H "Content-Type: application/json" \
  -d "{\"question\":\"What BMI band is typical for SI Level mortgage protection?\"}"
```

## CLI (no HTTP)

```bash
npm run query -- "Dialysis currently — typical SI outcome from the dump?"
```
