Claude Code talks to its model in Anthropic's Messages format, not OpenAI's.
Until now, running it on an open model meant putting a router in between to
translate. Our API now answers POST /v1/messages
itself, so Claude Code points at an open model with seven environment
variables and nothing else installed.
Yesterday we published a guide that did this through 9Router.
That route still works, and 9Router does more than translate. This one is
for when all you want is Claude Code on qwen3.8-27b, the same model the
chat completions and
Responses endpoints serve, at the same
price per token.
Everything below was run with Claude Code 2.1.296 on 13 October 2026. ParalonCloud is not affiliated with Anthropic; Claude Code is their tool, and we are describing how it behaves against our endpoint.
Setup
Make an API key on the API keys page (how keys work is in the authentication docs), then:
export ANTHROPIC_BASE_URL=https://paraloncloud.com
export ANTHROPIC_AUTH_TOKEN=sk-your-key
export ANTHROPIC_MODEL=qwen3.8-27b
export ANTHROPIC_SMALL_FAST_MODEL=qwen3.8-27b
export ANTHROPIC_DEFAULT_HAIKU_MODEL=qwen3.8-27b
export ANTHROPIC_DEFAULT_SONNET_MODEL=qwen3.8-27b
export ANTHROPIC_DEFAULT_OPUS_MODEL=qwen3.8-27b
claude
That is all of it. The same variables can go in the env block of Claude
Code's settings.json if you would rather not export them each time. The
model name is the id from the model list;
what is live right now is on the inference page.
Why five model variables and not one
Because Claude Code does not send everything to the model you chose. A session also makes small side requests, for a title or a summary, and sends them to other models by name.
We found this by putting a logging relay between Claude Code and our API.
With ANTHROPIC_MODEL, ANTHROPIC_SMALL_FAST_MODEL and
ANTHROPIC_DEFAULT_HAIKU_MODEL set, one request of the session still went
out asking for claude-sonnet-5, a model we do not have, and came back
"model not found". The session carried on, so you could miss it for weeks.
With the Sonnet and Opus variables set as well, all 9 requests of the next
session asked for qwen3.8-27b and all 9 were answered.
What Claude Code actually sends
From the same relay, one session of the task below:
| Requests in the session | 9 |
| Main requests (streamed) | 7, each with 20 tool definitions, max_tokens 32,000 and thinking: adaptive |
| Side requests (not streamed) | 2, no tools, max_tokens 2,112 |
| Messages in the last main request | 20 |
| Content blocks in use | text, thinking, tool_use, tool_result |
| Fields we accept and ignore | context_management, output_config, safeguards, cache_control |
Two things in there are worth knowing if you run an endpoint like this yourself.
It asks for thinking. thinking: adaptive on every main request. We
leave the model's reasoning on when a request asks for it and return it in
thinking blocks; a request that does not ask gets a direct answer, which
is faster to the first token.
It puts a system message among the turns. The Messages API has a
top-level system field, and the messages are meant to alternate between
user and assistant. Claude Code also sends a message with the role
system in the middle of the list. On our first day we answered that with a
400. Claude Code retried without it and carried on, at the cost of one
wasted request per session. We now join such messages to the system prompt,
since a chat template takes a system message at the start only.
What we measured
The task: a folder with a slugify.js that has a bug and a test.js with
three cases, two of them failing. The prompt asked Claude Code to run the
tests, find the bug, fix it, and run them again. That needs the whole loop:
a shell command, a file read, an edit, another shell command.
| Run 1 | Run 2 | Run 3 | |
|---|---|---|---|
| Result | fixed, 3 of 3 pass | fixed, 3 of 3 pass | fixed, 3 of 3 pass |
| Turns | 7 | 5 | 8 |
| Wall time | 52 s | 27 s | 55 s |
| Time spent waiting on the API | 25 s | 23 s | 35 s |
| Input tokens not from cache | 17,558 | 17,047 | 30,825 |
| Input tokens read from cache | 82,368 | 65,120 | 88,000 |
| Output tokens | 1,180 | 920 | 1,689 |
All three runs made the same fix: one regular expression changed to collapse runs of separators, and a second one added to strip a dash at either end.
Three observations.
The spread is the model, not the endpoint. Same task, same prompt, 27 to 55 seconds. The model takes a different path each time: sometimes it reads the test file before the source, sometimes it runs the tests twice. Do not quote one run as the speed.
Most of the prompt comes from cache. Claude Code sends its whole system
prompt and 20 tool definitions on every turn. The worker keeps those tokens
from the previous turn, so four in five of the input tokens in run 1 were
read from cache instead of being processed again. They come back in the
usage as cache_read_input_tokens, without anything in the request being
marked with cache_control. Getting a request back to the worker that
holds its prefix is its own problem; we wrote up how we
route to the GPU that has your KV cache.
It is cheap to try. At $0.12 per million input tokens and $1.70 per million output, the largest of the three runs comes to under two cents even if every cached token is counted at the full input price. There is no subscription: the API is pay as you go.
The endpoint from anything else
Claude Code is one client. Anything that speaks the Messages API works the
same way. The key goes in x-api-key, the header Anthropic's SDKs send, or
in Authorization: Bearer.
curl https://paraloncloud.com/v1/messages \
-H "x-api-key: sk-your-key" \
-H "content-type: application/json" \
-d '{
"model": "qwen3.8-27b",
"max_tokens": 200,
"system": "You answer in one sentence.",
"messages": [{"role": "user", "content": "What is a KV cache?"}]
}'
The answer is a Message: content blocks, a stop_reason of end_turn,
max_tokens or tool_use, and usage. Tools with an input_schema come
back as tool_use blocks and take their answers as tool_result blocks, and
"stream": true gives the usual message_start, content_block_*,
message_delta and message_stop events. The full list is in the
Messages API reference.
Three things to watch
The context window is 131,072 tokens. Claude Code does not know this
model and assumes a larger window. On a short task it makes no difference.
In a long session it can be refused by the API before it thinks to compact.
Run /compact yourself before that. Why the window is what it is on this
model, and what a longer one costs in GPU memory, is in
how much VRAM a 256k context needs.
Ignore the cost Claude Code prints. It has no price list for a model it
does not know, so the figure at the end of a session is not what was
charged. The real numbers are on Inference usage.
It also prints unrecognized_model on stderr for the same reason, and
carries on.
Server tools do not exist here. Web search, code execution and computer use run on Anthropic's side when you use their API. We answer a request that includes one with a 400 that names the tool. The tools Claude Code runs on your machine, which is all of its file and shell work, are unaffected.
What we did not test
- A long session. Everything above is a task of under a minute on one file.
- Images sent to the model through this endpoint, and Anthropic's Python and TypeScript SDKs. The request shape they send is the one in the curl example, which is tested; the SDKs themselves we have not run.
POST /v1/messages/count_tokens. It is not implemented, and we do not yet know what in a long Claude Code session depends on it.- Models other than
qwen3.8-27b.
Other tools on the same model
Claude Code is the one that needed a new endpoint. The tools that speak OpenAI's format have worked from the start, each with its own guide: Cline, pi and, through one local address for all of them, 9Router. How fast the model itself runs on the cards behind the API is measured in two RTX 5090s on Qwen3.8 27B.
Troubleshooting
| Symptom | Cause |
|---|---|
401 Invalid API key | the key is not a ParalonCloud key, or ANTHROPIC_AUTH_TOKEN is not set in the shell that started claude |
model not found for a Claude model name | one of the five model variables is missing |
A 400 naming tools[n] | the request includes a server tool; only tools with an input_schema are supported |
| The session stops with a context error | the conversation passed 131,072 tokens; /compact earlier |
Frequently asked questions
Can Claude Code run on a model that is not Claude?
Yes. Claude Code reads the address of its API from ANTHROPIC_BASE_URL and
the model names from the ANTHROPIC_*MODEL variables. Any server that
answers Anthropic's Messages API can stand in. Ours does, on Qwen3.8 27B.
Do I need a router such as LiteLLM or 9Router?
Not with an endpoint that speaks the Messages API itself. A router is still useful if you want fallback between several providers or one local address for many tools.
Is an open model as good as Claude at this?
We have not measured that and this article does not claim it. Claude Code is written for Claude models. What we measured is that an open 27B model completed a small find-and-fix task three times out of three through it.



