# OpenAI and Anthropic compatibility
URL: https://docs.munito.ai/compatibility

Keep your OpenAI or Anthropic SDK, and change three values:

|          | OpenAI SDK                                                         | Anthropic SDK                     |
| -------- | ------------------------------------------------------------------ | --------------------------------- |
| Base URL | `https://api.munito.ai/inference/v1`                               | `https://api.munito.ai/inference` |
| Key      | `MUNITO_API_KEY`                                                   | `MUNITO_API_KEY`                  |
| Model    | An ID from [Models](https://docs.munito.ai/models), such as `qwen/qwen3.8-27b` | The same IDs                      |

```python tab="OpenAI SDK, Python"
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.munito.ai/inference/v1",
    api_key=os.environ["MUNITO_API_KEY"],
)
response = client.chat.completions.create(
    model="qwen/qwen3.8-27b",
    messages=[{"role": "user", "content": "Name three rivers in Europe."}],
    max_tokens=2048,
)
print(response.choices[0].message.content)
```

```ts tab="OpenAI SDK, TypeScript"
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.munito.ai/inference/v1",
  apiKey: process.env.MUNITO_API_KEY,
});
const response = await client.chat.completions.create({
  model: "qwen/qwen3.8-27b",
  messages: [{ role: "user", content: "Name three rivers in Europe." }],
  max_tokens: 2048,
});
console.log(response.choices[0].message.content);
```

```python tab="Anthropic SDK, Python"
import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.munito.ai/inference",
    api_key=os.environ["MUNITO_API_KEY"],
)
message = client.messages.create(
    model="qwen/qwen3.8-27b",
    max_tokens=2048,
    messages=[{"role": "user", "content": "Name three rivers in Europe."}],
)
for block in message.content:
    if block.type == "text":
        print(block.text)
```

## Endpoints [#endpoints]

| Endpoint                         | Format                  |
| -------------------------------- | ----------------------- |
| `POST /v1/chat/completions`      | OpenAI Chat Completions |
| `POST /v1/responses`             | OpenAI Responses        |
| `POST /v1/messages`              | Anthropic Messages      |
| `POST /v1/messages/count_tokens` | Anthropic token count   |
| `POST /v1/audio/transcriptions`  | OpenAI speech to text   |
| `GET /v1/models`                 | OpenAI model list       |

Each path starts with `https://api.munito.ai/inference`. There is no embeddings endpoint and no file upload endpoint.

## What works differently [#what-works-differently]

- **No silent changes.** A parameter that Munito AI cannot apply returns `400`, and the error names the parameter.
- **Stored responses.** Munito AI stores a response only with `store: true` or `background: true`. Add `store: true` where your code uses `previous_response_id`.
- **Reasoning models.** A reasoning model writes its reasoning before the answer, and `max_tokens` counts both. Set `max_tokens` to 2048 or more. See [Reasoning](https://docs.munito.ai/features/reasoning).
- **Tools.** Function tools work on the three APIs. Hosted tools, such as a web search, do not.
- **Text only.** Munito AI generates text, so `audio` and `modalities` return `400`.
- **Errors.** Chat Completions and Responses send the OpenAI error body, and Messages sends the Anthropic one, so each SDK raises its usual exceptions. See [Errors](https://docs.munito.ai/errors).

The [API reference](https://docs.munito.ai/api) gives each parameter of each endpoint.
