API Endpoints
Browser analytics endpoints and the connected backend telemetry API.
Backend telemetry and Node SDK
Services connects a project and environment to a separate server-only ingest key. Existing public website tracking IDs remain unchanged and cannot authorize backend writes. Start the Node SDK before importing HTTP or logger modules. Keep keys out of browser bundles, HTML and URLs.
| Interface | Supported contract |
|---|---|
| OTLP receiver | POST /v1/traces, /v1/logs and /v1/metrics; HTTP JSON or protobuf, optional gzip, Authorization: Bearer backend key. No gRPC transport. |
| Node SDK | Automatic Node HTTP spans and Pino logs; standard metrics. Qualified real postgres.js and node:sqlite operations use explicit CLIENT spans. Start before application imports and await graceful shutdown; no durable local spool or SIGKILL flush. |
| Query and control | /api/v1/telemetry/projects/:projectId/environments/:environmentId: services, connection-status, service-summary, traces, logs, metric-catalog, metrics, outcomes and trace journey. Session authentication and current membership apply; ingest keys cannot read these APIs. |
| Confirmed outcomes | POST /api/v1/telemetry/outcomes with an outcomes-enabled ingest key and stable domain event identity. Separate confirmations and provenance; successful HTTP requests and browser form signals do not imply a purchase. |
| Browser association | Explicit first-party origin configuration links recorded requests to site/session/page evidence. Standard redirect-follow fetch uses qualified response context; existing trace context is preserved. No exported browser span or verified-person claim. |
| MCP | Streamable HTTP at /mcp; official protocol 2026-07-28 and legacy 2025-11-25 initialization. Scoped personal query tokens, separate from ingest keys; no OAuth server or stdio transport is advertised. Shared authorized query values, audited controls, and explicit expiring browser consent for view changes. |
Open Backend → Connection setup for installation and Agent connection for a query token. Backend-only projects are supported. Queries include evaluated scope/range, coverage and freshness; unavailable observations are not zero traffic. Public website shares never expose backend telemetry.
Node SDK installation
For a connected website, open Backend → Connection setup. For an independent backend, open Projects & services and create a project. Save the Details step, follow Install, then use Verify to check for a received request. Website tracking is installed separately from the website installation guide.
Install the published @pipetrace/sdk-node package with your package manager and commit the lockfile. The guide provides server variables and the startup command for your actual compiled entrypoint. Keep the backend key in runtime secret settings.
Self-hosted operators can alternatively distribute the versioned archive advertised by /sdk/manifest.json. The API build prepares this archive. Verify the manifest's SHA-512 integrity and pin the version; this operator distribution path is separate from the npm instructions shown in setup.
For ESM, use node --experimental-loader @pipetrace/sdk-node/hook bootstrap.mjs; the bootstrap starts the SDK, then dynamically imports the application. Set PIPETRACE_ENDPOINT, PIPETRACE_API_KEY and PIPETRACE_SERVICE_NAME. Services provides the complete bootstrap example. Native OpenTelemetry HTTP exporters can also send directly without the wrapper.
See backend data and redaction and retention and deletion for the separate browser/backend policies.
Sites
List Sites
GET /api/v1/sitesReturns all sites for the authenticated user.
Get Site
GET /api/v1/sites/:siteIdCreate Site
POST /api/v1/sites
{
"domain": "example.com",
"name": "My Website",
"jurisdiction": "PT"
}jurisdiction is optional: the ISO 3166-1 alpha-2 code of the country where the site's owner is established. With it, the site starts with consent required everywhere, anonymous counts before consent and 25 months of retention. Without it, the site keeps the behaviour from before privacy settings until you save them.
Update Site
PATCH /api/v1/sites/:siteId
{
"name": "Updated Name"
}Site Privacy Settings
PUT /api/v1/sites/:siteId/privacy
{
"jurisdiction": "PT",
"consentMode": "required",
"preConsentTier": "counts",
"retentionMonths": 25
}Replaces the site's whole privacy policy; every field is required and unknown fields are rejected. jurisdiction is the owner's ISO 3166-1 alpha-2 country code. consentMode is required or regional. preConsentTier is off, counts or sessions. retentionMonths is a whole number from 1 to 25. Returns the updated site. A regional policy for an owner established in the EEA, the UK, Gibraltar, the Channel Islands, the Isle of Man or Switzerland is rejected with 400 REGIONAL_NOT_ALLOWED. New events follow a saved policy within 5 minutes.
Delete Site
DELETE /api/v1/sites/:siteIdTracker policy answers
The tracker asks GET /api/v1/policy?site=… before it collects anything, and every POST /api/v1/track response with a body carries the same answer as policy (a Global Privacy Control request gets 204 with no body):
{ "maxTier": 0, "stop": "policy", "cap": "dnt" }maxTieris the highest privacy tier the server will store for this visitor: 0 (nothing), 1 (anonymous counts), 2 (anonymous sessions) or 3 (consented analytics).stopappears only withmaxTier: 0."gpc"means the browser sent Global Privacy Control: nothing is collected, and no consent lifts it."policy"means the site records nothing before consent: an explicitpipetrace.consent("granted")can still start consented analytics on the same page, unlesscapis"dnt".cap: "dnt"appears when the request carried Do Not Track: the visitor stays at most at anonymous counts, even after accepting, and the tracker does not keep cookies or browser storage for them.
Both fields are optional and additive; older trackers ignore them.
Analytics
Overview
GET /api/v1/sites/:siteId/analytics/overview?period=7dReturns aggregate statistics for the period.
{
"data": {
"visitors": 1234,
"pageviews": 5678,
"bounceRate": 45.2,
"avgDuration": 180,
"visitorsChange": 12.5,
"pageviewsChange": 8.3,
"tiers": {
"visits": { "anonymousCounts": 340, "anonymousSessions": 210, "consented": 900 },
"pageviews": { "anonymousCounts": 500, "anonymousSessions": 480, "consented": 4698 },
"visitors": { "anonymousSessions": 210, "consented": 1024 }
}
}
}tiers is optional and additive: existing fields keep their meaning across every privacy tier, and a caller reading only the old fields keeps working unchanged. See Privacy tiers and metrics below for what each field counts.
Time Series
GET /api/v1/sites/:siteId/analytics/timeseries?period=7dReturns data points for charts.
Top Pages
GET /api/v1/sites/:siteId/analytics/pages?period=7d&limit=10Pages are ranked by reach (visitors plus anonymous-count page views). Add sort=pageviews to pick and order the top pages by page views instead; sort=reach is the default.
Top Sources
GET /api/v1/sites/:siteId/analytics/sources?period=7d&limit=10Devices
GET /api/v1/sites/:siteId/analytics/devices?period=7dBrowsers
GET /api/v1/sites/:siteId/analytics/browsers?period=7dLive Count
GET /api/v1/sites/:siteId/analytics/liveReturns activity in the last 5 minutes:
{
"data": { "count": 7, "visitors": 7, "anonymousPageviews": 2 }
}visitors counts consented and anonymous-session visitors (tiers 2–3); anonymousPageviews counts anonymous-count (tier 1) page views in the same window, which have no visitor to count. count keeps its earlier meaning for existing consumers and always equals visitors. Because tier 1 timestamps are truncated to the minute they were received, the anonymous-page-view window can be off by up to a minute.
Privacy tiers and metrics
Pipetrace can count a visit before consent is given (see privacy tiers and data). Every analytics response keeps counting the same way across tiers, so these rules apply everywhere above:
- Visits are the entry pageview of an anonymous-count (tier 1) visitor, or the session of an anonymous-session or consented (tier 2–3) visitor. A consented continuation — a session that started when someone upgraded consent mid-visit — is not counted again; it was already counted anonymously.
- Visitors only exist for anonymous-session and consented visits (tiers 2–3). Anonymous counts (tier 1) have no visitor ID, so they add to visits and page views but never to visitors. An anonymous-session visitor is daily: its ID changes at UTC midnight, so the same person on two days is two visitors, and a session that crosses midnight is two visits.
- Goal conversion rate is converting visits ÷ visits, capped at 100%. An anonymous-count goal is counted per page rather than per visit, and a consented continuation's conversion is credited to the visit already counted anonymously, so the rate can be approximate where those apply.
- Bounce rate, average duration, scroll depth and Core Web Vitals are only ever measured for consented visits (tier 3).
- Journeys, paths and funnels use anonymous-session and consented visits (tiers 2–3). A consented journey can start on the page where consent was given, not the original landing page.
- Page, source, UTM, country, device and browser lists are ranked by how many visits and visitors reached that value, so an anonymous-count-only value can still appear and rank. Operating system is reported for consented visits only.
Use filter_privacy_tier to restrict any of the above to one collection method.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
period | string | One of: 24h, 7d, 30d, 90d |
limit | number | Max results to return (default: 10, max: 100) |
filter_privacy_tier | number | 1 (anonymous counts), 2 (anonymous sessions) or 3 (consented) — the "Collected as" filter. Any other value is rejected. |
HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 204 | No Content (successful delete) |
| 400 | Bad Request (validation error) |
| 401 | Unauthorized (missing/invalid token) |
| 404 | Not Found |
| 429 | Too Many Requests (rate limited) |
| 500 | Internal Server Error |