> For the complete documentation index, see [llms.txt](https://docs.dapta.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dapta.ai/dapta-forms/developers/environment-flags.md).

# Feature flags & environment

The environment settings a self-hosted Dapta Forms deployment can change that your users actually notice: demo form seeding, premium features, the Made with Dapta Forms badge, deployment wide tracking

A self-hosted deployment is configured entirely through environment variables. Most of them are plumbing, meaning database, ports and secrets, and are covered in [Self-hosting](/dapta-forms/developers/self-hosting.md). This page lists the ones that change **what people see**, so you can tell why your instance behaves differently from forms.dapta.ai.

None of these apply to the hosted product: on forms.dapta.ai these choices are already made for you.

> **⚠️ Note:** Anything starting with `NEXT_PUBLIC_` is a **build time** value, baked into the web image when you build it. Changing it means rebuilding and redeploying the web image, not restarting a container.

***

## New workspaces

| Setting          | Default | What your users see                                                                                                                                                                                                                                         |
| ---------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SEED_DEMO_FORM` | `true`  | Whether a brand new workspace starts with a ready made demo form to poke at, or an empty **Forms** list. Set it to `false` to ship empty workspaces. Other first run settings can take precedence over it: `.env.example` spells out the exact interaction. |

***

## Premium features

Dapta Forms itself is free and has no plans to unlock. The gate exists only so a deployment can put its own entitlements in front of the optional extras.

| Setting                | Default | What your users see                                                                                                                                           |
| ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PREMIUM_FEATURES`     | `open`  | `open` unlocks everything, which is what a fork gets and what you almost certainly want. `locked` checks each feature against an entitlement service instead. |
| `ENTITLEMENTS_API_URL` | unset   | Required only when `PREMIUM_FEATURES=locked`: the service that answers the entitlement check.                                                                 |
| `ENTITLEMENTS_API_KEY` | unset   | The credential for that service. Required only when `PREMIUM_FEATURES=locked`.                                                                                |

***

## Naming and cross links

| Setting                     | Default | What your users see                                                                                   |
| --------------------------- | ------- | ----------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_PRODUCT_NAME`  | `Forms` | The product name shown around the UI.                                                                 |
| `NEXT_PUBLIC_PLATFORM_URL`  | empty   | Adds the platform row to the app switcher. Unset renders neither it nor the platform navigation item. |
| `NEXT_PUBLIC_CALENDARS_URL` | empty   | Adds a calendars link to the app switcher.                                                            |

***

## Deployment wide tracking IDs

These are the marketing tags rendered on **public form pages only**, never in the dashboard. Each tag loads only when its ID is set, so a deployment with all of them unset makes zero third-party requests. They are defaults for the whole deployment, and a form's own settings under **Connect** override them per form. See [Tracking & pixels](/dapta-forms/connect/tracking-and-pixels.md).

| Setting                           | What your users see                                                                                  |
| --------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `NEXT_PUBLIC_GTM_ID`              | Loads a Google Tag Manager container on every public form page.                                      |
| `NEXT_PUBLIC_META_PIXEL_ID`       | Fires one Meta Pixel PageView per visit.                                                             |
| `NEXT_PUBLIC_POSTHOG_KEY`         | Captures one PostHog pageview per visit.                                                             |
| `NEXT_PUBLIC_POSTHOG_HOST`        | The PostHog ingestion URL. Defaults to PostHog US cloud, so set it for an EU or self-hosted project. |
| `NEXT_PUBLIC_HUBSPOT_TRACKING_ID` | Loads the HubSpot tracking code for your portal on public form pages.                                |

> **⚠️ Note:** These tags belong to the **form owner** and measure their respondents. They are not your deployment's own product analytics, which is a separate set of variables with deliberately different names so the two can never be pointed at the same key.

***

## Email

Nothing is emailed until you choose a provider. Until then, submission notices are written to the API log, so a fresh deployment still runs end to end.

| Setting           | Default             | What your users see                                                                                                                                                                                                     |
| ----------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `EMAIL_PROVIDER`  | `log-only`          | `log-only` prints notices to the log, `noop` drops them silently, `smtp` sends over SMTP, `http` posts each message to a mail API. Until this is set, [submission emails](/dapta-forms/connect/emails.md) never arrive. |
| `MAIL_FROM_EMAIL` | `forms@example.com` | The sender address on every email. Change it before you send anything real.                                                                                                                                             |
| `MAIL_FROM_NAME`  | `Forms`             | The sender name shown in the inbox.                                                                                                                                                                                     |

***

## Rate limits and destinations

| Setting                     | Default                                | What your users see                                                                                                                                                                                             |
| --------------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `RATE_LIMIT_ENABLED`        | `true`                                 | Whether the public form and submission endpoints are throttled at all.                                                                                                                                          |
| `RATE_LIMIT_CAPACITY`       | `60`                                   | The burst allowance per client IP address.                                                                                                                                                                      |
| `RATE_LIMIT_REFILL_PER_SEC` | `1`                                    | How fast that allowance builds back up. See [Public API & rate limits](/dapta-forms/developers/public-api.md).                                                                                                  |
| `TRUST_PROXY_HOPS`          | `1` when a public URL is set, else `0` | How many trusted proxies sit in front of the API. Set it wrong and every visitor shares one bucket, so real respondents start seeing throttle errors.                                                           |
| `HUBSPOT_PRIVATE_APP_TOKEN` | unset                                  | Set it and HubSpot works for the whole deployment: the **Connections** page shows **Provided by the server** instead of asking each account to connect. Unset, the HubSpot card reports a clear disabled state. |

***

## File uploads

The **File upload** question only exists on a deployment that has somewhere to put the files. `STORAGE_BUCKET` is the switch: unset, which is what a bare fork gets, the question type cannot be published and the upload endpoint answers `404`, so a clone with no bucket still runs end to end.

| Setting                                               | Default     | What your users see                                                                                                                                 |
| ----------------------------------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `STORAGE_BUCKET`                                      | unset       | The bucket uploads are written to. Setting it turns the **File upload** question on for the whole deployment.                                       |
| `STORAGE_REGION`                                      | `us-east-2` | The bucket's region. A mismatch fails the request rather than writing somewhere else.                                                               |
| `STORAGE_PROVIDER`                                    | unset       | Set it to `none` to keep a bucket configured but turn the feature off. It is not how you turn storage on: the bucket is.                            |
| `STORAGE_ENDPOINT`                                    | unset       | Point it at an S3-compatible service such as Cloudflare R2 or MinIO. Most self-hosted servers also need `STORAGE_FORCE_PATH_STYLE=true`.            |
| `STORAGE_ACCESS_KEY_ID` / `STORAGE_SECRET_ACCESS_KEY` | unset       | Only for a deployment with no instance or workload role to attach. On a pod with a role, leave both unset and the SDK finds the credentials itself. |
| `UPLOAD_MAX_FILE_MB`                                  | `10`        | The hard ceiling per file. A form owner can ask for less on their own question, never more.                                                         |
| `UPLOAD_PRESIGN_TTL_SEC`                              | `600`       | How long an upload address stays valid.                                                                                                             |
| `UPLOAD_DOWNLOAD_TTL_SEC`                             | `300`       | How long a link to read a file back stays valid.                                                                                                    |

The browser uploads straight to the bucket, so the bucket's CORS rules have to allow the origin your forms are served from. Allow `PUT` for the upload itself, and `GET` as well if you want Word documents to preview in the dashboard, since that is the one kind the dashboard fetches rather than pointing the browser at.

***

## Where the full list lives

These are the user visible ones. The complete reference, including every secret, port and database setting, lives in the repository:

* [`.env.example`](https://github.com/Dapta-Tech/dapta-forms/blob/develop/.env.example): every variable with its default and an inline explanation of what it does.
* [`SELF-HOSTING.md`](https://github.com/Dapta-Tech/dapta-forms/blob/develop/SELF-HOSTING.md): the same variables grouped by concern, with the ones that are required for a real deployment called out.

Server settings are validated when the API starts. A bad value stops the boot with a message naming the variable and the reason, rather than starting up in a broken state.

***

## What's next

* [Self-hosting](/dapta-forms/developers/self-hosting.md): the deployment itself.
* [Public API & rate limits](/dapta-forms/developers/public-api.md): what the throttle settings above actually do.
* [Tracking & pixels](/dapta-forms/connect/tracking-and-pixels.md): the per form version of the tracking IDs.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.dapta.ai/dapta-forms/developers/environment-flags.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
