SDK Compatibility

ModelRelay provides drop-in compatibility endpoints for the OpenAI and Anthropic APIs. If you have existing code using these providers’ SDKs, you can point them at ModelRelay with a base URL change to get unified billing, observability, and access to any model.

Why Use Compatibility Endpoints?

  • Minimal code changes - Point existing code at ModelRelay with a base URL change
  • Unified billing - Track usage across all providers through ModelRelay
  • Provider flexibility - Use any model through the same API interface
  • Gradual migration - Move to ModelRelay without rewriting your application

OpenAI Responses API

Endpoint: POST /v1/responses

Point the OpenAI SDK at ModelRelay by changing the base URL and using your ModelRelay API key.

Configuration

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.MODELRELAY_API_KEY,
  baseURL: "https://api.modelrelay.ai/v1",
});

const response = await client.responses.create({
  model: "claude-sonnet-4-5", // Use any ModelRelay model
  input: "What is the capital of France?",
});

console.log(response.output_text);
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["MODELRELAY_API_KEY"],
    base_url="https://api.modelrelay.ai/v1",
)

response = client.responses.create(
    model="claude-sonnet-4-5",  # Use any ModelRelay model
    input="What is the capital of France?",
)

print(response.output_text)
curl -X POST https://api.modelrelay.ai/v1/responses \
  -H "Authorization: Bearer $MODELRELAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "input": "What is the capital of France?"
  }'

Streaming

Enable streaming by setting stream: true:

const stream = await client.responses.create({
  model: "claude-sonnet-4-5",
  input: "Write a haiku about programming.",
  stream: true,
});

for await (const event of stream) {
  if (event.type === "response.output_text.delta") {
    process.stdout.write(event.delta);
  }
}
stream = client.responses.create(
    model="claude-sonnet-4-5",
    input="Write a haiku about programming.",
    stream=True,
)

for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)

Authentication

Use Authorization: Bearer <mr_sk_...> with your ModelRelay secret key. The compatibility layer maps this to X-ModelRelay-Api-Key internally.

Field Mapping

OpenAI Field ModelRelay Behavior
model Passed through to ModelRelay
input String or array of messages
instructions Mapped to system message
stream Enables SSE streaming
tools Passed through
tool_choice Passed through

Anthropic Messages API

Endpoint: POST /v1/messages

Point the Anthropic SDK at ModelRelay by changing the base URL and using your ModelRelay API key.

Configuration

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

const client = new Anthropic({
  apiKey: process.env.MODELRELAY_API_KEY,
  baseURL: "https://api.modelrelay.ai/v1",
});

const message = await client.messages.create({
  model: "claude-sonnet-4-5",
  max_tokens: 1024,
  messages: [
    { role: "user", content: "What is the capital of France?" }
  ],
});

console.log(message.content[0].text);
import os
import anthropic

client = anthropic.Anthropic(
    api_key=os.environ["MODELRELAY_API_KEY"],
    base_url="https://api.modelrelay.ai/v1",
)

message = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "What is the capital of France?"}
    ],
)

print(message.content[0].text)
curl -X POST https://api.modelrelay.ai/v1/messages \
  -H "x-api-key: $MODELRELAY_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 1024,
    "messages": [
      {"role": "user", "content": "What is the capital of France?"}
    ]
  }'

Streaming

Enable streaming by setting stream: true:

const stream = await client.messages.stream({
  model: "claude-sonnet-4-5",
  max_tokens: 1024,
  messages: [
    { role: "user", content: "Write a haiku about programming." }
  ],
});

for await (const event of stream) {
  if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
    process.stdout.write(event.delta.text);
  }
}
with client.messages.stream(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    messages=[
        {"role": "user", "content": "Write a haiku about programming."}
    ],
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

Authentication

The Anthropic compatibility endpoint supports two authentication styles:

  • x-api-key: <mr_sk_...> - Anthropic SDK default
  • Authorization: Bearer <mr_sk_...> - Alternative style

Both are mapped to X-ModelRelay-Api-Key internally.

Field Mapping

Anthropic Field ModelRelay Behavior
model Passed through to ModelRelay
messages Converted to ModelRelay format
system Mapped to system message
max_tokens Required, passed through
temperature Passed through
stop_sequences Passed through
tools Converted to ModelRelay tool format
tool_choice Passed through
stream Enables SSE streaming

Content Block Types

The Anthropic adapter supports all standard content block types:

Type Description
text Plain text content
image Base64-encoded images
tool_use Tool call from assistant
tool_result Tool execution result

Model Flexibility

The compatibility endpoints allow you to use any model available in ModelRelay, not just models from the corresponding provider:

// Use OpenAI SDK to call an Anthropic model
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.MODELRELAY_API_KEY,
  baseURL: "https://api.modelrelay.ai/v1",
});

await client.responses.create({
  model: "claude-opus-4-5", // Anthropic model via OpenAI API format
  input: "Hello!",
});
// Use Anthropic SDK to call an OpenAI model
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  apiKey: process.env.MODELRELAY_API_KEY,
  baseURL: "https://api.modelrelay.ai/v1",
});

await client.messages.create({
  model: "gpt-5.2", // OpenAI model via Anthropic API format
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello!" }],
});

Error Handling

Errors are returned in the format expected by each API:

OpenAI Format

{
  "error": {
    "message": "Invalid API key",
    "type": "authentication_error",
    "code": "invalid_api_key"
  }
}

Anthropic Format

{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key"
  }
}

Limitations

The compatibility endpoints provide high-fidelity API translation, but some provider-specific features may not be available:

  • Anthropic caching - cache_control blocks are not supported
  • Provider-specific extensions - Custom headers or fields may be ignored
  • Batch endpoints - Use ModelRelay’s native /responses/batch instead

For full access to ModelRelay features like state handles, built-in tools, and workflows, use the ModelRelay SDK or native API.

Next Steps