weatmood
dashboard
API reference

Build on one gateway.

OpenAI, Anthropic and Responses formats behind a single base URL and one API key. Bring the SDK you already use — nothing else has to change.

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.

OpenAIchat
POST /v1/chat/completions
Anthropicmessages
POST /v1/messages
Responsesbeta
POST /v1/responses
The path prefix is forgiving: /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.

bash
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!"}]
  }'
python
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)
javascript
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.

http
Authorization: Bearer wm-xxxxxxxxxxxxxxxxxxxxxxxx

x-api-key: wm-xxxxxxxxxxxxxxxxxxxxxxxx      # Anthropic style
anthropic-version: 2023-06-01
A request is rejected when the key is inactive, expired, past its token limit, or the plan quota is exhausted.

04Chat completions

POSThttps://weatmood.ru/v1/chat/completions

The OpenAI Chat Completions contract. Standard parameters are forwarded upstream unchanged.

paramtypedescription
modelstringModel ID from the catalogue.
messagesarrayRole and content message objects.
streambooleanStream tokens via server-sent events.
max_tokensintegerMaximum tokens to generate.
temperaturenumberSampling temperature.
toolsarrayFunction definitions for tool calling.
tool_choicestring | objectauto, required, none, or a named function.
response_formatobjectUse json_object for structured output.

Response

json
{
  "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.

sse
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

POSThttps://weatmood.ru/v1/messages

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.

bash
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

POSThttps://weatmood.ru/v1/responses

The newer OpenAI Responses format. Use input and instructions; the reply carries output items plus a flattened output_text.

bash
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
  }'
Streaming is not supported on this endpoint yet — use /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.

json
{
  "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

json
"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.

json
{
  "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..."
      }}
    ]
  }]
}
json
{
  "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..."
      }}
    ]
  }]
}
json
{
  "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"}
    ]
  }]
}
Multimodal capability depends on the model — check the catalogue below before sending files.

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.

json
"usage": {
  "prompt_tokens": 2013,
  "completion_tokens": 4,
  "prompt_tokens_details": {"cached_tokens": 2004}
}
Billed and counted: 2013 - 2004 + 4 = 13 tokens instead of 2017. Cached volume and the amount it saved are shown in your dashboard under Statistics.

11Models

GEThttps://weatmood.ru/v1/models

Use the model ID exactly as shown. This table is live — it is loaded from the catalogue endpoint.

model idcontextmax output
Every model costs the same against your plan quota — there is no per-model price. See Plans and limits below, or the pricing page for the full table.

12OpenCode

Register Weatmood as an OpenAI-compatible provider in ~/.config/opencode/opencode.json.

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"
}
Switch models with /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.

bash
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
powershell
$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
json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://weatmood.ru",
    "ANTHROPIC_AUTH_TOKEN": "wm-xxxxxxxxxxxxxxxxxxxxxxxx",
    "ANTHROPIC_MODEL": "claude-opus-5",
    "ANTHROPIC_SMALL_FAST_MODEL": "claude-sonnet-5"
  }
}
The base URL here has no /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.

python
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="")
python
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)
python
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.

windowbehaviour
5 hoursShort burst limit, refills continuously.
7 daysWeekly ceiling.
30 daysMonthly ceiling, sized so the weekly one stays usable all month.

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.

json
{
  "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.

endpointdescription
GET /v1/modelsModel catalogue.
GET /healthGateway health probe, no auth.
GET /api/plansPlans, unlimited pricing, top-up limits.
GET /api/user/subscriptionCurrent plan, quota windows, active pass.
GET /api/user/usageTotals, per-model breakdown, request log.
GET /api/user/usage-chartPer-day input, output and cached tokens.
GET /api/user/keysList and manage API keys.

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.

codemeaning
400Malformed request body.
401Missing or invalid API key.
402Balance empty, top up to continue.
403Key inactive, expired, or over limit.
404Unknown model ID.
429Rate limit or token window exhausted.
5xxUpstream provider error.