OrbitDocs packages are coming to npm soon. Until then, run it from the GitHub repo →
Reference

Environment variables

Every environment variable OrbitDocs reads, for the docs site, the NestJS integration, the CLI and the self-hosted platform.

OrbitDocs keeps secrets out of orbitdocs.config.ts and out of the build. The config only names a variable (clientSecretEnv, apiKeyEnv, …). The server that serves the docs reads its value at request time.

This page lists every variable, grouped by who reads it. A name in angle brackets, such as <ai.apiKeyEnv>, means "the variable whose name you set in that config key".

Where secrets are read

Private docs and Ask AI run on whatever serves the docs. That process needs the variables in the next section:

Docs served byReads variables from
Your Nest app (mountOrbitDocs)The Nest process: process.env, or the env object passed in auth.env / ai.env.
Next server mode (proxy.ts)The Next server's environment (on Vercel: the project's environment variables).
The self-hosted platformThe project's Settings → Environment only, never the platform's own environment. The session secret is derived per project. See Site environment variables.
A static hostNothing. Static hosts run no OrbitDocs code.

Private docs and Ask AI

Read by @orbitdocs/auth and @orbitdocs/ai on the serving process.

VariableRequiredDefaultWhat it doesRead in
ORBITDOCS_AUTH_SECRET (name set by access.session.secretEnv)Yes, with accessnoneSigns reader sessions (HS256). At least 32 characters; generate with openssl rand -hex 32. Every instance must share it.@orbitdocs/auth request handler, on every sign-in and gated request
<access.providers[].clientSecretEnv>Yes, per SSO providernoneThe OAuth client secret of that provider.@orbitdocs/auth, when sign-in starts and on the callback
<access.appSession.jwtSecretEnv>No (Supabase only)noneShared JWT secret of a legacy Supabase project. Without it, the project's public keys (JWKS) verify the session.@orbitdocs/auth app-session check
<access.appSession.secretKeyEnv>No (Clerk only)noneClerk secret key, to look up the reader's email when the session token has none.@orbitdocs/auth app-session check
<access.personalization.secretEnv>Yes, for personalization to runnoneHMAC-SHA256 key that signs the call to personalization.url (x-orbitdocs-signature: sha256=…). When unset, the hook is skipped and sign-in goes on.@orbitdocs/auth, after each sign-in
<ai.apiKeyEnv>Yes, with ainoneAPI key for the LLM provider. Required for openai-compatible too; use any value if your endpoint ignores keys.@orbitdocs/ai, on each Ask AI question

Errors when one is missing:

MessageFix
ORBITDOCS_AUTH_SECRET must be set to a random string of at least 32 characters (e.g. `openssl rand -hex 32`).Set the session secret on the serving process.
OKTA_CLIENT_SECRET is not set (client secret for Okta)Set that provider's clientSecretEnv.
ANTHROPIC_API_KEY is not set (API key for Ask AI)Set ai.apiKeyEnv.

The docs MCP server and the API MCP servers need no key. The API MCP server forwards the credentials the MCP client sends to your API.

Extraction (NestJS integration)

Read when orbitdocs extract, dev or build loads your Nest module in preview mode.

VariableRequiredDefaultWhat it doesRead in
<apis[].source.nest.env> keysNo{}Placeholders set before the module loads, for config your app reads at import time (DATABASE_URL, JWT_SECRET, …). A variable already in the environment wins.@orbitdocs/nestjs extractor, before require of the module
Your app's own variablesDepends on your appnonePreview mode starts no providers, but code that runs on import (module-level process.env reads, ConfigModule validation) still runs. Set them, or add placeholders in env.Your code
PATHNoinheritedThe build command runs with <root>/node_modules/.bin first, so the project's own nest wins over a global one.CLI, build command
orbitdocs.config.ts
source: {
  nest: {
    module: 'dist/app.module.js',
    build: 'nest build',
    env: { DATABASE_URL: 'postgres://placeholder', STRIPE_KEY: 'sk_test_placeholder' },
  },
},

Docs app build and runtime

Read by @orbitdocs/next in the docs app.

VariableRequiredDefaultWhat it doesRead in
NODE_ENVNo (set by Next)development in next dev, production in buildsIn development, specs are re-read on every request (the reference updates without a restart), and a Mock server environment at http://localhost:<mock.port> is added when mock is configured.@orbitdocs/next spec loader
ORBITDOCS_BASE_PATHNever set itoutput.basePathWritten into Next's env by withOrbitDocs so pages know the base path. Change output.basePath instead.@orbitdocs/next plugin, at build

The config file is TypeScript, so it can read your own variables. The sample app switches modes this way:

orbitdocs.config.ts
output: { mode: process.env.ORBITDOCS_MODE === 'server' ? 'server' : 'static', basePath: '/docs' },

ORBITDOCS_MODE is the sample's own name, not something OrbitDocs reads.

CLI

VariableRequiredDefaultWhat it doesRead in
ORBITDOCS_PLATFORM_URLFor publish, unless --platform is givennoneThe platform URL, such as https://docs.acme.com. --platform wins.orbitdocs publish
ORBITDOCS_TOKENFor publish, unless --token is givennoneA project publish token (odp_…). --token wins.orbitdocs publish

orbitdocs deploy --target vercel runs the Vercel CLI, which has its own login and variables. OrbitDocs reads none of them.

Generated SDK samples in the reference read the credential from an environment variable named after the operation's security scheme, such as API_KEY for a scheme named apiKey or BEARER_TOKEN for bearer (process.env.… in TypeScript, os.environ[…] in Python). See SDK samples. Those lines are sample code for your readers; OrbitDocs doesn't read them.

Platform

Read by the self-hosted platform (apps/platform). With Docker Compose, put them in apps/platform/.env: Compose reads it, and the platform container loads the whole file. See Install.

VariableRequiredDefaultWhat it doesRead in
PLATFORM_SECRETYesnoneAt least 32 characters. Signs dashboard sessions, encrypts stored Git tokens (AES-256-GCM), salts analytics visitor hashes and signs dashboard SSO state. The platform refuses to start without it.src/config.ts
PLATFORM_DOMAINNolocalhost with Compose; localhost:<PORT> withoutDashboard host. Sites are at <project>.<domain>, previews at <project>--<label>.<domain>. http(s):// and a trailing / are stripped.src/config.ts
PLATFORM_URLNohttps://<PLATFORM_DOMAIN> with Compose; without Compose http:// for localhost and https:// otherwisePublic URL of the dashboard. Used in webhook URLs, invitation links, commit status links, SCIM locations and site URLs (its scheme).src/config.ts
DATABASE_URLNopostgres://orbitdocs:orbitdocs@localhost:5433/orbitdocs; Compose sets it to the bundled PostgresPostgres connection. Migrations run against it on every start; the build queue lives in its pgboss schema.src/main.ts, src/config.ts
PORTNo8080Port the platform listens on. Caddy proxies to platform:8080.src/config.ts
DATA_DIRNo./data; /data in the imagePublished sites, build folders and uploads. Must be shared by all instances.src/config.ts
ADMIN_EMAILNononeEmail of the first admin. Created at start when no user has it; made an admin when one does. Needs ADMIN_PASSWORD.src/config.ts, src/auth/auth.service.ts
ADMIN_PASSWORDNononePassword for a newly created first admin. Never changes an existing account.same
PLATFORM_SSONonone (password sign-in only)JSON array of dashboard SSO presets, the same shape as access.providers entries. Invalid JSON stops the start.src/config.ts
<PLATFORM_SSO[].clientSecretEnv>Yes, per presetnoneThe client secret of that SSO preset.@orbitdocs/auth, on dashboard SSO
SCIM_TOKENNonone (SCIM off)Turns on SCIM 2.0 at /scim/v2; clients send Authorization: Bearer <token>.src/config.ts, src/scim/scim.controller.ts
SITE_OUTBOUND_ALLOWNononePrivate hosts and addresses hosted sites may still reach, such as an internal Keycloak: hostnames, *.suffix, IPs or CIDRs, comma-separated. Everything private is refused otherwise. See Outbound requests.src/config.ts, src/hosting/outbound.ts
BUILD_CONCURRENCYNo1Git sync builds this instance runs at once.src/git/git.service.ts
BUILD_TIMEOUT_MSNo900000 (15 minutes)Time limit for each build step (clone, install, build). A job expires after this plus 5 minutes.src/git/git.service.ts
NODE_ENVNoproduction in the imageSet by the Dockerfile.Node and Nest

Hosted sites don't read this environment. Each project sets the private docs and Ask AI variables its site needs under Settings → Environment; see Site environment variables.

Docker Compose only

VariableRequiredDefaultWhat it does
POSTGRES_PASSWORDNoorbitdocsPassword of the bundled Postgres, used in the DATABASE_URL Compose builds. Set it before the first start: the database keeps the password it was created with.

Your own Postgres

Set DATABASE_URL in .env to use an existing database instead of the bundled one, then remove the postgres service and the platform's depends_on from docker-compose.yml.

Given to Git sync builds

Install and build commands don't get the platform's environment. They get an allowlist of it (PATH, HOME, temp folders, locale, TLS certificates, package-manager caches and registries, proxies), the project's Build Environment Variables from Settings → Git, and these. PLATFORM_SECRET, DATABASE_URL, SSO secrets and NODE_ENV are never passed. See Git sync for the full list.

VariableValueWhy
CItrueTools behave as in CI (no prompts, no watch mode).
ORBITDOCS_PLATFORM_BUILD1Lets your scripts tell a platform build apart.
GIT_TERMINAL_PROMPT0Git fails instead of waiting for a password.

Last updated on

On this page