Messages (Anthropic shape)

POST/v1/messages

The same chat, in the Anthropic shape: a different request and response body.

Request

modelstringbodyrequired
the logical model name from GET /v1/models; a provider prefix is folded away
messagesarraybodyrequired
the conversation in Anthropic form: content is a string or an array of text / tool_use / tool_result blocks
max_tokensintegerbody
the output ceiling; optional, and the worst-case price is built on it
systemstring|arraybody
the system prompt — a string or an array of text blocks, merged into one system message
toolsarraybody
tools in Anthropic form: {name, description, input_schema}
tool_choiceobjectbody
{"type": "auto" | "any" | "tool", "name": …} — mapped to auto / required / that named function
streambooleanbody
true — the answer arrives as Anthropic events (message_start … message_stop)

Responses

Response

{
  "id": "chatcmpl-…",
  "type": "message",
  "role": "assistant",
  "model": "gpt-5.6-sol",
  "content": [{ "type": "text", "text": "Hello!" }],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": { "input_tokens": 11, "output_tokens": 2, "cost_usd": "0.0000465" }
}

moderation stopped the prompt before the model (type: content_policy_violation)

the body does not parse as JSON — the Anthropic converter reads it itself

no key in the request, or the key is not ours

the balance does not cover this request's worst-case price

model_not_found — the model is switched off by the admin — it leaves GET /v1/models too

the upstream answered with a rate limit; retry with a delay

the upstream is unreachable (type: upstream_error)

a timeout waiting for the upstream: 300 s read, 60 s without bytes on a stream

Details

Needs a key in Authorization: Bearer or x-api-key.

The gateway accepts the Anthropic shape but does NOT proxy it verbatim: the body is rewritten into chat/completions, and the upstream answer is folded back into an Anthropic message (the id comes from the upstream, the model is the logical one you asked for). That way any catalog model works here, not only Claude.

Carried over from the body: model, system, messages, max_tokens, temperature, top_p, stream, metadata, stop_sequences (as stop), tools (name/description/input_schema → function) and tool_choice (auto → auto, any → required, tool → that named function). This is the one text route where other fields do NOT reach the upstream: the converter builds a fresh body from that list. Assistant tool_use blocks and user tool_result blocks are converted both ways, and finish_reason becomes stop_reason (stop → end_turn, length → max_tokens, tool_calls → tool_use, content_filter → stop_sequence). The gateway does not require max_tokens: without it the field never appears in the body sent upstream, and the request's worst-case price is built on the output ceiling from the model's catalog row. Anthropic's telemetry block inside system (x-anthropic-billing-header: …) is dropped: its per-request nonce sits at the very front of the prompt and busts the upstream's prefix cache every time.

This request's cost arrives inside the answer: the x-teamtoken-cost-usd header and usage.cost_usd in the body. The value is a decimal string ("0.0000465"), not a number: a number would be re-displayed by the client language's own float rules (Python would show 4.65e-05), while a string reaches your code exactly as written. The cost can also fail to arrive at all — then it is in neither the header nor the field: on a non-streaming answer when the upstream did not report it, on a stream when the model has no catalog tariff. The stream here is synthetic: the upstream answers in full and the SSE is built from the finished message — so the cost is known before the first byte, the header is present on streams too, and cost_usd sits in message_start inside message.usage (into message_delta the gateway puts output_tokens only). There is no idempotency on this route: the gateway does not cache an Anthropic answer, so a byte-identical repeat reaches the model again and is paid for again. Alongside lives POST /v1/messages/count_tokens, which answers {"input_tokens": N} — an ESTIMATE (characters/4 plus per-message and per-tool overhead), not a tokenizer's verdict. Every error arrives in one envelope (the code field is not on every status): { "error": { "message": "...", "type": "...", "code": "PROVIDER_CODE" } }.

Moderation, when it is enabled, reads the request text and blocks only on a real verdict: a moderator that is down or erroring lets the request through. The answer always carries back the logical model name you asked for. If it does not fit the gateway's wait (300 s read by default, 60 s without bytes on a stream) you get a 504; the gateway marks that non-streaming attempt, and if the upstream finished and billed anyway, the reconciler credits the amount back to your balance as a compensating grant. Upstream host names are scrubbed out of error bodies, so an error's text can differ from what the upstream sent.

This path has no route of its own: one gateway handler takes every POST /v1/*, and its list of accepted paths is closed — any other /v1/* answers 404.

Code examples
curl https://api.teamtoken.store/v1/messages \
  -H "x-api-key: sk-…" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.6-sol",
    "max_tokens": 512,
    "system": "Be brief",
    "messages": [{ "role": "user", "content": "Hello" }]
  }'
from anthropic import Anthropic

# base_url without /v1 — the SDK appends the path itself
client = Anthropic(api_key="sk-…", base_url="https://api.teamtoken.store")

msg = client.messages.create(
    model="gpt-5.6-sol",
    max_tokens=512,
    messages=[{"role": "user", "content": "Hello"}],
)
print(msg.content[0].text)
print("cost_usd:", msg.usage.model_extra["cost_usd"])
Request
https://api.teamtoken.store/v1

The panel calls this domain; in your own code use the address above.

The key is never stored: it lives in this tab until you reload the page.

the logical model name from GET /v1/models; a provider prefix is folded away

the conversation in Anthropic form: content is a string or an array of text / tool_use / tool_result blocks

the output ceiling; optional, and the worst-case price is built on it

the system prompt — a string or an array of text blocks, merged into one system message

tools in Anthropic form: {name, description, input_schema}

{"type": "auto" | "any" | "tool", "name": …} — mapped to auto / required / that named function

true — the answer arrives as Anthropic events (message_start … message_stop)

This request really goes out and costs money at the model's tariff.

Response

Press “Send request” above and the answer shows up here.