Radium API
How to call Radium directly. Authentication, models, environments, tool calling, and the errors you'll actually hit.
API quickstart
Call the Radium API. Anthropic-compatible Messages endpoint, authentication, model names, production and staging base URLs, and OpenAI-compatible Chat Completions.
Quickstart
Radium serves an Anthropic-compatible Messages API. If your application already speaks that shape, or you use Anthropic-style tool calling, or you run Claude Code, this is the endpoint you want and the change is a base URL and a model name.
An OpenAI-compatible Chat Completions endpoint is available as well, and it is covered further down for applications that expect it.
Your first request
Set your key once:
export RADIUM_API_KEY="YOUR_RADIUM_API_KEY"
Then send this:
curl -s https://api.radium.cloud/v1/messages \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-H "x-api-key: $RADIUM_API_KEY" \
-d '{
"model": "hal-1.0",
"max_tokens": 2048,
"messages": [
{ "role": "user", "content": "Say only: radium hal connected." }
]
}'
That is the whole integration. Everything below is detail.
Authentication
Every request needs a key. The default header is x-api-key:
x-api-key: $RADIUM_API_KEY
Some deployments use a bearer token instead:
Authorization: Bearer $RADIUM_API_KEY
Use the mode Radium supplied with your key. If nobody specified one, start with x-api-key and you will almost certainly be right.
Models
| Model | Built for |
|---|---|
hal-1.0 |
Higher-capability coding and agentic work. Used in the examples on this page. |
clarke-1.0 |
General-purpose and structured work |
tycho-1.0 |
Faster, lighter-weight tasks |
Swap the identifier in the request body, or in your Claude Code configuration, and nothing else changes.
The Messages API
Base URL:
https://api.radium.cloud
Full endpoint:
POST https://api.radium.cloud/v1/messages
The request body is the standard Anthropic Messages shape.
curl
curl -s https://api.radium.cloud/v1/messages \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-H "x-api-key: $RADIUM_API_KEY" \
-d '{
"model": "hal-1.0",
"max_tokens": 2048,
"messages": [
{ "role": "user", "content": "Hello, Radium!" }
]
}'
Python
import anthropic
client = anthropic.Anthropic(
api_key="YOUR_RADIUM_API_KEY",
base_url="https://api.radium.cloud",
)
message = client.messages.create(
model="hal-1.0",
max_tokens=1024,
messages=[
{"role": "user", "content": "Hello, Radium!"}
],
)
print(message.content[0].text)
TypeScript
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: "YOUR_RADIUM_API_KEY",
baseURL: "https://api.radium.cloud",
});
const message: Anthropic.Message = await client.messages.create({
model: "hal-1.0",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello, Radium!" }],
});
console.log(message.content[0].text);
Tool calling works through the same endpoint, and it has its own page. See tool calling.
Production and staging
Messages API base URLs
| Environment | Base URL | Endpoint |
|---|---|---|
| Production | https://api.radium.cloud |
POST /v1/messages |
| Staging | https://stage.api.radium.cloud |
POST /v1/messages |
Credentials do not cross over Staging needs staging credentials. A production key will not authenticate against the staging endpoint, and that is deliberate.
Dedicated deployments
Organisations running on a dedicated Radium deployment use the host supplied to them, and every endpoint pattern on this page applies unchanged. If you need one, talk to us.
OpenAI-compatible Chat Completions
Use this only when your application expects an OpenAI-compatible Chat Completions API. Anthropic-compatible clients should use POST /v1/messages above.
The base URL for this path includes /v1:
https://api.radium.cloud/v1
curl -s https://api.radium.cloud/v1/chat/completions \
-H "content-type: application/json" \
-H "x-api-key: $RADIUM_API_KEY" \
-d '{
"model": "hal-1.0",
"max_tokens": 2048,
"temperature": 0,
"messages": [
{ "role": "user", "content": "Hello, Radium!" }
]
}'
Bearer authentication works here too, and the model identifiers are the same three.
Every endpoint
Endpoint summary
| Use case | Method | Endpoint |
|---|---|---|
| Messages, production | POST |
https://api.radium.cloud/v1/messages |
| Messages, staging | POST |
https://stage.api.radium.cloud/v1/messages |
| Chat Completions, production | POST |
https://api.radium.cloud/v1/chat/completions |
| Chat Completions, staging | POST |
https://stage.api.radium.cloud/v1/chat/completions |
Claude Code
Claude Code points at the Anthropic-compatible base URL and adds the request path itself, so configure it with the base URL alone:
export ANTHROPIC_BASE_URL="https://api.radium.cloud"
export ANTHROPIC_MODEL="hal-1.0"
export ANTHROPIC_API_KEY="$RADIUM_API_KEY"
Check it:
claude --print --model hal-1.0 "Say only: radium hal connected."
The one that catches everybody Do not put
/v1/messagesintoANTHROPIC_BASE_URL. Claude Code appends it, and a base URL with the path already on it returns a 404 on every request.
The full setup, including the scripted install, model selection, and troubleshooting, is on Run Claude Code on Radium.
Next
- Run Claude Code on Radium
- Tool calling, for the
tool_useandtool_resultcontract - MCP and Radium
- Errors and troubleshooting
Tool calling and MCP
Anthropic-compatible tool calling on the Radium Messages API, with the full tool_use and tool_result round trip, and where MCP fits alongside it.
Tool calling and MCP
Radium supports Anthropic-compatible tool calling on the Messages API. MCP is handled by the client application, and when that client is pointed at Radium it can expose MCP-provided tools to the model through the ordinary tool-calling flow.
These two things arrive together in most conversations, and they sit at different levels of the stack, so this page covers tool calling first and then places MCP against it.
Two different layers
Tool calling — API feature
Your client sends tool definitions with the request, the model returns a tool_use block asking for one, your client runs it, and your client sends the output back as tool_result. This happens between your application and Radium.
MCP — client-side protocol The Model Context Protocol connects an application such as Claude Code to external tool servers. Those servers expose tools, and the client decides how to present them to the model. This happens on your side, before any request reaches Radium.
┌─────────────────────── runs on your side ──────────────────────────┐
│ │
│ ┌────────────────┐ MCP ┌─────────────────────┐ │
│ │ MCP server │◄─────────────────►│ Your client │ │
│ │ yours, exposing │ │ application or │ │
│ │ tools │ │ Claude Code │ │
│ └────────────────┘ └──────────┬──────────┘ │
│ │ │
└────────────────────────────────────────────────────┼───────────────┘
│ tools
│ tool_use
│ tool_result
▼
┌─────────────────────┐
│ Radium │
│ POST /v1/messages │
└─────────────────────┘
MCP runs horizontally, on your infrastructure, between your client and your tool servers. Tool calling runs vertically, between your client and Radium. Radium answers the model half and never talks to your MCP server.
What is supported
- Tool definitions in the
toolsrequest field - JSON Schema-style
input_schemadefinitions - Model responses containing
tool_usecontent blocks - Returning tool outputs with
tool_resultcontent blocks - Multiple available tools in a single request
- Streaming responses with tools
All of it on the same endpoint you are already calling.
The round trip
Three turns. Your client does two of them.
Turn one — send the request with your tool definitions
curl -s https://api.radium.cloud/v1/messages \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-H "x-api-key: $RADIUM_API_KEY" \
-d '{
"model": "hal-1.0",
"max_tokens": 2048,
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {
"city": { "type": "string" }
},
"required": ["city"]
}
}
],
"messages": [
{ "role": "user", "content": "What is the weather in Tokyo?" }
]
}'
Turn two — the model asks for the tool
If it decides to call get_weather, the response carries a tool_use block:
{
"type": "tool_use",
"id": "toolu_...",
"name": "get_weather",
"input": {
"city": "Tokyo"
}
}
Radium has no idea what get_weather does and does not run it. That part is yours.
Turn three — run the tool and send the output back
Append the assistant turn containing the tool_use block, then a user turn containing the matching tool_result:
curl -s https://api.radium.cloud/v1/messages \
-H "content-type: application/json" \
-H "anthropic-version: 2023-06-01" \
-H "x-api-key: $RADIUM_API_KEY" \
-d '{
"model": "hal-1.0",
"max_tokens": 2048,
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {
"city": { "type": "string" }
},
"required": ["city"]
}
}
],
"messages": [
{ "role": "user", "content": "What is the weather in Tokyo?" },
{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_123",
"name": "get_weather",
"input": { "city": "Tokyo" }
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_123",
"content": "Tokyo is 24 C and clear."
}
]
}
]
}'
The one to get right The
tool_use_idon your result has to match theidthe model issued. Send the tool definitions again with the follow-up, because the conversation is stateless and the model needs them on every turn.
The loop repeats for as long as the model keeps asking.
Several tools at once
Put as many definitions in the tools array as the work needs, and the model picks. Each one needs a name, a description the model can reason about, and an input_schema. The description carries more weight than people expect, because it is the only thing telling the model when a tool applies.
Streaming
Streaming works with tools on the same endpoint, so an agent loop can render output while it runs. Behaviour under streaming is worth checking against your own client before you depend on it, since every framework assembles the stream a little differently.
Where MCP sits
There is no separate Radium MCP endpoint to call, and there is nothing to configure on our side. MCP servers run on your infrastructure, your client connects to them and discovers what they expose, and the resulting tool definitions travel to Radium through the Messages API as ordinary tools.
From the model's position, a tool that arrived over MCP and a tool you hard-coded look the same. That is the point of the design, and it is why MCP support is a property of your client rather than a property of your inference provider.
MCP with Claude Code
Claude Code connects to MCP servers, discovers their tools, and passes the definitions through the model API. Radium answers the model half of that exchange. So:
- Configure Radium as the model provider with
ANTHROPIC_BASE_URL,ANTHROPIC_MODEL, and your key. The full steps are on Run Claude Code on Radium. - Configure MCP servers in Claude Code exactly as you already do. Nothing about that changes.
- Treat MCP tools as client-managed. The server is yours, the execution is yours, and Radium receives the definitions and the conversation turns.
Before production
Every MCP server exposes its own schemas and its own permissions, and models differ in how they handle an unfamiliar tool surface. Run a small smoke test of the specific workflow you intend to rely on, with the model you intend to use, before you put it in front of anyone.
Compatibility gets the request through. The smoke test tells you it works.