TraceDart integration guide

Install the browser script, collect traffic, resolve returning anonymous visitors, and keep collection scoped to your domains.

Install the browser script

Paste the snippet into the head of every page you want to track. Use the production key generated for the site in the dashboard.

HTML
<script
  src="https://api.tracedart.com/analytics.js"
  data-api-key="td_sk_..."
  defer
></script>
  • Loads asynchronously
  • Starts a first-party visitor token
  • Captures pageviews, sessions, active time, scroll depth, and referrer context

Known user identity

TraceDart resolves returning visitors using the first-party visitor token, full and component fingerprint hashes, browser context, and network observations, including ASN, ISP, VPN/proxy, datacenter, and provider signals.

The collect API also accepts an optional userId field, which takes precedence over every other signal once it is present on a request. This is meant for server-side integrations that already authenticate the visitor and forward that ID when they call the collect endpoint directly.

A tracedart.identify(userId) browser helper is planned. Until it ships, the browser script has no way to attach a user ID on its own — only a server-side integration calling the collect API can set one.

Fingerprint signals

TraceDart creates one full td-v2 browser fingerprint hash and a set of smaller component hashes. Raw component values are not stored: the browser hashes each signal group first, then the backend HMACs those hashes before saving them.

Identity matching uses a userId attached through the collect API when one is present, then the first-party visitor token, then the full fingerprint hash, then a conservative component match across stable signal groups.

Component hashes

ComponentWhat it checksHow it is measured
stableBrowser/device basicsReads user agent, vendor, platform, hardware hints, cookies, DNT, PDF viewer, touch points, Client Hints, and Brave detection.
graphicsGPU and renderingQueries WebGL/WebGL2/WebGPU, renders canvas text/shapes, then hashes rendering output.
audioAudio stackRenders a fixed OfflineAudioContext oscillator/compressor graph and hashes the sample result.
fontsInstalled fontsMeasures hidden text against base font families to detect available fonts.
localeLanguage and regionReads browser languages, timezone, offset, Intl options, and speech voices.
capabilitiesBrowser feature setChecks API presence, CSS support, media preferences, storage, touch, plugins, and permissions.
displayScreen and layoutReads screen/window dimensions, color depth, DPR, viewport, orientation, and measured UI sizes.
networkBrowser network hintsReads Network Information API type, effective type, save-data, downlink bucket, and RTT bucket.
mathRuntime math behaviorRuns fixed floating-point Math operations and hashes the results.
timingTimer precisionSamples performance.now() deltas and buckets the timer resolution.
storageStorage environmentChecks cookies, local/session storage, IndexedDB, openDatabase, quota, persistence, and OPFS.
mediaCodecs and devicesChecks media codec support, MediaCapabilities, WebCodecs, and media device counts.
permissionsPermission statesQueries browser permissions such as camera, microphone, geolocation, clipboard, notifications, sensors, and push.
automationBot/headless hintsChecks webdriver, headless user agent, plugin/MIME counts, chrome runtime, window gaps, visibility, and permissions API presence.

Separate risk and context signals

TraceDart also records browser timezone context, private-mode detection, parsed browser/device fields, IP geolocation, ASN, ISP, VPN/proxy/Tor/datacenter, and provider signals. Those help explain traffic quality and risk, but they are separate from the browser fingerprint component hashes.

Track custom events

Use custom events for actions that matter more than a pageview: referral clicks, coupon copies, lead submissions, checkout clicks, demo requests, tool usage, or account creation.

After the install script has loaded, call window.tracedart.track with a stable event name and a small properties object.

JavaScript
window.tracedart?.track("demo_request", {
  plan: "portfolio",
  source: "pricing"
});
  • Use lowercase snake_case event names, such as referral_click or email_signup_success
  • Send useful metadata, not sensitive data
  • Keep property values short and stable so tables stay readable

TraceDart stores events with the current visitor, session, pageview, page URL, timestamp, referrer, UTM context, device, browser, location, and any custom properties you send. Events appear in the dashboard under Events & Goals, visitor timelines, and page-level event tables.

Event properties

Properties sent with tracedart.track(name, props) are explorable in the dashboard: open Events & Goals and click an event name to see its property keys ranked by frequency, then click a key for a per-value breakdown — count and unique visitors — over the selected date range. Keep values low-cardinality so that breakdown stays readable: plan names, categories, and step labels work well; raw IDs, emails, and other high-cardinality or sensitive values do not.

Track clicks

For outbound links, referral links, affiliate buttons, or CTA clicks, attach a listener and send the destination plus campaign context.

JavaScript
document.querySelectorAll("[data-track-referral]").forEach((link) => {
  link.addEventListener("click", () => {
    window.tracedart?.track("referral_click", {
      label: link.textContent.trim(),
      destination_host: new URL(link.href).hostname,
      campaign: link.dataset.campaign,
      placement: link.dataset.placement
    });
  });
});

Track forms

Track the form action, result, source, and page. Do not send email addresses, passwords, payment data, health data, full prompts, or other sensitive values in event properties.

JavaScript
const form = document.querySelector("[data-lead-form]");

form?.addEventListener("submit", async (event) => {
  event.preventDefault();

  window.tracedart?.track("lead_submit", {
    source: "footer",
    page: window.location.pathname
  });

  try {
    await submitLeadForm(form);
    window.tracedart?.track("lead_success", {
      source: "footer",
      page: window.location.pathname
    });
  } catch {
    window.tracedart?.track("lead_error", {
      source: "footer",
      page: window.location.pathname
    });
  }
});

Track product or content tools

For calculators, search, filters, AI tools, or recommendation flows, track the action and numeric context rather than raw user text.

JavaScript
window.tracedart?.track("tool_used", {
  tool_name: "unit_converter",
  input_count: 4
});

window.tracedart?.track("site_search", {
  search_area: "docs",
  query_length: searchInput.value.trim().length
});

Goals & funnels

Goals are user-defined in Events & Goals in the dashboard. A goal matches either a custom event name exactly, or a page path — an exact path, or a prefix ending in * (for example /thanks* matches /thanks and /thanks/confirmed). The goals overview reports completions, unique converting visitors, and a conversion rate (converting visitors divided by unique visitors for the selected range).

If a site has no goals configured yet, TraceDart falls back to treating conversion-style event names as goals automatically — purchase, signup, lead, and names ending in _success or _conversion among them. This fallback only applies until you define your own goals.

JavaScript
window.tracedart?.track("email_signup_success", {
  source: "blog_footer"
});

window.tracedart?.track("purchase_conversion", {
  plan: "starter",
  billing_cycle: "annual"
});

Funnels build on the same event and path building blocks. Define 2-8 ordered steps in Events & Goals, each an event name or a path (wildcards allowed). A visitor only advances to a step after completing the previous step within the selected date range, and the dashboard reports per-step visitor counts and conversion, both from the previous step and from the funnel's start.

Guard events before the script loads

If your app may fire events before the deferred script has loaded, wrap tracking in a tiny helper. This keeps your UI code from throwing if analytics is unavailable.

JavaScript
function trackEvent(name, properties = {}) {
  if (window.tracedart?.track) {
    window.tracedart.track(name, properties);
  }
}

trackEvent("cta_click", {
  placement: "hero",
  label: "Start trial"
});

The tracker also exposes window.analyticsTrack as an alias for the same function.

Webhooks

Create webhooks per site in Settings → Webhooks. They fire on goal completions (goal.completed), and the signing secret (td_whs_...) is shown once, at creation time — store it somewhere safe.

Every delivery is a POST with a JSON body and three relevant headers: content-type: application/json, x-tracedart-event: goal.completed, and x-tracedart-signature: sha256=<hex>, where the hex digest is an HMAC-SHA256 of the raw request body, keyed with the webhook's signing secret.

Payload

FieldTypeNotes
typestringAlways "goal.completed" today.
siteIdstringSite the goal belongs to.
goal.id / goal.nameobjectThe configured goal that completed.
visitorIdstringThe converting visitor.
sessionIdstringThe session the completion happened in.
event.name / event.pageUrlobjectPresent for event goals — the event name and the page URL it fired on.
pageview.path / pageview.urlobjectPresent for path goals — the page path and full URL that matched.
occurredAtstringISO 8601 timestamp of the completion.

Verify deliveries

Recompute the signature over the raw, unparsed request body — re-serializing a parsed JSON object will not reproduce the same bytes and the signature will not match.

JavaScript
const crypto = require("node:crypto");

function isValidSignature(rawBody, signatureHeader, secret) {
  const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  const provided = String(signatureHeader || "").replace("sha256=", "");

  const expectedBuffer = Buffer.from(expected, "hex");
  const providedBuffer = Buffer.from(provided, "hex");

  return (
    expectedBuffer.length === providedBuffer.length &&
    crypto.timingSafeEqual(expectedBuffer, providedBuffer)
  );
}

Retries and delivery

Failed deliveries retry up to 8 attempts total, with exponential backoff starting around 60 seconds and capped at 6 hours between attempts. A non-2xx response or a timeout counts as a failed attempt, and redirects are not followed — a 3xx response is recorded as a failure rather than chased. Respond with a 2xx status as soon as you have accepted the delivery, and do slower processing afterward.

Webhook URLs must be public http or https addresses; localhost, loopback, private (RFC1918), and link-local addresses are rejected, in both IPv4 and IPv6 form.

  • Verify the signature against the raw request body, not a re-parsed or re-serialized copy
  • Return a 2xx status quickly, then do slower work asynchronously
  • Treat deliveries as at-least-once and dedupe on the payload if your handler is not naturally idempotent

Data requests & export

Visitor-level requests

Open any visitor's profile in the dashboard to Export data — a JSON download of that visitor's sessions, pageviews, events, and identity records (tokens, fingerprints, fingerprint components, and network observations) — or Delete visitor, which permanently erases the same visitor across every raw table. Aggregate rollups behind historical charts are left untouched, since they store anonymous daily counts rather than records tied to an individual visitor. Both actions require the admin role, and both have API equivalents:

MethodEndpointNotes
GET/api/dashboard/sites/:id/visitors/:visitorId/exportJSON export of the visitor's full record.
DELETE/api/dashboard/sites/:id/visitors/:visitorIdPermanent, transactional erasure across all raw tables.

Raw CSV export

Settings → Data export produces CSV downloads of sessions, pageviews, or events for the selected date range. Each download returns up to 10,000 rows; for larger date ranges, page through the dataset using the cursor returned in the API's x-next-cursor response header until it comes back empty.

Sharing & teams

Public dashboards

Settings → Public dashboard generates a read-only link (analytics.tracedart.com/public/?token=...) showing the same aggregate stats as your dashboard overview — traffic, sources, devices, locations — with no visitor-level data. Configured goal names and their completion counts are included, so avoid enabling sharing on a site where those are sensitive. Disable sharing at any time to revoke the link immediately.

Teams

Every account has a workspace. Invite teammates from the Team section using single-use invite links that expire after 14 days, each granting one role: viewer (read-only across every dashboard view), admin (manage goals, funnels, segments, webhooks, API keys, and exports), or owner (everything admin can do, plus managing members and invites). Revoke outstanding invites when someone offboards, so an unused link cannot be redeemed later.

Saved segments let you save the active filter combination from the filter bar and reapply it later without rebuilding it.

Realtime shows active visitors live, over roughly the last 5 minutes.

Protect allowed origins

Each site key should only collect from domains configured for that site. Requests from unknown origins are rejected by the backend.

Add the domains you own in the dashboard before installing the script on a live site.