01Overview
One gateway, three dialects, one API key. Point an existing OpenAI or Anthropic client at Weatmood and every model in the catalogue becomes available without touching your code.
/v1/chat/completions, /chat/completions and /openai/v1/chat/completions all reach the same endpoint, so a misconfigured base URL still works.02Quick start
Create a key in the dashboard, then send your first request. Everything below is copy-paste ready.
curl https://weatmood.ru/v1/chat/completions \
-H "Authorization: Bearer $WEATMOOD_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"messages": [{"role": "user", "content": "Hello!"}]
}'
from openai import OpenAI
client = OpenAI(
api_key="wm-xxxxxxxxxxxxxxxxxxxxxxxx",
base_url="https://weatmood.ru/v1",
)
r = client.chat.completions.create(
model="gpt-5.6-sol",
messages=[{"role": "user", "content": "Hello!"}],
)
print(r.choices[0].message.content)
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "wm-xxxxxxxxxxxxxxxxxxxxxxxx",
baseURL: "https://weatmood.ru/v1",
});
const r = await client.chat.completions.create({
model: "gpt-5.6-sol",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(r.choices[0].message.content);
03Authentication
Send your key as a Bearer token, or as x-api-key when using the Anthropic dialect. Keys carry a name, an optional token limit, an expiry date, their own RPM ceiling and an active switch.
Authorization: Bearer wm-xxxxxxxxxxxxxxxxxxxxxxxx
x-api-key: wm-xxxxxxxxxxxxxxxxxxxxxxxx # Anthropic style
anthropic-version: 2023-06-01
04Chat completions
The OpenAI Chat Completions contract. Standard parameters are forwarded upstream unchanged.
Response
{
"id": "chatcmpl-...",
"object": "chat.completion",
"model": "gpt-5.6-sol",
"system_fingerprint": "fp_f9845bfb4812",
"service_tier": "priority",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "Hi there!",
"refusal": null,
"annotations": []
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 9,
"completion_tokens": 4,
"total_tokens": 13,
"prompt_tokens_details": {"cached_tokens": 0},
"completion_tokens_details": {"reasoning_tokens": 0}
}
}
05Streaming
Set "stream": true to receive incremental chunks over SSE, closed by data: [DONE]. Tool calls stream too. Anthropic streams additionally carry named event: lines, exactly as the official SDK expects.
data: {"choices":[{"delta":{"role":"assistant","content":""},"finish_reason":null}]}
data: {"choices":[{"delta":{"content":"Hi"},"finish_reason":null}]}
data: {"choices":[{"delta":{"content":" there"},"finish_reason":null}]}
data: {"choices":[{"delta":{},"finish_reason":"stop"}]}
data: [DONE]
06Anthropic API
Native Anthropic Messages requests are accepted and answered in the same shape: content blocks, stop_reason, tool_use. The dialect is detected from the body, so an Anthropic payload works on the OpenAI endpoint as well, and the other way round.
curl https://weatmood.ru/v1/messages \
-H "x-api-key: $WEATMOOD_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-5",
"max_tokens": 256,
"system": "You are concise.",
"messages": [{"role": "user", "content": "Hello!"}]
}'
07Responses API
The newer OpenAI Responses format. Use input and instructions; the reply carries output items plus a flattened output_text.
curl https://weatmood.ru/v1/responses \
-H "Authorization: Bearer $WEATMOOD_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-sol",
"instructions": "Answer in one word.",
"input": "Capital of France?",
"max_output_tokens": 32
}'
/v1/chat/completions with "stream": true.08Tool calling
Function calling works in both dialects and is translated automatically: OpenAI tools and tool_calls become Anthropic tools and tool_use, and tool results map back. Multi-turn loops are supported.
{
"model": "gpt-5.6-sol",
"messages": [{"role": "user", "content": "Weather in Paris?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}],
"tool_choice": "auto"
}
Returning the result
"messages": [
{"role": "user", "content": "Weather in Paris?"},
{"role": "assistant", "tool_calls": [{
"id": "call_1", "type": "function",
"function": {"name": "get_weather", "arguments": "{\"city\":\"Paris\"}"}
}]},
{"role": "tool", "tool_call_id": "call_1", "content": "15C, sunny"}
]
09Images and PDF
Attach images and PDF documents as content parts. Several spellings are accepted — data URLs, bare base64, image_url, file and input_file — and normalised before the request reaches the model.
{
"model": "gpt-5.6-sol",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Summarise this document"},
{"type": "file", "file": {
"filename": "report.pdf",
"file_data": "data:application/pdf;base64,JVBERi0xLjQK..."
}}
]
}]
}
{
"model": "gpt-5.6-sol",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "What is on this picture?"},
{"type": "image_url", "image_url": {
"url": "data:image/png;base64,iVBORw0KGgo..."
}}
]
}]
}
{
"model": "claude-opus-5",
"max_tokens": 512,
"messages": [{
"role": "user",
"content": [
{"type": "document", "source": {
"type": "base64",
"media_type": "application/pdf",
"data": "JVBERi0xLjQK..."
}},
{"type": "text", "text": "Summarise this document"}
]
}]
}
10Prompt caching
When the provider serves part of your prompt from its cache, those tokens are free. They are excluded from billing and from your plan quota, so repeating a long system prompt costs almost nothing.
"usage": {
"prompt_tokens": 2013,
"completion_tokens": 4,
"prompt_tokens_details": {"cached_tokens": 2004}
}
11Models
Use the model ID exactly as shown. This table is live — it is loaded from the catalogue endpoint.
12OpenCode
Register Weatmood as an OpenAI-compatible provider in ~/.config/opencode/opencode.json.
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"weatmood": {
"npm": "@ai-sdk/openai-compatible",
"name": "Weatmood",
"options": {
"baseURL": "https://weatmood.ru/v1",
"apiKey": "wm-xxxxxxxxxxxxxxxxxxxxxxxx"
},
"models": {
"gpt-5.6-sol": { "name": "GPT 5.6 Sol" },
"gpt-5.6-terra": { "name": "GPT 5.6 Terra" },
"claude-opus-5": { "name": "Claude Opus 5" },
"gemini-3.1-pro-preview": { "name": "Gemini 3.1 Pro" }
}
}
},
"model": "weatmood/gpt-5.6-sol"
}
/model inside OpenCode, or keep the default from the model field.13Claude Code
Claude Code speaks the Anthropic dialect, which the gateway serves natively. Point it at Weatmood with environment variables or a settings file.
export ANTHROPIC_BASE_URL="https://weatmood.ru"
export ANTHROPIC_AUTH_TOKEN="wm-xxxxxxxxxxxxxxxxxxxxxxxx"
export ANTHROPIC_MODEL="claude-opus-5"
export ANTHROPIC_SMALL_FAST_MODEL="claude-sonnet-5"
claude
$env:ANTHROPIC_BASE_URL = "https://weatmood.ru"
$env:ANTHROPIC_AUTH_TOKEN = "wm-xxxxxxxxxxxxxxxxxxxxxxxx"
$env:ANTHROPIC_MODEL = "claude-opus-5"
$env:ANTHROPIC_SMALL_FAST_MODEL = "claude-sonnet-5"
claude
{
"env": {
"ANTHROPIC_BASE_URL": "https://weatmood.ru",
"ANTHROPIC_AUTH_TOKEN": "wm-xxxxxxxxxxxxxxxxxxxxxxxx",
"ANTHROPIC_MODEL": "claude-opus-5",
"ANTHROPIC_SMALL_FAST_MODEL": "claude-sonnet-5"
}
}
/v1 — Claude Code appends it itself. Adding it twice is handled, but the clean form is preferred.14SDKs
Official SDKs work unchanged — only the base URL differs.
from openai import OpenAI
client = OpenAI(api_key="wm-...", base_url="https://weatmood.ru/v1")
r = client.chat.completions.create(
model="gpt-5.6-sol",
messages=[{"role": "user", "content": "Hello!"}],
stream=True,
)
for chunk in r:
print(chunk.choices[0].delta.content or "", end="")
from anthropic import Anthropic
client = Anthropic(api_key="wm-...", base_url="https://weatmood.ru")
msg = client.messages.create(
model="claude-opus-5",
max_tokens=256,
messages=[{"role": "user", "content": "Hello!"}],
)
print(msg.content[0].text)
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-5.6-sol",
api_key="wm-...",
base_url="https://weatmood.ru/v1",
)
print(llm.invoke("Hello!").content)
15Plans and limits
Every account sits on a plan. Three token windows run at the same time and the first one to fill pauses requests until it slides. Each plan also sets a requests-per-minute ceiling.
Unlimited pass
An hourly pass lifts all three windows for its duration and raises RPM. Your plan stays intact underneath and returns untouched when the pass expires — tokens spent under the pass never count against it.
{
"error": {
"message": "5-hour token limit reached for plan 'Start'. Resets at 2026-08-05 18:42:00 UTC (in 37 min).",
"type": "rate_limit_error",
"code": 429
}
}
16Account API
Gateway routes authenticate with your API key. Account routes are used by the dashboard and rely on the browser session.
17Error codes
Errors mirror the dialect you called: an error object for OpenAI, a type: error envelope for Anthropic. The upstream provider is never revealed.