Logo

Analytics

Track page views and custom events with the Quotient analytics API

Overview

Use the analytics API to connect activity on your site, such as viewing a page or custom event that you define, to the marketing that brought each visitor there.

The client SDK (@quotientjs/client or @quotientjs/react) runs in the browser. It adds the visitor's session, attribution, and identity to each event. The server SDK (@quotientjs/server) tracks backend events about a person you already know.

EndpointAPI KeySDKMethod
Track a browser eventpublicClient SDKclient.analytics.event(event)
Track a server eventprivateServer SDKquotient.analytics.event(event)

Track a Client Event with @quotientjs/client

client.analytics.event(event)

POST /api/v0/analytics/web

Auth: public key · scope: ANALYTICS_WRITE

Every client event includes the current session ID, device ID, browser fingerprint, page URL, and attribution. Attribution comes from the utm_* and qt_* parameters on the visitor's incoming URL and lasts for the current session. If a tagged link or client.audience.people.upsert() identifies the visitor, the SDK includes their personId too. You only provide the event.

eventTypeExtra fieldsDescription
"pageView"noneA page view. The SDK tracks these automatically by default
"custom"customEventId: stringThe ID of an event defined by your business, such as "completedOnboarding"
// Page view (usually automatic; see Auto-Tracking below)
await client.analytics.event({
  eventType: "pageView",
});

// Custom event
await client.analytics.event({
  eventType: "custom",
  customEventId: "completedOnboarding",
});

Returns: void

Register each custom event in Quotient before sending it. Pass its immutable event ID as customEventId; the API rejects IDs that have not been registered for your business.

Pass idempotencyKey on any event to avoid recording it twice, such as when a retry resends the same request. Quotient checks for a matching key from your business for 24 hours; a duplicate within that window is dropped instead of recorded again. This check depends on our caching layer being reachable; a rare outage there can still let a duplicate through.

Track a Server Event

quotient.analytics.event(event)

POST /api/v0/analytics/server

Auth: private key · scope: ANALYTICS_WRITE

Use a server event when an activity that matters to your marketing analytics does not take place in a browser. These activities often happen in webhooks, OAuth callbacks, scheduled jobs, or other backend code. For example, you might track when a free trial expires, a customer upgrades their plan, or a user completes onboarding.

The server API currently accepts custom events only. Each event must be about a known person, so include their personId, the person's identifier in Quotient. It must belong to an existing person in your business. Because the event does not come from a browser, the SDK cannot add a browser session or its attribution automatically. Pass the visitor's browser context yourself as browserContext (see Server-Side Conversions), or attribute the event to a campaign directly with campaignId.

FieldTypeRequiredDescription
eventType"custom"YesServer events are always custom events today
personIdstringYesThe Quotient identifier of the person this event is about
customEventIdstringYesA custom event ID already registered for your business
campaignIdstringNoAttributes the event to a specific campaign
browserContextBrowserContextNoWhat the browser SDK knew about the visitor when the conversion happened, read from the qt_browser_context cookie or client.getBrowserContext()
idempotencyKeystringNoPrevents recording the same event twice, such as when a retry resends the same request. Quotient checks for a matching key from your business for 24 hours (a rare caching-layer outage can still let a duplicate through)
await quotient.analytics.event({
  eventType: "custom",
  personId: "person_abc123",
  customEventId: "upgradedPlan",
});

Returns: void

Read the Browser Context

client.getBrowserContext()

Returns what the browser SDK currently knows about the visitor: device, session, person, referrer, and attribution. The SDK also writes the same object to the qt_browser_context cookie on every tracked event, so a server on your own domain can read it without any call from the page.

const browserContext = client.getBrowserContext();

Returns: BrowserContext

Use it when a conversion completes on a server that the cookie cannot reach, such as an API on another domain, and pass the object along in your request body. Server-Side Conversions walks through both paths and the shape of the object.

Auto-Tracking with React

QuotientProvider tracks a page view when your app loads and after each navigation. Auto-tracking is on by default, so no additional setup is needed.

<QuotientProvider clientOptions={{ apiKey: "pk_your_public_api_key" }}>
  <YourApp />
</QuotientProvider>

If another tool on the page already sends Quotient page views, pass autoTrackPageViews={false} to avoid counting each navigation twice.

See the React SDK article for full provider setup. For manual tracking, use client.analytics.event() via the useQuotient() hook.

Common Patterns

Custom Event Tracking

import { useQuotient } from "@quotientjs/react";

function CompleteOnboardingButton() {
  const { client } = useQuotient();

  const handleClick = async () => {
    await completeOnboarding();
    void client?.analytics.event({
      eventType: "custom",
      customEventId: "completedOnboarding",
    });
  };

  return <button onClick={handleClick}>Complete onboarding</button>;
}

Page View Tracking in a SPA

If you're not using the React SDK's autoTrackPageViews, you can track route changes manually:

import { useEffect } from "react";
import { useLocation } from "react-router-dom";
import { useQuotient } from "@quotientjs/react";

function PageTracker() {
  const location = useLocation();
  const { client } = useQuotient();

  useEffect(() => {
    void client?.analytics.event({ eventType: "pageView" });
  }, [location, client]);

  return null;
}

Next Steps