Migrate from OpenRouter
BetaWe just launched Apps: hosted models, actions and pages, on the same bill as your inference.Read the Apps docs
Gateway/Get started/Migrate from OpenRouter

Migrate from OpenRouter

Model slugs match OpenRouter. Swap the base URL and the key; the rest of your code stays.

Change two lines

const client = new OpenAI({
  // baseURL: "https://openrouter.ai/api/v1",
  baseURL: "https://api.inferencebureau.com/v1",
  apiKey: process.env.IB_API_KEY,
});

What stays the same

  • Model slugs, such as openai/gpt-4o-mini.
  • The chat completions request and response shape, including streaming, tools, and response_format.
  • Token usage fields in the response.

What is different

Inference Bureau
AI SDKReplace @openrouter/ai-sdk-provider with @inferencebureau/ai-sdk-provider: ib("openai/gpt-4o-mini") takes the same model slugs. See AI SDK.
Model fallbackOff. The model you request is the model that answers, unless model fallback is allowed in Directives. OpenRouter's models list is accepted and ignored.
Provider choiceDispatch tries certified providers in a fixed order (see Routing). Limit them with allowedProviders or deniedProviders in Directives, not per request.
PresetsOpenRouter's @preset/… models become team aliases: send org/fast as the model, and define it once in Directives as a model id or a preset (model, fallback models, and defaults for temperature, top_p, max output tokens and reasoning effort). Values in the request win over the preset's.
data_collectionInstead of provider.data_collection: "deny" per request, set data.requireNoTraining in Directives to use only providers listed as not training on prompts; requireZdr requires zero data retention. Per-request provider preferences are not used.
max_tokensWithout max_tokens, output is limited to 4,096 tokens, because every request reserves its worst-case cost up front. Set it explicitly for longer answers.
Balance and limitsPrepaid: requests are refused with 402 when the balance can't cover them. Every team has default rate limits (600 requests and 2,000,000 tokens a minute, 10 at once); see Rate limits.
CostsLook up any request with GET /v1/requests/:id for its final charge.
HeadersOpenRouter-specific headers such as HTTP-Referer and X-Title are not used. Send X-Client-Request-ID for your own correlation id.
Claude modelsChat completions works, but tools and tool_choice go through an OpenAI-shaped translation. For Claude tool use, especially forced tools, call POST /v1/messages with the Anthropic SDK: requests pass through natively.
Web searchOpenRouter's :online suffix and plugins aren't supported. Claude searches through the web_search tool, and Perplexity Sonar searches on every request. See Web search.
RetriesIf a provider fails before it starts answering, the request is retried on the same model, at most three attempts in all. Each attempt is listed on the receipt. See Routing.
End usersThe user field works as on OpenRouter: it is recorded as your end user and never forwarded. Logs, usage export and per-end-user limits and budgets in Directives use it. See End users and tags.
TagsSend ib-tags (or ib.tags) to break costs down by feature. They are kept by Inference Bureau and cost nothing extra.
EmbeddingsPOST /v1/embeddings works for certified embedding models; GET /v1/models lists them with type: "embedding".
Responses APIPOST /v1/responses works on models certified for it. Responses are kept only with store: true (OpenRouter keeps none), for 30 days, so previous_response_id can continue them. OpenAI's web_search needs max_tool_calls; its other hosted tools are refused.

Only certified models can be called. GET /v1/models lists the ones your key may use, with their capabilities, and Models shows the full catalog with certification status.