How to choose a Claude API relay: price, caching and tool calls
A Claude API relay gives you an API address and a key from a third party. Most relays work like the official Anthropic API: point Claude Code or an SDK at the relay's base URL and it runs. Relays differ a lot in price, caching and tool support, and you can check the points below yourself in about half an hour.
The RoamAI teamPublished October 30, 2026
What a relay is
A relay gives you an API address and a key. You send your requests to it, it passes them on to the model and charges your balance for the usage. Many users in mainland China use one because Anthropic does not serve that region, so signing up for and paying for the official API is hard there.
Price: count the multiplier and the top-up rate together
Relays usually state their price as a multiplier: credit is charged at the official Anthropic price times a factor. The multiplier alone is misleading. You also need to know what you pay for $1 of credit. The real price is:
price you pay = official USD price × multiplier × what you pay for $1 of creditAn example with made-up relays, for a model whose official input price is $2 per million tokens:
- Relay A: multiplier 0.5, ¥1 buys $1 of credit. 2 × 0.5 × ¥1 = ¥1 per million tokens.
- Relay B: multiplier 1, credit sold at the exchange rate, ¥7.2 for $1. 2 × 1 × ¥7.2 = ¥14.4 per million tokens.
B's multiplier is only twice A's, but its real price is more than 14 times higher. Convert every relay to the same currency per million tokens before you compare.
Caching: does it work, and how is it billed
In a Claude Code session most of the input is history that gets sent again on every turn, and prompt caching is what keeps that cheap. Official cache reads cost about a tenth of the input price, and less on some newer models. If a relay does not support caching, or bills cache reads at the input price, Claude Code costs several times more.
To test it, send the same long prefix twice and look at the usage in each response:
from anthropic import Anthropic
client = Anthropic(base_url="https://relay.example.com", api_key="YOUR_KEY")
# A long text, such as a README of ten thousand characters or more
doc = open("README.md", encoding="utf-8").read()
for i in range(2):
message = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1024,
system=[{"type": "text", "text": doc, "cache_control": {"type": "ephemeral"}}],
messages=[{"role": "user", "content": "Summarize this document in one sentence."}],
)
u = message.usage
print(i + 1, "written", u.cache_creation_input_tokens, "read", u.cache_read_input_tokens, "uncached", u.input_tokens)- If cache_creation_input_tokens is above 0 on the first request (written to the cache) and cache_read_input_tokens is above 0 on the second (read from the cache), caching works.
- If both are 0, the relay does not support caching or the prefix is too short. Prefixes below a minimum length are not cached; the minimum depends on the model and ranges from a few hundred to a few thousand tokens. A text of ten thousand characters or more stays clear of it.
- Send the two requests within 5 minutes of each other. The cache expires after 5 minutes by default.
Then find the two requests in the relay's usage log. The cached part should be charged at the cache read price, not the input price.
Tool calls and streaming
Claude Code reads files, edits code and runs commands through tool calls, and its answers arrive as a stream. Some relays convert requests to another format and back, and tool calls and streaming are the two things that break most often when they do. To test tool calls:
message = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=1024,
tools=[{
"name": "get_weather",
"description": "Get the current weather in a city",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}],
messages=[{"role": "user", "content": "What is the weather in Shanghai right now?"}],
)
print(message.stop_reason)
for block in message.content:
if block.type == "tool_use":
print(block.name, block.input)If stop_reason is tool_use and a line like get_weather {'city': 'Shanghai'} is printed, tool calls work.
For streaming, run the client.messages.stream example from Call Claude from your code. The text should arrive piece by piece, not all at once after a long wait.
Run a real task in Claude Code
Once the checks above pass, give Claude Code a real job. Set the address and key as in Use Claude Code with an API key, then in a project directory ask it to read a few files, change some code and run the tests.
- The task finishes with no errors and no dropped connections.
- After a few turns, most of the input in the usage log is cache reads.
- The charges match what you work out from the price list.
Is it the model you asked for
Check which models /v1/models lists, then check that the model field in each response and the model recorded in the usage log match the one you requested. The relay reports both of these itself, so they only show what it says it served. A stronger check is to run the same task through the official API or another provider and compare the results. If you cannot do that, at least make sure the caching, tool call and Claude Code checks above all pass.
Billing and terms
- Each request shows its model, tokens and cost. Without that you cannot check what you were charged.
- Whether the balance expires, and whether a top-up can be refunded.
- Whether you can get an invoice, and what kind.
- Whether each person on a team can have their own key, and whether a key can be limited in concurrency and models.
Data and reliability
- Your requests pass through the relay. Read its privacy policy for what it stores and for how long, and do not send secrets or sensitive data to a relay you do not trust.
- Try it a few times during evening peak hours and watch the response time and error rate.
- Errors should say what went wrong: an empty balance, an invalid key and a rate limit should be easy to tell apart.
One key per person for Claude Code
RoamAI is a Claude API for teams: create an API key in the console and use it in Claude Code, Claude Desktop or an SDK. VIP adds lower usage prices, dedicated servers and a named contact.
Get started