Curated models for your best work

Join the waitlist

Router docs

Structured output and tools

Validated structured outputs, tool calls, and reasoning controls.

Structured output

Strict JSON Schema uses response_format in Chat, text.format in Responses, and output_config.format in Messages. TokenSpend validates the final JSON before returning success.

Structured streaming returns 400. Unsupported model and protocol pairs also return 400 before forwarding. A model response that misses the schema returns 502 with upstream_schema_violation. See each model's protocol capability in the registry JSON.

The registry's jsonSchemaProfiles lists accepted and normalized keywords. TokenSpend may send equivalent schema syntax to a model, then validates the result against your original schema.

Tools

TokenSpend validates every tool name and argument against the request's JSON Schema before returning it. Invalid, undeclared, repeated, partial, or truncated calls return a retryable 502.

Tool schemas may declare JSON Schema draft-07 or 2020-12. On tools that are not marked strict, format, pattern, and propertyNames are forwarded to the model unchanged but are not enforced by TokenSpend. Strict tools and structured output reject them.

  • auto permits text or valid calls.
  • required requires at least one valid call.
  • none rejects returned calls.
  • Named choice permits only that declared tool.
  • Disabling parallel calls permits one call.

Tool streams are validation-buffered. No argument delta is released until the complete stream passes validation. Unsupported model, protocol, choice, or streaming combinations return 400 before forwarding. See the registry JSON.

Tool and reasoning requests use one provider attempt. TokenSpend does not hide a retry or model switch. An incurred validation failure still produces one exact failed receipt.

Reasoning

Supported GLM and DeepSeek Chat routes use reasoning.enabled. Marked native OpenAI routes use reasoning_effort. Native Messages routes use thinking.

The registry lists accepted values. Marked OpenAI models currently accept low, medium, and high effort. Messages currently accepts enabled and disabled thinking.

Muse reasoning is always on and requires at least 2,048 output tokens. Reasoning stays separate from visible content. Empty reasoning-only output returns reasoning_output_exhausted.

Public continuation state is preserved only on a compatible protocol. Replayed cross-protocol state returns 400. A response that would require dropped state returns a retryable 502. DSML, thinking tags, parser markers, special tokens, and internal control fields are rejected.