Add an API Key
Log in at platform.opper.ai and create an API key. Each key is tied to a project — we recommend creating a new project per application or environment.Set it as an environment variable:
export OPPER_API_KEY="your-api-key"
Select API
Choose which API format to use. All options route through Opper with full observability.Or use a compatible API — all routes add observability, virtual keys, and model routing:
Opper Multimodal API
Recommended. Built for agents and AI-native applications. Specify tasks, not prompts — 200+ models, all modalities.
OpenAI
Use the Responses and Chat Completions endpoints
Anthropic
Use the Messages endpoint
Gemini
Use the Generate Content endpoint
Opper Multimodal API
A declarative API built for agents and AI-native applications. Specify tasks, not prompts — the platform handles execution across 200+ models and all modalities with built-in observability, fallbacks, and structured output.- Text
- Streaming
- Structured
- Chat
- Tools
- Image
- Audio
- Embeddings
- Realtime
The simplest way to call a model — pass a string in, get a string back.
curl -X POST https://api.opper.ai/v3/call \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPPER_API_KEY}" \
-d '{
"name": "respond",
"instructions": "Respond in Swedish",
"input": "What are the benefits of using an AI gateway?"
}'
Example output
{
"data": "En AI-gateway ger en enda integrationspunkt för flera modeller, med fördelar som automatisk failover, lastbalansering, enhetlig loggning och möjligheten att byta leverantör utan kodändringar.",
"meta": {
"function_name": "respond",
"execution_ms": 486,
"models_used": ["openai/gpt-4.1-nano"],
"usage": { "input_tokens": 26, "output_tokens": 293 }
}
}
Same as text, but stream the response token by token.
curl -X POST https://api.opper.ai/v3/call/stream \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPPER_API_KEY}" \
-d '{
"name": "respond",
"instructions": "Respond in Swedish",
"input": "What are the benefits of using an AI gateway?"
}'
Example output (streamed)
data: {"delta": "En AI"}
data: {"delta": "-gateway"}
data: {"delta": " ger en"}
data: {"delta": " enda integrationspunkt"}
data: {"delta": " för flera"}
data: {"delta": " modeller..."}
data: [DONE]
Use input and output schemas to get structured, typed responses.
curl -X POST https://api.opper.ai/v3/call \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPPER_API_KEY}" \
-d '{
"name": "analyze-sentiment",
"instructions": "Analyze the sentiment of the given text",
"input": {"text": "The product launch exceeded all expectations!"},
"input_schema": {
"type": "object",
"properties": {
"text": { "type": "string" }
},
"required": ["text"]
},
"output_schema": {
"type": "object",
"properties": {
"sentiment": { "type": "string" },
"confidence": { "type": "number" },
"reasoning": { "type": "string" }
},
"required": ["sentiment", "confidence", "reasoning"]
}
}'
Example output
{
"data": {
"sentiment": "positive",
"confidence": 0.95,
"reasoning": "The phrase 'exceeded all expectations' strongly indicates a positive sentiment about the product launch."
},
"meta": {
"function_name": "analyze-sentiment",
"execution_ms": 512,
"models_used": ["openai/gpt-4.1-nano"],
"usage": { "input_tokens": 32, "output_tokens": 28 }
}
}
Pass a conversation history to maintain context across multiple turns.
curl -X POST https://api.opper.ai/v3/call \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPPER_API_KEY}" \
-d '{
"name": "chat",
"instructions": "You are a helpful assistant",
"input": {
"messages": [
{"role": "user", "content": "What is the best way to handle retries?"},
{"role": "assistant", "content": "Exponential backoff is a common approach."},
{"role": "user", "content": "Can you show me a simple example?"}
]
},
"input_schema": {
"type": "object",
"properties": {
"messages": {
"type": "array",
"items": {
"type": "object",
"properties": {
"role": {"type": "string"},
"content": {"type": "string"}
},
"required": ["role", "content"]
}
}
},
"required": ["messages"]
},
"output_schema": {
"type": "object",
"properties": {
"reply": {"type": "string"},
"topic": {"type": "string"}
},
"required": ["reply", "topic"]
}
}'
Example output
{
"data": {
"reply": "Here's a simple retry example with exponential backoff: start with a 1-second delay, then double it after each failure (1s, 2s, 4s, 8s), with a maximum of 5 retries.",
"topic": "retry-patterns"
},
"meta": {
"function_name": "chat",
"execution_ms": 743,
"models_used": ["openai/gpt-4.1-nano"],
"usage": { "input_tokens": 58, "output_tokens": 45 }
}
}
Supply tool definitions in the input schema and let the model decide when to call them.
curl -X POST https://api.opper.ai/v3/call \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPPER_API_KEY}" \
-d '{
"name": "agent-round",
"instructions": "Use the available tools to help the user",
"input": {
"message": "What is the weather in Stockholm?",
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string" }
},
"required": ["location"]
}
}
]
},
"input_schema": {
"type": "object",
"properties": {
"message": { "type": "string" },
"tools": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"description": { "type": "string" },
"parameters": { "type": "object" }
},
"required": ["name", "description"]
}
}
},
"required": ["message", "tools"]
},
"output_schema": {
"type": "object",
"properties": {
"message": { "type": "string" },
"tool_call": {
"type": "object",
"properties": {
"name": { "type": "string" },
"arguments": { "type": "object" }
},
"required": ["name", "arguments"]
}
}
}
}'
Example output
{
"data": {
"message": "I'll check the weather in Stockholm for you.",
"tool_call": {
"name": "get_weather",
"arguments": {
"location": "Stockholm"
}
}
},
"meta": {
"function_name": "agent-round",
"execution_ms": 1149,
"models_used": ["openai/gpt-4.1-nano"],
"usage": { "input_tokens": 51, "output_tokens": 17 }
}
}
Generate images by specifying an image model and a base64-encoded output field.
curl -X POST https://api.opper.ai/v3/call \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPPER_API_KEY}" \
-d '{
"name": "generate-image",
"instructions": "Generate an image based on the description",
"input": {"description": "A serene mountain landscape at sunset"},
"input_schema": {
"type": "object",
"properties": {
"description": { "type": "string" }
},
"required": ["description"]
},
"output_schema": {
"type": "object",
"properties": {
"image": {
"type": "string",
"contentMediaType": "image/png",
"contentEncoding": "base64"
}
},
"required": ["image"]
}
}'
Example output
{
"data": {
"image": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA..."
},
"meta": {
"function_name": "generate-image",
"execution_ms": 8240,
"models_used": ["openai/gpt-image-1"],
"usage": { "input_tokens": 18, "output_tokens": 0 }
}
}
This example takes audio in, summarizes it as text, and narrates the summary back as audio.
curl -X POST https://api.opper.ai/v3/call \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPPER_API_KEY}" \
-d '{
"name": "audio-summarize",
"instructions": "Listen to the audio and provide a text summary and an audio narration of the summary",
"input": {
"audio": "<base64-encoded-audio>"
},
"input_schema": {
"type": "object",
"properties": {
"audio": {
"type": "string",
"contentMediaType": "audio/wav",
"contentEncoding": "base64"
}
},
"required": ["audio"]
},
"output_schema": {
"type": "object",
"properties": {
"summary": { "type": "string" },
"audio_summary": {
"type": "string",
"contentMediaType": "audio/wav",
"contentEncoding": "base64"
}
},
"required": ["summary", "audio_summary"]
}
}'
Example output
{
"data": {
"summary": "A brief introductory statement announcing a test of audio processing.",
"audio_summary": "UklGRgAABQBXQVZFZm10IBAAAA..."
},
"meta": {
"function_name": "audio-summarize",
"execution_ms": 2150,
"models_used": ["openai/gpt-4o-audio-preview"],
"usage": { "input_tokens": 120, "output_tokens": 85 }
}
}
Generate embedding vectors for semantic search and similarity tasks.
curl -X POST https://api.opper.ai/v3/call \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPPER_API_KEY}" \
-d '{
"name": "embed-text",
"instructions": "Generate an embedding vector for the input text",
"input": {"text": "The benefits of using an AI gateway"},
"input_schema": {
"type": "object",
"properties": {
"text": { "type": "string" }
},
"required": ["text"]
},
"output_schema": {
"type": "object",
"properties": {
"embedding": {
"type": "array",
"items": { "type": "number" },
"description": "The embedding vector"
}
},
"required": ["embedding"]
}
}'
Example output
{
"data": {
"embedding": [0.0023, -0.0121, 0.0456, -0.0012, 0.0789, "..."]
},
"meta": {
"function_name": "embed-text",
"execution_ms": 134,
"models_used": ["openai/text-embedding-3-small"],
"usage": { "input_tokens": 8, "output_tokens": 0 }
}
}
Bidirectional voice and audio over WebSocket — ideal for voice agents and conversational interfaces.Step 1. Create a function with instructions for the voice session:Step 2. Connect to the real-time voice session via WebSocket:Step 3. Send and receive audio frames over the connection:
cURL
curl -X POST https://api.opper.ai/v3/call \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPPER_API_KEY}" \
-d '{
"name": "pizza-agent",
"instructions": "You are a pizza ordering assistant. Help customers browse the menu and place orders."
}'
WebSocket
wscat -c "wss://api.opper.ai/v3/realtime/pizza-agent" \
-H "Authorization: Bearer ${OPPER_API_KEY}"
Send audio
{"type": "audio", "data": "<base64-encoded-audio-chunk>"}
Receive audio
{"type": "audio", "data": "<base64-encoded-audio-response>"}
Where are the SDKs?
Updated Python and Node SDKs for the v3 API are coming soon. In the meantime, you can use the API directly via cURL or any HTTP client. The previous platform version SDKs are still available:OpenAI Compatible
Use the OpenAI SDK pointed at Opper’s compatible endpoint. Adds observability, virtual keys, and model routing to every call.pip install openai
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.opper.ai/v3/compat",
api_key=os.getenv("OPPER_API_KEY"),
)
response = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[
{"role": "user", "content": "Hi there!"}
],
)
print(response.choices[0].message.content)
Anthropic Compatible
Use the Anthropic SDK pointed at Opper’s Messages endpoint. Adds observability, virtual keys, and model routing to every call.pip install anthropic
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://api.opper.ai/v3/compat",
api_key=os.getenv("OPPER_API_KEY"),
)
message = client.messages.create(
model="anthropic/claude-sonnet-4.5",
max_tokens=1024,
messages=[
{"role": "user", "content": "Hi there!"}
],
)
print(message.content[0].text)
Gemini Compatible
Use the Google GenAI SDK pointed at Opper’s Interactions endpoint. Adds observability, virtual keys, and model routing to every call.pip install google-genai
import os
from google import genai
client = genai.Client(
api_key=os.getenv("OPPER_API_KEY"),
http_options={"base_url": "https://api.opper.ai/v3/compat"},
)
response = client.models.generate_content(
model="gcp/gemini-2.5-flash-eu",
contents="Hi there!",
)
print(response.text)