> Raw Markdown twin (generated at build time from the source Markdown). Rendered page: https://docs.gatellm.io/en/quickstart/openai-compatible · Doc index: https://docs.gatellm.io/en/llms.txt


# Connect an OpenAI upstream

This chapter assumes you've already got the gateway running (see [Docker single node](/en/quickstart/docker-single-node.md)). Below we configure an OpenAI upstream + a `gpt-4o` model, then call it from the OpenAI SDK / curl, and explain a few cross-protocol details.

## Prerequisites

- The gateway is running (`http://localhost:7890`) and you can log in to the Console
- `ENCRYPTION_KEY` is set — the upstream API key and access key you're about to save are encrypted before storage; if unset, saving reports `encryption_key not set in config`. See [Docker single node → Prerequisites](/en/quickstart/docker-single-node.md#prereq)
- An OpenAI API key (`sk-...`)

## 1. Create an upstream

Console → **Upstreams** → **New**, fill in:

| Field | Value | Description |
|------|-----|------|
| Name | `openai` | Unique upstream identifier |
| Protocol | `openai` | Determines the executor and request schema |
| Base URL | `https://api.openai.com/v1` | The upstream's real address, no trailing `/` |
| API Key | `sk-...` | The key the upstream gave you; click "Add" to add more, distributed by weight |
| Enabled | ✓ | |

Save. The upstream `openai` appears in the list with status active.

## 2. Create a model

In the `openai` upstream row, click **Expand** → model sub-table → **New model**, fill in:

| Field | Value | Description |
|------|-----|------|
| Name | `gpt-4o` | The model name clients use when calling |
| Upstream | `openai` | Select the upstream you just created |
| Upstream model ID | `gpt-4o` | The upstream's real model name |
| Enabled | ✓ | |

Save. When clients call using `gpt-4o`, the gateway routes to `gpt-4o` on the `openai` upstream.

> "Name" is what's exposed to clients; "upstream model ID" is the real name sent to the upstream. When they differ, that's how model aliasing/renaming works.

## 3. Configure a key group to allow it

Console → **Access Keys** → **Key Groups** tab → **New**:

| Field | Value | Description |
|------|-----|------|
| Name | `default` | Group name |
| Models | Select `gpt-4o`, or `*` (all) | Determines which models this group's keys can call |
| Enabled | ✓ | |

## 4. Issue an access key

Console → **Access Keys** → **New**:

| Field | Value | Description |
|------|-----|------|
| Name | `my-app-key` | Identifier |
| API Key | click "Generate" | Auto-generates a string; the credential the client actually carries |
| Group | `default` | Select the group you just created |
| Enabled | ✓ | |

Save. Click the "Copy" button on that row to get the full key value.

> The client uses **this access key**, not the upstream's `sk-...`.

## 5. Call with the OpenAI SDK

OpenAI Python / Node SDK:

```text
base_url = http://localhost:7890/v1
api_key  = <your access key>
```

Python example:

```python
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:7890/v1",
    api_key="<your access key>",
)

resp = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "hello"}],
)
print(resp.choices[0].message.content)
```

## 6. Or use curl

```bash
curl http://localhost:7890/v1/chat/completions \
  -H "Authorization: Bearer <your access key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role":"user","content":"hello"}]
  }'
```

Receiving a model reply means it works.

## Cross-protocol translation

An OpenAI upstream + an OpenAI client is a "same-protocol identity path": the gateway does no translation and just forwards directly. But you can also call this `gpt-4o` model with the Anthropic SDK / Gemini SDK — the gateway translates the client protocol to the upstream protocol (`openai`), then translates the response back to the client's format.

For example, calling with the Anthropic SDK:

```bash
curl http://localhost:7890/v1/messages \
  -H "x-api-key: <your access key>" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","max_tokens":1024,"messages":[{"role":"user","content":"hi"}]}'
```

The request body is in Anthropic format; the gateway translates it to OpenAI format and sends it to the upstream, then translates the response back to Anthropic format. The client is unaware. For the full interop matrix, see [Protocol interop matrix](/en/reference/protocol-matrix.md).

## FAQ

**Q: Client reports 401?**
The access key isn't right. Check that `Authorization: Bearer` is followed by the gateway access key (not the upstream's `sk-...`).

**Q: Client reports 403 model_access_denied?**
The key group your key belongs to doesn't include `gpt-4o` in its "models" list. Go back to the key group and add that model, or change it to `*`.

**Q: Client reports 404 model_not_found?**
The model name is misspelled, or the model has `hide_name` set (only accessible by alias). Check that the model's "Name" field in the Console matches the client's `model` parameter.

**Q: Client reports 502 bad_gateway?**
The upstream is unreachable. Check that OpenAI's `base_url` (must be `https://api.openai.com/v1`, no trailing `/`) and API key are correct, and whether the upstream is reachable.

**Q: How do I make multiple upstreams (multiple OpenAI keys) fail over?**
Use a load balancer; see [Multi-upstream load balancing](/en/quickstart/multi-upstream-load-balancing.md).

**Next**: [Endpoints · auth · protocol interop](/en/reference/endpoints.md) for the full endpoint list; [Client integration and gateway differences](/en/reference/clients-and-gateway-diffs.md) for each SDK's connection method and gateway-specific behavior; [Anthropic cross-protocol](/en/quickstart/anthropic-interop.md) for the reverse cross-protocol example.
