TypeScript SDK
@mubit-ai/sdk is for Node.js developers. It hands you the OpenAI or Anthropic client already pointed at Mubit, and it manages your Mubit organization from code. This page covers version 1.0.6.
Install
npm install @mubit-ai/sdk openai # add @anthropic-ai/sdk if you call Claudeopenai and @anthropic-ai/sdk aren't dependencies of the package: install the ones you use. The package needs Node.js 22.12 or newer. It ships ES modules and a CommonJS entry point, and its types come with it.
Set your keys
The SDK uses two kinds of key: an inference key (mbt_ or mw_) to send model calls, and a management key (mwm_) to manage Mubit. SDKs and tools shows how to create each one.
export MUBIT_API_KEY=<your inference key>
export MUBIT_MANAGEMENT_KEY=<your management key>new Mubit() reads both from the environment. You can also pass them in:
import { Mubit } from "@mubit-ai/sdk";
const client = new Mubit({
apiKey: process.env.MUBIT_API_KEY,
managementKey: process.env.MUBIT_MANAGEMENT_KEY,
});Your code needs the key for the job it does. Code that only sends model calls needs only the inference key. Code that only manages Mubit needs only the management key. Without the key a method needs, the SDK throws an error before it sends anything.
| Option | What it sets |
|---|---|
apiKey | The inference key, for model calls. |
managementKey | The management key, for the management methods. |
baseUrl | The Mubit API address. The default is https://api.mubit.ai. |
maxRetries | How many times a failed management call is retried. The default is 2. |
Send model calls through Mubit
Your code keeps using the provider's own client. client.calls.openai() and client.calls.anthropic() give you one that already points at Mubit and carries your inference key. Mubit records each call and forwards it to the provider with the provider key stored for your project. Your calls, the tasks they form and the models trained from them then show in the console.
import { Mubit } from "@mubit-ai/sdk";
const client = new Mubit();
const openai = client.calls.openai(); // a stock OpenAI client
const reply = await openai.chat.completions.create({
model: "gpt-5-mini",
messages: [{ role: "user", content: "Classify this ticket: the invoice total is wrong." }],
});
console.log(reply.choices[0].message.content);Both methods take the provider client's own options, such as timeout, maxRetries and defaultHeaders, and pass them through unchanged:
import { Mubit } from "@mubit-ai/sdk";
const client = new Mubit();
const claude = client.calls.anthropic({ timeout: 30 * 1000, maxRetries: 3 });Other providers, or your own client setup
Any provider client works when you give it Mubit's base URL for that provider and your inference key as its API key:
| Provider | Base URL |
|---|---|
| OpenAI | https://api.mubit.ai/openai/v1 |
| Anthropic | https://api.mubit.ai/anthropic |
| Google Gemini | https://api.mubit.ai/gemini |
| OpenRouter, Groq, Together, Mistral (OpenAI-compatible) | https://api.mubit.ai/compat/<provider>/v1, for example https://api.mubit.ai/compat/groq/v1 |
import Anthropic from "@anthropic-ai/sdk";
const claude = new Anthropic({
baseURL: "https://api.mubit.ai/anthropic",
apiKey: process.env.MUBIT_API_KEY,
});Connect covers each provider, and OpenAI-compatible the compatible services. A project can also use a Neon AI Gateway key: see Connect with the Neon AI Gateway.
Manage Mubit from code
With a management key, your code can do what you do in the console. Manage Mubit lists every method. This example reads the tasks, rates a call, trains a new version and rolls it out:
import { Mubit } from "@mubit-ai/sdk";
const client = new Mubit();
for await (const task of client.tasks.list()) {
// every task, across all pages
console.log(task.id, task.name, task.stage);
}
const taskId = "task_triage12";
const calls = await client.calls.list({ task: taskId, limit: 20 });
await client.calls.feedback(calls.data[0].id, { rating: "down", comment: "Missed the sales tax line." });
await client.tasks.train(taskId); // train a new version now
const versions = await client.tasks.versions(taskId);
const version = versions.data[0];
await client.versions.rollout(version.id, { canary_percent: 10 }); // serve it on 10% of the task's calls
await client.versions.promote(version.id); // then on all of them
await client.versions.rollback(version.id); // or go back to the previous versionThe namespaces are org, projects, keys, providers, managementKeys, calls, tasks, versions, lessons, imports, usage, billing, activity and jobs. Answers are the API's JSON as plain objects.
Follow a job
A long-running operation runs as a job. jobs.wait polls the job until it ends. It throws if the job fails or is canceled, or if the wait passes timeoutMs (60 seconds by default):
import { Mubit } from "@mubit-ai/sdk";
const client = new Mubit();
const job = await client.jobs.wait("job_example1", { timeoutMs: 5 * 60 * 1000 });
console.log(job.status);Pages, retries and safe repeats
- Lists come in pages. A list call returns its first page, as
page.dataandpage.next_cursor. Loop over the result withfor awaitand the client fetches the next pages for you. - Busy or failing calls are retried. On a
429or5xxanswer, or a network error, the client waits, honouring the server'sRetry-Afterwhen it sends one, and retries up tomaxRetriestimes (2 by default). - A retried write isn't applied twice. Every
POSTcarries anIdempotency-Keyheader. The client makes one for you, or you can pass your own as{ idempotencyKey: "..." }in the last argument.
Errors
Every error the management methods throw is a MubitError, so one catch handles all of them. The error has these fields:
| Field | What it holds |
|---|---|
status | The HTTP status, or null when no answer came. |
code | A short reason, such as not_found. A connection that failed has connection_error. |
requestId | The request's id. Quote it when you contact support. |
details | More about the failure, when there is any. |
Each status has its own subclass, so you can also test the class name: ConfigurationError (no key, or a bad option), BadRequestError (400), AuthenticationError (401), PermissionDeniedError (403), NotFoundError (404), ConflictError (409), PayloadTooLargeError (413), RateLimitError (429, after the retries; it also has retryAfter), InternalServerError (500) and ServiceUnavailableError (503).
import { Mubit } from "@mubit-ai/sdk";
const client = new Mubit();
try {
await client.tasks.get("task_triage12");
} catch (err) {
const failure = err as { status?: number | null; code?: string; requestId?: string | null };
if (failure.status !== 404) throw err;
console.log(failure.code, failure.requestId);
}Errors from model calls you send through Mubit are the provider client's own, for example OpenAI.APIError.
The package also has helpers for runtime calibration. The guide shows that feature with plain HTTP calls.
Related
- SDKs and tools: the keys, and the other tools.
- Manage Mubit: every method, with its Python method, command and MCP tool.
- Migrate to 1.0: moving code from an earlier version.
- Frameworks: the Vercel AI SDK, LangChain and the OpenAI Agents SDK.