nod.

Track conversions and intent milestones with the pixel API

Send purchases, leads, and explicit Journey milestones without turning generic form activity into attribution evidence.

Updated July 31, 2026

Once the pixel is installed, you can send it custom events from your own page code. This is how you tell nod. about a purchase, a lead, or anything else that isn't an automatic pageview — an "Add to cart" click, a form submission, a signup.

The API sends only after analytics consent is granted. Calling it while consent is unknown or denied is a no-op.

The API

The pixel exposes one global function:

window.nod('track', name, props);

name is the event name, props is a plain object of properties. Call it from anywhere on the page, after the pixel snippet has loaded.

nod('track', 'Newsletter Signup', { source: 'footer' });

Tracking a purchase

For purchases, always include order_id, value, and currency:

nod('track', 'Purchase', {
  value: 99,
  currency: 'EUR',
  order_id: 'YOUR-ORDER-ID',
});

order_id matters more than it looks. nod. uses it to build a deterministic event id for the purchase, so if the thank-you page reloads — a customer hits refresh, a browser restores the tab — the same purchase doesn't get counted twice. Without order_id, a reload can register as a second sale.

Event names for purchases are matched case-insensitively: 'Purchase' and 'purchase' both work and both get the same reload-safe treatment. You don't need to worry about matching a specific casing.

Tracking a lead

Leads work the same way. Use 'Lead' (or 'generate_lead', the alias some analytics setups use) as the event name:

nod('track', 'Lead', { value: 50 });

nod.'s attribution engine recognizes both Lead and generate_lead as lead conversions, case-insensitively.

Tracking explicit intent milestones

V3 uses a closed milestone vocabulary. These events can own Intent Capture when they are linked to an eligible observed touch in the same session:

  • newsletter_subscribed
  • account_created
  • lead_created
  • demo_requested
  • quote_requested
  • add_to_cart
  • checkout_started
nod('track', 'newsletter_subscribed', {
  milestone_id: 'signup-123',
});

milestone_id is optional. If supplied, it must be an opaque 1 to 128-character token using letters, digits, ., _, :, or -. Do not put an email, phone number, name, or form value into it. nod. validates it and stores only a workspace-scoped HMAC digest.

For a declarative form:

<form
  data-nod-milestone="newsletter_subscribed"
  data-nod-milestone-id="signup-123"
>
  <!-- your fields -->
</form>

A generic form_submit, email-field blur, or identify event never becomes a milestone automatically. Unknown names remain ordinary custom events. Milestones annotate the existing source-bearing session touch; they do not create another click or visit.

Passing a hashed email

If your site already computes a hashed email for its own tools, you can pass it along:

nod('track', 'Purchase', {
  value: 99,
  currency: 'EUR',
  order_id: 'YOUR-ORDER-ID',
  email_hash: hashedEmail,
});

You can pass email_hash when you already have it. For lead/form helpers, the pixel can hash the email locally with Web Crypto and sends only the digest. The raw address is never persisted or transmitted.

Where these conversions show up

Purchases and leads sent this way appear in nod.'s attribution reports as pixel-based conversions, credited across the touches that led to them.

If you're on Shopify, the order webhook is the source of truth for order facts — revenue, order number, refund and cancellation state. A pixel purchase that shares the same numeric Shopify order id as a webhook order is treated as a duplicate signal and deduplicates against it rather than creating a second row. This means it's safe to fire the pixel purchase event on the same thank-you page Shopify already reports from — nod. won't double-count the order. Just make sure order_id is the numeric Shopify order id, not the order name (#1001) — those aren't interchangeable.

Common mistakes

MistakeWhat happens
Omitting order_id on a purchaseA thank-you-page reload can register as a second sale.
Passing the Shopify order name (#1001) instead of the numeric order idThe pixel purchase won't line up with the webhook order and won't dedupe against it.
Passing a raw email in email_hashDon't. Pass an existing digest or use the lead/form helper that hashes locally before transport.
Using an arbitrary custom event as an intent milestoneIt stays telemetry. Use one of the explicit milestone names.
Putting an email or phone number into milestone_idThe event's merchant id is rejected. Use an opaque internal token.
Treating a milestone as a second ad touchIt only annotates the observed touch that opened the same session.