Auto-capture
Three signals need no code on your site. Each one is a switch per project in
Settings › Auto-Erfassung (config:write), on by default:
| Switch | What the SDK sends | Where you see it |
|---|---|---|
| Outbound links | click {kind: "external", href: <host>} for links to other websites | Verhalten › Links & Downloads |
| File downloads | click {kind: "download", href, ext} for links to files | Verhalten › Links & Downloads |
| 404 pages | not_found {path, via} once per not-found page; the page view itself is reported under the 404 path | Verhalten › 404-Seiten |
All three come from things the SDK already reads – the clicked link and the page it is on. Nothing new is read from or stored on the device, so the consent mode of the project applies unchanged: with „only after consent“ nothing is sent before consent, as for every other signal.
Outbound links
A click on a link whose host is not one of the project's domains. The destination is stored as
host only (www. removed in the tables) – never the path or query of the other site.
Off: the click still counts as a click (engagement, heatmaps, click counts), but without the destination. Goals that match on an outbound host stop counting.
File downloads
A link with the download attribute or whose path ends in one of the project's download
extensions (default pdf, zip, docx, xlsx, pptx, csv, editable on the same settings page). Files on
your own domains are stored with their canonical path (/files/preisliste.pdf), files elsewhere with
the host (cdn.example.net), plus the extension. Files on personal pages
never carry their path.
Off: file links are ordinary link clicks (internal or outbound). Goals on click with
kind: download stop counting – the settings page lists the affected goals before you switch.
404 pages
X3 recognizes a not-found page in three ways:
- Marker (always on): any element with
data-x3-404(or the project'snotFound.markerAttr) – see Data attributes. - Meta tag (switch „Meta-Tag“):
<meta name="x3-status" content="404">in the page head. - Title rule (optional): a case-insensitive pattern for the document title, e.g.
404|nicht gefunden|not found. Checked with the same safe-regex rules as every other pattern.
export const metadata = { title: "Seite nicht gefunden", other: { "x3-status": "404" } };
export default function NotFound() {
return <main>Diese Seite gibt es nicht (mehr).</main>;
}The SDK reports the page view under the project's 404 path (/404, below a host prefix if the site
has one) and sends not_found {path, via} with the requested path once per page view. Routers that
render the not-found view or set its title after the navigation are covered: the SDK checks again
after the route change has rendered and before the page view is first sent.
In Verhalten › 404-Seiten, „Von eigener Seite“ counts hits that came through a link on your own site (own domain as referrer, or an in-app navigation) – these are broken internal links you can fix. External referrers (search engines, other sites) point to old URLs worth a redirect.
Off: no not_found events; the marker still reports the page view under the 404 path, as
before.
Per page: init option
The project switch decides. A single page can switch a signal off, never back on:
init({ key: "pk_3x_…", autocapture: { outboundLinks: false, downloads: false, notFound: false } });The script-tag attribute data-auto does not touch these switches.
Enforced on the server, too
Pages that still run an older script or a cached config (up to a few minutes after a change) are
covered by the API: with a switch off it drops not_found events and removes destination, file and
extension from incoming clicks before storing them. 404 paths that match a personal-page rule are
never stored.
API and MCP
| Route | Scope | |
|---|---|---|
GET /v1/projects/{project}/auto-capture | analytics:read | switches, download extensions, configRev, affected goals, activity of the last 30 days |
PATCH /v1/projects/{project}/auto-capture | config:write | {autoCapture?, downloadExtensions?, configRev?} – a newer stored config answers 409 conflict |
GET /v1/projects/{project}/analytics/outbound-links | analytics:read | rows per host |
GET /v1/projects/{project}/analytics/downloads | analytics:read | rows per file and extension |
GET /v1/projects/{project}/analytics/not-found | analytics:read | rows per requested path |
The table routes take the analytics filter plus sort=field:desc (up to three),
q (search), f.<field>=<op>:<value> per column (eq, in, contains, isEmpty for text;
eq, gte, lte, between for numbers; before, after, between for days as YYYY-MM-DD) and
limit (≤ 500). total counts the matching rows before the limit, disabled says the switch is off.
Unknown columns or operators answer 422 validation_error. The same tables are MCP tools – see
MCP tools.