Skip to content

Configuration

The Ony.ai server reads its configuration from environment variables (or a local .env), all prefixed ONY_. This page documents the ones that matter. The full annotated list lives in .env.example in the repo.

For a real deployment, the only variable you are required to set is the signing secret. Everything else has a sensible default or is optional.

.env
# Signs decision tokens and the audit chain. Generate a strong, unique value per environment.
ONY_SIGNING_SECRET=$(openssl rand -hex 32)
Variable Default Purpose
ONY_ENV local production for any public host. local/test/dev enable dev conveniences (passwordless reset token, dev login, webhook-signature skip) that are unsafe in production
ONY_EDITION oss oss is fully featured standalone. cloud unlocks the managed multi-tenant extension points
ONY_SIGNING_SECRET dev-only-change-me Signs decision tokens and the audit chain. Override per environment
ONY_DATABASE_URL postgresql+psycopg://ony:ony@localhost:5432/ony SQLAlchemy database URL
ONY_REDIS_URL redis://localhost:6379/0 Valkey/Redis for rate limiting, idempotency, and call correlation. Optional for a single API instance (falls back to in-memory)
ONY_PUBLIC_BASE_URL empty Public base URL clients and the telephony provider reach. Must be https://<your-domain> in production so webhook callback URLs are correct
ONY_WEB_BASE_URL ONY_PUBLIC_BASE_URL Base URL for user-facing links (reset/invite emails, SMS deep links). Set separately when the public base is a webhook-only edge
ONY_DEFAULT_HANDOFF_TTL_SECONDS 900 Server-assigned handoff TTL. The client-supplied expires_at is only a hint
ONY_DETAILS_RETENTION_DAYS 0 After N days a daily sweep scrubs the sensitive details payload from handoffs, keeping metadata and the audit chain. 0 = keep forever
ONY_LOG_FORMAT plain plain (human) or json (structured, for log shippers)
ONY_SENTRY_DSN empty Optional Sentry error reporting; events are scrubbed before sending

Telephony is optional. Leave the whole section blank to configure a carrier from the dashboard (Settings -> Integrations -> Telephony), or run on the built-in mock provider, where handoffs are decided in the dashboard with no real call. If you set a provider here, only that provider’s credentials are needed.

Variable Default Purpose
ONY_TELEPHONY_PROVIDER signalwire Active carrier: signalwire, twilio, telnyx, plivo, or mock
.env
ONY_TELEPHONY_PROVIDER=signalwire
ONY_SIGNALWIRE_SPACE_URL=
ONY_SIGNALWIRE_PROJECT_ID=
ONY_SIGNALWIRE_API_TOKEN=
ONY_SIGNALWIRE_FROM_NUMBER=
ONY_SIGNALWIRE_AUTH_TOKEN= # the space's signing key (starts "PSK_"), NOT an API token

Each provider is selected with ONY_TELEPHONY_PROVIDER and needs its own credentials:

  • Twilio (twilio): ONY_TWILIO_ACCOUNT_SID, ONY_TWILIO_AUTH_TOKEN, ONY_TWILIO_FROM_NUMBER. The auth token also verifies webhook signatures.
  • Telnyx (telnyx): ONY_TELNYX_ACCOUNT_SID (TeXML application id), ONY_TELNYX_API_KEY, ONY_TELNYX_PUBLIC_KEY (base64 Ed25519 public key for webhook verification), ONY_TELNYX_FROM_NUMBER.
  • Plivo (plivo): ONY_PLIVO_AUTH_ID, ONY_PLIVO_AUTH_TOKEN, ONY_PLIVO_FROM_NUMBER. The auth token signs webhooks and authenticates REST.

The inbound “talk to your agent” voice feature can use an LLM brain and higher-accuracy transcription, but works without either.

Variable Default Purpose
ONY_LLM_PROVIDER auto auto (use whatever key is set), openai, anthropic, or none (force the deterministic fallback)
ONY_OPENAI_API_KEY empty Key for the OpenAI-compatible brain. Point ONY_OPENAI_BASE_URL at Groq/Together/OpenRouter/a local server to switch backends
ONY_ANTHROPIC_API_KEY empty Key for the Anthropic (Claude) brain
ONY_ASR_MODE carrier carrier uses the telephony provider’s built-in recognition (zero config); whisper transcribes via an OpenAI-compatible endpoint (needs ONY_WHISPER_API_KEY)

With no key configured, the brain falls back to deterministic intent matching, so inbound voice still works.

Variable Default Purpose
ONY_RATE_LIMIT_ENABLED true Rate limiting on the auth surface, OTP sends, call placement, and handoffs. Disable only for isolated load testing
ONY_TRUSTED_PROXY_HOPS 0 Number of trusted reverse proxies for client-IP extraction. 0 uses the socket peer (no proxy). The compose files set this for you
ONY_TRUST_CF_CONNECTING_IP false Behind a Cloudflare Tunnel, key per-IP rate limiting off CF-Connecting-IP. Leave false for a plain reverse proxy
ONY_FORWARDED_ALLOW_IPS 127.0.0.1 Which upstream peers uvicorn trusts X-Forwarded-* from behind a TLS-terminating edge
ONY_TURNSTILE_SITE_KEY / ONY_TURNSTILE_SECRET_KEY empty Cloudflare Turnstile CAPTCHA on signup/login. Both empty disables it (the OSS/Lite default)

Multi-channel escalation retries and falls back across channels when a call goes unanswered (call -> Telegram -> SMS by default). Off by default; the out-of-box behavior is a single call plus one backup-contact attempt. See escalation.

Variable Default Purpose
ONY_ESCALATION_ENABLED false Enable the multi-channel escalation engine
ONY_TELEGRAM_BOT_TOKEN empty Telegram decision channel bot token (from @BotFather)
ONY_TELEGRAM_BOT_USERNAME empty The bot’s username (no @), used to build the account-linking deep link
ONY_TELEGRAM_WEBHOOK_SECRET empty Matched against the X-Telegram-Bot-Api-Secret-Token header (required in production when the bot token is set)
ONY_SLACK_BOT_TOKEN empty Slack decision channel bot token
ONY_SLACK_SIGNING_SECRET empty Verifies X-Slack-Signature (required in production when the bot token is set)

Point Ony.ai at any OpenID Connect provider (Authentik, Keycloak, Google Workspace, Azure AD). SSO is disabled while ONY_OIDC_ISSUER is empty. Register the callback URL <ONY_PUBLIC_BASE_URL>/api/v1/auth/oidc/callback with your IdP.

Variable Default Purpose
ONY_OIDC_ISSUER empty Discovery base URL. Empty disables SSO
ONY_OIDC_CLIENT_ID / ONY_OIDC_CLIENT_SECRET empty OIDC client credentials
ONY_OIDC_SCOPES openid email profile Requested scopes
ONY_OIDC_ALLOWED_DOMAINS empty Comma-separated email domains allowed to just-in-time create an account on first SSO login. Empty = no JIT
ONY_OIDC_ADMIN_GROUP / ONY_OIDC_VIEWER_GROUP empty Map OIDC groups to Ony.ai roles. Admin wins over viewer; absent both, a JIT user defaults to member
ONY_OIDC_GROUPS_CLAIM groups Name of the token claim carrying group membership

Password-reset, invite, and welcome emails. Leave ONY_EMAIL_PROVIDER empty for the console fallback (the message is printed to the server log), which is fine for a single-admin self-host. Set smtp and point it at any relay for a multi-user deployment.

Variable Default Purpose
ONY_EMAIL_PROVIDER empty smtp or empty (console fallback)
ONY_EMAIL_FROM Ony <noreply@ony.ai> From header and envelope sender
ONY_SMTP_HOST / ONY_SMTP_PORT empty / 587 SMTP relay host and port
ONY_SMTP_USERNAME / ONY_SMTP_PASSWORD empty SMTP credentials
ONY_SMTP_TLS_MODE starttls starttls (587), tls (implicit SMTPS, 465), or none (local relay)

The optional backup overlay (deploy/docker-compose.backup.yml) runs a nightly pg_dump with optional at-rest encryption and an offsite copy - see BACKUP.md for the full ONY_BACKUP_* set. For a privacy review, this window and ONY_DETAILS_RETENTION_DAYS above are the two retention variables: together they bound how long sensitive payloads persist (see data handling).

Variable Default Purpose
ONY_BACKUP_RETENTION_DAYS 30 Days of nightly database dumps the backup overlay keeps before pruning

These apply only to the managed hosted edition, which enforces plans. OSS self-host is always fully featured, so an empty Stripe key means no checkout.

Variable Default Purpose
ONY_STRIPE_SECRET_KEY empty Stripe secret key (use TEST keys outside production)
ONY_STRIPE_WEBHOOK_SECRET empty Verifies Stripe webhook signatures
ONY_STRIPE_PRICE_PRO / ONY_STRIPE_PRICE_TEAM empty Map plans to Stripe recurring price ids

The ony connector on each machine keeps its own local config, separate from the server environment above.

  • ~/.ony/config.json - the machine’s device identity: server URL, device id, device token, per-device decision key, and the global default mode. Written by ony enroll / ony init. It holds a long-lived device token, so on POSIX it is created owner-only (0600). Override the directory with the ONY_HOME environment variable.
  • <project>/.ony/project.json - per-project settings, chiefly the mode (on, away, or off) set by ony on|away|off or the /ony skill, and the headless_gate flag from ony hooks install --headless. The project mode overrides the global default for every session in that project.

See the CLI reference for the commands that write these files.