Zarstat

Docs

Docs

Install the first-party script on your origin. Zarstat stores a visitor ID in localStorage — the snippet does not set cookies.

Markdown · same page for crawlers. index, follow.

On the board

Filters (visit-count, goal, chip compose): /docs/filters. Server collect: /docs/collect. Read API: /docs/api. MCP: /docs/mcp. Metrics: /docs/metrics.

Install

Two calls. Amount is rand, not cents. Full walkthroughs: HTML · Next.js. Hub: all install guides.

<script src="https://YOUR_DOMAIN/cashline.js" data-site="YOUR_SITE"></script>
<script>
  cashline('pageview');
  cashline('purchase', {
    amount: 199,
    currency: 'ZAR',
    reference: 'ORD-1042'
  });
</script>

zarstat() is an alias for cashline(). Existing sites can keep calling cashline(). The snippet sends the current pathname (and search) and watches pushState, replaceState, and popstate so Next.js and other SPA route changes are not stuck on the first /. It does not invent paths.

Other hosts (paste the same snippet; there is no official WordPress plugin): WordPress · Webflow · Vue · Shopify · Google Tag Manager · Astro · Laravel · Django · Framer.

Pageview

Call on each view you care about. First referrer, landing page, and UTM are attached from the first visit. Last referrer and last UTM are sent from the current page.

cashline('pageview');

Goal

Fire after a real signup (or any named action). The default funnel treats signup as step two. See goals and funnels.

cashline('goal', { name: 'signup' });

Identify

Optional. Attach a first-party label to the current visitor. Later events from this browser reuse it. The journeys table shows the label when collect stored one. This is not a login.

cashline('identify', { id: 'user_1042' });

Scroll

Optional. Send a depth of 25, 50, 75, or 100. The snippet does not attach a scroll listener — call it yourself if you want the board table.

cashline('scroll', { depth: 50 });

Outbound

Automatic. Clicks on <a href> that leave the current origin send type: outbound. Same-origin file links: downloads. See exit clicks. Headlines (sessions, bounce, conversion, new vs returning): board metrics. Chip compose (visit-count, goal): filters. Subdomains: hostnames.

Read API

Small public JSON for one site. Auth is the same site id the dashboard already uses. There is no extra secret. There is no CLI.

GET https://www.zarstat.co.za/api/read?site=YOUR_SITE&range=7d

range is 7d, 30d, or all (default all). Response: overview (visitors, ZAR, RPV, pageviews, purchases), pages, and channels (first touch). Empty sites return zeros and empty arrays — no sample rows.

Split reads: /docs/api (/overview, /timeseries, /pages, /referrers, /realtime, /countries, /devices, /browsers, /campaigns, /payments). JSON-RPC: /api/mcp. Same site id. Same honest empty. First-party proxy: /docs/proxy. CSP: /docs/csp.

Purchase

Fire after your store confirms an order. Amount is in major units (rand, not cents). From a backend: server collect.

cashline('purchase', {
  amount: 199,
  currency: 'ZAR',
  reference: 'ORD-1042'
});

Paystack metadata

A South African SaaS should put visitor_id on Paystack initialize. Full walkthrough: Paystack visitor_id. Peach and Yoco are text notes only.

What is stored

  • visitor_id — first-party, cookieless, reused across sessions
  • session_id — one tab session
  • first_referrer, landing_page, first UTM
  • last_referrer, last UTM — current hit

Billing

Subscriptions use Paystack TEST. Starter is R149, Growth is R299. The server initializes with email + plan + attribution metadata, then verifies the reference. Configure the webhook to /api/paystack/webhook for charge.success, subscription.create, invoice.payment_failed, and subscription.disable.

Dummy R99 on /test · Subscribe · Cookieless notes · RPV · Best channel · Launch · Contact

Compare: Google Analytics · Plausible · DataFast · Simple Analytics · Umami · Pirsch