---
title: "Analytics"
description: "Cookie-free form analytics - views, unique visitors, starts, submissions, conversion and the sources behind them."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.getquickforms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Analytics

quickforms counts how often a form is viewed and how many of those views turn into submissions, without cookies and without storing IP addresses. Combined with [partial submissions](https://docs.getquickforms.com/partial-submissions/) and [attribution](https://docs.getquickforms.com/tracking/), it shows views, unique visitors, starts, submissions, the conversion rate, and the sources, campaigns and referrers behind live submissions.

## Counting views

The [embed widget](https://docs.getquickforms.com/embed/) and the [hosted form page](https://docs.getquickforms.com/hosted-forms/) count a view when the form is shown, by calling `POST /f/{form}/view` with an anonymous session ID. The session ID is random, per form, and kept in the browser's `sessionStorage`, so it lasts for the tab. Nothing is sent from the editor's live preview.

To count views for your own form, call the endpoint when the form is shown:

```bash title="Count a view"
curl -X POST https://YOUR-QUICKFORMS-HOST/f/FORM_ID/view \
  -H "Content-Type: application/json" \
  -d '{"session": "3f9c2a7e5b1d4c8a"}'
```

| Field | Description |
| --- | --- |
| `session` | Optional. An anonymous ID for the visitor, up to 64 characters. Used to count unique visitors. |

The response is always `204` with no body. A view isn't counted when:

- the form isn't published,
- the request has a valid `X-Quickforms-Sandbox` header ([sandbox](https://docs.getquickforms.com/sandbox/) previews), or
- the user agent looks like a bot, crawler, link preview or headless browser.

The endpoint is rate limited to 120 view and progress requests a minute per IP, with a `429` above that.

## What is stored

For each form and day, quickforms stores two numbers: views and unique visitors. Nothing else about the visit is kept.

- **Views** go up by one for every counted view.
- **Visitors** go up by one the first time a session ID is seen for that form that day. To check that, a SHA-256 hash of the session ID is held in the cache until the end of the day. It is never written to the database.

No cookies are set, and IP addresses and user agents are not stored with views. A visitor is a browser tab's session on a given day, so the same person in two tabs, or on two days, counts twice.

The rest of the numbers come from data quickforms already has:

- **Starts** are [partial submissions](https://docs.getquickforms.com/partial-submissions/), so they are only recorded while partials are on.
- **Submissions** are live (non-sandbox) submissions.
- **Sources, campaigns, referrers and click IDs** come from each submission's [attribution](https://docs.getquickforms.com/tracking/) in `meta.tracking`.

## `GET /api/v1/forms/{form}/analytics`

Analytics for one form over the last `days` days, including today. Uses a team [API key](https://docs.getquickforms.com/api/#authentication).

| Query | Description |
| --- | --- |
| `days` | 1 to 365, default 30. |

### Request

```bash
curl -G https://YOUR-QUICKFORMS-HOST/api/v1/forms/FORM_ID/analytics \
  -H "Authorization: Bearer $QUICKFORMS_TOKEN" \
  -H "Accept: application/json" \
  --data-urlencode "days=7"
```

### 200 response

```json
{
  "data": {
    "days": 7,
    "views": 3,
    "visitors": 2,
    "starts": 2,
    "submissions": 2,
    "conversion_rate": 1,
    "series": [
      { "day": "2026-10-31", "views": 0, "visitors": 0, "submissions": 0 },
      { "day": "2026-11-01", "views": 0, "visitors": 0, "submissions": 0 },
      { "day": "2026-11-02", "views": 0, "visitors": 0, "submissions": 0 },
      { "day": "2026-11-03", "views": 0, "visitors": 0, "submissions": 0 },
      { "day": "2026-11-04", "views": 0, "visitors": 0, "submissions": 0 },
      { "day": "2026-11-05", "views": 0, "visitors": 0, "submissions": 0 },
      { "day": "2026-11-06", "views": 3, "visitors": 2, "submissions": 2 }
    ],
    "sources": [{ "value": "newsletter", "submissions": 2 }],
    "campaigns": [],
    "referrers": [{ "value": "news.example.com", "submissions": 1 }],
    "click_ids": { "Google Ads": 1 }
  }
}
```

| Field | Description |
| --- | --- |
| `days` | The window, as requested. |
| `views` | Counted views in the window. |
| `visitors` | Unique visitors, summed per day. |
| `starts` | Live partial submissions started in the window. |
| `submissions` | Live submissions in the window. |
| `conversion_rate` | `submissions / visitors`, rounded to three decimals, or `null` with no visitors. |
| `series` | One entry per day, oldest first, with `views`, `visitors` and `submissions`. |
| `sources` | Up to 10 `utm_source` values by number of live submissions. |
| `campaigns` | Up to 10 `utm_campaign` values by number of live submissions. |
| `referrers` | Up to 10 referrer domains by number of live submissions. |
| `click_ids` | Live submissions per ad network, from the click ID they carried: `Google Ads` (`gclid`), `Meta` (`fbclid`), `Microsoft Ads` (`msclkid`), `TikTok` (`ttclid`), `LinkedIn` (`li_fat_id`) and `X` (`twclid`). Networks with none are left out. |

Submissions in the window count whether or not they came through a counted view, so `conversion_rate` can be above `1`, for example when a form is posted to directly.

For starts, completions and where people stop, see the [funnel](https://docs.getquickforms.com/partial-submissions/#funnel).

## MCP

The [MCP server](https://docs.getquickforms.com/mcp/) has a read-only `get-form-analytics` tool. It takes `form_id` and optionally `days` (1 to 365, default 30), and returns the same object as the API, wrapped in `data`.

Source: https://docs.getquickforms.com/analytics/index.mdx
