Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

OpenAI Compatibility

ScaiGrid exposes an OpenAI-compatible API surface at /oai/v1/. Point any OpenAI SDK at ScaiGrid by changing the base URL — no code changes required.

This page covers what works, what differs, and how to migrate.

Why use the OpenAI layer#

  • Drop-in migration. Existing codebases that target api.openai.com switch to ScaiGrid by changing one config value.
  • Third-party tool compatibility. Libraries that assume the OpenAI shape (LangChain, LlamaIndex, agent frameworks) work unmodified.
  • SDK maturity. OpenAI's SDKs are the most battle-tested. Use them; get ScaiGrid's routing, accounting, and multi-tenancy transparently.

When NOT to use the OpenAI layer#

  • New integrations. The native /v1/ API has more features — multimodal content handling, structured sessions, extended model metadata — that don't fit OpenAI's shape. New code should use /v1/.
  • Tight ScaiLabs integrations. Other ScaiLabs products (ScaiBot, ScaiBunker, etc.) use /v1/ exclusively.

See Philosophy for the reasoning.

Base URLs#

Two equivalent ways to reach the compat layer:

text
1
2
https://openai.scailabs.ai/v1          (preferred — dedicated vhost)
https://scaigrid.scailabs.ai/oai/v1    (same routes on the main domain)

Both serve the exact same endpoints. openai.scailabs.ai exists so your configuration says base_url = "https://openai.scailabs.ai/v1" and looks like what the OpenAI SDK expects.

Using with the OpenAI Python SDK#

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from openai import OpenAI

client = OpenAI(
    base_url="https://openai.scailabs.ai/v1",
    api_key="sgk_your_scaigrid_key",  # your ScaiGrid API key, not an OpenAI key
)

response = client.chat.completions.create(
    model="scailabs/poolnoodle-omni",  # ScaiGrid model slug
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)

Everything works — streaming, tool calls, embeddings, images, audio. The SDK doesn't know it's not talking to OpenAI.

Using with the OpenAI Node SDK#

typescript
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://openai.scailabs.ai/v1",
  apiKey: process.env.SCAIGRID_API_KEY,
});

const response = await client.chat.completions.create({
  model: "scailabs/poolnoodle-omni",
  messages: [{ role: "user", content: "Hello!" }],
});
console.log(response.choices[0].message.content);

Supported endpoints#

OpenAI endpoint ScaiGrid compat Notes
POST /chat/completions Full support, including streaming and tool calls
GET /models Returns ScaiGrid frontend models with context_window, max_output_tokens extensions
GET /models/{id}
POST /embeddings
POST /images/generations
POST /audio/transcriptions
POST /audio/speech
POST /batches
GET /batches/{id}
POST /batches/{id}/cancel
POST /responses
GET /responses/{id}
POST /fine-tuning/jobs Via ScaiMind Use the native ScaiMind API, not compat
POST /files Via ScaiDrive or ScaiMatrix
POST /assistants Via ScaiCore Different mental model, no compat layer

Differences from real OpenAI#

Model names#

OpenAI uses model IDs like gpt-4, gpt-4o, gpt-3.5-turbo. ScaiGrid uses frontend model slugs like openai/gpt-4o, scailabs/poolnoodle-omni, anthropic/claude-opus. The slug tells routing which upstream to use.

python
1
2
3
4
5
6
7
8
# OpenAI-SDK style, targeting OpenAI directly
client.chat.completions.create(model="gpt-4o", ...)

# Same SDK, targeting ScaiGrid
client.chat.completions.create(model="openai/gpt-4o", ...)

# Or use a different provider entirely — same SDK
client.chat.completions.create(model="anthropic/claude-opus", ...)

List available models:

python
1
2
for m in client.models.list():
    print(m.id)

Extended fields on /models#

ScaiGrid adds fields OpenAI's response doesn't:

json
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "id": "scailabs/poolnoodle-omni",
  "object": "model",
  "created": 1713888000,
  "owned_by": "scaigrid",
  "display_name": "Poolnoodle Omni",
  "context_window": 256000,
  "max_output_tokens": 32768,
  "modality": "chat"
}

context_window, max_output_tokens, and modality are additive — OpenAI SDK users ignore them. Custom clients can use them for capacity planning.

Streaming error frames#

When a stream errors out mid-completion, the OpenAI-compat layer emits:

tsql
1
2
3
4
event: error
data: {"code": "BACKEND_ERROR", "message": "..."}

data: [DONE]

This differs from OpenAI's behavior (which silently truncates or returns a plain data: {"error": ...} line). If your client doesn't listen for the error event type, you'll still see [DONE] but miss the error details.

Most OpenAI SDKs handle this gracefully — they surface the error via the usual error callback. Custom SSE parsers may need updates.

Request IDs#

Every response has an x-scaigrid-request-id header. For support, quote this ID. The OpenAI SDK doesn't expose response headers by default — access them through the SDK's response object (varies by SDK version).

Authentication#

Always a ScaiGrid API key (sgk_) or ScaiGrid-issued JWT. Never pass an actual OpenAI key — it won't work, and you don't want to anyway, since ScaiGrid handles the upstream authentication.

Migrating a LangChain / LlamaIndex app#

Both libraries construct their LLM client with a base URL parameter. Point it at ScaiGrid:

LangChain:

python
1
2
3
4
5
6
7
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    base_url="https://openai.scailabs.ai/v1",
    api_key=os.environ["SCAIGRID_API_KEY"],
    model="scailabs/poolnoodle-omni",
)

LlamaIndex:

python
1
2
3
4
5
6
7
from llama_index.llms.openai import OpenAI

llm = OpenAI(
    api_base="https://openai.scailabs.ai/v1",
    api_key=os.environ["SCAIGRID_API_KEY"],
    model="scailabs/poolnoodle-omni",
)

Done. All downstream usage — agents, tools, RAG pipelines — inherits ScaiGrid's routing, accounting, and error handling.

What the compat layer does not give you#

  • Native ScaiGrid features. Structured sessions (/v1/sessions), rooms, persona management, bunker provisioning, skill bindings, checkpoint resolution — all live under /v1/modules/ and have no OpenAI equivalent.
  • Per-model ScaiGrid metadata in the SDK's type system. context_window etc. come through as extra fields the SDK doesn't type.
  • ScaiGrid error codes in the SDK's exception types. Errors show up as generic openai.APIError with ScaiGrid's message inside. Branch on the message or switch to native /v1/ endpoints if you need typed error handling.

What's next#

Updated 2026-05-18 15:01:29 View source (.md) rev 17