Skip to content
Relaykit
DocsChat completions

Build

Chat completions

Send OpenAI-format chat requests to every model with one key. Request fields, roles, the response and usage object, and what changes for Claude models.

Updated View .md
On this page

POST /v1/chat/completions is the OpenAI Chat Completions API. It is the one request format that every model in the catalogue accepts, so it is the safest default for new code: switch models by changing one string.

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

Base URL https://api.oneaiapikey.com/v1

Send a request

Point any OpenAI SDK at the base URL above and use your key. Nothing else in your code changes.

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": "Explain what an API gateway does in two sentences."}
    ],
    "max_tokens": 300
  }'
import os
from openai import OpenAI

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

reply = client.chat.completions.create(
    model="gpt-5.6-terra",
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "Explain what an API gateway does in two sentences."},
    ],
    max_tokens=300,
)
print(reply.choices[0].message.content)
print(reply.usage)
import OpenAI from "openai";

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

const reply = await client.chat.completions.create({
  model: "gpt-5.6-terra",
  messages: [
    { role: "system", content: "You are a concise assistant." },
    { role: "user", content: "Explain what an API gateway does in two sentences." },
  ],
  max_tokens: 300,
});
console.log(reply.choices[0].message.content);
console.log(reply.usage);

Request fields

Field Type Notes
model string Required. An exact id from the models table, for example gpt-5.6-terra.
messages array Required. The conversation so far, oldest first. See roles.
max_tokens / max_completion_tokens integer Upper limit for the reply. Set it: it caps cost and keeps long answers from timing out.
temperature, top_p number Sampling controls. Leave unset unless you need them; some reasoning models accept only the default.
stop string or array Stop sequences.
stream boolean true sends the reply as server-sent events. See Streaming.
stream_options object {"include_usage": true} adds a final chunk with token counts.
tools, tool_choice, parallel_tool_calls Function calling. See Tool calling.
response_format object JSON mode and JSON Schema. See Structured output for which models honour it.
reasoning_effort string low, medium or high on reasoning models. See Reasoning models.

Other OpenAI fields (seed, n, logprobs, presence_penalty, frequency_penalty, user …) are passed to the provider as they are. Whether they have an effect depends on the model, as it would if you called the provider directly.

Roles

Role Use it for
system Instructions that apply to the whole conversation. Put one at the start. (developer is accepted too.)
user What the person or your app asks. Text, or a list of parts with images and files.
assistant Earlier replies from the model, sent back so it remembers the conversation. Also carries tool_calls.
tool The result of a tool the model asked you to run, with its tool_call_id.

The API is stateless: it does not remember earlier requests. To continue a conversation, send the whole history again, with the model’s previous answers as assistant messages:

Multi-turn history
messages = [
    {"role": "system", "content": "You are a helpful SQL tutor."},
    {"role": "user", "content": "What is a LEFT JOIN?"},
    {"role": "assistant", "content": "A LEFT JOIN returns every row from the left table …"},
    {"role": "user", "content": "Show me an example with orders and customers."},
]

Every request is billed for all the tokens it sends, so a long history costs more with each turn. Trim or summarise old turns, and see prompt caching for how repeated prefixes get cheaper.

Response

200 OK
{
  "id": "chatcmpl-…",
  "object": "chat.completion",
  "created": 1791420807,
  "model": "gpt-5.6-terra",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "An API gateway is a single entry point …" },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 31,
    "completion_tokens": 42,
    "total_tokens": 73,
    "prompt_tokens_details": { "cached_tokens": 0 },
    "completion_tokens_details": { "reasoning_tokens": 0 }
  }
}
  • choices[0].message.content is the reply. With tools it may be null and tool_calls is set instead.
  • finish_reason is stop (finished), length (hit max_tokens), tool_calls (wants a tool run) or content_filter.
  • usage lists the tokens you are billed for. prompt_tokens_details.cached_tokens and completion_tokens_details.reasoning_tokens appear when the provider reports them. Reasoning tokens are already included in completion_tokens.
  • The X-Request-Id response header identifies the request. Quote it if you contact support.

The response carries token counts, not a price. The cost of each request is on the usage page; the rates are in the models table.

Claude models in this format

Claude models accept chat completions too: the gateway translates the request to Anthropic’s format and the answer back. Most code works unchanged. The differences:

  • If you leave out max_tokens, the gateway sends 8,192, because Anthropic’s API requires a limit. Set your own.
  • response_format is not forwarded to Claude. Use a forced tool or the Messages endpoint instead (see Structured output).
  • n, seed, logprobs, presence_penalty, frequency_penalty and logit_bias have no Anthropic equivalent and are dropped.
  • reasoning_effort turns on Claude’s extended thinking; the thinking text comes back as reasoning_content (see Reasoning models).
  • Images and PDFs given by URL are downloaded by the gateway and sent to Claude inline.

If you need Anthropic-only features such as cache_control breakpoints, use the Anthropic Messages endpoint with claude-sonnet-5-5 instead.

↑ ↓ moveEnter openEsc close