# Models and media

Base URL `https://omnirail.org/api/v1`, header `Authorization: Bearer $OMNIRAIL_KEY`. MCP tool names in brackets.

## Find a model [list_models]

`GET /models` (no key needed) lists every model with its live price. Filter with `?kind=` (`text`, `image`, `video`, `tts`, `stt`, `embedding`, `rerank`, `decision`). With a scoped key, `GET /models?scoped=1` lists only what the key may use. Pick the cheapest model that does the job.

## Chat [chat]

`POST /chat/completions`, OpenAI format, `stream: true` supported. Always set `max_tokens` (it also counts reasoning tokens: keep it at 1024 or more for reasoning models, or set `reasoning_effort`).
- Images: `image_url` content parts (vision models); PDFs: `file` content parts on any model (`pdf_engine`: native, text or ocr). MCP: `images`, `files`.
- Web: `web_search: true` grounds the answer with live results (citations in `annotations`, about $0.01 extra). MCP: `web: true`.
- Auto routing: `model: "auto"`, `"auto:cheap"`, `"auto:fast"` or `"auto:best"`, optional `route: { max_price_per_mtok, allow, deny }`; the answer's `routing` says which model ran and why, billed at that model's price.

## Images [generate_image, edit_image]

`POST /images` (`model`, `prompt`, optional `n` 1-4, `aspect_ratio`, `resolution`, `quality`, reference images) returns `b64_json`. `POST /images/edits` needs at least one source `image` (http(s) or data URL) and an edit-capable model. Unsupported parameters answer 400 with the allowed values. The local MCP server saves files with `save_to`.

## Video [generate_video, get_video]

`POST /videos` (`model`, `prompt`, `duration`, `resolution`, `aspect_ratio`, `generate_audio`, `first_frame` for image-to-video) answers `202` with `id`, `token` and `poll_url`. Poll `GET /videos/{id}` about every 30 s; when `status` is `completed`, `cost` is charged and `content_urls` stream the MP4. Or pass `webhook_url` (see webhooks.md). Failed jobs are free. Videos are the most expensive calls: estimate and ask first.

## Voice [speak, transcribe]

- `POST /audio/speech` (`model`, `input` up to 20,000 characters, optional `voice`, `response_format` mp3 or pcm, `speed`) returns the audio bytes.
- `POST /audio/transcriptions`: multipart `file` + `model`, or JSON `input_audio: { data, format } | { url }`; returns `{ text, usage }`.

## Retrieval [embed, rerank]

- `POST /embeddings` (`model`, `input`: a string or up to 512 strings, optional `dimensions`) returns `data[].embedding`.
- `POST /rerank` (`model`, `query`, `documents` up to 1,000, optional `top_n`) returns `results[{ index, relevance_score }]`, best first.

## Autopilot [build, get_job]

`POST /jobs` `{ prompt, budget_usd? }` (default budget $2, hard cap) plans and produces copy, images, edits, video and voice, picking a model per step. Poll `GET /jobs/{id}` about every 20 s; texts come inline, assets as URLs.

## Holds and costs

Each call reserves its worst case, then charges what the provider reports (plus OmniRail's markup, minus the $RAIL pool discount while it is funded). Read the real cost from `usage.cost`, `cost` or the `X-OmniRail-Charge` header.
