#Environment reference
Values tolerate Vercel-style quoting ("…") and a literal trailing \n. Empty values count as unset.
Everything per project (retention, consent mode, relevance rules, quotas) lives in the database, not
in the environment.
#API – core
| Variable | Default | Description |
|---|
X3_ENV | development | development, test or production. Production enables live conversion uploads and refuses to start with incomplete settings. |
PORT | 4310 | Port of the standalone server. |
X3_PUBLIC_API_URL | http://localhost:4310 | Public origin of the API (snippets, OAuth metadata, links). https in production. |
X3_DASHBOARD_URL | http://localhost:4311 | Public origin of the dashboard (CORS, e-mail links, Composio callbacks). |
X3_SECRET | – (required in production) | ≥ 32 characters. HMAC secret for CSRF tokens, OAuth state, idempotency and keyed hashes. |
X3_ENCRYPTION_KEY | – (required in production) | 32 bytes, base64. AES-256-GCM key for destination secrets. Rotating it makes stored secrets unreadable – re-enter them. |
CRON_SECRET | – (required in production) | ≥ 16 characters. Bearer token for /v1/cron/* (Vercel Cron sends it automatically). |
X3_DASHBOARD_KEY | – (required in production) | ≥ 32 characters, same value in the dashboard. Requests carrying it may pass the end user's IP and user agent (login throttles, audit). |
X3_ALLOW_SIGNUP | off | 1 allows self-service sign-up (dashboard and OAuth login page). |
X3_SMTP_URL | – | smtp(s)://user:pass@host:port for magic links and invitations. Without it links are only shown in development. |
X3_MAIL_FROM | – | Sender, e.g. 3x <no-reply@example.com>. |
#API – database
| Variable | Default | Description |
|---|
X3_DATABASE_URL | – | Pooled connection used for requests (Neon: the -pooler host). |
X3_DATABASE_URL_UNPOOLED | X3_DATABASE_URL | Direct connection for migrations and long jobs. |
DATABASE_URL, POSTGRES_URL | – | Fallbacks set by Vercel/Neon integrations (production only). |
X3_ALLOW_REMOTE_DB | off | Outside production only localhost databases are used unless this is 1 – protects production data from local runs. |
X3_AUTO_MIGRATE | off | 1 applies pending migrations on the first request. |
X3_DB_POOL_MAX | 5 | Connections per instance (1–50). |
X3_MIGRATIONS_DIR | bundled | Directory of the SQL migrations (only for unusual layouts). |
X3_MIGRATE_ON_BUILD | off | Vercel build: 1 runs npm run migrate during the build (see apps/api/vercel.json). |
#API – network and privacy
| Variable | Default | Description |
|---|
X3_TRUSTED_IP_HEADERS | Vercel: x-real-ip,x-forwarded-for; elsewhere empty (socket address) | Client IP header chain, first match wins. Cloudflare: cf-connecting-ip; nginx/Caddy: the header the proxy sets (x-real-ip); plain Node: unset. Never x-forwarded-for unless your proxy overwrites it. |
X3_COUNTRY_HEADERS | x-vercel-ip-country,cf-ipcountry | Headers carrying the visitor's country code. |
X3_MCP_ALLOWED_ORIGINS | empty | Browser origins allowed to call /mcp (MCP inspectors). claude.ai and Claude Code send no Origin. |
X3_OAUTH_ISSUER | X3_PUBLIC_API_URL | OAuth issuer override (https or loopback). |
X3_OAUTH_EXTRA_REDIRECTS | empty | Comma-separated additional OAuth redirect URIs (besides Claude's hosted callbacks and loopback URIs). |
The visitor IP feeds bot budgets, per-IP rate limits and the daily session hash (it is never
stored). A wrong setting either lets clients spoof their IP or makes every visitor share the proxy's
address (one giant "session", budgets exhausted at once).
| Platform | Value |
|---|
| Vercel | unset – 3x uses x-real-ip,x-forwarded-for, which Vercel overwrites |
| Cloudflare (proxied) in front of any host | cf-connecting-ip |
| nginx / Caddy / Traefik | the header your proxy sets from the socket address, usually x-real-ip |
| Node directly on the internet | unset (socket address) |
| Netlify | x-nf-client-connection-ip |
| Fly.io | fly-client-ip |
Sites that use a first-party proxy forward the visitor IP in x-3x-client-ip together with a proxy
key; that header is trusted only with a valid key, independent of this setting.
#API – background jobs
| Variable | Default | Description |
|---|
X3_SCHEDULER | off | 1 runs the in-process scheduler (standalone Node; ticks every minute). |
X3_CRON_BUDGET_MS | 40000 | Time budget of one tick. Set ≈ function maxDuration − 20 s (Vercel Hobby 60 s → 40000, Pro/fluid 300 s → 280000). |
X3_TICK_MAX_HOPS | 12 | A tick that leaves due work re-invokes /v1/cron/tick up to this many times (0 = off). |
#API – deployment storage guard (off by default)
Meant for small single-tenant deployments on capped database plans; it acts on the whole
database. Per-project quotas live in the project settings instead.
| Variable | Default | Description |
|---|
X3_STORAGE_LIMIT_BYTES | unset (guard off) | Database size limit, e.g. 1000000000. |
X3_STORAGE_CLEANUP_ABOVE_BYTES | 75 % of the limit | Above it, the cleanup job prunes the oldest raw data early. |
X3_STORAGE_PAUSE_ABOVE_BYTES | 90 % of the limit | Above it, ingest stores nothing for any project (browsers still get a success answer) until space is free. |
#API – conversions
| Variable | Default | Description |
|---|
X3_CONVERSIONS_MODE | live in production, else dry_run | Deployment ceiling: live, test, dry_run (Test modes). |
X3_CONVERSIONS_DISABLED | off | 1 = kill switch, everything dry_run. |
X3_META_BASE_URL | Graph API | Mock base URL, ignored in live. |
X3_LINKEDIN_BASE_URL | https://api.linkedin.com | Mock base URL, ignored in live. |
X3_GOOGLE_ADS_BASE_URL | Google Ads API | Mock base URL, ignored in live. |
X3_TIKTOK_BASE_URL | https://business-api.tiktok.com | Mock base URL, ignored in live. |
X3_GOOGLE_ADS_API_VERSION | v23 | Google Ads REST version for direct uploads and the Composio proxy. |
#API – Composio (ad costs)
| Variable | Default | Description |
|---|
COMPOSIO_API_KEY | – | Project key ak_… (production) or user key uak_… (needs COMPOSIO_PROJECT_ID). Never logged. |
COMPOSIO_PROJECT_ID | – | Required with a uak_ key. |
COMPOSIO_BASE_URL | https://backend.composio.dev/api/v3.1 | API base (mocks in tests). |
COMPOSIO_AUTH_CONFIG_GOOGLEADS | – | Auth config ac_… for Google Ads. |
COMPOSIO_AUTH_CONFIG_METAADS | – | Auth config for Meta Ads. |
COMPOSIO_AUTH_CONFIG_LINKEDIN_ADS | – | Auth config for LinkedIn Ads. |
COMPOSIO_AUTH_CONFIG_TIKTOK_ADS | – | Auth config for TikTok Ads. |
COMPOSIO_WEBHOOK_SECRET | – | Standard Webhooks signing secret (whsec_…). |
COMPOSIO_TOOLKIT_VERSIONS | built-in pins | JSON map of pinned toolkit versions. |
#API – development and diagnostics
| Variable | Default | Description |
|---|
X3_DEBUG | off | 1 enables debug logs. |
X3_VALIDATE_RESPONSES | off | 1 validates every response against its contract (tests; also in the dashboard client). |
X3_SDK_DIR | bundled | Directory with the SDK script builds served at /v1/s/*. |
X3_SEED_PASSWORD | demo-password-123 | Password of the demo user created by npm run db:seed. |
X3_COMPOSIO_MOCK_PORT | 4317 | Port of the local Composio mock server (apps/api/src/modules/ads/composio/mock.ts, replays the recorded samples); point COMPOSIO_BASE_URL at it. |
X3_LOAD_DATABASE_URL | local x3_load on port 54331 | Database of the load-test seed script (apps/api/scripts/seed-load.ts); never a production database. |
#Dashboard
| Variable | Default | Description |
|---|
X3_API_URL | http://localhost:4310 | API origin the server components call (can be an internal URL). |
X3_PUBLIC_API_URL | X3_API_URL | Public API origin shown in snippets and docs links. |
X3_DASHBOARD_KEY | – | Same value as on the API; without it the API sees the dashboard's IP for every login. |
X3_TRUSTED_IP_HEADERS | Vercel: x-real-ip,x-forwarded-for | Header chain of the dashboard's own edge, used to forward the visitor IP. |
X3_VALIDATE_RESPONSES | off | Validate API responses (development). |
#Example app and your own site
| Variable | Description |
|---|
NEXT_PUBLIC_X3_KEY | Publishable key pk_3x_… of the project (safe in the browser). |
X3_API_ORIGIN | API origin the first-party proxy forwards to. |
X3_PROXY_KEY | Proxy key (sk_3x_…, scope ingest:proxy) – server only, lets the proxy forward the visitor IP. |
X3_API_URL, X3_SECRET_KEY, X3_PROJECT_ID | Server helper (@3x-engine/sdk/server): API origin, secret key with the needed scopes, optional project id. |
X3_EXAMPLE_TRANSPORT | Example app only: proxy (default, SDK through /n3) or direct (SDK talks to X3_API_ORIGIN). |