Skip to content

API reference

Base path: /api/v1. Interactive docs (Swagger UI) at http://localhost:8000/docs, schema at /openapi.json.

flowchart LR
    subgraph stocks
        N["GET /stocks/{ticker}/news"]
        S["GET /stocks/{ticker}/summary"]
        ST["GET /stocks/{ticker}/summary/stream<br/>(SSE)"]
    end
    subgraph config
        SO["/sources  GET POST PATCH DELETE<br/>/sources/check  POST"]
        LL["/settings/llm  GET PUT"]
    end
    subgraph stats
        U["GET /usage"]
        UR["GET /usage/runs"]
    end
    H["GET /health"]

Endpoints

Method and path Purpose
GET /health Liveness: {"status": "ok"}
GET /stocks/{ticker}/news Merged headlines and per-source errors
GET /stocks/{ticker}/summary One-shot summary (StockSummary JSON); records usage
GET /stocks/{ticker}/summary/stream The same, as SSE events
GET /sources List news sources
POST /sources/check Try a feed URL once: {ok, kind, item_count, sample, error}; saves nothing
POST /sources Create {name, url_template, enabled?} (201)
PATCH /sources/{id} Update any of name, url_template, enabled
DELETE /sources/{id} Delete (204)
GET /settings/llm {provider, model, base_url, thinking, thinking_effort, api_key_set}
PUT /settings/llm Update; see below
GET /usage Per provider/model: runs, requests, tokens, average duration
GET /usage/runs?limit=20 Latest runs, newest first (1 to 200)

Status codes

Code When
200 / 201 / 204 Success
404 Unknown source id
409 Creating a source would exceed the configured source limit
422 Invalid ticker or body (for example a non-http URL)
502 /summary: no news, or the model failed
503 OpenAI selected without an API key

The streaming endpoint reports prerequisite failures (including an invalid ticker or missing API key) as an error SSE event with HTTP 200, so browser EventSource clients can display the reason. Non-streaming endpoints retain the HTTP status codes above. Partial summary events contain only fields that pass the same Pydantic field validation as the final answer.

Usage recording is best effort. If its database write fails, the completed summary is still returned and the server logs usage_record_failed; that run will be absent from usage totals.

Examples

# Change the model and turn thinking off
curl -X PUT localhost:8000/api/v1/settings/llm -H 'content-type: application/json' \
  -d '{"provider":"ollama","model":"gpt-oss:120b-cloud","base_url":"http://localhost:11434/v1","thinking":false}'

# Add an API token for an Ollama that needs one (never returned afterwards)
curl -X PUT localhost:8000/api/v1/settings/llm -H 'content-type: application/json' \
  -d '{"provider":"ollama","model":"gpt-oss:120b","base_url":"https://ollama.com/v1","api_key":"..."}'

# Usage per model
curl localhost:8000/api/v1/usage

PUT /settings/llm field semantics:

Field Omitted / null Value
api_key keep the stored key "" removes it, anything else replaces it
thinking keep the stored value true / false
thinking_effort keep the stored value low, medium or high
base_url clears it (default URL is used) a server-allow-listed origin; remote origins require HTTPS