Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TokenBanking SDK

One API key, every model, always routed to the cheapest available supplier. Streaming, tool calling, retries and timeouts all work out of the box, and you can cap what you're willing to pay per request.

Works with Node.js ≥ 20 or Bun.

Get an API key

  1. Sign in at https://tokenbanking.aimake.website/.
  2. Load credits under Dashboard → Credits (USDC on Arc, or Stripe).
  3. Create a key under Dashboard → API keys and copy the tb_… token. Treat it like a password; you can copy it again from the key list.
export TOKENBANKING_API_KEY="tb_…"

Installation

npm install tokenbanking
# or
bun add tokenbanking

Quickstart

import TB from "tokenbanking";

// apiKey defaults to $TOKENBANKING_API_KEY, baseURL to the hosted router.
const tb = new TB.Client();

const response = await tb.chat.completions.create({
  model: "minimax/minimax-m2.7",
  messages: [{ role: "user", content: "Explain USDC in two sentences." }],
  maxPrice: { input: 1.0, output: 1.0 }, // USD per 1M tokens
});

console.log(response.choices[0].message.content);

Model ids are the vendor-prefixed ids listed on the Models pageminimax/minimax-m2.7, deepseek/deepseek-v3.2, z-ai/glm-5.2, and so on.

Configuration is picked up from the environment when not passed explicitly:

Env var Purpose Default
TOKENBANKING_API_KEY Your TokenBanking consumer key
TOKENBANKING_BASE_URL Router base URL https://tb-proxy.aimake.website/v1

Price caps (maxPrice)

maxPrice caps what you're willing to pay, in USD per 1M tokens. Anything you leave out is unlimited. Suppliers above your cap are skipped; if no supplier fits, the request fails with 402 instead of overpaying.

const chat = await tb.chat.completions.create({
  model: "minimax/minimax-m2.7",
  messages: [{ role: "user", content: "Hello!" }],
  maxPrice: { input: 1.0 }, // output & cached: no limit
});

The SDK lifts maxPrice out of the request body into x-tb-max-price-* headers, so it never reaches the upstream provider.

TypeScript

maxPrice is an extension to the standard chat-completions body, so TypeScript needs to be told about it — wrap the params in WithMaxPrice<…>:

import TB, { type WithMaxPrice } from "tokenbanking";
import type { ChatCompletionCreateParamsNonStreaming } from "openai/resources/chat/completions";

const params: WithMaxPrice<ChatCompletionCreateParamsNonStreaming> = {
  model: "minimax/minimax-m2.7",
  messages: [{ role: "user", content: "Hello!" }],
  maxPrice: { input: 1.0, output: 1.0 },
};

const chat = await tb.chat.completions.create(params);

On responses.create it is typed natively, so no wrapper is needed there.

Fallback

Pass any OpenAI-compatible client as fallback. If the router is unreachable or returns 402 / 408 / 429 / 5xx, the same request is transparently replayed against the fallback with its own base URL and API key:

import TB from "tokenbanking";
import OpenAI from "openai";

const tb = new TB.Client({
  fallback: new OpenAI({ apiKey: process.env.OPENAI_API_KEY }),
});

Streaming

const stream = await tb.chat.completions.create({
  model: "minimax/minimax-m2.7",
  messages: [{ role: "user", content: "Write a haiku about foxes." }],
  stream: true,
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

Tool calling

const response = await tb.chat.completions.create({
  model: "minimax/minimax-m2.7",
  messages: [{ role: "user", content: "What's the weather in São Paulo?" }],
  tools: [
    {
      type: "function",
      function: {
        name: "get_weather",
        description: "Get the current weather for a city",
        parameters: {
          type: "object",
          properties: { city: { type: "string" } },
          required: ["city"],
        },
      },
    },
  ],
});

for (const call of response.choices[0].message.tool_calls ?? []) {
  if (call.type !== "function") continue;
  console.log(call.function.name, JSON.parse(call.function.arguments));
}

Feed results back as role: "tool" messages, exactly as with openai-node.

Responses API

tb.responses.create is a shim over /v1/chat/completions (the router is chat-completions native):

const response = await tb.responses.create({
  model: "minimax/minimax-m2.7",
  input: "Complete the sentence: 'The quick brown fox jumps over the'",
  maxPrice: { input: 1.0, output: 1.0 },
});

console.log(response.output_text);

Note: it supports text/image input, instructions, function tools and streaming. Responses-only features (previous_response_id, built-in tools, background, …) throw a clear error. For full control, use tb.chat.completions.create.

Everything else from openai-node

TB.Client extends the OpenAI client, so per-request options work unchanged:

await tb.chat.completions.create(
  { model: "minimax/minimax-m2.7", messages: [{ role: "user", content: "hi" }] },
  {
    headers: { "x-my-header": "value" }, // custom headers
    timeout: 30_000,
    maxRetries: 1,
  },
);

Errors

Errors are the standard openai-node classes (APIError, RateLimitError, …). A 402 means no supplier fits your maxPrice, or your credits ran out — top up at https://tokenbanking.aimake.website/dashboard/credits.

Using the plain OpenAI SDK

Don't want to switch SDKs? The router is fully OpenAI-compatible — point the official openai client at TokenBanking and set the price-cap headers yourself:

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.TOKENBANKING_API_KEY,
  baseURL: "https://tb-proxy.aimake.website/v1",
});

const chat = await client.chat.completions.create(
  {
    model: "minimax/minimax-m2.7",
    messages: [{ role: "user", content: "Explain USDC in two sentences." }],
  },
  {
    headers: {
      // USD per 1M tokens; omit a header for no limit on that side
      "x-tb-max-price-input": "1.00",
      "x-tb-max-price-output": "1.00",
      // "x-tb-max-price-cached": "0.10",
    },
  },
);

Or set the caps once for every request via defaultHeaders:

const client = new OpenAI({
  apiKey: process.env.TOKENBANKING_API_KEY,
  baseURL: "https://tb-proxy.aimake.website/v1",
  defaultHeaders: {
    "x-tb-max-price-input": "1.00",
    "x-tb-max-price-output": "1.00",
  },
});

The same headers work with any HTTP client (curl, Python openai, etc.). If no supplier fits the caps, the router responds 402. Automatic fallback is a client-side feature of this SDK, so with plain openai you'd handle failover yourself.

Development

bun install
bun test          # run tests
bun run typecheck # tsc --noEmit
bun run build     # emit dist/

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages