API Reference
The SolRouter API provides a unified, OpenAI-compatible interface for chat, completions, multimodal input, tool calling, streaming, and structured output.
Base URL
https://api.solrouter.io/ai
All examples on this page use that base URL.
Authentication
Authenticate every request with your SolRouter API key using the Authorization header:
Authorization: Bearer sr_your_api_key
Example request headers
POST /chat/completions HTTP/1.1
Host: api.solrouter.io
Authorization: Bearer sr_your_api_key
Content-Type: application/json
Accept: application/json
Example with curl
curl https://api.solrouter.io/ai/chat/completions \
-H "Authorization: Bearer $SOLROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o-mini",
"messages": [
{ "role": "user", "content": "Hello!" }
]
}'
API keys begin with the
sr_prefix and can be created from your account dashboard.
Endpoints
SolRouter currently exposes a unified AI gateway under /ai.
| Endpoint | Method | Purpose |
|---|---|---|
/chat/completions | POST | Multi-turn chat, system prompts, tool calling, multimodal requests, structured output |
/completions | POST | Legacy prompt-completion format for plain text generation |
/models | GET | Provider model catalogue and metadata |
/models/{id} | GET | Model-specific metadata, pricing, context length, modalities |
Most modern applications should use
/chat/completions.
POST /chat/completions
Creates a chat completion from a list of messages.
Request body
{
"model": "openai/gpt-4o-mini",
"messages": [
{
"role": "system",
"content": "You are a concise assistant."
},
{
"role": "user",
"content": "Explain how a context window works."
}
]
}
Full request schema
| Field | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Model ID in provider/model-name format |
messages | array | Yes | Conversation history |
stream | boolean | No | Enables SSE streaming |
max_tokens | number | No | Maximum output tokens |
max_completion_tokens | number | No | Alternative output cap used by some models |
temperature | number | No | Sampling temperature |
top_p | number | No | Nucleus sampling |
n | number | No | Number of completions to generate |
stop | string | string[] | No | Stop sequence(s) |
presence_penalty | number | No | Penalizes repeated topics |
frequency_penalty | number | No | Penalizes repeated tokens |
tools | array | No | Tool / function definitions |
tool_choice | string | object | No | Force or control tool selection |
response_format | object | No | Structured JSON output settings |
seed | number | No | Deterministic sampling hint where supported |
user | string | No | End-user identifier for tracing |
models | string[] | No | Fallback model chain |
route | string | No | Routing strategy such as fallback |
messages
messages is an ordered array of role/content objects.
Text-only example
[
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "Summarise this article." }
]
Multi-turn conversation
[
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "What is a transformer model?" },
{ "role": "assistant", "content": "A transformer is a neural network architecture..." },
{ "role": "user", "content": "Explain it in simpler terms." }
]
Message fields
| Field | Type | Required | Description |
|---|---|---|---|
role | string | Yes | One of system, user, assistant, tool |
content | string | array | Yes | Plain text or multimodal content blocks |
name | string | No | Optional participant name |
tool_call_id | string | Tool messages only | Associates tool output with a previous tool call |
Multimodal content blocks
For vision-capable models, content can be an array of typed blocks.
Example with image input
{
"model": "openai/gpt-4o",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "What is shown in this image?"
},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/chart.png"
}
}
]
}
]
}
Supported content block types
| Type | Description |
|---|---|
text | Plain text block |
image_url | Remote image URL or data URL |
input_audio | Audio input block where supported |
file | Document or file input where supported |
image_url object
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Public image URL or data URI |
detail | string | No | Optional image detail hint such as low, high, or auto where supported |
Tool calling
Tool calling lets the model request that your application execute a function.
Request with tool definitions
{
"model": "openai/gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "What's the weather in Berlin?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Returns the current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name"
}
},
"required": ["city"]
}
}
}
]
}
Tool call response fragment
{
"choices": [
{
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Berlin\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
]
}
Returning tool output
After executing the function, send the tool result back as a tool message:
{
"model": "openai/gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "What's the weather in Berlin?"
},
{
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Berlin\"}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call_123",
"content": "{\"temperature_c\":18,\"condition\":\"Cloudy\"}"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Returns the current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string" }
},
"required": ["city"]
}
}
}
]
}
Structured output
You can instruct the model to return machine-readable JSON.
json_object
{
"model": "openai/gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Return a JSON object with title and summary for this article."
}
],
"response_format": {
"type": "json_object"
}
}
json_schema
{
"model": "openai/gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "Extract invoice information."
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "invoice",
"schema": {
"type": "object",
"properties": {
"invoice_number": { "type": "string" },
"total": { "type": "number" },
"currency": { "type": "string" }
},
"required": ["invoice_number", "total", "currency"],
"additionalProperties": false
}
}
}
}
Streaming
Enable streaming with:
{
"stream": true
}
Example request
curl https://api.solrouter.io/ai/chat/completions \
-H "Authorization: Bearer $SOLROUTER_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"model": "openai/gpt-4o-mini",
"stream": true,
"messages": [
{ "role": "user", "content": "Write a haiku about latency." }
]
}'
Example SSE response
data: {"id":"chatcmpl_1","object":"chat.completion.chunk","choices":[{"delta":{"role":"assistant","content":"Low"},"index":0}]}
data: {"id":"chatcmpl_1","object":"chat.completion.chunk","choices":[{"delta":{"content":" ping whispers"},"index":0}]}
data: {"id":"chatcmpl_1","object":"chat.completion.chunk","choices":[{"delta":{"content":" through the wire"},"index":0}]}
data: {"id":"chatcmpl_1","object":"chat.completion.chunk","choices":[{"delta":{},"finish_reason":"stop","index":0}],"usage":{"prompt_tokens":18,"completion_tokens":10,"total_tokens":28,"cost":0.0000042}}
data: [DONE]
When streaming is enabled, SolRouter appends usage information to the final chunk when supported by the selected model.
Successful response format
Standard non-streaming response
{
"id": "chatcmpl_abc123",
"object": "chat.completion",
"created": 1710000000,
"model": "openai/gpt-4o-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "A context window is the amount of text a model can consider at once."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 19,
"total_tokens": 43,
"cost": 0.0000123
}
}
Response fields
| Field | Type | Description |
|---|---|---|
id | string | Unique completion ID |
object | string | Object type such as chat.completion |
created | number | Unix timestamp |
model | string | Final model used for the request |
choices | array | Returned completion candidates |
usage | object | Token usage and cost information |
choices[]
| Field | Type | Description |
|---|---|---|
index | number | Choice index |
message | object | Assistant message |
finish_reason | string | null | Reason generation stopped |
Common finish_reason values
| Value | Meaning |
|---|---|
stop | Natural completion or stop sequence reached |
length | Hit output token limit |
tool_calls | Model wants a tool/function to be executed |
content_filter | Filter or safety system interrupted generation |
null | Streaming still in progress |
Usage and billing
Every response may include a usage object with:
| Field | Type | Description |
|---|---|---|
prompt_tokens | number | Input tokens counted for billing |
completion_tokens | number | Output tokens counted for billing |
total_tokens | number | Sum of prompt and completion tokens |
cost | number | Total billed USD amount for the request |
Example
{
"usage": {
"prompt_tokens": 312,
"completion_tokens": 87,
"total_tokens": 399,
"cost": 0.0000148
}
}
Free models may still return token counts while
costis0.
POST /completions
This endpoint supports the legacy prompt-completion format.
Example request
{
"model": "openai/gpt-3.5-turbo-instruct",
"prompt": "Write a short tagline for a fast API router.",
"max_tokens": 32,
"temperature": 0.7
}
Example response
{
"id": "cmpl_123",
"object": "text_completion",
"created": 1710000000,
"model": "openai/gpt-3.5-turbo-instruct",
"choices": [
{
"text": "One endpoint. Every model. Built for speed.",
"index": 0,
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 11,
"completion_tokens": 10,
"total_tokens": 21,
"cost": 0.0000031
}
}
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Completion-capable model |
prompt | string | string[] | Yes | Plain text prompt |
max_tokens | number | No | Maximum generated tokens |
temperature | number | No | Sampling temperature |
top_p | number | No | Nucleus sampling |
n | number | No | Number of completions |
stream | boolean | No | Stream output |
stop | string | string[] | No | Stop sequences |
presence_penalty | number | No | Topic repetition penalty |
frequency_penalty | number | No | Token repetition penalty |
GET /models
Returns the model catalogue currently available through SolRouter.
Example request
curl https://api.solrouter.io/ai/models \
-H "Authorization: Bearer $SOLROUTER_API_KEY"
Example response
{
"data": [
{
"id": "openai/gpt-4o-mini",
"name": "GPT-4o Mini",
"context_length": 128000,
"pricing": {
"prompt": "0.15",
"completion": "0.60"
},
"modalities": {
"input": ["text", "image"],
"output": ["text"]
}
}
]
}
Common model fields
| Field | Type | Description |
|---|---|---|
id | string | Unique model ID |
name | string | Human-readable display name |
context_length | number | Maximum supported context |
pricing | object | Input/output pricing |
modalities | object | Supported input/output modalities |
description | string | Model summary |
top_provider | object | Upstream provider metadata |
architecture | object | Tokenizer and modality metadata |
per_request_limits | object | Maximum completion or request constraints |
canonical_slug | string | Stable slug if available |
is_free | boolean | Indicates free-tier models |
expiration_date | string | null | Retirement date when applicable |
GET /models/{id}
Returns metadata for a specific model.
Example request
curl https://api.solrouter.io/ai/models/openai%2Fgpt-4o-mini \
-H "Authorization: Bearer $SOLROUTER_API_KEY"
Example response
{
"id": "openai/gpt-4o-mini",
"name": "GPT-4o Mini",
"context_length": 128000,
"pricing": {
"prompt": "0.15",
"completion": "0.60"
},
"modalities": {
"input": ["text", "image"],
"output": ["text"]
},
"description": "Fast, low-cost multimodal model."
}
Error format
When a request fails, the API returns a JSON error body.
Example error response
{
"error": {
"message": "insufficient balance — please top up to use paid models",
"type": "payment_required",
"code": "insufficient_balance"
}
}
Common status codes
| Status | Meaning |
|---|---|
400 | Invalid request payload |
401 | Missing or invalid API key |
402 | Insufficient balance for paid model |
404 | Unknown endpoint or unavailable model |
408 | Upstream timeout |
409 | Request conflict |
422 | Validation error |
429 | Rate limited |
500 | Internal server error |
502 | Upstream provider unavailable |
503 | Temporary service outage |
Common error codes
| Code | Meaning |
|---|---|
invalid_api_key | API key is malformed or revoked |
insufficient_balance | Account has no credit for selected model |
context_length_exceeded | Request exceeds model context window |
rate_limit_exceeded | Too many requests in a short interval |
model_not_found | Unknown or retired model ID |
invalid_request_error | Payload is malformed or unsupported |
upstream_unreachable | SolRouter could not reach the selected provider |
Complete examples
TypeScript / JavaScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.solrouter.io/ai",
apiKey: process.env.SOLROUTER_API_KEY,
});
const completion = await client.chat.completions.create({
model: "openai/gpt-4o-mini",
messages: [
{ role: "system", content: "You are a concise assistant." },
{ role: "user", content: "Write a one-sentence summary of API gateways." },
],
});
console.log(completion.choices[0].message.content);
console.log(completion.usage);
Python
from openai import OpenAI
import os
client = OpenAI(
base_url="https://api.solrouter.io/ai",
api_key=os.environ["SOLROUTER_API_KEY"],
)
completion = client.chat.completions.create(
model="openai/gpt-4o-mini",
messages=[
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Write a one-sentence summary of API gateways."},
],
)
print(completion.choices[0].message.content)
print(completion.usage)
fetch
const response = await fetch("https://api.solrouter.io/ai/chat/completions", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SOLROUTER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "anthropic/claude-sonnet-4",
messages: [
{ role: "user", content: "Explain what tool calling is." },
],
}),
});
const data = await response.json();
console.log(data);
Next steps
- Streaming — SSE response handling and UI patterns
- Tool Calling — function execution flow in detail
- Structured Output — JSON objects and JSON schema enforcement
- Vision & Multimodal — image and file input formats
- Errors — retry strategy, rate limits, and operational guidance