Add cloud catalog models to Jan without leaving local-first.
Updated 2026-07-16
Jan runs models on your machine by design, and its Model Providers settings accept any OpenAI-compatible endpoint for the days local is not enough: add a provider, set the Base URL to https://api.apisrouter.com/v1, paste one key, and Claude, GPT, Gemini, and DeepSeek ids join your local lineup.
Quick answer: one provider in Settings.
Open Jan's Settings and go to Model Providers. Click the plus control next to the provider list to add a custom provider, give it a name (APIsRouter), and on recent builds pick the OpenAI API format when the dialog asks (Jan v0.8.1 added an OpenAI-or-Anthropic format selector; for a gateway choose OpenAI). Then fill the two fields that matter: Base URL https://api.apisrouter.com/v1 and your API key. Add the models you want by id: Jan's docs are explicit that the id property must match the model name the endpoint serves, so copy ids from the catalog listing (claude-sonnet-4-6, gpt-5.4-mini, gemini-3.5-flash) rather than typing from memory. Save, and the ids appear in the model selector next to whatever you run locally. Labels have moved between releases (older versions called this area Remote Engines), so treat provider, format, URL, key, models as the stable skeleton.
Name: APIsRouter
API Format: OpenAI (v0.8.1+ selector)
Base URL: https://api.apisrouter.com/v1
API Key: sk-YOUR-APISROUTER-KEY
Models: add ids that match the endpoint, e.g.
claude-sonnet-4-6, gpt-5.4-mini, gemini-3.5-flashHow Jan treats remote providers.
Jan (menloresearch on GitHub, roughly 44K stars) is the local-first desktop client: models download to your machine, run through llama.cpp, and work offline, with the app even exposing its own OpenAI-compatible server at http://127.0.0.1:1337/v1 for other tools. Remote providers are the deliberate second lane, for models too large to run locally or tasks that earn frontier quality. A custom provider in the OpenAI format is a plain endpoint description: base URL, key, declared model ids. Conversations against those ids leave as standard chat-completions requests with the id as the model string, so a multi-vendor gateway needs exactly one entry. Claude for careful writing, DeepSeek for volume summarization, Gemini for speed, one key behind all of them. The philosophical fit is better than it first sounds. Local-first users tend to be deliberate about what leaves the machine, and a gateway keeps the remote lane equally deliberate: one endpoint to firewall, one usage log to read, one balance that only moves when you chose to send something out. Nothing about the local lane changes; your downloaded models keep working offline exactly as before.
Declaring models: the id contract.
Jan does not fetch a custom endpoint's catalog for you; the models you declare are the models you get, and the id is the contract. The authoritative spelling comes from the gateway's /v1/models listing, version suffixes included. A declared id that drifts from the listing produces not-found errors only when that model is selected, which reads like a flaky provider until you compare strings. Declare deliberately. A local-first picker works best when the remote rows are few and purposeful: one fast id for everyday remote turns (gpt-5.4-mini or claude-haiku-4-5-20251001), one frontier id for the work that justifies leaving the machine (claude-sonnet-4-6), and whatever specialist your workload earns (deepseek-v4-flash for long multilingual summaries, gemini-3.5-flash when latency is the feature). Each row is easy to add later; a pasted-in catalog is noise you scroll past daily. If you also use Jan's local API server to serve other tools, keep the mental model straight: that server is Jan being a provider at 127.0.0.1:1337/v1; the custom provider entry is Jan being a client. The two are independent, and configuring one never affects the other.
curl -s https://api.apisrouter.com/v1/models \
-H "Authorization: Bearer $APISROUTER_API_KEY" | head -50
# declare these ids verbatim in the provider's model listChoosing which conversations leave the machine.
Because remote usage is prepaid and per-key metered, the cost of the remote lane is a number you read, not a subscription you guess at. Run a month of your real split and the usage log tells you exactly what leaving the machine costs, per model, per day.
- Everyday remote turns, quick questions, rewrites, translations, belong on the fast tier: gpt-5.4-mini and claude-haiku-4-5-20251001 answer quickly and keep the balance almost still.
- claude-sonnet-4-6 is the step-up for work a local model visibly cannot carry: long careful drafting, subtle code review, analysis you will forward.
- gemini-3.5-flash earns its row on latency; for short interactive turns it feels closest to a local model's responsiveness.
- deepseek-v4-flash is the volume pick for summarizing long documents you would not feed a small local model.
- Keep private material on local models entirely; the split between lanes is the point of running Jan in the first place.
Pay-as-you-go · transparent per-model pricing
Selected models are priced below official list prices. Exact input, output, cache, and per-request prices are shown for each model.
| Model | Official Price | Our Price |
|---|---|---|
| Claude Haiku 4.5 20251001 | $1.00 / $5.00 per M | $0.80 / $4.00 per M |
| Claude Sonnet 4.6 | $3.00 / $15.00 per M | $2.40 / $12.00 per M |
| GPT-5.4 Mini | $0.75 / $4.50 per M | $0.60 / $3.60 per M |
| Gemini 3.5 Flash | $1.50 / $9.00 per M | $1.20 / $7.20 per M |
| DeepSeek V4 Flash | $0.14 / $0.28 per M | $0.13 / $0.25 per M |
Failure modes specific to Jan.
Not-found errors on a specific model are the id contract: the declared id does not match the endpoint's spelling. Compare against the /v1/models output character for character. Authentication failures on every request are the key field. A provider that saves but never answers usually has a Base URL problem: the /v1 suffix must be present, since Jan appends route paths like /chat/completions to the base you give it, and a doubled or missing segment 404s. If the provider was created on an older build, check the API format: v0.8.1 introduced the OpenAI-or-Anthropic selector, and a gateway entry accidentally set to the Anthropic format speaks the wrong dialect to a /v1/chat/completions endpoint. And remember which lane you are debugging. Local model failures (VRAM, quantization, llama.cpp settings) and remote failures (URL, key, ids) share a chat window but nothing else; the model selector shows which lane a failing conversation belongs to before you start pulling on the wrong thread.
Who adds a gateway lane to Jan.
- Local-first users who occasionally need frontier quality and want that occasional lane on a prepaid balance rather than a vendor subscription.
- Developers on machines that cannot run large local models well, using Jan as the interface and the gateway for the heavy lifting.
- Privacy-deliberate users who want exactly one remote endpoint to reason about, firewall, and audit, instead of one per vendor.
- People comparing local versus cloud output on real tasks, where the remote candidates are declared rows, not new accounts.
- Developers without access to a given vendor's billing. Top-up based access with no card requirement removes the per-provider sign-up dependency.
Verify the endpoint and debug the first remote turn.
Curl the models listing and one chat completion first; with both passing, everything left is in the provider entry. This also hands you the exact id spellings to declare. Inside Jan, send one short message on the fast remote id. Authentication errors are the key; not-found is the id; silence or 404s are the Base URL shape. If the remote lane works but feels slow on the frontier id, that is model latency, not a configuration problem; reasoning models take their time on long turns. Once remote turns flow, the APIsRouter console shows per-request model, token counts, and spend. For a local-first user this log is unusually satisfying reading: it is the complete record of everything that ever left the machine, per model, per day, with the local lane contributing exactly nothing to it.
curl -s https://api.apisrouter.com/v1/chat/completions \
-H "Authorization: Bearer $APISROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-5.4-mini",
"messages":[{"role":"user","content":"ping"}]}'FAQ
How do I add a custom OpenAI-compatible provider to Jan?
Settings, Model Providers, then the plus control to add a provider. Name it, choose the OpenAI API format on builds that ask (v0.8.1+), set Base URL https://api.apisrouter.com/v1, paste your key, and declare model ids that match the endpoint's listing.
Why does my declared model return not-found?
Jan sends the declared id verbatim as the model string, and its docs require the id to match the endpoint's model name exactly. Pull the /v1/models listing and copy the spelling, version suffixes included, instead of typing ids from memory.
Does adding a remote provider change how local models work?
No. Local models keep running on-device through llama.cpp, offline included. The provider entry adds a separate remote lane to the selector, and conversations only touch the network when you pick a remote id.
Should the Base URL include /v1?
Yes: https://api.apisrouter.com/v1. Jan appends routes like /chat/completions to the base you configure, so a missing /v1 404s and a doubled one does too. If requests fail, read the composed URL in the error before changing anything else.
Can Jan reach Claude and Gemini through one provider entry?
Yes. In the OpenAI format the model id travels as a plain string, so claude-sonnet-4-6, gemini-3.5-flash, gpt-5.4-mini, and deepseek-v4-flash can all be declared under one entry, billed through one key, and switched per conversation.
Is this the same as Jan's local API server?
No. The local server at 127.0.0.1:1337/v1 is Jan serving its local models to other tools. The custom provider entry is Jan consuming a remote endpoint. They are independent features that happen to share the OpenAI wire format.