Skip to Content
ReferenceEnvironment variables

Environment variables

Two kinds of thing live here. Credentials, which live nowhere else, and overrides, which beat karani.toml for one run.

.env.example is the template. Nothing in it is required to run a pass — with no variables set at all, karani uses an in-memory store and a local model.

Credentials

VariableNeeded for
DATABASE_URLKeeping state between runs. Any Postgres DSN.
OPENROUTER_API_KEYprovider = "openrouter"
OPENAI_API_KEYprovider = "openai" against the API itself
ANTHROPIC_API_KEYprovider = "anthropic"
SLACK_BOT_TOKENPushing to Slack (xoxb-...)
SLACK_APP_TOKENThe Socket Mode listener (xapp-...)
SLACK_CHANNELWhich conversation to push to
NOTION_TOKENThe Notion mirror
GMAIL_CLIENT_IDThe watcher’s OAuth client
GMAIL_CLIENT_SECRETThe same
GMAIL_REFRESH_TOKENReading the mailbox, read-only
MINIO_ACCESS_KEY, MINIO_SECRET_KEYObject storage for the documents
MEM0_PG_URLThe vector store, separate from DATABASE_URL on purpose

A key for a provider you do not use is not needed, and its absence is never an error: with no key for the configured provider, karani falls back to the local model and says so once (ADR 0019).

Overrides

These shadow a karani.toml value for one run. Use them for experiments; put the answer in the file.

Model routing

VariableDefaultNotes
QUAL_PROVIDERfrom [llm.qualify]Any registered provider name
QUAL_MODELfrom [llm.qualify]Provider-specific slug
QUAL_REASONING_EFFORThighlow, medium, high
QUAL_MAX_TOKENS8000Completion cap, including reasoning tokens
QUAL_TIMEOUT_SECONDS180Thinking models are slow
LOCAL_LLM_MODELfrom [llm.*]For provider = "local"
RESUME_PATHdata/resume.mdWhich resume to judge against

Filtering

VariableDefaultNotes
MIN_COMP_USD160000Hard-fail comp floor where disclosed
TARGET_COMP_USD220000Score bonus threshold
STALE_JOB_DAYS10Days unseen before a posting is closed

HTTP

VariableDefaultNotes
HTTP_TIMEOUT30Per request, seconds
HTTP_CONCURRENCY6Global cap
HTTP_PER_HOST_CONCURRENCY3Per host
USER_AGENTkarani/...Sent on every request

Switches

These turn a behaviour off, and each one exists because the behaviour costs something — money, network, or both.

VariableEffect
KARANI_AUTO_PREP=offStop a screen/interview status change from building a prep pack. Two model calls, unattended.
KARANI_ATS_QUESTIONS=offStop the console reading real application forms. It then uses the standard field set and touches no network.
KARANI_INTEL=offStop company-dossier probes.
KARANI_MEMORYoff, basic (default) or mem0.
KARANI_PASS_DEADLINE_SECONDSThe hard ceiling on one hunt pass. Default 3000, clamped below the hourly tick (ADR 0025).

The test suite sets KARANI_AUTO_PREP and KARANI_INTEL off for the same reason it strips every credential: a deterministic test must not spend money or reach the network.

Ollama

Not karani’s variables, but karani’s behaviour depends on them, and getting them wrong is the single most expensive mistake available:

VariableSet it toWhy
OLLAMA_CONTEXT_LENGTH16384The 4096 default silently truncates a qualification prompt
OLLAMA_NUM_PARALLEL1More than one slot splits the context window, quietly undoing the above

Infrastructure has the full story, including why launchctl setenv does not survive a reboot and what karani installs to work around it.

Resolution order

Loosest first:

  1. Schema defaults
  2. karani.toml
  3. An environment variable
  4. A command-line flag
karani config check # what it resolved to, per task
Last updated on