# Mistral (La Plateforme) — API Research (Phase 0) Researched 2026-07-30 against official docs (docs.mistral.ai, mistral.ai/pricing) and a **live `/v1/models` probe with a real key** (`/tmp/zyquo-probe/mistral.json`). The live list is authoritative for model existence, aliases, context lengths, capability flags, and deprecation dates. --- ## 1. Base URL & Endpoints Base: `https://api.mistral.ai` | Endpoint | Method | Purpose | |---|---|---| | `/v1/chat/completions` | POST | Chat (streaming + non-streaming) | | `/v1/models` | GET | List models (rich metadata) | | `/v1/models/{id}` | GET | Model metadata | | `/v1/fim/completions` | POST | Fill-in-the-middle (Codestral; not needed for chat) | | `/v1/embeddings` | POST | Embeddings (not needed) | Docs: https://docs.mistral.ai/api/ ## 2. Authentication `Authorization: Bearer $MISTRAL_API_KEY`. Keys created in the La Plateforme console. ## 3. Chat Model Catalog From the live probe (capability flags `completion_chat`, `function_calling`, `reasoning`, `vision`, `max_context_length`, `deprecation` are all per-model in the `/v1/models` response) + https://docs.mistral.ai/getting-started/models/models_overview/ + https://mistral.ai/pricing/api. Max output tokens: Mistral does not publish a separate max-output limit — output is bounded by the shared context window (`max_tokens` ≤ context minus prompt). All chat models support **streaming, function calling, and JSON mode**. Pricing in USD per 1M tokens (input/output); cached input tokens get a 90% discount. ### Recommended (current, non-deprecated) | Model ID (canonical) | `-latest` alias | Marketing name | Context | Vision | Reasoning | $/1M in | $/1M out | |---|---|---|---|---|---|---|---| | `mistral-medium-2604` | `mistral-medium-latest` (also `mistral-medium-3-5`, `mistral-medium-3.5`, `mistral-medium`, `mistral-medium-3`) | Mistral Medium 3.5 — **flagship** | 262,144 | ✅ | ✅ (`reasoning_effort`) | $1.50 | $7.50 | | `mistral-large-2512` | `mistral-large-latest` | Mistral Large 3 | 262,144 | ✅ | ❌ | $0.50 | $1.50 | | `mistral-small-2603` | `mistral-small-latest` (also `magistral-small-latest`) | Mistral Small 4 (hybrid instruct+reasoning+code) | 262,144 | ✅ | ✅ | $0.15 | $0.60 | | `codestral-2508` | `codestral-latest` (also `mistral-code-latest`, `mistral-code-fim-latest`) | Codestral (coding) | 256,000 | ❌ | ❌ | $0.30 | $0.90 | | `ministral-14b-2512` | `ministral-14b-latest` | Ministral 3 14B | 262,144 | ✅ | ❌ | $0.20 | $0.20 | | `ministral-8b-2512` | `ministral-8b-latest` | Ministral 3 8B | 262,144 | ✅ | ❌ | $0.15 | $0.15 | | `ministral-3b-2512` | `ministral-3b-latest` | Ministral 3 3B | 131,072 | ✅ | ❌ | $0.10 | $0.10 | Note: `mistral-large-latest` (Large 3, open-weight) is now priced *below* `mistral-medium-latest` (Medium 3.5, frontier) — Medium 3.5 is the flagship despite the name. ### Legacy / deprecated (still live in the API — mark "legacy" in ModelCatalog, hide by default) | Model ID | Context | Deprecated on | Replacement | $/1M in/out | |---|---|---|---|---| | `mistral-medium-2508`, `mistral-medium-2505` | 131,072 | 2026-08-31 | `mistral-medium-3-5` | unverified (old Medium 3 pricing) | | `magistral-medium-2509` / `magistral-medium-latest` | 131,072 | **2026-07-31 (tomorrow!)** | `mistral-medium-3-5` | $2.00 / $5.00 | | `magistral-small-2509` | 131,072 | **2026-07-31** | `mistral-small-latest` | $0.50 / $1.50 | | `mistral-small-2506` | 131,072 | **2026-07-31** | `mistral-small-latest` | unverified | | `devstral-2512` / `devstral-latest` / `devstral-medium-latest` | 262,144 | **2026-07-31** | `mistral-medium-3-5` | Devstral 2: $0.40 / $2.00 | | `open-mistral-nemo` (+ `open-mistral-nemo-2407`, `mistral-tiny-2407`, `mistral-tiny-latest`) | 131,072 | **2026-07-31** | `ministral-8b-2512` | $0.15 / $0.15 | **Notable:** the standalone **Magistral reasoning line is deprecated** — reasoning moved into `mistral-medium-latest` / `mistral-small-latest` (docs: "Native reasoning models (magistral-small/medium-latest) have been deprecated"; `magistral-small-latest` is literally an alias of `mistral-small-2603` in the live list). **Pixtral is gone** from the live list (absorbed into vision-capable mainline models). Excluded from catalog: `voxtral-*` (audio), `mistral-embed*`, `codestral-embed*`, `mistral-moderation-*`, `mistral-ocr-*`, `labs-leanstral-*` (Lean theorem-proving lab model), `mistral-vibe-cli-*` (product aliases of medium/small). ## 4. Request / Response Format **OpenAI-compatible** with minor Mistral extensions. Full parameter list (https://docs.mistral.ai/api/): `model` (required), `messages` (required; roles `system`/`user`/`assistant`/`tool`), `temperature` (recommend 0.0–0.7; default varies per model — live probe exposes `default_model_temperature`, e.g. 0.3 for most, 1.0 for medium-3.5), `top_p`, `max_tokens`, `stream` (default false), `stop` (string or array), `random_seed`, `response_format` (`{"type": "text" | "json_object" | "json_schema"}`), `tools`, `tool_choice` (`auto`/`none`/`any`/`required`), `parallel_tool_calls` (default true), `presence_penalty`, `frequency_penalty`, `n`, `prompt_cache_key`, and Mistral-specific `safe_prompt` (default false) and `prompt_mode` / `reasoning_effort` (see §6). ```json POST /v1/chat/completions { "model": "mistral-medium-latest", "messages": [ { "role": "system", "content": "You are a helpful assistant." }, { "role": "user", "content": "Reply with exactly: OK" } ], "temperature": 0.3, "max_tokens": 128, "stream": false } ``` Response is standard OpenAI shape: `id`, `object: "chat.completion"`, `created`, `model`, `choices[].message`, `choices[].finish_reason`, `usage: {prompt_tokens, completion_tokens, total_tokens}`. **Deviation to handle in the client:** for reasoning-capable models with `reasoning_effort: "high"`, `message.content` is **not a string** but an **array of chunks**: `{"type": "thinking", "thinking": [{"type":"text","text":"..."}]}` followed by `{"type": "text", "text": "..."}`. The Swift `Codable` model must accept `content` as string OR chunk array. **Vision:** OpenAI style content parts — `{"type": "image_url", "image_url": ""}` (both URL and base64 data URI supported; https://docs.mistral.ai/capabilities/vision/). Vision models: mistral-medium, mistral-large-3, mistral-small-4, ministral-3 family (per live capability flags). ## 5. Streaming Standard OpenAI SSE: `data: {chat.completion.chunk}` events with `choices[0].delta.content`, terminated by `data: [DONE]`. Usage arrives on the final chunk. **Reasoning wrinkle:** during the thinking phase, `delta.content` is a **list containing thinking chunks**, then transitions to **plain strings** for the answer phase — the SSE parser must handle both shapes for the same field. ## 6. Special Parameters - **`safe_prompt`** (bool, default false): injects Mistral's safety guardrail system prompt before the conversation. - **Reasoning** (https://docs.mistral.ai/capabilities/reasoning/): on `mistral-medium-latest` / `mistral-small-latest`, use **`reasoning_effort`**: `"high"` → full thinking chunks in output (recommended for agentic/code with medium-3.5); `"none"` → plain string output, no thinking. (`prompt_mode: "reasoning"` also exists in the API reference as a reasoning switch — appears to be the older Magistral-era mechanism; exact interaction with `reasoning_effort` unverified.) - **Multi-turn with reasoning:** replay the **full** assistant message including the `thinking` chunk back into history — stripping reasoning traces degrades quality (official guidance). - **`random_seed`** for reproducibility; **`prompt_cache_key`** for prompt caching (cached input: 90% discount). - Temperature guidance: 0.0–0.7 recommended; per-model defaults exposed in `/v1/models` (`default_model_temperature`). ## 7. Rate Limits & Errors (https://docs.mistral.ai/admin/user-management-finops/tier + help.mistral.ai) Two plans: **Free** (Experiment) and **Scale** (pay-as-you-go, higher limits). Limits are per model along two independent axes: **requests per second** and **tokens per minute** (plus tokens/month on free tier; ~1B tokens/month on the free Experiment tier — semi-verified, third-party). Mistral **no longer publishes exact numbers** — live values are in Admin Console → Limits. Org- and workspace-level monthly spending caps can suspend API access when reached. Higher limits: contact support with model/RPS/token-volume details. Errors: OpenAI-style JSON. 401 invalid key, 422 invalid request/params (Mistral is stricter than OpenAI here — validation errors come back as 422 with `detail`), 429 rate limit, 5xx server. Exact error body shape varies (`{"object":"error","message",...}` vs FastAPI-style `{"detail":[...]}` on 422) — confirm both in Phase 7. Backoff on 429/5xx. ## 8. `/models` Listing **Yes — the richest of all providers.** `GET /v1/models` → `{"object":"list","data":[...]}` where every entry includes: `id`, `name` (canonical), `description`, `max_context_length`, `aliases[]`, `deprecation` (ISO date or null), `deprecation_replacement_model`, `default_model_temperature`, `type`, and a full `capabilities` object (`completion_chat`, `completion_fim`, `function_calling`, `reasoning`, `vision`, `ocr`, `classification`, `moderation`, `audio`, `audio_transcription`, `audio_speech`, `fine_tuning`, …). Zyquo Cloud's dynamic refresh can build the entire Mistral catalog from this endpoint alone: filter `completion_chat == true && ocr == false && moderation == false && audio* == false`, dedupe by `name` (aliases each appear as separate entries), and flag `deprecation != null` as legacy.