OpenAI-compatible
Keep your OpenAI code, change the base URL
SpicyAPI speaks the OpenAI chat completions format. Point any compatible SDK, framework or chat app at our base URL, use a model ID from the catalog, and stream replies as usual.
What is an OpenAI-compatible API?
It accepts the same requests as OpenAI's chat API. Any tool built for OpenAI can talk to SpicyAPI once you change three settings.
- Your app or chat clientOpenAI SDK, LangChain, SillyTavern…
- SpicyAPIapi.spicyapi.ai/v1
- Chat models26 models behind one key
Good for
- Apps already on the OpenAI SDKSwap the address and key. The rest of your code stays.
- Roleplay and chat appsSillyTavern, RisuAI and Agnai connect as a custom OpenAI endpoint.
- Agent frameworksLangChain, Vercel AI SDK and Aider work through their OpenAI adapters.
Connect in three steps
- Step 1
Create an API key
Log in and create a key in the console. It starts with sk-spicy-.
header Authorization: Bearer sk-spicy-… - Step 2
Change the base URL
Replace OpenAI's address with https://api.spicyapi.ai/v1.
base URL https://api.spicyapi.ai/v1 - Step 3
Pick a model ID
Copy a chat model ID from the list below and send your first message.
model xai/grok-4.7/chat
Three values to change
Most clients add /chat/completions themselves, so enter the base URL only up to /v1. Apps that ask for the full endpoint need https://api.spicyapi.ai/v1/chat/completions.
- Base URLhttps://api.openai.com/v1https://api.spicyapi.ai/v1
- API keysk-proj-…sk-spicy-…
- Modelgpt-4oPick a chat model ID
Setup for your client
Copy the snippet for the SDK, framework or app you already use. Click your tool to jump to its snippet.
curl https://api.spicyapi.ai/v1/chat/completions \
-H "Authorization: Bearer $SPICY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "MODEL_ID_FROM_CATALOG",
"messages": [{ "role": "user", "content": "Write a two-line opening scene." }],
"stream": true
}'API type: OpenAI-compatible (custom endpoint / proxy)
Base URL: https://api.spicyapi.ai/v1
API key: sk-spicy-...
Model: MODEL_ID_FROM_CATALOG # a chat model id ending in /chatChoose the OpenAI-compatible option, paste the base URL and your key, and pick a model whose ID ends in /chat.
import OpenAI from "openai";
import { randomUUID } from "node:crypto";
const client = new OpenAI({
apiKey: process.env.SPICY_API_KEY,
baseURL: "https://api.spicyapi.ai/v1",
});
// One key per business action. The SDK retries automatically, so without it a
// dropped response can create a second task and a second charge.
const idempotencyKey = randomUUID();
const completion = await client.chat.completions.create(
{
model: "MODEL_ID_FROM_CATALOG",
messages: [{ role: "user", content: "Say hello in five words." }],
},
{ headers: { "Idempotency-Key": idempotencyKey } },
);
console.log(completion.choices[0].message.content);Set baseURL on the client and pass a model ID from the catalog.
import os
import uuid
from openai import OpenAI
client = OpenAI(
api_key=os.environ["SPICY_API_KEY"],
base_url="https://api.spicyapi.ai/v1", # or set OPENAI_BASE_URL
)
# One key per business action. The SDK retries automatically, so without it a
# dropped response can create a second task and a second charge.
idempotency_key = str(uuid.uuid4())
completion = client.chat.completions.create(
model="MODEL_ID_FROM_CATALOG",
messages=[{"role": "user", "content": "Say hello in five words."}],
extra_headers={"Idempotency-Key": idempotency_key},
)
print(completion.choices[0].message.content)Set base_url on the client, or export OPENAI_BASE_URL.
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { generateText } from "ai";
import { randomUUID } from "node:crypto";
const spicy = createOpenAICompatible({
name: "spicyapi",
apiKey: process.env.SPICY_API_KEY,
baseURL: "https://api.spicyapi.ai/v1",
});
const { text } = await generateText({
model: spicy("MODEL_ID_FROM_CATALOG"),
prompt: "Say hello in five words.",
// Per call, never on the client: one key shared by every request would make
// the second request replay the first one's answer.
headers: { "Idempotency-Key": randomUUID() },
});Use the openai-compatible provider with our base URL.
import os
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="MODEL_ID_FROM_CATALOG",
base_url="https://api.spicyapi.ai/v1",
api_key=os.environ["SPICY_API_KEY"],
# Retries here would resend an already-accepted request without an
# Idempotency-Key, which bills twice. Send the key yourself (see the
# OpenAI Python recipe) before turning retries back on.
max_retries=0,
)
print(llm.invoke("Say hello in five words.").content)ChatOpenAI takes base_url and api_key directly.
export OPENAI_API_BASE=https://api.spicyapi.ai/v1
export OPENAI_API_KEY=$SPICY_API_KEY
aider --model openai/MODEL_ID_FROM_CATALOGTwo environment variables, then prefix the model with openai/.
Third-party clients change their config formats between versions. If a snippet here stops matching, the client's own documentation wins.
Chat models you can use
Copy the ID exactly as shown. Prices and context limits are on each model's page.
- Grok 4.7 · Chatxai/grok-4.7/chat
- DeepSeek V4.1 Flash · Chatdeepseek/v4.1-flash/chat
- Grok 4.3 · Chatxai/grok-4.3/chat
- Claude Haiku 5.5 · Chatanthropic/claude-haiku-5.5/chat
- Claude Sonnet 5.5 · Chatanthropic/claude-sonnet-5.5/chat
- Claude Opus 5.5 · Chatanthropic/claude-opus-5.5/chat
- GLM 5.3 Flash · Chatzai/glm-5.3-flash/chat
- GLM 5.3 · Chatzai/glm-5.3/chat
- DeepSeek V4 Pro · Chatdeepseek/v4-pro/chat
- Gemini 3.7 Flash · Chatgoogle/gemini-3.7-flash/chat
- Grok 4.6 · Chatxai/grok-4.6/chat
- DeepSeek V4 Flash · Chatdeepseek/v4-flash/chat
Fix common errors
Most first-time problems are one of these three. Each card shows what you see and the one thing to change.
- 401
Unauthorized
The key is missing, or it is an OpenAI key. Send your SpicyAPI key: Authorization: Bearer sk-spicy-…
- 404
Not found
The base URL is one level off. Use https://api.spicyapi.ai/v1, not the bare domain and not with /chat/completions added twice.
- model
Model not found
OpenAI names such as gpt-4o are not aliases here. Use a full ID in the form maker/model/chat.
