OneHop Docs

Chat & messages

Call chat completions, responses, and Anthropic messages through one gateway.

OneHop speaks the protocols your SDK already uses. Point the base URL at the right family, pass a OneHop model slug, and your existing client works unchanged.

FamilyBase URLEndpoints
OpenAI-compatiblehttps://api.onehop.ai/v1chat/completions, responses
Anthropic-compatiblehttps://api.onehop.ai/anthropicv1/messages
Google GenAI / Vertexhttps://api.onehop.ai/vertex-aimodels/{model}:generateContent

Tool calls, system prompts, and message shapes behave exactly as the provider documents them. Sampling and output-limit parameters are the exception: some upstreams reject them, so they are dropped before the request is forwarded. See Parameter support before you rely on max_tokens as a cost guard.

Chat completions (OpenAI)

curl https://api.onehop.ai/v1/chat/completions \
  -H "Authorization: Bearer $ONEHOP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.5",
    "messages": [{ "role": "user", "content": "Explain prepaid billing in one line." }]
  }'
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.ONEHOP_API_KEY,
  baseURL: "https://api.onehop.ai/v1",
});

const completion = await client.chat.completions.create({
  model: "openai/gpt-5.5",
  messages: [{ role: "user", content: "Hello from OneHop" }],
});

Streaming

Set stream: true and read server-sent events as usual. OneHop streams chunks straight through without buffering the whole response, and bills the real usage once the upstream finishes.

curl https://api.onehop.ai/v1/chat/completions \
  -H "Authorization: Bearer $ONEHOP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.5",
    "stream": true,
    "messages": [{ "role": "user", "content": "Stream a haiku" }]
  }'

Disconnects abort upstream

If your client disconnects mid-stream, OneHop aborts the upstream request. You are billed for usage the provider actually reported; otherwise the record is reconciled or marked failed.

Anthropic messages

The recommended Anthropic entry point is /anthropic/v1/messages. Use the x-api-key header, just like the native Anthropic SDK.

curl https://api.onehop.ai/anthropic/v1/messages \
  -H "x-api-key: $ONEHOP_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-opus-4.8",
    "max_tokens": 256,
    "messages": [{ "role": "user", "content": "Hello from OneHop" }]
  }'

Responses & Vertex

  • Responses: POST /v1/responses (or the short alias POST /responses) for clients built on the OpenAI Responses protocol.
  • Vertex / Gemini: point at https://api.onehop.ai/vertex-ai and call :generateContent / :streamGenerateContent with the model in the path.

To see which protocols a given model supports, filter the catalog — /v1/models?protocol=anthropic_messages. See Models & discovery for the full filter list.

Parameter support

Not every model honors output-limit and sampling parameters. Where an upstream rejects a parameter, OneHop drops it so the request still succeeds — but the parameter has no effect, and you are billed for the tokens actually produced.

max_tokens is not a reliable spend cap on the OpenAI-compatible endpoint. If you need a hard ceiling on spend, use per-key monthly credit limits instead.

Measured 2026-07-25 on POST /v1/chat/completions:

Model familymax_tokensmax_completion_tokensSampling (temperature, top_p, penalties)
openai/*ignoredignoredignored
google/*, gemini/*ignoredignoredhonored
minimax/*, moonshot/*ignored (upstream applies its own default)ignored (same)honored
deepseek/*honoredignoredhonored
anthropic/* (via /anthropic/v1/messages)honoredn/adepends on model generation, see below

Anthropic tightened sampling parameters with each Claude generation, and the official API rejects the deprecated ones outright (HTTP 400). OneHop drops them before forwarding so your request succeeds instead of erroring, and lists what it dropped in x-onehop-ignored-params. Measured 2026-07-26 against the official API:

Claude generationtemperaturetop_k, top_p
Opus 4.7 and newer, Fable 5, Opus 5droppeddropped
4.6 generationdroppedhonored
4.5 and olderhonoredhonored

The same rule applies to the anthropic_messages protocol on non-Anthropic models (zai/*, moonshot/*, …): sampling parameters are forwarded untouched there. GET /v1/models reports the per-model truth in supported_parameters.

Reasoning models make this more expensive than it looks: reasoning tokens are billed as output tokens but never appear in the stream. On openai/gpt-5.6-sol a measured request spent 1540 of 2201 output tokens on reasoning alone.

When a request contains a parameter that will not be honored, the response carries an x-onehop-ignored-params header listing them:

x-onehop-ignored-params: max_completion_tokens,temperature

Check that header in integration tests if your application depends on these parameters. Anything not listed in the table above is forwarded untouched.

Counting tokens

POST /v1/messages/count_tokens estimates the input token count of a request before you send it. It is free — no credits are consumed and no entry appears in your logs — but it does count toward your rate limit, because it reaches upstream.

curl https://api.onehop.ai/v1/messages/count_tokens \
  -H "x-api-key: $ONEHOP_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "minimax/minimax-m3",
    "messages": [{"role": "user", "content": "Hello"}]
  }'
{ "input_tokens": 6 }

The endpoint accepts model, messages, system, tools, tool_choice, and thinking. Anything else (max_tokens, temperature, stream, …) is rejected by the official schema, so OneHop drops those fields and reports them in x-onehop-ignored-params rather than failing your request.

Not every model supports it — anthropic/claude-* currently does not. Token counting has to be answered by the provider, and the accounts serving Claude do not expose it, so those models return an upstream error rather than a count. Treat count_tokens as best-effort: if it errors, fall back to your own estimate instead of failing the user's request.

Model echo

The model field in the response echoes the model id you requested, including the author/model prefix — request anthropic/claude-fable-5 and you get anthropic/claude-fable-5 back, not the bare upstream id. The one exception is model fallback: when a fallback you configured actually served the request, the response reports the model that answered, because reporting anything else would be a lie about which model produced the output.