# Configuration

Copy `.env.example` to `.env` and set what you use. Features whose variables are unset stay off and say so, rather than failing at startup. Never commit a real `.env`.

## Core

| Variable | Purpose |
| --- | --- |
| `DATABASE_URL` | Postgres connection (local default `postgres://payvy:payvy@127.0.0.1:5446/payvy`) |
| `PAYVY_BIND` | Listen address (local default `127.0.0.1:7430`) |
| `PAYVY_API_KEY` | API key, at least 32 characters: `openssl rand -hex 32` |
| `PAYVY_PUBLIC_URL` | Public URL of the web app; sign-in links point here |

## Document storage (S3-compatible)

| Variable | Purpose |
| --- | --- |
| `PAYVY_S3_ENDPOINT`, `PAYVY_S3_BUCKET`, `PAYVY_S3_REGION` | Store location (R2, B2, S3, Garage, SeaweedFS…) |
| `PAYVY_S3_ACCESS_KEY`, `PAYVY_S3_SECRET_KEY` | Store credentials |
| `PAYVY_S3_PATH_STYLE` | Path-style addressing (needed by most self-run stores) |
| `PAYVY_S3_CREATE_BUCKET` | Create the bucket at startup (local stores only) |

Without storage, document commands say storage isn't set up.

## Email intake

| Variable | Purpose |
| --- | --- |
| `PAYVY_INBOUND_DOMAIN` | e.g. `in.example.com` |
| `PAYVY_INBOUND_SECRET` | At least 32 characters; the email worker signs with it |

Leave unset to turn intake off. See [Bills by email](https://docs.payvy.com/guide/email-intake/).

## Reading bills (extraction)

| Variable | Purpose |
| --- | --- |
| `PAYVY_EXTRACT_PROVIDER` | `anthropic` or `openai-compatible` |
| `PAYVY_EXTRACT_API_KEY` | Provider key (not needed for a local model) |
| `PAYVY_EXTRACT_MODEL` | Model name (required for openai-compatible; Claude default `claude-opus-5-5`) |
| `PAYVY_EXTRACT_BASE_URL` | Provider endpoint, e.g. `http://127.0.0.1:11434/v1` for Ollama |
| `PAYVY_EXTRACT_AUTO` | Read new inbox documents in the background (default on) |

## Bank payments

| Variable | Purpose |
| --- | --- |
| `PAYVY_SECRETS_KEY` | 64 hex characters (`openssl rand -hex 32`). Seals bank tokens. **Losing it means reconnecting every bank.** |

## Outbound mail (sign-in links)

One sender: Cloudflare Email Service (`PAYVY_CLOUDFLARE_ACCOUNT_ID`, `PAYVY_CLOUDFLARE_EMAIL_TOKEN`, `PAYVY_MAIL_FROM`), or Amazon SES (`PAYVY_SES_REGION`, `PAYVY_SES_ACCESS_KEY_ID`, `PAYVY_SES_SECRET_ACCESS_KEY`, with the From domain verified in SES). With no sender configured, links are written to the server log — fine for local use.

Tests use the separate `PAYVY_TEST_*` variables from `.env.example`.