Run your Khoj second brain on a custom OpenAI base URL.

Updated 2026-07-16

Khoj documents an OpenAI-proxy setup with two surfaces: an OPENAI_BASE_URL environment variable that seeds models on first run, and an AI Model API entry in the admin panel with an Api Base Url field. Point either at https://api.apisrouter.com/v1 and chat, agents, and automations run on any catalog model.

Quick answer: env var on first run, admin panel any time.

Khoj's self-hosting compose file carries a commented OPENAI_BASE_URL line intended, in its own words, for other OpenAI API compatible providers. Set it to https://api.apisrouter.com/v1 with OPENAI_API_KEY holding a gateway key before first startup, and Khoj's initialization does something unusually helpful: it queries the endpoint's model list and seeds its chat-model table with every id the endpoint serves, so the catalog shows up in Khoj's model picker without manual entry. On an already-initialized server, use the admin panel instead. Create an AI Model API entry (fields: Name, Api Key, Api Base Url) pointing at the gateway, then create Chat Model entries whose Name is the exact model id, with Model Type set to Openai and linked to that AI Model API. Both surfaces are documented in Khoj's OpenAI-proxy guide at docs.khoj.dev.

services:
  server:
    environment:
      - OPENAI_BASE_URL=https://api.apisrouter.com/v1
      - OPENAI_API_KEY=sk-YOUR-APISROUTER-KEY

What Khoj does with its chat model.

Khoj (khoj-ai on GitHub, roughly 36K stars) is a self-hostable AI second brain: it indexes your notes and documents (markdown, org-mode, PDFs, and more), then lets you chat over them, run custom agents with their own personas and tools, schedule automations that fire on a cron, and launch multi-step research runs. There is a hosted app, but the self-hosted server is where custom endpoints apply, and it is the deployment this page describes. Every one of those features funnels through the chat model you select. Document chat packs retrieved note chunks into the prompt, agents add tool calls and persona instructions, automations run the same pipeline unattended, and research mode chains many model calls per question. Model Type Openai tells Khoj to speak /v1/chat/completions to the Api Base Url of the linked AI Model API entry, forwarding the model Name as a plain string, which is why a Claude or DeepSeek id works there as long as the endpoint serves it. Search embeddings are a different subsystem. Khoj embeds your documents with a local sentence-transformers model by default, so indexing and semantic search keep working regardless of what you do with the chat endpoint. Routing chat through a gateway moves the reasoning bill only.

Full setup: admin panel entries step by step.

On a running server, the whole integration is three admin screens. First, add the AI Model API: open /server/admin/database/aimodelapi/add, name it, paste the gateway key into Api Key, and set Api Base Url to https://api.apisrouter.com/v1. Second, add chat models: at /server/admin/database/chatmodel/add, set Name to an exact catalog id (claude-sonnet-4-6, deepseek-v4-flash), set Model Type to Openai, link the Ai Model Api entry you just made, and set Max prompt size to a value that fits the model's context window. The docs advise leaving Tokenizer unset for OpenAI-type models. Repeat per model you want in the picker. Third, select the model: on /settings, pick your new chat model as the default. Agents can override the model per agent, which is how one Khoj instance runs a fast id for daily automations and a frontier id for research.

1) /server/admin/database/aimodelapi/add
   Name:         APIsRouter
   Api Key:      sk-YOUR-APISROUTER-KEY
   Api Base Url: https://api.apisrouter.com/v1

2) /server/admin/database/chatmodel/add
   Name:         claude-sonnet-4-6   (exact catalog id)
   Model Type:   Openai
   Ai Model Api: APIsRouter
   Max prompt size: 100000

3) /settings -> select the new chat model

Choosing models for a second brain.

Because chat models are rows you add against one AI Model API, keeping two or three ids in the picker costs nothing. The practical setup is a fast default plus a frontier escalation, both billed through the same key so the usage log shows what each tier actually costs on your notes.

  • Document chat is input-heavy: retrieved note chunks dwarf the answer. Per-input-token price drives cost per question, which favors claude-haiku-4-5-20251001, deepseek-v4-flash, or gemini-3.5-flash for everyday recall.
  • Research mode multiplies calls. One research question can chain many model turns, so the id you assign there moves the bill more than any other setting; claude-sonnet-4-6 is the balanced pick, gpt-5.4 the escalation.
  • Scheduled automations run unattended. Price them like a subscription: calls per day times tokens per call, which is exactly what the per-key usage log reports.
  • Personal knowledge is contradiction-rich (plans change, notes go stale), and models differ in how well they flag conflicting notes rather than blending them; test two ids on the same question set before committing.
  • Max prompt size is per chat model in Khoj, so a long-context id only pays off if you raise that field to match.

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.

ModelOfficial PriceOur Price
Claude Sonnet 4.6$3.00 / $15.00 per M$2.40 / $12.00 per M
Claude Haiku 4.5 20251001$1.00 / $5.00 per M$0.80 / $4.00 per M
GPT-5.4$2.50 / $15.00 per M$2.00 / $12.00 per M
DeepSeek V4 Flash$0.14 / $0.28 per M$0.13 / $0.25 per M
Gemini 3.5 Flash$1.50 / $9.00 per M$1.20 / $7.20 per M

Failure modes specific to Khoj.

The env var is a first-run seed, not a live setting. OPENAI_BASE_URL is read during initialization to create the provider entry and discover models; on a server that has already initialized, editing the compose file changes nothing you can see. Use the admin panel for changes after first boot, or reset the database if you genuinely want a fresh seed. The placeholder-key trap: when OPENAI_BASE_URL is set without OPENAI_API_KEY, Khoj fills the key with a placeholder so that local servers like Ollama work. A gateway requires a real key, so if first-run seeding happened without one, chats fail with authentication errors until you paste the key into the AI Model API entry in the admin panel. Auto-discovery seeds everything. Because initialization lists every model the endpoint serves, a multi-vendor gateway can seed a long model table. Harmless, but worth pruning in the admin panel so the picker stays usable. Chat model Name is exact. Khoj forwards it verbatim; a typo surfaces as model-not-found on first message, and the gateway's /v1/models output is the authoritative spelling. And if semantic search over your notes misbehaves, that is the local embedding subsystem, unrelated to the chat endpoint.

Who routes Khoj through a gateway.

  • Self-hosters who want frontier-model chat over their notes without a vendor account per model family; one key covers Claude, GPT, DeepSeek, and Gemini ids.
  • Users running scheduled automations daily, where a fast id keeps the recurring cost flat and the usage log makes it visible.
  • Privacy-minded setups that keep indexing and embeddings local and expose only chat prompts to one auditable endpoint.
  • Tinkerers comparing chat models over an identical personal corpus: every candidate is one chat-model row against the same AI Model API.
  • 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 chat.

Check the gateway first: list models with your key and confirm the ids you plan to register. Khoj's own auto-discovery does the same call during first-run seeding, so if this curl works, seeding will too. Failures localize cleanly. Authentication errors mean the Api Key on the AI Model API entry is wrong or still the seeded placeholder. Model-not-found means a chat model Name does not match the catalog spelling. Responses that cut off mid-answer usually mean Max prompt size or the model's output ceiling is set too low for the conversation. Indexing and search problems are the local embedding pipeline and have nothing to do with the endpoint. Once chats flow, the APIsRouter console shows per-request model, token counts, and spend. Automations and research runs are where second-brain costs hide, and per-key usage is how you see them per feature instead of as one monthly surprise.

curl -s https://api.apisrouter.com/v1/models \
  -H "Authorization: Bearer $APISROUTER_API_KEY" | head -50

FAQ

Does Khoj support an OpenAI-compatible proxy or gateway?

Yes, as a documented setup: create an AI Model API entry with an Api Base Url pointing at the endpoint, then add chat models with Model Type Openai. The compose file also exposes OPENAI_BASE_URL for first-run seeding.

Can Khoj chat with Claude or DeepSeek models through this?

Yes. Model Type Openai forwards the chat model Name as a plain string over /v1/chat/completions to the Api Base Url. Any id the gateway serves works, including Claude, DeepSeek, GLM, and Gemini ids.

Why did changing OPENAI_BASE_URL in docker-compose do nothing?

The variable seeds providers and models during first-run initialization only. On an initialized server, edit the AI Model API entry in the admin panel instead; that is the live setting.

Does the custom base URL affect Khoj's document search?

No. Khoj embeds and searches your documents with a local sentence-transformers model by default. The AI Model API entry moves chat, agents, automations, and research only.

What is Max prompt size on the chat model entry?

A per-model cap on how much prompt Khoj packs into a request. Set it to fit the model's context window; too low truncates retrieved notes, and a long-context id only helps if this field is raised to match.

Does this apply to the hosted Khoj app?

No, custom endpoints are a self-hosting feature. The hosted app manages its own models server-side; the admin-panel and environment surfaces here belong to a server you run yourself.