---
title: "Chat completions API · OpenAI-compatible, hosted in the EU"
description: "Send chat messages to open-weight models with the OpenAI chat completions format. Requests are processed in EU data centres and never used for training."
canonical: "https://inference.eu/api/chat-completions/"
language: "en"
---

POST /v1/chat/completions

# Chat completions API: OpenAI-compatible and processed in the EU

The chat completions endpoint is the main way to generate text with the inference.eu API. You send a list of messages, pick an open-weight model, and get the assistant's reply back in the same JSON shape the OpenAI API uses. Existing code and SDKs work after you change the base URL and the key, and every request is processed in European data centres.

[Contact sales](https://inference.eu/contact/)[Example request](#example)

1.  01API format: OpenAI
2.  02EU data centres
3.  03Covered by one DPA

POST /v1/chat/completions

```
curl https://api.inference.eu/v1/chat/completions \
  -H "Authorization: Bearer $INFERENCE_EU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-oss-120b",
    "messages": [
      {"role": "system", "content": "You answer questions about EU employment law in plain English."},
      {"role": "user", "content": "How long is the minimum paid annual leave in the EU?"}
    ],
    "temperature": 0.3,
    "max_tokens": 400
  }'
```

## What the endpoint does

`POST /v1/chat/completions` takes a conversation and returns the next assistant message. The conversation is a list of messages, each with a `role` (`system`, `user`, `assistant` or `tool`) and `content`. The model reads the whole list on every call, so the API itself is stateless: to continue a conversation, append the reply and the next user message and send the list again.

Because the format matches OpenAI's, the official Python and JavaScript SDKs, LangChain, LlamaIndex and most agent frameworks can call it without an adapter. You choose the model with the `model` field, so switching between open models is a one-string change.

## Key request fields

Only `model` and `messages` are required. `max_tokens` caps the length of the reply, and `temperature` and `top_p` control how varied it is: keep `temperature` low for extraction and classification, higher for drafting. `stop` ends generation at a given string, and `seed` makes sampling more repeatable when you need stable test output.

Set `stream` to `true` to receive tokens as they are generated. Add `tools` to let the model call your functions, and `response_format` to force JSON that matches a schema. Images go into `content` as `image_url` parts when you use a vision model. Parameters a model does not support are ignored or rejected with a clear error.

## The response shape

A completed request returns an object with an `id`, the `model` that answered, and a `choices` array. The reply text is in `choices[0].message.content`. If the model decided to call a tool, `message.tool_calls` holds the function name and JSON arguments instead.

`finish_reason` tells you why generation stopped: `stop` means the model finished naturally, `length` means it hit `max_tokens`, and `tool_calls` means it is waiting for your tool results. The `usage` object reports `prompt_tokens`, `completion_tokens` and `total_tokens`, which is what you are billed on and what you should log to watch costs per feature.

## A practical pattern for product features

Most product features follow the same shape: a fixed system message that sets tone and rules, a few lines of retrieved context, and the user's question. Keep the system message stable across requests so that prompt caching can reuse it, and put variable content at the end.

For anything a program reads, such as tags, routing decisions or extracted fields, combine a low `temperature` with `response_format` so you get valid JSON rather than parsing prose. For chat interfaces, stream the reply so users see text straight away, and trim old turns or summarise them once the conversation approaches the model's context window.

## Errors and edge cases

Errors use the OpenAI shape: an HTTP status and an `error` object with `message`, `type` and `code`. A 400 usually means an invalid field or a prompt longer than the model's context window. A 401 means the key is missing or wrong, 404 an unknown model id, and 429 that you have reached a rate limit for your plan.

Check `finish_reason` on every response. A `length` result means the answer was cut off, so raise `max_tokens` or ask for a shorter answer. Retry 429 and 5xx responses with exponential backoff, and honour the `Retry-After` header when it is present.

## Chat completions

Endpoint

POST /v1/chat/completions

Category

Endpoints

API format

OpenAI

Base URL

api.inference.eu/v1

Processing

EU data centres

Training on your data

Never

## Chat completions: common questions

The questions buyers, developers and legal teams ask us most. Something missing? Ask us directly.

Yes. The request body, response body, streaming format and error shape follow the OpenAI chat completions API. Point the OpenAI SDK at the inference.eu base URL, use your inference.eu key, and choose one of the open-weight models we host. Fields that only make sense for OpenAI's own models may not be available.

Prompts and responses are processed in data centres in the European Union. If a location fails, traffic moves to another European location rather than to a provider outside the EU. Your requests are used to generate the answer and are never used to train models.

Any chat, reasoning, code or vision model in our catalogue, such as \`gpt-oss-120b\`. Call \`GET /v1/models\` to list the exact ids available to your key, and pass one of them in the \`model\` field. The models page on this site describes each one in more detail.

The endpoint does not store conversations. Your application keeps the message list and sends it with every request, appending the assistant's reply and the next user message each time. For long chats, drop or summarise older turns so the request stays inside the model's context window.

It means the model stopped because it reached \`max\_tokens\` or the end of its context window, so the reply is incomplete. Raise \`max\_tokens\`, shorten the prompt, or ask the model for a more concise answer. Reasoning models count their thinking towards this limit too.

Yes. Both frameworks have OpenAI-compatible chat model classes that accept a custom base URL and API key. Set the base URL to the inference.eu API, set the key from \`INFERENCE\_EU\_API\_KEY\`, and pass the model id. Tool calling and streaming work through the same classes.

Rate limits depend on your plan and the model you call. We agree them with you when you sign up and can raise them for production traffic. When you exceed a limit the API returns HTTP 429, and your client should retry after the time given in \`Retry-After\`.

No. What you send is used to answer the request and nothing else. Prompts and completions are not used to train or fine-tune any model, ours or anyone else's. If you need detail on logging and retention for your contract, we confirm it with you in writing.

Chat completions is stateless and takes a list of messages, which is what most existing code uses. The Responses API takes \`input\` and \`instructions\`, returns typed output items and supports built-in tools such as web search and remote MCP servers. Both reach the same models.

[Ask a question](https://inference.eu/contact/)

## Related

[API overview](https://inference.eu/api/)

-   [StreamingStream tokens from open models as they are generated, with OpenAI and Anthropic server-sent events. Examples, chunk format and error handling.Guides](https://inference.eu/api/streaming/)
-   [Tool callingLet open models call your functions and APIs with OpenAI-compatible tool calling. Define tools, run the loop, handle arguments, processed in the EU.Guides](https://inference.eu/api/tool-calling/)
-   [Structured outputsGet valid JSON that matches your schema from open models with OpenAI-compatible structured outputs. JSON mode, json\_schema, strict mode and pitfalls.Guides](https://inference.eu/api/structured-outputs/)
-   [List modelsList the open-weight models your inference.eu key can use with GET /v1/models, in the OpenAI format. Pick model ids for chat, embeddings, speech and more.Endpoints](https://inference.eu/api/models/)

## Move your AI workloads to EU infrastructure

Tell us which models you use and roughly how much traffic you have. We reply within one working day with pricing and next steps.

-   Reply within one working day
-   Pricing for your volume
-   DPA ready to sign
