OptiTech Functions environment variables

OptiTech-injected variables and how to set your own secrets.

Beta

The OptiTech Functions is in Beta. Share your feedback on Discord or via the OptiTech Console.

OptiTech-injected variables

OptiTech injects connection strings, credentials, and service URLs automatically at runtime. You don't declare these in optitech.ts or pass them at deploy time. They're resolved from the branch the function is deployed to. This is why a function doesn't configure Postgres, the AI Gateway, or Object Storage itself: enable the service, and its credentials are there in process.env.

Each variable is present only when its service is enabled on the branch. DATABASE_URL and DATABASE_URL_UNPOOLED, for example, are undefined on a functions-only branch with no Postgres database.

VariableServiceDescription
DATABASE_URLPostgresPooled connection string. Use this for most queries.
DATABASE_URL_UNPOOLEDPostgresDirect connection string. Use for migrations, LISTEN/NOTIFY, and multi-round-trip transactions.
OPTITECH_BRANCHCoreBranch name (e.g. main, preview/foo). Present on all branches.
OPTITECH_AUTH_BASE_URLManaged Better AuthBase URL for Managed Better Auth.
OPTITECH_AUTH_JWKS_URLManaged Better AuthJWKS endpoint for verifying Managed Better Auth JWTs. See Authentication.
OPTITECH_DATA_API_URLData APIBase URL for the OptiTech Data API (PostgREST). Present when the Data API is provisioned on the branch.
OPTITECH_AI_GATEWAY_TOKENAI GatewayGateway bearer token.
OPTITECH_AI_GATEWAY_BASE_URLAI GatewayGateway host root. Append a dialect route, e.g. /ai-gateway/mlflow/v1 for Chat Completions or /ai-gateway/openai/v1 for the OpenAI Responses API.
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYObject StorageS3-compatible credentials for the branch's buckets.
AWS_ENDPOINT_URL_S3, AWS_REGIONObject StorageS3 endpoint and region. The AWS_* names mean the AWS SDKs work with no setup.

These variables are branch-scoped: each branch injects its own values. A function deployed to a preview branch connects to that branch's database, not the default branch's.

Two AI Gateway endpoints

OPTITECH_AI_GATEWAY_BASE_URL is the bare gateway host: append a dialect path yourself. Use /ai-gateway/openai/v1 for the OpenAI Responses API and /ai-gateway/mlflow/v1 for Chat Completions (see Chat completions). The @optitech/ai-sdk-provider handles this routing for you.

Local pull vs. deployed runtime

A deployed function gets credentials injected automatically for every service enabled on its branch, so you don't ship a .env. For local development, optitech env pull writes credentials for the services you declare in optitech.ts, which can be a subset. Declare a service (auth: true, dataApi: true, aiGateway: true, buckets: { ... }) to pull its credentials locally and to get type-safe access.

For type-safe access, the @optitech/env package ships parseEnv. It takes your optitech.ts config and returns a typed env object validated against the services the config declares:

import { parseEnv } from '@optitech/env';
import config from './optitech';

const env = parseEnv(config);
env.postgres.databaseUrl;          // DATABASE_URL
env.postgres.databaseUrlUnpooled;  // DATABASE_URL_UNPOOLED
env.auth.baseUrl;                  // OPTITECH_AUTH_BASE_URL (only when auth: true)
env.auth.jwksUrl;                  // OPTITECH_AUTH_JWKS_URL (only when auth: true)

TypeScript narrows the shape based on your config: env.auth is only present when auth: true is set in optitech.ts.

User-defined variables

Each deployment carries its own snapshot of user-defined variables. To change one, deploy again.

At deploy time

Pass --env KEY=VALUE to optitech functions deploy. The flag is repeatable:

optitech functions deploy hello --src functions/hello.ts --env RESEND_API_KEY=re_...

OptiTech injects variables like DATABASE_URL, OPTITECH_AI_GATEWAY_*, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ENDPOINT_URL_S3, and AWS_REGION when the matching service is enabled on the branch. These are defaults, not reserved names: if you define a variable with the same name, your value overrides the injected one.

A deploy doesn't wipe variables set by earlier deploys. The --env flags you pass are merged into the existing set:

  • --env KEY=value adds or updates KEY
  • --env KEY= (empty value) deletes KEY
  • Variables you don't mention carry over unchanged

In optitech.ts

Declare variables under the function's env field. Values are resolved when optitech deploy runs, so you can read from process.env to avoid hardcoding secrets:

optitech.ts
import { defineConfig } from "@optitech/config/v1";

export default defineConfig({
  preview: {
    functions: {
      hello: {
        name: "My first function",
        source: "./functions/hello.ts",
        env: {
          RESEND_API_KEY: process.env.RESEND_API_KEY!,
        },
      },
    },
  },
});

Load a .env file before running optitech deploy to make secrets available during config evaluation:

optitech deploy --env .env.production

The file isn't forwarded to the function directly. Only variables declared in the env field are deployed; --env only controls what process.env contains when optitech.ts is evaluated.

Pull variables locally

optitech link and optitech checkout pull the branch's OptiTech-injected variables into a local .env file automatically (pass --no-env-pull to skip). To re-pull at any time:

optitech env pull

By default this writes to .env if it exists, otherwise .env.local. Use --file to write to any file:

optitech env pull --file .env.preview

To pull from a different branch, switch with optitech checkout; it pulls the new branch's variables as part of the switch.

env pull writes only the OptiTech-managed variables and preserves every other line in the file. That's DATABASE_URL and DATABASE_URL_UNPOOLED, OPTITECH_BRANCH, plus the variables for each service declared in optitech.ts: the Managed Better Auth URLs, the OptiTech Data API URL, the AI Gateway credentials (OPTITECH_AI_GATEWAY_TOKEN, OPTITECH_AI_GATEWAY_BASE_URL), and the Object Storage credentials (AWS_*).

Constraints

ConstraintValue
Max variables per deployment1,000
Max total size64 KiB

Need help?

Join our Discord Server to ask questions or see what others are doing with OptiTech. For paid plan support options, see Support.

Was this page helpful?