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

# Connect Microsoft Clarity

> Sync rage clicks, scroll depth, and engagement signals from Microsoft Clarity's Data Export API and use them in automation rules.

Microsoft Clarity provides behavioural metrics — rage clicks, dead clicks, scroll depth, engagement time — for each landing page. This integration uses Clarity's **Data Export API** (not the tracking script alone), so a per-business Clarity **project ID** and **API token** are required.

Open it from a business's **Settings → Data Sources → Clarity**.

<Note>
  This is a **backend API integration**, not a JavaScript snippet. Clarity must already be installed and collecting data on the client's site before you connect it here.
</Note>

## Generate Clarity credentials

1. In Microsoft Clarity, open the project for this client.
2. Go to **Settings → Data Export**.
3. Copy the **Project ID**.
4. Select **Generate new API token** and copy the token.

You'll paste both into the Clarity panel in The Agency Engineer.

## Clarity panel

The Clarity panel surfaces connection state and credentials:

* **Status badge** — **Connected** when a token is stored and verified.
* **Description** — *Sync rage clicks, scroll depth, and other behavioral metrics from Microsoft Clarity. Generate a token at Clarity → Settings → Data Export → Generate new API token. The Clarity API allows 10 calls per project per day — the daily scheduler uses 4 of those.*
* **Last synced** — Timestamp of the most recent successful sync (for example, *31/05/2026, 05:00:46*).

### Fields

| Field      | Notes                                                                                                             |
| ---------- | ----------------------------------------------------------------------------------------------------------------- |
| Project ID | Alphanumeric, 6–20 characters. Found in Clarity → Settings → Data Export.                                         |
| API Token  | Paste a new value to replace the existing one. Stored server-side. **Testing burns 1 of 10 daily Clarity calls.** |

### Actions

* **Update** — Save changes to Project ID or API Token.
* **Test** — Verify the token by making one API call. Counts against your **10 daily Clarity calls**.
* **Refresh** — Reload the connection state.
* **Sync enabled** (toggle) — Pause or resume the daily scheduler without disconnecting.
* **Disconnect** — Remove credentials. Historical metrics already stored are retained.

<Warning>
  Use **Test** sparingly. Each test call consumes one of your **10 daily API calls per project**. If you exhaust the quota, the daily scheduler may skip a day.
</Warning>

## API limits enforced by the integration

The Data Export API has hard limits the integration respects:

* **10 calls** per project per UTC day.
* **1–3 days** of data per request (`numOfDays`).
* Up to **3 dimensions** per call.
* **No pagination** — up to \~1,000 rows per response.

The daily scheduler uses **4 of the 10 daily calls** to cover the dimension combos described below. That leaves 6 calls for manual tests and the client portal's connection test.

## What data is synced

Each API call slices data by up to three of these dimensions:

`Browser`, `Device`, `Country/Region`, `OS`, `Source`, `Medium`, `Campaign`, `Channel`, `URL`

The daily scheduler runs four default combos (one API call each):

1. `URL` + `Device`
2. `URL` + `Source`
3. `URL` + `Country/Region`
4. `URL` + `Campaign` + `Channel`

### Metric groups returned by Clarity

Clarity returns groups including `Traffic`, `ScrollDepth`, `EngagementTime`, `DeadClickCount`, `RageClickCount`, `ExcessiveScroll`, `QuickbackClick`, `ScriptErrorCount`, `ErrorClickCount`, plus `PopularPages`, `PageTitle`, and `ReferrerUrl`.

The sync normalises and stores these fields per dimension tuple:

| Stored field         | Source group (typical) |
| -------------------- | ---------------------- |
| `sessions`           | Traffic                |
| `bot_sessions`       | Traffic                |
| `distinct_users`     | Traffic                |
| `pages_per_session`  | Traffic                |
| `scroll_depth`       | ScrollDepth            |
| `engagement_time_ms` | EngagementTime         |
| `dead_clicks`        | DeadClickCount         |
| `rage_clicks`        | RageClickCount         |
| `excessive_scroll`   | ExcessiveScroll        |
| `quick_backs`        | QuickbackClick         |
| `script_errors`      | ScriptErrorCount       |
| `error_clicks`       | ErrorClickCount        |

Dimension values land in columns like `url`, `device`, `country`, `source`, `campaign`, `channel`, `browser`, `os`, `medium`. URLs are normalised for consistent joins. Raw API rows are also kept in `raw_payload` for audit and debugging.

Rows are stored in **`clarity_daily_metrics`** keyed by `(business_id, date, dimension_hash)` so different breakdowns don't get summed together incorrectly.

## How the sync works

```mermaid theme={null}
flowchart LR
  A[Clarity Data Export API] --> B[fetchClarityMetrics - 4 calls]
  B --> C[Normalize + upsert clarity_daily_metrics]
  D[Daily clarityScheduler] --> B
  E[Business settings UI] --> F[clarity_business_config]
  F --> D
  C --> G[getBusinessBehavioralAggregates]
  G --> H[Rules engine clarity_* metrics]
```

1. **Configuration** — Saving credentials writes them to `clarity_business_config`. **Test** verifies the token (uses 1 daily call).
2. **Scheduled sync** — The daily `clarityScheduler` runs once per UTC day per enabled business, fetches 1 day of data, upserts into `clarity_daily_metrics`, and tracks each job in `clarity_sync_jobs`.
3. **Failure handling** — Bad auth **disables** the config automatically. Rate-limit errors leave it enabled so it retries the next UTC day.
4. **Client portal** — The same config and test endpoints are available under client-user routes for client-facing setup.

<Note>
  There is **no Clarity metrics report screen** in the frontend today — only this connection/settings panel. The data is consumed by the rules engine (below).
</Note>

## How the data is used

### Automation rules (primary use)

Synced data is rolled up **business-wide** over the rule's date window via `getBusinessBehavioralAggregates` (using the `Device,URL` slice to avoid double-counting).

Those aggregates feed the rule builder and are attached to **every** campaign / ad set / ad evaluation:

| Metric                       | Description                    |
| ---------------------------- | ------------------------------ |
| `clarity_sessions`           | Total sessions.                |
| `clarity_rage_clicks`        | Total rage clicks.             |
| `clarity_dead_clicks`        | Total dead clicks.             |
| `clarity_excessive_scroll`   | Total excessive-scroll events. |
| `clarity_quick_backs`        | Total quick-back events.       |
| `clarity_rage_click_rate`    | Rage clicks ÷ sessions.        |
| `clarity_dead_click_rate`    | Dead clicks ÷ sessions.        |
| `clarity_quick_back_rate`    | Quick backs ÷ sessions.        |
| `clarity_scroll_depth`       | Average scroll depth.          |
| `clarity_engagement_time_ms` | Average engagement time (ms).  |

If Clarity isn't configured or has no data for the window, values are **`null`** and conditions that depend on them **don't trigger** — rules still run for other metrics.

Example rules:

* Pause spend when `clarity_rage_click_rate` exceeds a threshold over the last 7 days.
* Send an alert when `clarity_dead_clicks` spikes after a landing page change.

### Prepared but not wired

`getUrlBehavioralAggregates` (per landing URL) exists in the model but isn't yet called elsewhere. **Per-URL** rules and optimiser logic are not active today — only business-wide aggregates are used.

## Summary

| Area                         | Role of Clarity                                                |
| ---------------------------- | -------------------------------------------------------------- |
| Settings                     | Connect token, test, enable/disable, disconnect.               |
| Database                     | Daily behavioural snapshots keyed by URL + traffic dimensions. |
| Rules engine                 | Business-wide UX frustration and engagement signals.           |
| Reports / Facebook dashboard | Not integrated yet.                                            |
| Per-URL optimisation         | Model ready, not yet used in app flow.                         |

## Troubleshooting

| Symptom                                      | Fix                                                                                                                  |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| **Test** returns 401                         | Token is invalid or expired. Generate a new one in Clarity → Settings → Data Export and paste it into **API Token**. |
| Config auto-disabled                         | Bad auth disables the config. Reconnect with a fresh token and re-enable **Sync enabled**.                           |
| **Last synced** is more than a day old       | Rate limit may have been hit. Wait until the next UTC day or check `clarity_sync_jobs` for the failure reason.       |
| Rules with `clarity_*` conditions never fire | Either Clarity has no data for that window, or `clarity_business_config` is disabled. Re-run **Test** to confirm.    |

## Next steps

<CardGroup cols={2}>
  <Card title="Connect GoHighLevel" icon="plug" href="/getting-started/integrations/connect-crm">
    Pair Clarity signals with GHL lead qualification rules.
  </Card>

  <Card title="Business dashboard" icon="chart-line" href="/product/dashboard">
    See where Clarity-fed rules feed back into KPIs.
  </Card>
</CardGroup>
