Skip to content
Guides

Goals

A goal is any conversion you want to count: a signup, a purchase, a contact. Kymo captures three kinds.

Automatic goals

These need no code. beat.js watches for them:

  • WhatsApp links (wa.me, api.whatsapp.com, web.whatsapp.com, whatsapp:).
  • Phone links (tel:).
  • Email links (mailto:).
  • Form submits — any <form> submission, filed as form:<name> using the form's name or id.

Key-page goals

To count a view of a specific path as a conversion, list it in data-goals on the script tag, comma-separated:

<script defer src="https://kymo.in/beat.js"
        data-site="yoursite.com"
        data-goals="/signup,/onboarding/complete"></script>

A pageview of a listed path records a goal named page:/signup.

Custom goals

Fire a goal from your own code with window.kymo:

// a simple named goal
window.kymo('newsletter-signup');

// a goal with revenue attached
window.kymo('purchase', { revenue: 49 });

The name is capped at 100 characters. revenue must be a number; it feeds the revenue totals in the dashboard.

Stripe purchases

A payment confirmed on your server is more reliable than one fired from a success page, which a visitor can close early or reload. Kymo takes a Stripe webhook for exactly that.

  1. Add the endpoint

    In the Stripe Dashboard, under Developers → Webhooks, add https://kymo.in/api/stripe and subscribe it to checkout.session.completed.

  2. Tag the Checkout Session

    Kymo reads three metadata fields. The first is required; the other two are attribution and are both optional.

    // in the browser, before you create the session
    const { visitor } = await fetch('https://kymo.in/api/whoami').then(r => r.json());
    const ft = JSON.stringify(window.kymo.attribution() || {});
    
    // on your server
    const session = await stripe.checkout.sessions.create({
      // … your line items and URLs …
      metadata: {
        kymo_site: 'yoursite.com',  // required
        kymo_visitor: visitor,      // same-day attribution
        kymo_ft: ft                 // first touch, capped at 500 characters
      }
    });

    kymo_ft is the value from window.kymo.attribution(). Stripe caps a metadata value at 500 characters, so trim it before sending — First-touch attribution has the snippet that does it, and the field-by-field detail.

Each completed checkout lands as a purchase goal with its revenue. If kymo_ft is missing or unreadable, the purchase is still recorded, without first-touch data.

Reading goals

The Goals page shows, per goal: completions, conversion rate against site visitors, revenue where present, and two source columns.

  • First touch — the source that first brought the converting visitors to your site, which can be months before they converted.
  • Last touch — the source of the visit that converted.

A dash in the First touch column means Kymo has no first touch for those visitors: they converted before first-touch capture shipped, they cleared their browser storage, or the site has data-attribution="off". See First-touch attribution.

Revenue

Attach revenue to a goal with window.kymo('purchase', { revenue: 49 }) and it totals in the dashboard's revenue view. Fire it wherever you confirm a payment — your checkout's success page is the usual spot, and the Stripe webhook above is the sturdier one.