---
title: "Chat completion (OpenAI-compatible) with model choice and routing"
method: POST
path: "/api/v1/chat/completions"
tags: ["Routing"]
---

# Chat completion (OpenAI-compatible) with model choice and routing

`POST /api/v1/chat/completions`

## Request

- Base URL: `https://api.llm-broker.net`
- URL: `https://api.llm-broker.net/api/v1/chat/completions`
- Auth: none required

model = our product or any market model id (GET /api/v1/broker/models): the cheapest eligible provider serves it. routing narrows by exact min_score per category, sort (price|value|speed|score), region and max_price. Errors: 400 invalid_routing, 402 insufficient_balance, 409 no_matching_offer.

## Request body

- ChatCompletionRequest
  - `frequency_penalty` number
  - `max_completion_tokens` integer: Same as max_tokens
  - `max_tokens` integer
  - `messages` object[], required
  - `model` string, required: Our products (james, elliot, taylor, james-direct) or any market model id from GET /api/v1/broker/models (vendor/model) — served by the cheapest eligible provider.
  - `presence_penalty` number
  - `response_format` object: {"type": "json_object"} or {"type": "json_schema", "json_schema": …}
  - `routing` BrokerRouting: Narrows which offer serves the request. Never loosens product guarantees. No matching offer → 409 no_matching_offer.
    - `capabilities` union: Every chosen provider must support all of these
      - 'reasoning' | 'structured_output' | 'tools' | 'vision'
      - string[]
    - `category` 'coding' | 'instruction_following' | 'math' | 'reasoning': Use case for level, min_score and sort=score|value
    - `family` string: Model family: vendor (anthropic), name start (claude, qwen3) or id prefix (deepseek/deepseek-v4). New generations are included automatically.
    - `level` 'solid' | 'strong' | 'top' | 'best': Needs category. solid/strong/top = the threshold of that level; best = only the offer with the highest measured score in category (within all other filters). Not together with min_score. Also for taylor (overrides the key's level for this request).
    - `max_price` object: Customer price cap in CHF per 1M tokens (incl. our margin)
      - `input` number
      - `output` number
    - `min_context` integer: Minimum context window (tokens)
    - `min_score` number: Only offers whose score in category (our own measurement) is at least this
    - `region` union: Execution location of the provider (eu includes ch)
      - 'ch' | 'eu' | 'us' | 'asia' | 'global'
      - string[]
    - `sort` 'price' | 'value' | 'speed' | 'score': cheapest · best score per CHF · highest throughput · highest score
  - `seed` integer
  - `stop` union
    - string
    - string[]
  - `stream` boolean
  - `temperature` number
  - `tool_choice` union
    - 'auto' | 'none' | 'required'
    - object
  - `tools` object[]
  - `top_p` number

## Response `200`

Completion (or SSE stream with stream=true)

- object

## Other responses

- `400`: Invalid request or routing
- `402`: Insufficient balance
- `409`: No offer matches the routing

---

[API](https://skmtc.dev/llm-broker/apis/astrioncore-core-api.md) · [All operations](https://skmtc.dev/llm-broker/apis/astrioncore-core-api/llms.txt) · [OpenAPI document](https://skmtc.dev/llm-broker/apis/astrioncore-core-api/revisions/f85835487bf5?raw)
