Quickstart
Inferray speaks three text formats — OpenAI Chat Completions, OpenAI Responses, and Anthropic Messages — and every text model answers on all three. Image models have their own endpoint. Keep your SDK, keep your prompts, and change two things: the base URL and the key.
- Base URL —
https://api.inferray.com/v1 - Auth —
Authorization: Bearer inferray_..., orx-api-keyif your SDK sends that
Create a key
Sign up and create a key in the console. Keys are scoped to a project, so you can keep staging and production spend apart from the first request.
export INFERRAY_API_KEY="inferray_..."
The full secret is shown once, when the key is created. Store it then.
Chat Completions
The OpenAI-compatible endpoint, at /v1/chat/completions. Your Inferray key goes where your provider key used to; everything else in the call stays the same.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.inferray.com/v1",
apiKey: process.env.INFERRAY_API_KEY,
});
const resp = await client.chat.completions.create({
model: "gpt-5.5",
messages: [{ role: "user", content: "ship it" }],
});
console.log(resp.choices[0].message.content);
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.inferray.com/v1",
api_key=os.environ["INFERRAY_API_KEY"],
)
resp = client.chat.completions.create(
model="gpt-5.5",
messages=[{"role": "user", "content": "ship it"}],
)
print(resp.choices[0].message.content)
curl https://api.inferray.com/v1/chat/completions \
-H "Authorization: Bearer $INFERRAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"messages": [{"role": "user", "content": "ship it"}]
}'
Messages
The Anthropic-compatible endpoint, at /v1/messages. Every model in the catalogue answers on it — the OpenAI and Google ones too, not only Claude. The Anthropic SDK's x-api-key header works exactly like the bearer token.
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.inferray.com",
apiKey: process.env.INFERRAY_API_KEY,
});
const msg = await client.messages.create({
model: "claude-opus-4-8",
max_tokens: 1024,
messages: [{ role: "user", content: "ship it" }],
});
Responses
The other OpenAI-compatible endpoint, at /v1/responses. It is what Codex and the newer OpenAI SDK methods speak, and every model in the catalogue answers on it — Claude and Gemini included.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.inferray.com/v1",
apiKey: process.env.INFERRAY_API_KEY,
});
const response = await client.responses.create({
model: "gpt-5.5",
input: "ship it",
});
console.log(response.output_text);
curl https://api.inferray.com/v1/responses \
-H "Authorization: Bearer $INFERRAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.5",
"input": "ship it"
}'
store is passed through as you send it. Set store: false and the response is not retained upstream; leave it unset and the provider's default applies. Note that Inferray serves POST /v1/responses only — the retrieval, cancel, and delete routes for stored responses are not exposed, so treat a stored response as something the provider holds rather than something you can fetch back through Inferray.
List the models
GET /v1/models returns the catalogue in the shape OpenAI clients expect, so a tool that populates its model picker from the API finds one.
curl https://api.inferray.com/v1/models \
-H "Authorization: Bearer $INFERRAY_API_KEY"
{
"object": "list",
"data": [
{ "id": "claude-opus-4-8", "object": "model", "created": 1700000000, "owned_by": "anthropic" }
]
}
The list is the catalogue itself, so every id it returns is one you can call on any of the three endpoints. It costs nothing and is never billed, but it does require a valid key — which makes it a quick way to check that a key works.
Streaming
Set stream: true and tokens arrive as they are generated. Usage is still counted, so streamed requests show up in your logs like any other.
const stream = await client.chat.completions.create({
model: "gpt-5.5",
messages: [{ role: "user", content: "ship it" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
Coding agents
Most agents need a base URL and a key and nothing else. Claude Code takes two environment variables; the others want a provider block or a settings form. Each one has its own page under coding agents.
Errors
Errors come back in the shape your SDK already expects, with a message that says what to do about it.
| Status | What it means |
|---|---|
401 | The key is missing, malformed, or no longer active. |
402 | Your balance is too low to cover the request. Top up, or turn on auto top-up. |
404 | That model isn't on this endpoint. The response lists the ones that are. |
503 | We couldn't confirm your balance, so nothing was sent or charged. Retry. |
Next
- Browse the models — context windows, capabilities, and per-model pricing
- Check what it costs — per-token pricing and what you are charged for