OhMyGPT

Messages

Call Claude, and any other chat model, through the Anthropic Messages protocol.

POST /v1/messages speaks the Anthropic Messages protocol. Use it for Claude with the Anthropic SDKs and Claude Code, and for every other chat model in the catalog, which answers with the same content blocks. The full schema is in the endpoint reference.

EndpointPOST https://api.ohmygpt.com/v1/messages
SDK base URLhttps://api.ohmygpt.com
Authx-api-key: $OHMYGPT_API_KEY or Authorization: Bearer $OHMYGPT_API_KEY

Set the base URL without /v1. The Anthropic SDKs and Claude Code append /v1/messages themselves, so https://api.ohmygpt.com/v1 produces /v1/v1/messages and a 404.

import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.ohmygpt.com",
    api_key=os.environ["OHMYGPT_API_KEY"],
)

message = client.messages.create(
    model="anthropic/claude-haiku-4-5",
    max_tokens=256,
    messages=[{"role": "user", "content": "Explain QUIC in two sentences."}],
)
print(message.content[0].text)

You don't need to send anthropic-version; 2023-06-01 is added when it is missing. To use Claude Code, see Claude Code.

Claude

Claude models receive your body and your anthropic-* headers, anthropic-beta included, as you sent them. Prompt caching, extended thinking, server tools, and beta features work as Anthropic documents them.

Other models

Any other chat model also works here, with tools:

curl https://api.ohmygpt.com/v1/messages \
  -H "x-api-key: $OHMYGPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ohmygpt/mock",
    "max_tokens": 64,
    "messages": [{"role": "user", "content": "What is the weather in Paris?"}],
    "tools": [{
      "name": "get_weather",
      "description": "Get weather",
      "input_schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}
    }]
  }'
{
  "type": "message",
  "role": "assistant",
  "model": "mock",
  "content": [
    { "type": "tool_use", "id": "call_mock_1", "name": "get_weather", "input": { "city": "" } }
  ],
  "stop_reason": "tool_use",
  "usage": { "input_tokens": 71, "output_tokens": 8 }
}

On these models:

  • stop_reason is one of end_turn, max_tokens, tool_use, or refusal.
  • usage.output_tokens includes the model's reasoning tokens.
  • anthropic-* headers, container, mcp_servers, and server tools such as web_search_20250305 are Claude features; use them with Claude models.
  • cache_control is not sent. It changes what is cached, not the answer.

Protocols has the general rules.

Counting tokens

POST /v1/messages/count_tokens returns the input token count for a Claude request. It is free and does not create a usage record.

curl https://api.ohmygpt.com/v1/messages/count_tokens \
  -H "x-api-key: $OHMYGPT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "anthropic/claude-haiku-4-5", "messages": [{"role": "user", "content": "Hello, Claude"}]}'
{ "input_tokens": 10 }

Use it with Claude models.

Streaming

stream: true returns the Anthropic event sequence from message_start to message_stop, with ping events in between. A : x-cost-credits comment line comes right before message_stop. If the model fails after the stream has started, the stream ends with an error event. See Streaming.

On this page