> Fetch https://askmiles.ai/llms.txt first: it indexes every public Miles capability. This file is the markdown twin of https://askmiles.ai/docs/chat-api/overview.

# Chat API overview

An OpenAI-compatible endpoint that returns the answer Miles would give on the site: one model, no server-side state, read-only tools.

## What it is

`https://askmiles.ai/v1` is an OpenAI-compatible chat completions endpoint. Point a server-side OpenAI client at it and ask a card or points question the way a person would. What comes back is the answer Miles would give on askmiles.ai, from the same tools and the same data, instead of the ingredients for one.

| | |
|---|---|
| Base URL | `https://askmiles.ai/v1` |
| Model | `miles`. It is the only one; `/v1/models` returns it and nothing else, and any other `model` value is echoed but not honoured. |
| Endpoints | `POST /v1/chat/completions`, `GET /v1/models`, `GET /v1/health` (no auth; answers whether something can serve a completion, not whether the site is up). |
| Authentication | A bearer token: a [personal API key](https://askmiles.ai/docs/getting-started/personal-key) for your own account, or an [OAuth access token](https://askmiles.ai/docs/getting-started/oauth-app) with scope `miles:chat` for someone else's. |

## What it is not

- **Stateful.** Miles keeps no conversation. Send the whole `messages` array every turn. History is truncated to the last 26 messages.
- **A way to write.** Tools are read-only on this surface, always. A `messages` array supplied by the caller cannot reach a wallet write, whatever scopes the token holds.
- **Instructable.** A `system` message is passed through as caller data, not as Miles' instructions. Miles' own framing wins. Put what matters in the user turn.
- **A general model.** Only `system`, `user` and `assistant` roles; there is no `tool` role. Image and audio parts return 400 naming the part type.
- **For browsers.** Browser clients are deliberately unsupported; call it from a server or an agent.

## Timing

A non-streaming turn times out at 90 seconds. A streaming turn sends nothing until synthesis starts, measured 15 to 23 seconds on simple questions and longer with tool rounds, so the timeout protects the answer itself, not the classification and tool stages that run first.

## Response extras

Non-streaming responses carry a `miles` object with `tools_called` and `duration_ms`: which tools ran, and how long the turn took. Streaming responses do not carry it. It is outside the OpenAI shape; ignore it if you do not need it.

## Third-party callers

A token minted to a registered OAuth app is treated as an outside agent: household member names and similar personal fields are redacted from tool results before synthesis, the same boundary the MCP server applies. A personal API key is the member and sees everything.
