Skip to main content
Anthropic setup is just an API key. This page exists for one quirk: how GoModel maps the OpenAI-style reasoning.effort knob onto Claude’s native thinking and effort controls, which differ by model generation.

Configure

Or in config.yaml:
Anthropic’s /v1/messages requires max_tokens on every request. GoModel injects ANTHROPIC_DEFAULT_MAX_TOKENS (default 4096) when a caller omits it, keeping the OpenAI-compatible surface lenient.

Claude subscription (OAuth token)

GoModel also accepts a Claude subscription OAuth token as the Anthropic credential. Generate one with claude setup-token (requires a Claude subscription — Pro, Max, Team, or Enterprise — and the Claude Code CLI) and set it as the provider key:
Tokens with the sk-ant-oat prefix are detected automatically: GoModel sends them as Authorization: Bearer with the oauth-2025-04-20 beta instead of x-api-key. No extra configuration is needed.
Anthropic authorizes subscription OAuth tokens only for Claude Code traffic. Use this to route your own Claude Code through GoModel (see the Claude Code guide); requests from other clients are rejected upstream with “This credential is only authorized for use with Claude Code”. Endpoints outside the Claude Code surface (such as model listing) may also be rejected — if provider model discovery fails, configure the models list for the provider explicitly.

Reasoning effort mapping

GoModel accepts the OpenAI-shaped "reasoning": {"effort": "..."} object as well as the Chat Completions string form "reasoning_effort": "..." (a non-empty reasoning.effort wins when both are present; an empty object falls back to the string form) and translates them to Claude’s native controls. The five accepted levels are low, medium, high, xhigh, and max; values are matched case-insensitively and any other value is downgraded to low and logged. The translation depends on whether the model supports adaptive thinking.
Adaptive routing is an explicit allowlist, not a version comparison. New model IDs are treated as legacy until added to the list. For pre-4.7 models the legacy fallback keeps working via budget_tokens; models from Opus 4.7 onward reject budget_tokens outright, so a new adaptive-only model ID fails with an upstream 400 until it is added to the allowlist.
For legacy models the effort string maps to a thinking budget; max_tokens is bumped above the budget when needed. xhigh and max are adaptive-only levels, so on legacy models they are capped at the high budget rather than inflating max_tokens past what those models can emit:
Omit reasoning to leave thinking at the model’s default. GoModel only sets thinking: {type: "adaptive"} when you pass reasoning.effort (or reasoning_effort). Without it, Opus 4.6 to 4.8 and Sonnet 4.6/5 do not engage extended thinking, while Fable 5/5.1, Mythos 5/5.1, and Opus 5 think adaptively on their own (see the always-on note below). Effort is a separate control that governs overall token spend (text and tool calls) whether or not thinking is engaged, and Anthropic defaults it to high when unset. It is a behavioral signal for depth and verbosity, not a hard budget — actual usage varies per request and is bounded by max_tokens.
Effort levels are model-gated upstream: xhigh is available on Fable 5/5.1, Opus 5, Sonnet 5, and Opus 4.8/4.7; max on those plus Opus 4.6 and Sonnet 4.6. GoModel forwards the level you send; Anthropic rejects it with a 400 if the target model does not support it. Manual budget_tokens thinking is rejected from Opus 4.7 onward, which is why GoModel uses adaptive thinking for those models.
On Fable 5/5.1, Mythos 5/5.1, and Opus 5 thinking is always on, whether or not you send reasoning; reasoning.effort only tunes its depth. The tokens it spends are reported as usage.completion_reasoning_tokens in Chat Completions responses. The reasoning text itself is not returned; only the token count is.

Sampling parameters

Anthropic removed temperature and top_p from Fable 5/5.1, Mythos 5/5.1, Opus 5, Sonnet 5, and Opus 4.8/4.7 — any value, including the OpenAI SDK default of temperature: 1, is rejected upstream with a 400. GoModel drops both fields for those models and logs the discarded values, so clients that always send a temperature keep working. Older models still receive them as sent, with one exception below. Anthropic treats temperature and top_p as mutually exclusive on every model: a request carrying both is rejected with 400 "`temperature` and `top_p` cannot both be specified for this model". Since OpenAI-compatible clients routinely fill in both defaults, GoModel forwards temperature and drops top_p (logging the discarded value) when it sees both. Send only top_p if that is the knob you want to control. Independently of the model, when extended thinking is engaged Anthropic requires temperature = 1. GoModel drops any other temperature value (and logs it) rather than failing the request.

Structured output

response_format works on Anthropic models, mapped onto Claude’s native structured outputs (output_config.format). The same applies to text.format on /v1/responses, which GoModel translates into response_format first.
The response is an ordinary chat completion whose message.content is the JSON text, with finish_reason: "stop" — the same shape OpenAI returns. Streaming is unaffected: the JSON arrives as normal content deltas. Tools and response_format can be sent together; Claude either calls a tool (finish_reason: "tool_calls") or answers with schema-constrained JSON. Anthropic’s schema compiler is stricter than OpenAI’s, so GoModel adapts the schema before sending it:
  • every object schema gets the mandatory "additionalProperties": false, on each allOf branch too — Anthropic requires it and merges the branches itself
  • validation-only keywords Anthropic does not honor (minimum, maximum, multipleOf, maxItems, uniqueItems, minLength, maxLength, propertyNames, not, if/then/else, …) are dropped
  • pattern is kept, because Anthropic does enforce it — except for the regex features its engine rejects (lookarounds, backreferences, \b/\B), which would 400 the request; those patterns are dropped and the loss is logged
  • minItems is kept when it is 0 or 1, the only values Anthropic accepts, and dropped otherwise
  • oneOf is relaxed to anyOf, and unknown string format values are dropped. A schema carrying both oneOf and anyOf at the same level cannot be expressed — Anthropic rejects the allOf that would hold the second one — so oneOf is dropped and the loss is logged
  • required is left exactly as sent: Anthropic accepts optional properties, so a property you left out of required stays optional
Nested objects, arrays, enum, const, anyOf, allOf, and $ref/$defs are passed through unchanged. $ref has limits GoModel cannot paper over, and Anthropic returns a 400 naming each one: references must be local (#/$defs/… — an external URL is refused), non-recursive (a definition that refers to itself, directly or in a cycle, is refused), and outside allOf (resolve the reference yourself before composing with allOf).
strict is not forwarded — Anthropic always enforces the schema it is given. A non-strict schema is therefore enforced too, minus the constraints listed above. Structured output is available on every Claude model GoModel can currently reach.

When the content is not schema-valid JSON

The schema constrains what the model generates, not how the turn ends. Check the completion before parsing message.content:
  • finish_reason: "length" — the answer hit max_tokens and the JSON is cut off mid-value. Raise max_tokens and retry.
  • finish_reason: "tool_calls" — the model called a tool instead of answering, so message.content is empty.
  • finish_reason: "refusal" — Claude declined the request; GoModel passes Anthropic’s refusal stop reason through unchanged and there is no JSON to parse.
Only finish_reason: "stop" with non-empty content is worth handing to a JSON parser; treat anything else as an error rather than parsing it.

Verbosity

OpenAI’s verbosity (and text.verbosity on /v1/responses) has no Anthropic equivalent. GoModel logs the requested value and drops it rather than failing the request. Ask for shorter or longer answers in the prompt instead.

Forced tool choice on Fable 5.1

Fable 5.1 and Mythos 5.1 accept only tool_choice: "auto" and "none"; forcing a call with "required" or {"type": "function", ...} returns a 400 from Anthropic. GoModel follows Anthropic’s documented replacement: the choice is downgraded to auto and an instruction is appended to the system prompt — “You must respond by calling one of the provided tools.” for required, or “You must respond by calling the tool named <name>.” for a named function. The downgrade is logged. parallel_tool_calls: false is still honored. Fable 5 and every other Claude model keep forced tool use unchanged.
The instruction is strong guidance, not a hard guarantee: the model can still answer in text. If you relied on forced tool choice to obtain JSON, use structured output instead.

Native passthrough

To send Claude-native request fields that have no OpenAI-compatible equivalent (for example inline mid-task system entries in the messages array), use the passthrough route /p/anthropic/messages, which forwards the body verbatim.
Last modified on September 12, 2026