Environment variables

Every variable each service reads. Locally none of them are required. On Render, the Blueprint sets or asks for the ones that matter.

In development (next dev for the dashboard, any NODE_ENV other than production or test for the API), each service fills in local defaults so they find each other with no .env files. Production and tests get no defaults. To override a value locally, copy api/.env.example to api/.env or offer-app/.env.example to offer-app/.env.local.

API

Service offersdk-api, code in api/.

VariableDefaultDescription
DATABASE_URLDev: local PostgresPostgres connection string. The Blueprint uses the database's internal URL.
ADMIN_API_KEYDev: dev-admin-keyFull-access key. The dashboard and the Workflows service use the same value. You set it.
BETTER_AUTH_SECRETDev fallbackSigns dashboard sessions. Required in production. Generated by the Blueprint.
APP_URLhttp://localhost:6768The dashboard's public URL. Sessions are issued for it and only its origin is trusted. MCP clients are sent to its /oauth/consent page to approve a connection.
PUBLIC_API_URLOn Render: RENDER_EXTERNAL_URLThis API's public HTTPS URL. PayPal webhooks are registered under it when an app connects PayPal, and the MCP server's OAuth metadata uses it as the origin. Set it for a custom domain, or when the API runs outside Render or behind a proxy.
SECRETS_KEYBETTER_AUTH_SECRET, then ADMIN_API_KEYEncrypts stored PayPal client secrets.
ANTHROPIC_API_KEYNoneTurns on dynamic save offers in cancel flows. Without it, flows use their static offer.
DECIDE_MODELclaude-opus-5-5Model that picks dynamic save offers.
DECIDE_TIMEOUT_MS20000How long to wait for the model before falling back to the static offer.
RENDER_API_KEYNoneWith RENDER_WORKFLOW_SLUG, runs pauses as Render Workflow tasks.
RENDER_WORKFLOW_SLUGNoneThe Workflows service to start tasks on. The Blueprint sets offersdk-workflows.
PORT3000, dev: 6767Port to listen on.
MIGRATE_ON_BOOTtrueSet to false to run bun run migrate yourself.
DATABASE_POOL_MAX10Postgres pool size for the API.
AUTH_DATABASE_POOL_MAX5Postgres pool size for dashboard sign-in.
WEBHOOKS_WORKERtrueSet to false to not deliver webhooks from this instance.
WEBHOOKS_ALLOW_PRIVATE_URLSfalse, dev: trueAllows webhook endpoints on localhost and private networks. Development only.
PAUSE_WORKERtrueSet to false to stop this instance checking for pauses that are due.
PAUSE_WORKER_INTERVAL_MS10 min, or 60 min with WorkflowsHow often the API checks for pauses that are due.
PAYPAL_API_URLPayPal's sandbox or live URLSends every PayPal call to another base URL. The tests use it for a fake PayPal.
Changing the encryption secret disconnects PayPal. Stored PayPal secrets are encrypted with SECRETS_KEY, or with BETTER_AUTH_SECRET when it isn't set. If that value changes, the API can no longer read them and every app has to connect PayPal again. Set SECRETS_KEY on its own if you expect to rotate the auth secret.

Dashboard

Service offer-app, code in offer-app/.

VariableDefaultDescription
OFFER_API_URLDev: http://localhost:6767The API's public URL, shown in snippets. mock uses the built-in mock API. Unset outside development also means the mock.
OFFER_API_ADMIN_KEYDev: dev-admin-keyThe API's ADMIN_API_KEY. Required whenever OFFER_API_URL is set.
OFFER_API_INTERNAL_URLNoneA private address for server-to-server calls, such as offersdk-api:10000. Wired by the Blueprint.
ANTHROPIC_API_KEYNoneTurns on the Agent page.
AGENT_APPROVAL_SECRETDerived from another secretSigns the agent's change approvals. Set the same value on every instance if you run more than one.
DEMO_ENABLEDDev: trueShows the read-only demo login on the sign-in page (pre-filled at /demo-account). The first sign-in builds the demo workspace. Off unless you set it.
CORS_ORIGINS*Origins allowed to call the dashboard's public routes from the browser. A comma-separated list, or * for any.
DEMO_APP_IDNoneApp for the public PayPal checkout demo at /demo/checkout.
DEMO_PUBLISHABLE_KEYNoneThat app's publishable key.
BETTER_AUTH_SECRETA fixed dev valueMock mode only, where sign-in runs inside the dashboard. Unset, sessions are signed with a value that is public in the source, so set your own on any mock dashboard other people can reach.
BETTER_AUTH_URLNoneMock mode only. The dashboard's own URL.

Workflows

Service offersdk-workflows, code in workflows/.

VariableDescription
OFFER_API_URLThe API's public URL. The tasks call its admin-only /pauses routes. You set it.
ADMIN_API_KEYCopied from the API by the Blueprint.

Scripts

pnpm seed:demo reads APP_URL, the dashboard whose demo workspace it builds (or rebuilds with --reset), and defaults to http://localhost:6768. With --reset it also reads ADMIN_API_KEY, the API's admin key. That defaults to dev-admin-key for a local dashboard and is required for a deployed one. See Deploy on Render for resetting a deployed dashboard's demo.