OpenAI Node.js SDK with a custom Base URL
Use the official openai-node package with MonkeyAI by changing the client baseURL, not by rewriting SDK internals. Verify the key and Model ID first, then test the exact endpoint your application uses.
Install and configure the client
npm install openai export OPENAI_API_KEY="YOUR_KEY"
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: "https://monkeytheme.com/v1",
});baseURL with an uppercase URL. The SDK constructor also reads OPENAI_API_KEY by default, but keeping it explicit makes the configuration easier to audit.Check the key and exact Model ID first
List models before writing generation code. Use an ID returned to your own key rather than copying a model name from a screenshot.
const models = await client.models.list(); for (const model of models.data) console.log(model.id);
On August 3, 2026, unauthenticated production checks of /v1/models, /v1/responses and /v1/chat/completions all returned structured 401 API_KEY_REQUIRED. That proves the routes reach the authentication layer. It does not prove authenticated model or feature support.
Send one minimal Responses request
const response = await client.responses.create({
model: "MODEL_ID_FROM_LIST",
input: "Reply with OK",
max_output_tokens: 16,
store: false,
});
console.log(response.output_text);
console.log("request_id", response._request_id);OpenAI recommends Responses for new projects. A compatible gateway can still support endpoints unevenly, so run this minimal request before adding tools, streaming or conversation state.
Chat Completions is a different response shape
const completion = await client.chat.completions.create({
model: "MODEL_ID_FROM_LIST",
messages: [{ role: "user", content: "Reply with OK" }],
max_completion_tokens: 16,
});
console.log(completion.choices[0].message.content);
console.log("request_id", completion._request_id);Do not swap only the path. Responses uses input and typed output items; Chat Completions uses messages and choices. See the endpoint comparison before migrating an existing client.
Timeouts, retries and useful error logs
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: "https://monkeytheme.com/v1",
timeout: 30_000,
maxRetries: 2,
});
try {
// Make the request here.
} catch (err) {
console.error({
name: err.name,
status: err.status,
request_id: err.request_id,
message: err.message,
});
}The official SDK defaults to a ten-minute client timeout and two retries for connection errors, 408, 409, 429 and 5xx responses. A reverse proxy may time out sooner. Do not increase every timeout blindly, and remember that an outer retry loop can multiply requests.
Common configuration mistakes
| Symptom | Check |
|---|---|
| 404 | Use baseURL: "https://monkeytheme.com/v1", without a duplicated /v1 or resource path. |
| 401 API_KEY_REQUIRED | Confirm the process can read OPENAI_API_KEY; never print the full value. |
| model not found | Copy the exact ID from client.models.list(). |
| Parser reads undefined | Use output_text for Responses or choices[0].message.content for Chat Completions. |
| One action creates several attempts | Count SDK retries and application retries together. |
Sources and related guides
- Official openai-node README: constructor, Responses, Chat Completions, retries, timeouts and request IDs.
- API Base URL and /v1
- API key and model troubleshooting
- API 504 timeout troubleshooting
FAQ
Should baseURL include /v1?
Yes. For this gateway, initialize the OpenAI client with https://monkeytheme.com/v1. Do not append /chat/completions to baseURL; the SDK adds the resource path.
Can I hardcode the API key in server.js?
You can, but you should not. Read it from OPENAI_API_KEY or another server-side secret and keep .env files out of version control.
Does a 401 mean the Node.js SDK is incompatible?
No. A structured 401 means the request reached the authentication layer. Check the key and Authorization header before changing SDK code.
Why can /v1/models work while generation fails?
The model-list route checks authentication and model visibility. A generation route also depends on the selected model, account routing and upstream response.
Does MonkeyAI support every openai-node feature?
This guide does not make that claim. Route checks confirm authentication-layer reachability; models, tools, streaming and Responses features require authenticated tests.
How many times does openai-node retry by default?
The official README says the SDK retries connection errors, 408, 409, 429 and 5xx responses twice by default. Set maxRetries deliberately when diagnosing duplicate attempts.