Connect providers
A provider is where a bot's model runs. Your backend adds one with fxbot.providers, or with fxbot.signIns for an account. Every kind, and what fxbot reads from it, is in Providers.
A server on your network
For ollama, lmstudio, and custom, which is any server with an OpenAI-style Chat Completions API.
const local = await fxbot.providers.add({ kind: "ollama", model: "qwen3:8b" });- Ollama and LM Studio default to their usual address on this machine. Give
baseUrlfor another, such ashttp://192.168.1.20:11434/v1. Acustomserver needs one. - An address must use
https, orhttpon localhost. apiKeyis for acustomserver that wants a key.contextWindowoverrides the context window the server reports, for every model it serves.
The server must be running: add asks it for its models first.
An API key
For openai, gateway, openrouter, opencode, and opencode-go.
const openai = await fxbot.providers.add({ kind: "openai", apiKey: process.env.OPENAI_API_KEY!, model: "gpt-5" });add checks the key with the provider, and refuses one the provider rejects. Then the SDK seals the key in Postgres. A listed provider says only hasKey: true, never the key.
To change a key, update it. It's checked again:
await fxbot.providers.update(openai.id, { apiKey: newKey });An account, with a device code
For chatgpt, grok, and vercel. The person signs in on any device, and the SDK claims the tokens on your backend.
Start the sign-in, and show its link and code:
const signIn = await fxbot.signIns.start({ kind: "chatgpt" }); console.log(`Open ${signIn.verificationUrl} and enter ${signIn.userCode}`);Ask how it's going until it's done. A finished sign-in names the new provider:
import { setTimeout as sleep } from "node:timers/promises"; let provider: string | undefined; while (!provider) { await sleep(2000); const status = fxbot.signIns.get(signIn.id); if (status.status === "failed") throw new Error(status.error); provider = status.provider; }For a Vercel account with more than one team, pick the team to bill:
const teams = await fxbot.providers.teams(provider); await fxbot.providers.update(provider, { teamId: teams[0].id });
One sign-in runs at a time: a new one replaces one still waiting. signIns.cancel(id) stops one. To sign in again to a provider you have, as after a failed refresh, pass its id: signIns.start({ kind: "chatgpt", provider: id }).
A Vercel account needs fxbot's Vercel OAuth app: pass its id to createFxbot as vercelClientId.
Then: models and bots
List the provider's models, and pick its default model:
const models = await fxbot.providers.models(openai.id); // ids, and a context window when known await fxbot.providers.update(openai.id, { model: "gpt-5" });Make it the default provider, so new bots start on it:
await fxbot.settings.update({ defaultProvider: openai.id }); const bot = await fxbot.profiles.create({ name: "Scout" });Or give a bot its provider, and a model of its own, when you make it:
profiles.create({ name, provider, model }). A bot with no model follows its provider's default.To move a bot to another provider, update it:
await fxbot.profiles.update(bot.id, { provider: local.id, model: "qwen3:8b" });A bot with a chat starts a new one there, from a summary of the old one. See Moving a bot to another provider.
providers.remove(id) removes a provider that no bot uses.
From a page
The client has the same calls over fxbot's HTTP API: client.providers.add(...), client.signIns.start(kind), and client.signIns.get(id). A key goes up to the server once and never comes back. See Build a page on the client.
If it doesn't work
addsays the provider rejected this key. It answered 401 or 403. Check the key, and that it's for that kind.addcan't reach a server on your network. Start the server first, and checkbaseUrl. Ollama's ends in/v1.signIns.startasks forFXBOT_VERCEL_CLIENT_ID. PassvercelClientIdtocreateFxbot.- A ChatGPT sign-in fails. The account or workspace must allow device code sign-in. The error says how to turn it on.
sendsays there's no model. Give the provider a default model, as in step 1, or give the bot one.sendsays the bot has no provider. Set a default provider before you make bots, or give each bot one.providers.removesays bots use the provider. Move them to another provider first.