> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.empiriolabs.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.empiriolabs.ai/_mcp/server.

# OpenAI, Anthropic, and Gemini Compatibility

EmpirioLabs AI exposes compatibility endpoints so you can adopt the platform without rewriting existing integrations. Point your OpenAI, Anthropic, or Google Gemini SDK at the EmpirioLabs base URL and start making requests immediately.

## OpenAI-compatible Chat Completions

`POST /v1/chat/completions`

Accepts the same request body as the OpenAI Chat Completions API. Supports `messages`, `model`, `stream`, `temperature`, `max_tokens`, and other standard parameters.

```bash
curl "https://api.empiriolabs.ai/v1/chat/completions" \
  -H "Authorization: Bearer $EMPIRIOLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-7-max",
    "messages": [{ "role": "user", "content": "Summarize this in one sentence." }]
  }'
```

**Using the OpenAI Python SDK:**

```python
from openai import OpenAI

client = OpenAI(
    api_key="sk-empiriolabs-your_key_here",
    base_url="https://api.empiriolabs.ai/v1",
)

response = client.chat.completions.create(
    model="qwen3-7-max",
    messages=[{"role": "user", "content": "Hello!"}],
)
```

> **System prompts**
>
> Every chat model ships with a short default system message that establishes its identity (for example, "You are DeepSeek V4 Flash"). The default is prepended to your request automatically when you do not include a `role: "system"` or `role: "developer"` message. If you provide one, it fully replaces the default. No merging or prepending happens, and multiple system messages in a single request are forwarded to the upstream as-is.

## Structured outputs

Chat models that advertise structured output can constrain their responses with the OpenAI `response_format` parameter on `POST /v1/chat/completions`. There are two levels:

* **JSON mode** returns a valid JSON object with a shape you describe in your prompt.
* **JSON schema** forces the response to match a JSON Schema you provide.

Support is per model. Check the `structured_output` field on `GET /v1/models/{modelId}` (`"json_schema"` means strict schema support, `"json_object"` means JSON mode only), or look for the "Structured Outputs" capability on the model page. Sending a format a model does not support returns a 400.

**JSON mode:**

```bash
curl "https://api.empiriolabs.ai/v1/chat/completions" \
  -H "Authorization: Bearer $EMPIRIOLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-7-max",
    "messages": [{ "role": "user", "content": "Give me the capital of France as JSON with keys city and country." }],
    "response_format": { "type": "json_object" }
  }'
```

**JSON schema (schema-enforced):**

```bash
curl "https://api.empiriolabs.ai/v1/chat/completions" \
  -H "Authorization: Bearer $EMPIRIOLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4-pro",
    "messages": [{ "role": "user", "content": "Extract structured facts about Paris." }],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "city_info",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "city": { "type": "string" },
            "population": { "type": "integer" }
          },
          "required": ["city", "population"],
          "additionalProperties": false
        }
      }
    }
  }'
```

The OpenAI SDKs support both shapes natively through their own `response_format` argument, so no EmpirioLabs-specific code is needed.

> **Other endpoints**
>
> Structured output also works on the other text endpoints. `POST /v1/completions` accepts the same `response_format`. `POST /v1/responses` uses the Responses API `text.format` field (for example `{ "text": { "format": { "type": "json_schema", "name": "...", "strict": true, "schema": { ... } } } }`), which the OpenAI SDK sets for you. `POST /v1/messages` accepts an OpenAI-shaped `response_format` when you need it alongside the Anthropic request shape.

## OpenAI Responses-compatible endpoint

`POST /v1/responses`

Accepts the same request body as the OpenAI Responses API. Supports `model`, `input`, `instructions`, and related fields.

```bash
curl "https://api.empiriolabs.ai/v1/responses" \
  -H "Authorization: Bearer $EMPIRIOLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seed-2-0-pro",
    "input": "Write a launch checklist."
  }'
```

## Anthropic-style Messages endpoint

`POST /v1/messages`

Accepts the same request body as the Anthropic Messages API. Requires `model`, `messages`, and `max_tokens`.

```bash
curl "https://api.empiriolabs.ai/v1/messages" \
  -H "Authorization: Bearer $EMPIRIOLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mistral-medium-3-1",
    "messages": [{ "role": "user", "content": "Hello" }],
    "max_tokens": 256
  }'
```

## Google Gemini-compatible endpoint

`POST /v1beta/models/{model}:generateContent`

Accepts the native Google Gemini request body (`contents`, `systemInstruction`, `generationConfig`, `tools`) for any chat model in the catalog. Streaming uses `POST /v1beta/models/{model}:streamGenerateContent?alt=sse`, and `POST /v1beta/models/{model}:countTokens` returns a fast token estimate.

Authenticate with your EmpirioLabs API key in the `x-goog-api-key` header or the `?key=` query parameter, the same places Gemini clients already put their key. `Authorization: Bearer` works too.

```bash
curl "https://api.empiriolabs.ai/v1beta/models/qwen3-7-max:generateContent" \
  -H "x-goog-api-key: $EMPIRIOLABS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contents": [{ "role": "user", "parts": [{ "text": "Hello!" }] }]
  }'
```

**Using the google-genai Python SDK:**

```python
from google import genai

client = genai.Client(
    api_key="sk-empiriolabs-your_key_here",
    http_options={"base_url": "https://api.empiriolabs.ai"},
)

response = client.models.generate_content(
    model="qwen3-7-max",
    contents="Hello!",
)
```

Pricing, parameters, and billing match `/v1/chat/completions` for the same model. Streamed responses end without a `[DONE]` sentinel, matching Gemini behavior.

## SDK configuration cheat sheet

| SDK                  | Configuration                                                                                               |
| -------------------- | ----------------------------------------------------------------------------------------------------------- |
| OpenAI Python        | `OpenAI(api_key="sk-empiriolabs-...", base_url="https://api.empiriolabs.ai/v1")`                            |
| OpenAI Node          | `new OpenAI({ apiKey: "sk-empiriolabs-...", baseURL: "https://api.empiriolabs.ai/v1" })`                    |
| Anthropic Python     | Point `base_url` to `https://api.empiriolabs.ai` and set `api_key` to your EmpirioLabs key                  |
| Google Gen AI Python | `genai.Client(api_key="sk-empiriolabs-...", http_options={"base_url": "https://api.empiriolabs.ai"})`       |
| Google Gen AI Node   | `new GoogleGenAI({ apiKey: "sk-empiriolabs-...", httpOptions: { baseUrl: "https://api.empiriolabs.ai" } })` |
| cURL                 | Set `Authorization: Bearer sk-empiriolabs-...` and use the EmpirioLabs base URL                             |

For coding agents, IDE assistants, and CLIs, see [Integrations](/integrations) for OpenCode, Claude Code, Cline, Aider, Continue, Cursor, and other OpenAI-compatible tools.

## Model support

Not every model supports every endpoint format. Use `GET /v1/models/{modelId}` to check a specific model's `capabilities` (streaming, system prompt, web search, images, video) and `supported_parameters` before integrating.