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

# Python (Unified Mode)

## Setup

```bash
pip install openai
```

```python
from openai import OpenAI

client = OpenAI(
    api_key="sk-proxy-YOUR_KEY_HERE",
    base_url="https://api.trygateway.ai/v1"
)
```

## Basic chat

### OpenAI

```python
response = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
```

### Anthropic

```python
response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
```

### Gemini

```python
response = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
```

## Streaming

Works identically across all providers:

```python
stream = client.chat.completions.create(
    model="anthropic/claude-sonnet-4-6",
    messages=[{"role": "user", "content": "Write a short poem about code."}],
    stream=True
)

for chunk in stream:
    content = chunk.choices[0].delta.content
    if content:
        print(content, end="")
```

## System messages

```python
response = client.chat.completions.create(
    model="anthropic/claude-sonnet-4-6",
    messages=[
        {"role": "system", "content": "You are a senior software engineer. Be concise."},
        {"role": "user", "content": "What's the difference between a mutex and a semaphore?"}
    ]
)
```

System messages are translated to each provider's native format automatically (e.g., Anthropic's `system` parameter, Gemini's `system_instruction`).

## Tool calling

The same tool definition works for every provider:

```python
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"}
                },
                "required": ["city"]
            }
        }
    }
]

response = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[{"role": "user", "content": "What's the weather in Paris?"}],
    tools=tools,
    tool_choice="auto"
)

# Standard OpenAI tool_calls format, regardless of provider
tool_call = response.choices[0].message.tool_calls[0]
print(f"{tool_call.function.name}({tool_call.function.arguments})")
```

## Multi-turn conversation

```python
messages = [
    {"role": "system", "content": "You are a helpful math tutor."},
    {"role": "user", "content": "What is a derivative?"}
]

response = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=messages
)

messages.append(response.choices[0].message)
messages.append({"role": "user", "content": "Can you give me an example?"})

response = client.chat.completions.create(
    model="openai/gpt-4o",
    messages=messages
)

print(response.choices[0].message.content)
```

## Switching providers

The power of unified mode: swap providers by changing one string. Your code, prompts, tools, and response handling all stay the same.

```python
models = [
    "openai/gpt-4o",
    "anthropic/claude-sonnet-4-6",
    "google/gemini-2.5-flash",
]

for model in models:
    response = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": "What is 2+2?"}]
    )
    print(f"{model}: {response.choices[0].message.content}")
```