Open app
Moonborn — Developers

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_KEY instead of OPENAI_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