OpenAI Client with Anthropic Upstream
AISIX lets an application keep the OpenAI Chat Completions request shape while the gateway calls an Anthropic upstream model. Use this pattern when application code is already built around an OpenAI-compatible SDK, but the platform team wants to route that traffic to Claude.
AISIX resolves the model alias, translates the request to Anthropic Messages, calls Anthropic with the stored provider credential, and translates the response back into an OpenAI-compatible chat completion.
Prerequisites
Before starting, prepare the following:
- A self-hosted AISIX gateway with the admin and proxy listeners available.
- The admin key from the gateway
config.yaml. - An Anthropic API key.
- A plaintext caller API key value for the application.
- Node.js and the official OpenAI SDK if you want to run the SDK example.
How Translation Works
The application keeps the OpenAI-compatible client contract. Provider selection and protocol translation stay in the gateway.
For each request, AISIX receives the OpenAI-compatible chat-completions body, resolves the requested model alias to an Anthropic-backed model, sends an Anthropic Messages request upstream, and returns an OpenAI-compatible chat-completions response to the client.
AISIX also translates token usage and stop reasons into the OpenAI-compatible response shape so SDK consumers can keep their existing parsing path.
This path fits common OpenAI-compatible chat requests. Prefer the Anthropic-style /v1/messages route when the application depends on Anthropic-specific content blocks, cache control, thinking blocks, or exact Anthropic tool semantics.
Configure the Anthropic Upstream
Create a provider key for Anthropic. Set api_base to the bare host because AISIX appends the Anthropic route path.
curl -sS -X POST "http://127.0.0.1:3001/admin/v1/provider_keys" \
-H "Authorization: Bearer YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"display_name": "anthropic-prod",
"provider": "anthropic",
"adapter": "anthropic",
"secret": "YOUR_ANTHROPIC_API_KEY",
"api_base": "https://api.anthropic.com"
}'
Copy the returned provider key ID, then create a model alias that points to the Anthropic provider key.
Create the Anthropic-backed model alias:
curl -sS -X POST "http://127.0.0.1:3001/admin/v1/models" \
-H "Authorization: Bearer YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"display_name": "claude-prod",
"provider": "anthropic",
"model_name": "claude-3-5-haiku-20241022",
"provider_key_id": "YOUR_PROVIDER_KEY_ID"
}'
The display_name is the model value the OpenAI-compatible client sends to AISIX. The model_name is the upstream Anthropic model ID AISIX sends to Anthropic.
Copy the returned model ID if you plan to delete the example resources later.
Create a Caller API Key
Hash the plaintext caller key:
export AISIX_API_KEY="sk-anthropic-via-openai"
export CALLER_KEY_HASH=$(printf '%s' "${AISIX_API_KEY}" | shasum -a 256 | awk '{print $1}')
Create the caller API key with access to the Anthropic-backed alias:
curl -sS -X POST "http://127.0.0.1:3001/admin/v1/apikeys" \
-H "Authorization: Bearer YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"key_hash": "'"${CALLER_KEY_HASH}"'",
"allowed_models": ["claude-prod"]
}'
Copy the returned caller API key ID if you plan to delete the example resources later.
Call the Alias with the OpenAI SDK
Install the OpenAI SDK:
npm install openai
Create a minimal chat-completions client:
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AISIX_API_KEY,
baseURL: "http://127.0.0.1:3000/v1",
});
const completion = await client.chat.completions.create({
model: "claude-prod",
messages: [{ role: "user", content: "Say hello from AISIX." }],
});
console.log(completion.choices[0]?.message.content);
console.log(completion.usage);
Run the example:
AISIX_API_KEY="sk-anthropic-via-openai" node anthropic-via-openai-sdk.mjs
The response is OpenAI-compatible. The caller does not receive Anthropic-shaped content blocks.
Verify with HTTP
You can also inspect the response with curl:
curl -sS -X POST "http://127.0.0.1:3000/v1/chat/completions" \
-H "Authorization: Bearer sk-anthropic-via-openai" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-prod",
"messages": [{"role":"user","content":"Say hello from AISIX."}]
}'
A successful response has the OpenAI-compatible chat-completions shape:
{
"object": "chat.completion",
"model": "claude-prod",
"choices": [
{
"message": {
"role": "assistant",
"content": "Hello from AISIX."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 9,
"completion_tokens": 5,
"total_tokens": 14
}
}
Next Steps
You have now routed an OpenAI-compatible client to an Anthropic upstream. Continue with OpenAI-Compatible API for the caller-facing route behavior, Anthropic Messages when you want the Anthropic request and response shape end to end, or Provider Compatibility for endpoint and provider support boundaries.