# API reference

> Reference for OpenAI- and Anthropic-compatible endpoints: base URLs, auth headers, chat, responses, messages, models, streaming, tool calls and usage.

Source: https://oneaiapikey.com/docs/api-reference

The gateway implements the public OpenAI and Anthropic HTTP APIs, so official SDKs and most third-party clients work unchanged. This page lists what is supported, the fields that matter, and where behaviour differs from calling a provider directly.

## Base URLs

| Format | Base URL | Used by |
| --- | --- | --- |
| OpenAI | `https://api.oneaiapikey.com/v1` | OpenAI SDKs, Codex CLI, Cursor, Cline, most editors |
| Anthropic | `https://api.oneaiapikey.com` | Anthropic SDKs, Claude Code |

All endpoints use HTTPS, accept and return JSON (UTF-8), and stream with server-sent events when `stream` is true.

## Authentication

Create keys under [API keys](https://oneaiapikey.com/console/keys) in the console. A key works for both formats; send it in whichever header your client uses:

| Header | Format | Notes |
| --- | --- | --- |
| `Authorization: Bearer sk-…` | Both | Standard for OpenAI clients. Claude Code sends this when you set `ANTHROPIC_AUTH_TOKEN`. |
| `x-api-key: sk-…` | Anthropic | What the Anthropic SDKs send by default. |
| `anthropic-version: 2023-06-01` | Anthropic | Required by the Messages API. SDKs add it automatically. |

> **Per-key controls:** Under [API keys](https://oneaiapikey.com/console/keys) you can give each key a name, a spending cap, an expiry date and an allowed-model list. Use one key per app or teammate so you can revoke a single key without downtime elsewhere.

## Endpoints

- [POST`/v1/chat/completions`Chat with any model. The most widely supported endpoint. (OpenAI format)](https://oneaiapikey.com/docs/api-reference#chat-completions)
- [POST`/v1/responses`OpenAI Responses API, used by Codex CLI and newer OpenAI SDK features. (OpenAI format)](https://oneaiapikey.com/docs/api-reference#responses)
- [POST`/v1/messages`Anthropic Messages API, used by Claude Code and the Anthropic SDKs. (Anthropic format)](https://oneaiapikey.com/docs/api-reference#messages)
- [GET`/v1/models`List the model ids your key can call. (OpenAI format)](https://oneaiapikey.com/docs/api-reference#models)
- [POST`/v1/embeddings`Vector embeddings, when an embedding model is enabled. (OpenAI format)](https://oneaiapikey.com/docs/api-reference#embeddings)

## Chat completions

POST `https://api.oneaiapikey.com/v1/chat/completions` (OpenAI format)

The universal endpoint. Every model in the catalogue that supports the OpenAI format can be called here, including Claude models, which the gateway translates for you.

### Request body

`model`stringrequired

Exact model id, for example `gpt-5.6-terra`. See [models by format](https://oneaiapikey.com/docs/api-reference#model-formats).
`messages`arrayrequired

Conversation so far. Each item has a `role` (`system`, `user`, `assistant`, `tool`) and `content`.
`stream`boolean

Send tokens as server-sent events. Recommended for long outputs.
`stream_options`object

`{"include_usage": true}` adds a final chunk with token usage.
`max_tokens / max_completion_tokens`integer

Upper bound on generated tokens. Reasoning models prefer `max_completion_tokens`.
`temperature, top_p`number

Sampling controls. Some reasoning models ignore or reject them.
`tools, tool_choice`array, string | object

Function calling. See [tool calling](https://oneaiapikey.com/docs/api-reference#tool-calling).
`response_format`object

Ask for JSON output (`{"type": "json_object"}` or a JSON schema) on models that support it. Not forwarded to Claude models; see [structured output](https://oneaiapikey.com/docs/structured-output).
`stop`string | array

Stop generating when one of these strings appears.

Other standard OpenAI parameters are forwarded when the target model supports them. Unsupported parameters are either ignored or rejected with a `400` by the upstream model. The full field list, and what changes for Claude models, is on [Chat completions](https://oneaiapikey.com/docs/chat-completions).

Example request:

```bash
curl https://api.oneaiapikey.com/v1/chat/completions \
  -H "Authorization: Bearer $RELAYKIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-terra",
    "messages": [
      {"role": "system", "content": "You are a concise assistant."},
      {"role": "user", "content": "Give me three names for a CLI tool."}
    ],
    "max_tokens": 200
  }'
```

### Response

200 OK:

```json
{
  "id": "chatcmpl-9f2c…",
  "object": "chat.completion",
  "created": 1760000000,
  "model": "gpt-5.6-terra",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "1. shipit\n2. tern\n3. relay"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 27,
    "completion_tokens": 14,
    "total_tokens": 41
  }
}
```

`finish_reason` is `stop` for a natural end, `length` when `max_tokens` was hit, and`tool_calls` when the model wants you to run a tool.

## Responses API

POST `https://api.oneaiapikey.com/v1/responses` (OpenAI format)

OpenAI's newer request shape (`input` instead of `messages`, typed output items). Codex CLI uses it by default. It is fully supported for GPT-family models. Claude models are translated, but the stateful fields (`previous_response_id`, `conversation`) are rejected; for other families use chat completions. Responses are not stored, so there is no `GET` or `DELETE` on `/v1/responses/{id}`. See [Responses API](https://oneaiapikey.com/docs/responses).

curl:

```bash
curl https://api.oneaiapikey.com/v1/responses \
  -H "Authorization: Bearer $RELAYKIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-terra",
    "input": "Summarise the Unix philosophy in one line."
  }'
```

Python:

```python
resp = client.responses.create(
    model="gpt-5.6-terra",
    input="Summarise the Unix philosophy in one line.",
)
print(resp.output_text)
```

Node:

```js
const resp = await client.responses.create({
  model: "gpt-5.6-terra",
  input: "Summarise the Unix philosophy in one line.",
});
console.log(resp.output_text);
```

## Messages (Anthropic)

POST `https://api.oneaiapikey.com/v1/messages` (Anthropic format)

The native Anthropic format, used by Claude Code and the Anthropic SDKs. Use it for models marked [Anthropic format](https://oneaiapikey.com/docs/api-reference#model-formats). Prefer it for Claude when you need Anthropic-specific features such as prompt caching controls, extended thinking blocks or exact `stop_reason` values.

Required fields: `model`, `max_tokens` and `messages`. Optional: `system`, `stream`, `temperature`, `stop_sequences`, `tools`, `tool_choice`,`thinking`, `output_config`. `anthropic-beta` headers are forwarded to the upstream.`anthropic-version` defaults to `2023-06-01` when you leave it out. Token counting (`/v1/messages/count_tokens`) is not available. See [Anthropic Messages](https://oneaiapikey.com/docs/anthropic-messages).

curl:

```bash
curl https://api.oneaiapikey.com/v1/messages \
  -H "x-api-key: $RELAYKIT_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-5-5",
    "max_tokens": 1024,
    "system": "You are a senior code reviewer.",
    "messages": [{"role": "user", "content": "Review: def add(a, b): return a - b"}]
  }'
```

Python:

```python
import os
import anthropic

client = anthropic.Anthropic(base_url="https://api.oneaiapikey.com", api_key=os.environ["RELAYKIT_API_KEY"])

msg = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    system="You are a senior code reviewer.",
    messages=[{"role": "user", "content": "Review: def add(a, b): return a - b"}],
)
print(msg.content[0].text)
```

Node:

```js
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({ baseURL: "https://api.oneaiapikey.com", apiKey: process.env.RELAYKIT_API_KEY });

const msg = await client.messages.create({
  model: "claude-sonnet-5-5",
  max_tokens: 1024,
  system: "You are a senior code reviewer.",
  messages: [{ role: "user", content: "Review: def add(a, b): return a - b" }],
});
console.log(msg.content[0].text);
```

200 OK:

```json
{
  "id": "msg_01H…",
  "type": "message",
  "role": "assistant",
  "model": "claude-sonnet-5-5",
  "content": [
    {
      "type": "text",
      "text": "Bug: the function subtracts instead of adding. Use `return a + b`."
    }
  ],
  "stop_reason": "end_turn",
  "usage": {
    "input_tokens": 31,
    "output_tokens": 19,
    "cache_creation_input_tokens": 0,
    "cache_read_input_tokens": 0
  }
}
```

## List models

GET `https://api.oneaiapikey.com/v1/models` (OpenAI format)

Returns the model ids your key is allowed to call. If a key has an allowed-model list, only those models appear. Sent with`x-api-key` and `anthropic-version` headers (as the Anthropic SDKs do), the same route answers in Anthropic's list format.

Request:

```bash
curl https://api.oneaiapikey.com/v1/models \
  -H "Authorization: Bearer $RELAYKIT_API_KEY"
```

200 OK (shortened):

```json
{
  "object": "list",
  "data": [
    {
      "id": "claude-opus-5-5",
      "object": "model"
    },
    {
      "id": "claude-sonnet-5",
      "object": "model"
    },
    {
      "id": "claude-haiku-4-5",
      "object": "model"
    }
  ]
}
```

## Embeddings

POST `https://api.oneaiapikey.com/v1/embeddings` (OpenAI format)

Accepts the standard OpenAI embeddings request. It only works with embedding models; chat models return an error here. Check `GET /v1/models` to see whether an embedding model is enabled for your account before building on it.

Example request:

```bash
curl https://api.oneaiapikey.com/v1/embeddings \
  -H "Authorization: Bearer $RELAYKIT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<embedding-model-id>",
    "input": ["first document", "second document"]
  }'
```

## Streaming (SSE)

Set `"stream": true` and read the response as `text/event-stream`. Official SDKs handle parsing for you. If you parse by hand, split on blank lines, read the `data:` field, and ignore event types you do not recognise (for example keep-alive `ping` events).

OpenAI format:

```text
data: {"id":"chatcmpl-1","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":""}}]}

data: {"id":"chatcmpl-1","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Hel"}}]}

data: {"id":"chatcmpl-1","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"lo"}}]}

data: {"id":"chatcmpl-1","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-1","object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":2,"total_tokens":14}}

data: [DONE]
```

Anthropic format:

```text
event: message_start
data: {"type":"message_start","message":{"id":"msg_1","role":"assistant","content":[],"usage":{"input_tokens":12,"output_tokens":1}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"Hello"}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn"},"usage":{"output_tokens":2}}

event: message_stop
data: {"type":"message_stop"}
```

- OpenAI format ends with `data: [DONE]`. Add `"stream_options": {"include_usage": true}` to receive token usage in the last chunk.
- Anthropic format ends with `message_stop`; token usage arrives in `message_start` and `message_delta`.
- An error that happens mid-stream arrives as an error event; treat the partial output as incomplete.

## Tool calling

Function and tool calling work on models that support them upstream (current Claude and GPT models do). Send tool definitions in the format of the endpoint you are calling; the gateway translates between formats when a Claude model is called through the OpenAI endpoint.

OpenAI format:

```json
{
  "model": "gpt-5.6-terra",
  "messages": [
    {
      "role": "user",
      "content": "What is the weather in Pune?"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Current weather for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string"
            }
          },
          "required": [
            "city"
          ]
        }
      }
    }
  ],
  "tool_choice": "auto"
}
```

Anthropic format:

```json
{
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "messages": [
    {
      "role": "user",
      "content": "What is the weather in Pune?"
    }
  ],
  "tools": [
    {
      "name": "get_weather",
      "description": "Current weather for a city",
      "input_schema": {
        "type": "object",
        "properties": {
          "city": {
            "type": "string"
          }
        },
        "required": [
          "city"
        ]
      }
    }
  ]
}
```

1. The model replies with `tool_calls` (OpenAI) or a `tool_use` content block (Anthropic).
2. Your code runs the tool and sends the result back: a `tool` role message with the matching `tool_call_id`, or a `tool_result` block with the matching `tool_use_id`.
3. The model continues with the result. Each round trip is a separate, separately billed request.

> **Best fidelity:** Cross-format translation covers text, images, PDFs, tools, streaming and `reasoning_effort`. It does not carry over `response_format` or Anthropic `cache_control` markers, so for structured output and prompt caching on Claude call it through `/v1/messages`.

## Usage & billing

Every successful response reports the tokens you were charged for. Your prepaid balance is reduced by _input tokens × input rate + output tokens × output rate_, using the per-million-token rates on the [models page](https://oneaiapikey.com/models). Cached input tokens are billed at the lower cached rate where a model has one.

| Meaning | OpenAI format | Anthropic format |
| --- | --- | --- |
| Input tokens | `usage.prompt_tokens` | `usage.input_tokens` |
| Output tokens | `usage.completion_tokens` | `usage.output_tokens` |
| Cached input read | `usage.prompt_tokens_details.cached_tokens` | `usage.cache_read_input_tokens` |
| Cache write | n/a | `usage.cache_creation_input_tokens` |
| Reasoning / thinking | Included in `completion_tokens` | Included in `output_tokens` |

**Worked example.** A Claude Sonnet 5.5 request with 12,000 input tokens and1,500 output tokens costs $0.0264 for input ($2.20 per 1M) plus$0.0165 for output ($11 per 1M), so **$0.0429** in total.

The console shows your live [balance](https://oneaiapikey.com/console/billing) and a [per-request usage log](https://oneaiapikey.com/console/usage) with model, tokens and cost, so you can reconcile any charge. Requests rejected by the gateway (invalid key, no balance, unknown model) are not charged.

## Rate limits & timeouts

- **Gateway limits.** There is no per-account request rate limit on `/v1/*`. Per-model limits are off by default; when one applies, the `429` message says "Rate limit reached: at most N requests per M minutes".
- **Upstream limits.** Providers throttle a model under heavy load. These surface as `429` or `503` and are safe to retry with backoff. The gateway does not retry for you.
- **Streaming timeout.** A stream is closed after **300 seconds** without data from the model.
- **Non-streaming requests.** The gateway does not cut them off, but your client or a proxy may. Use `stream: true` for long outputs and reasoning models, and set your HTTP client timeout to several minutes.
- **Request size.** Request bodies are limited to 128 MB (`413` above that).

Details and retry code: [Rate limits and retries](https://oneaiapikey.com/docs/rate-limits). Planning sustained high volume (batch jobs, many parallel agents)? Email [support@relaykit.dev](mailto:support@relaykit.dev) before launch so we can confirm capacity.

## Errors

Errors use the OpenAI envelope, `{"error": {"message", "type", "code"}}`, with an HTTP status that tells you what to do: `400` fix the request, `401` check the key, `403` balance, key limits or model access, `404` unknown model or route, `429` and `5xx` retry with backoff. Errors from Claude models on `/v1/messages` use Anthropic's `{"type": "error", "error": {...}}` shape. Every response carries an `X-Request-Id` header to quote to support. See [Errors](https://oneaiapikey.com/docs/errors) for every message.

## Not available

These parts of the OpenAI and Anthropic APIs are not offered. Requests to them fail with `404` or `501`:

- Files, fine-tuning, image variations, Assistants, Threads and Batch (OpenAI).
- Stored responses: `GET` / `DELETE /v1/responses/{id}`.
- Token counting, Message Batches and the Files API (Anthropic).

## Models by format

Exact ids to send in the `model` field, and which endpoint family each one accepts. Rates are USD per 1M tokens.

| Model id | Endpoints | In / Out |
| --- | --- | --- |
| [claude-opus-5-5](https://oneaiapikey.com/models/claude-opus-5-5)Claude | openaianthropic | $4.40 / $22 |
| [claude-sonnet-5](https://oneaiapikey.com/models/claude-sonnet-5)Claude | openaianthropic | $2.20 / $11 |
| [claude-haiku-4-5](https://oneaiapikey.com/models/claude-haiku-4-5)Claude | openaianthropic | $1.10 / $5.50 |
| [gpt-6.1-sol](https://oneaiapikey.com/models/gpt-6-1-sol)GPT | openai | $2.20 / $11 |
| [gpt-5.6-sol](https://oneaiapikey.com/models/gpt-5-6-sol)GPT | openai | $5.50 / $33 |
| [gpt-5.6-terra](https://oneaiapikey.com/models/gpt-5-6-terra)GPT | openai | $2.20 / $13.20 |
| [grok-4.6](https://oneaiapikey.com/models/grok-4-6)Grok | openai | $2.20 / $6.60 |
| [claude-sonnet-5-5](https://oneaiapikey.com/models/claude-sonnet-5-5)Claude | openaianthropic | $2.20 / $11 |
| [grok-4.7](https://oneaiapikey.com/models/grok-4-7)Grok | openai | $2.20 / $6.60 |
| [deepseek-v4-flash](https://oneaiapikey.com/models/deepseek-v4-flash)DeepSeek | openai | $0.24 / $0.96 |
| [deepseek-v4-pro](https://oneaiapikey.com/models/deepseek-v4-pro)DeepSeek | openai | $1.32 / $3.96 |
