Migrate from Anthropic

Joule Cloud is OpenAI-shaped, not Anthropic-shaped, so this guide is slightly more work than the OpenAI one. The good news: Anthropic's Messages API maps cleanly onto OpenAI Chat Completions, and Claude Haiku 4.5 is available through the router where licensing allows.

The shape diff

AnthropicJoule Cloud (OpenAI-shape)
anthropic.messages.create({ model, messages, system })openai.chat.completions.create({ model, messages }) with system prompt as {role:"system"}
response.content[0].textresponse.choices[0].message.content
response.usage.input_tokens / output_tokensX-Energy-Joules response header (joules, not tokens)
tool_use blocktool_calls array on message
tool_result block{role:"tool", tool_call_id, content}
Streaming via response_format: "stream"Streaming via stream: true (SSE)

System prompts

Anthropic's top-level system parameter becomes a system-role message:

// Anthropic
- await client.messages.create({
-   model: "claude-haiku-4-5",
-   system: "You are concise.",
-   messages: [{role:"user", content:"hi"}],
- });

+ // Joule Cloud (OpenAI shape)
+ await client.chat.completions.create({
+   model: "auto",          // or "claude-haiku-4.5" to keep Claude
+   messages: [
+     {role:"system", content:"You are concise."},
+     {role:"user", content:"hi"},
+   ],
+ });

Multi-turn with tool use

Anthropic's tool_use / tool_result blocks become OpenAI tool_calls / tool messages. Tool definitions are similar but the wrapping differs.

tools: [{
  type: "function",
  function: {
    name: "get_weather",
    description: "Get current weather in a location",
    parameters: { /* JSON schema */ },
  },
}]

What you gain

What you lose (and how to keep it)

Code

// Anthropic SDK
import Anthropic from "@anthropic-ai/sdk";
const a = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

const r = await a.messages.create({
  model: "claude-haiku-4-5",
  max_tokens: 1024,
  system: "You are concise.",
  messages: [{ role: "user", content: "Summarize this contract." }],
});
console.log(r.content[0].text);

// ─── Joule Cloud equivalent ───
import OpenAI from "openai";
const jc = new OpenAI({
  baseURL: "https://api.greenjoules.cloud/v1",
  apiKey: process.env.JC_API_KEY,
});

const r = await jc.chat.completions.create({
  model: "claude-haiku-4.5",      // or "auto"
  max_tokens: 1024,
  messages: [
    { role: "system", content: "You are concise." },
    { role: "user", content: "Summarize this contract." },
  ],
});
console.log(r.choices[0].message.content);
console.log(r.response?.headers?.["x-energy-joules"]);  // ← new

For the underlying API surface and headers, see API reference. For the routing rules, see Routing & placement.