OpenAI-compat migration
One-line swap from the OpenAI SDK to Moonborn's `/v1/openai` shim. Streaming, tool calling, and function calling pass through.
If you're already using the OpenAI SDK, the cheapest path to Moonborn
is a base-URL swap. The /v1/openai/chat/completions shim accepts
OpenAI-shaped requests, returns OpenAI-shaped responses, and the model
field carries a persona ID instead of gpt-4.
1. Swap the client
import OpenAI from 'openai';
const client = new OpenAI({
apiKey: process.env.MOONBORN_API_KEY,
baseURL: 'https://api.moonborn.co/v1/openai',
});Three changes:
- API key env var:
MOONBORN_API_KEYinstead ofOPENAI_API_KEY. - Base URL:
https://api.moonborn.co/v1/openai. - Model:
persona://<persona_id>instead of a model name.
2. Make a call
const reply = await client.chat.completions.create({
model: 'persona://persona_01H...',
messages: [{ role: 'user', content: 'What drives you?' }],
});
console.log(reply.choices[0].message.content);The response shape matches OpenAI exactly. Moonborn-specific metadata
rides on x-moonborn-* response headers — drift score, voice
fingerprint match, audit ID. Your OpenAI client ignores them by
default; pull them out of reply.response.headers if you want them.
3. Stream
const stream = await client.chat.completions.create({
model: 'persona://persona_01H...',
messages: [{ role: 'user', content: 'Tell me a quiet truth.' }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}Streaming passes through unchanged. SSE chunks have OpenAI's delta
shape; the drift envelope arrives as a final header on stream close.
4. Tool / function calling
const reply = await client.chat.completions.create({
model: 'persona://persona_01H...',
messages: [{ role: 'user', content: 'What time is it in Istanbul?' }],
tools: [
{
type: 'function',
function: {
name: 'get_time',
parameters: { type: 'object', properties: { tz: { type: 'string' } } },
},
},
],
});Tool calls pass through. The persona's voice still wraps the tool-result handling — you get an in-character explanation around the data your tool returned.
5. List your personas-as-models
const models = await client.models.list();
for (const m of models.data) {
console.log(m.id); // persona://persona_01H...
}GET /v1/openai/models returns your workspace's personas in OpenAI's
models shape. Useful for IDE pickers, model selectors in admin UIs, etc.
What's not OpenAI-compatible
- Image generation, embeddings, audio. Not Moonborn's domain. Keep your OpenAI client side-by-side for those endpoints.
- Custom assistants API. Use Moonborn's native personas surface — see Build your first persona.
Tier
Free and up. The endpoint inherits your workspace's rate limit; see the rate limits reference.
Next
- Companion: MCP server integration.
- Background: OpenAI-compatible integration.
- Models endpoint reference.