> 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/security-and-privacy.md).

# Security & Privacy

What Dapta Forms stores with a submission and what it never collects, how integration credentials are protected, how webhooks are signed, how the public form is rate limited, who in your workspace can

Dapta Forms collects the answers people give you, and nothing else. This page explains exactly what is stored, what is never collected, how your integration credentials and webhook deliveries are protected, and how you delete data when you no longer need it.

***

## What is stored with a submission

Every response is one row per person and per session. It holds:

| Stored              | Detail                                                                                                                                             |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Answers             | One value per question, keyed by the question's **Field key**.                                                                                     |
| Score               | The total score, recomputed on the server from your published form.                                                                                |
| Timestamps          | When the person started, when a partial was captured, and when they completed.                                                                     |
| Campaign parameters | Any `utm_source`, `utm_medium`, `utm_campaign`, `utm_term` and `utm_content` that were on the link they opened.                                    |
| Session id          | A random id created per browser tab, used to keep one submission per person instead of many.                                                       |
| Uploaded files      | When the form has a **File upload** question: the file itself in object storage, plus its name, size and reported type on the response. See below. |

You see all of it in **Submissions**, and the same fields go into the CSV export. If a step is answered by a Calendly booking, the booking facts (the invitee's email, name and the meeting time) come with it.

***

## What is never collected

Dapta Forms does not store any of the following with a response:

* **No IP address.** The public form is rate limited per address, but that counter lives in memory only and is never written next to an answer.
* **No device or browser fingerprint.** No user agent, no screen size, no operating system.
* **No location.** No country, no city, no geolocation.
* **No referrer.** Where the visitor came from is only known through the UTM parameters you put on your own links.

The funnel numbers in **Analytics** are built from the same session ids: views, starts, step views and submits. There is no device breakdown and no geography report because that data is not collected in the first place.

> **⚠️ Note:** If you add a **Google Tag Manager**, **Meta Pixel**, **PostHog** or **HubSpot tracking** ID under **Connect → Tracking & pixels**, that vendor collects whatever its own script collects, under its own privacy policy. With no ID set, a published form makes zero third party requests. See [Tracking & pixels](/dapta-forms/connect/tracking-and-pixels.md).

***

## Integration credentials

You connect HubSpot and Calendly once for the whole workspace, on the **Connections** page. When you paste a token, the field tells you what happens to it: *The token is validated, encrypted, and stored server-side. It is never shown again.*

<figure><img src="https://3835013762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FCy5rSNtQmtqYCGzJlNEB%2Fuploads%2Fgit-blob-7859344e16da94200d3ba95e125df0c4af542507%2Fforms-connections-02-hubspot-connected.png?alt=media" alt="The HubSpot card on the Connections page showing the Connected badge, Connected as HubSpot, ending in the last four characters, and the Disconnect button"><figcaption><p>A connected provider shows only the account label and the last four characters of the token. The token itself is never displayed again.</p></figcaption></figure>

* The card only ever shows the account label, the last four characters and the date you connected.
* There is no way to read a stored token back, from the interface or from an export.
* To rotate a token, click **Disconnect** and connect again with the new one.
* Only an **admin** or an **owner** can connect or disconnect a provider.

Your webhook **Signing secret** works the same way. Once it is saved, the field reads *A secret is set. Leave blank to keep it, or type a new one.* and never shows the value again.

None of this reaches the respondent. The public form page is served with your questions and design only: webhook URLs, signing secrets and CRM mappings are stripped before the form is sent to a browser.

***

## Webhook deliveries

Webhooks are the one place where your data leaves Dapta on purpose, so they have their own guardrails.

* **HTTPS only.** The **Endpoint URL** must start with `https://`. Plain `http://` is refused except for `localhost` while you develop.
* **Signed on request.** Set a **Signing secret** and every delivery carries an `X-Forms-Signature` header holding an HMAC-SHA256 of the exact body, so your endpoint can prove the request came from your form. See [Verify the signature](/dapta-forms/connect/webhooks/verify-signature.md).
* **Private addresses are refused.** If a URL resolves to a private, reserved, loopback or internal address, the delivery is blocked before anything is sent and the history row explains: *Blocked before sending: that address is private, reserved, or internal, and we never post to those.*
* **Redirects are never followed.** A `3xx` answer counts as a failure, so a delivery cannot be bounced to an address you did not choose.
* **Bounded.** Each attempt times out after 10 seconds, and a delivery is retried at most five times before it is marked **Failed**.

Every attempt, with what was sent and what came back, is kept in the card's **Webhook history**. Read [Delivery, retries & history](/dapta-forms/connect/delivery-and-retries.md) for the full lifecycle.

***

## Uploaded files

A [File upload](/dapta-forms/builder/question-types/file-upload.md) question stores the file people attach. It is handled apart from the answers, and the rules around it are its own.

* **The file never passes through Dapta's servers.** The browser is given a single-use address that can write one file and nothing else, and it sends the bytes straight to storage.
* **That address expires in minutes.** So does every address used to read a file back. Links are created at the moment someone clicks, and are never written into a page, an email, a webhook payload or the CSV export.
* **The type is verified.** Before a response is saved, the file's actual contents are checked against its extension. A file whose bytes disagree with its name is refused and the submission fails.
* **Programs and web pages are refused outright**, on every form, whatever the question is configured to accept. See [File upload](/dapta-forms/builder/question-types/file-upload.md).
* **Only your workspace can read them.** There is no public URL for an uploaded file, so there is nothing to share by accident and nothing to guess.

***

## Rate limits on the public form

The public surface (loading a form, submitting it, recording a funnel event, confirming a booking) is throttled per IP address: a burst of 60 requests, refilling at one request per second. Past that, the request is answered with `429` and the message *Too many requests. Please slow down.* plus a `Retry-After` hint.

This protects your form from submission spam and from someone scraping your configuration. A real respondent filling out a form never comes close to the limit.

***

## Who can see what

Workspaces are the privacy boundary. A form, its submissions and its analytics belong to one workspace, and only people in that workspace can reach them.

| Role       | Can see and do                                                                                                                                                                                               |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Member** | Their own forms: build, publish, delete, read submissions and analytics, set up webhooks and field mappings, manage their own public page.                                                                   |
| **Admin**  | Everything a member can, on everyone's forms, plus invite people, change roles, activate or deactivate members, edit the brand kit and the notification emails, connect and disconnect HubSpot and Calendly. |
| **Owner**  | Everything an admin can, plus remove an accepted member and act on other owners. A workspace always keeps at least one owner.                                                                                |

Switching workspaces switches everything with it: you never see another workspace's forms or responses in the list. Removing a member takes their access away and leaves the forms and submissions untouched. See [Members & roles](/dapta-forms/account/members-and-roles.md).

***

## Deleting data

You are in control of retention: nothing is deleted automatically, and nothing is kept once you delete it, with one exception noted below for uploaded files.

**Delete one response:** open **Submissions**, use the row action **Delete** and confirm *Delete this submission? This cannot be undone.* The answers, the score and the timestamps go with it. A file the person uploaded is no longer listed, but the stored file itself is not deleted.

**Delete a form and everything it collected:** open the kebab menu on the form row in **Forms** and choose **Delete**. The confirmation reads *Delete this form and all its submissions?* Deleting the form removes its submissions, its funnel events, its bookings and its per-form email overrides in one step. The files its responses uploaded are not deleted.

> **⚠️ Note:** Neither delete can be undone, and neither reaches copies that already left. A contact you created in HubSpot, or a payload your webhook endpoint already stored, has to be deleted there too.

***

## Signing out

**Log out** in the profile menu ends more than the current tab. It revokes your Dapta Forms session and also ends the Dapta sign in it shares, so you are signed out of the other Dapta products in that browser as well. You land back on the sign-in card with **Continue with Dapta**.

A session that simply expires on its own is different: it only ends your Forms session and leaves the Dapta sign in alone.

***

## Reporting a security issue

If you believe you have found a vulnerability in Dapta Forms, do not open a public issue. Write to `security@dapta.ai` with a description, the impact and the steps to reproduce it. The project also accepts private advisories on its [GitHub repository](https://github.com/Dapta-Tech/dapta-forms).

***

## What's next

* [Webhooks](/dapta-forms/connect/webhooks.md): endpoint URL, signing secret and what triggers a delivery.
* [Verify the signature](/dapta-forms/connect/webhooks/verify-signature.md): check that a request really came from your form.
* [Members & roles](/dapta-forms/account/members-and-roles.md): who can do what in a workspace.
* [Submissions](/dapta-forms/results/submissions.md): read, filter and delete responses.
* [Tracking & pixels](/dapta-forms/connect/tracking-and-pixels.md): the analytics tags you can add yourself.


---

# 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/security-and-privacy.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.
