What's public, what's authenticated, and why.
Public endpoints (no auth)
askbowtie runs on Cloudflare's edge. A few endpoints are reachable without authentication — intentionally, because the tracker on your visitors' browsers needs them:
| Endpoint | What it does | Why it's public |
|---|---|---|
/bowtie.js |
The loader you embed | Installed on your site |
/t.js |
The full tracker, pulled in by the loader | Runs in your visitors' browsers |
/api/ingest |
Receives tracking events | Where the tracker sends data |
/api/tracker-config |
Per-domain tracker settings | The tracker reads its config here |
These endpoints aren't open doors. /api/ingest only accepts events for a domain that is already registered to an account (a domain whitelist), and it enforces per-IP rate limits and payload-size limits to prevent abuse. An unregistered domain is silently ignored.
What tracker-config exposes
This endpoint returns the small amount of config the tracker needs to run. It exposes only:
- Whether the domain is registered (so unknown domains stop sending)
- Ad-platform pixel IDs and conversion labels, if you've configured them — these have to be in client-side JavaScript to fire a conversion pixel, exactly as they would be if you added the ad platform's own tag directly
It does not expose your conversion rules, funnel definitions, alert thresholds, or any visitor data.
Authenticated surfaces
| Surface | Auth | How it works |
|---|---|---|
Dashboard (/app) |
Session cookie | One first-party, HttpOnly, Secure cookie. Passwordless sign-in — we never store a password. |
MCP (/mcp) |
Bearer token | Authorization: Bearer ab_…. The token is SHA-256 hashed at rest; we only ever store the hash. An Origin allowlist and a per-call domain check gate every request. |
MCP tokens are shown once when you create them and never again. If you lose one, revoke it in settings and mint a new one.
How your data is isolated
Each tracked site's data lives in its own database at the edge — sites are not co-mingled in shared tables. Access is scoped to your account: every read checks that your user has a role on that domain (owner, admin, or viewer), and an MCP token can be scoped to a single domain. A request for a domain you don't have access to is refused before any data is touched.
What the tracker collects
From your visitors:
- Page paths (query strings are not stored)
- Referrer
- Browser, OS, and device type (parsed from the User-Agent)
- A random, anonymous session id held in
localStorage(not a cookie) - Events: page loads, clicks (element context only), form submissions, errors, performance metrics
What it deliberately does not collect:
- No cookies are set on visitor browsers
- IP addresses are not stored — an IP is used only transiently for rate-limiting and an approximate-country lookup, then discarded
- No form field values, ever
- No click text — clicks record the element (tag, id, class, link target), never the words inside
- No cross-site identifiers
PII scrubbing
Before anything leaves the page, the tracker scrubs likely personal data — email addresses, phone numbers, and card numbers are replaced with placeholders. Input values are never captured in the first place.
Running a strict Content-Security-Policy
If your site sends a Content-Security-Policy header, allow the tracker to load and report by adding askbowtie to two directives:
script-src 'self' https://askbowtie.com;
connect-src 'self' https://askbowtie.com;
script-src lets bowtie.js / t.js load; connect-src lets the tracker send events to /api/ingest. Nothing else is required — the tracker loads no fonts, frames, or images from askbowtie.
Reporting a security issue
Found a vulnerability? Email [email protected]. Please give us reasonable time to fix it before disclosing, and don't access other users' data or run denial-of-service tests in the process.