Endpoints & Formats

Endpoints & Formats

Nexotao has two “front doors” for chat. Both use the same models — only the request format differs. This page helps you pick the right one so your requests don’t get rejected.

Choose in 5 seconds

If you…Use endpointBase URL
Use the OpenAI SDK / library, or a tool that asks for an “OpenAI base URL”/v1/chat/completionshttps://api.nexotao.com/v1
Use the Anthropic SDK, or want native Anthropic format/v1/messageshttps://api.nexotao.com
Use Codex (OpenAI Responses API)/v1/responseshttps://api.nexotao.com/v1

Golden rule: /v1/chat/completions accepts every model — including Claude. When in doubt, use it. Nexotao translates the format automatically.

The most common mistake

Sending an OpenAI-format body to the /v1/messages endpoint.

/v1/messages is the native Anthropic path: the body is forwarded upstream without translation. Leftover OpenAI markers are handled in two different ways — some are silently stripped, others make the request fail.

Fields that are silently stripped (not rejected)

These OpenAI-only fields have no Messages API equivalent. The gateway removes them from the body before forwarding, so the request still succeeds — but the values you send have no effect at all, and nothing in the response warns you:

frequency_penalty, presence_penalty, n, seed, user, logit_bias, logprobs, top_logprobs, stream_options, parallel_tool_calls, response_format, output_format

In addition:

  • stop is renamed to stop_sequences (its Anthropic equivalent), so your intent survives. If stop_sequences is already set, stop is simply dropped.
  • context_management is stripped — Anthropic’s context-editing beta isn’t available on our upstream, and forwarding the field would fail the request.
  • temperature, top_p, and top_k are stripped only for claude-opus-5, claude-opus-4-8, and claude-opus-4-7, which no longer accept sampling parameters. On claude-opus-4-6 and claude-sonnet-4-6 all three are forwarded and work normally.

What actually fails the request

  • role: "system" inside messages. The Messages API only knows the user and assistant roles; system instructions go in a separate top-level system field.
  • A missing max_tokens. In Anthropic format this field is required.
  • OpenAI fields outside the strip list above, such as max_completion_tokens. Those are forwarded as-is and rejected upstream as unknown input.

These failures surface as a 400 with the code upstream.invalid_request.

Fix: just send it to /v1/chat/completions (base URL ending in /v1). That endpoint accepts OpenAI format as-is, including for Claude models, and translates it for you — role: "system" is moved into the system field, and max_tokens gets a default when you omit it.

- POST https://api.nexotao.com/v1/messages         (Anthropic format only)
+ POST https://api.nexotao.com/v1/chat/completions  (OpenAI format, every model)

Option 1 — OpenAI format (most common)

Endpoint /v1/chat/completions. Base URL ends in /v1, key sent via Authorization: Bearer. Works for GPT, DeepSeek, Grok, and Claude.

from openai import OpenAI
 
# Just change the base URL — any model, including Claude
client = OpenAI(base_url="https://api.nexotao.com/v1", api_key="sk-nexo-...")
 
resp = client.chat.completions.create(
    model="claude-opus-4-8",  # or gpt-5.6-terra, DeepSeek-V4-Pro, etc.
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "What is consistent hashing?"},
    ],
)
print(resp.choices[0].message.content)
curl https://api.nexotao.com/v1/chat/completions \
  -H "Authorization: Bearer sk-nexo-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-4-8",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

Option 2 — Native Anthropic format

Endpoint /v1/messages. Base URL without /v1, key sent via x-api-key. Claude models only, and the body must be Anthropic format (system outside messages, max_tokens required).

from anthropic import Anthropic
 
client = Anthropic(base_url="https://api.nexotao.com", api_key="sk-nexo-...")
 
msg = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=256,
    system="You are a concise assistant.",   # outside messages
    messages=[{"role": "user", "content": "What is consistent hashing?"}],
)
print(msg.content[0].text)
curl https://api.nexotao.com/v1/messages \
  -H "x-api-key: sk-nexo-..." \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-opus-4-8",
    "max_tokens": 256,
    "messages": [{"role": "user", "content": "Hello"}]
  }'

At a glance

/v1/chat/completions/v1/messages
FormatOpenAINative Anthropic
Base URL…/v1 (no /v1)
Key headerAuthorization: Bearerx-api-key
ModelsAll (GPT, DeepSeek, Grok, Claude)Claude only
systeminside messagesseparate field
max_tokens requirednoyes

New to tokens, models, or API keys? Start with Core Concepts. Want to try it without any code? Open the Playground.