Skip to content
pixelary Docs

JavaScript API

window.pixelary

Pixelary tracks page views, forms and clicks on its own. When a conversion happens somewhere only your code knows about, such as a confirmed payment or an accepted booking, send it yourself. One call reaches the browser pixel and the Conversions API, counted once.

Set up

The script defines window.pixelary. Because it loads asynchronously, add the two-line stub before it: calls made earlier are queued and run in order once Pixelary starts.

<head>
<script>
  window.pixelary = window.pixelary || function () {
    (window.pixelary.q = window.pixelary.q || []).push(arguments);
  };
</script>
<script async src="https://cdn.pixelary.app/s/px_7hq2lm4x.js"></script>

pixelary(…) never throws. A command with bad arguments is dropped, and the reason is logged in debug mode.

JavaScript
pixelary("track", name, data?, options?)   // send an event
pixelary("identify", user)                   // customer details for the next events
pixelary("consent", values, options?)        // the visitor's consent answer
pixelary("config", { auto_events })         // switch automatic events on this page

track

JavaScript
pixelary("track", "Purchase",
  {
    value: 49.9,
    currency: "USD",
    content_ids: ["sku-1", "sku-2"],
    content_type: "product",
    content_name: "T-shirt",
    num_items: 2,
    order_id: "ORD-1001",
    coupon: "SPRING",            // custom parameter
  },
  {
    event_id: "ORD-1001",        // optional; generated when missing
    user: {                      // raw values, this event only
      email: "Jane@Example.com",
      phone: "+1 555 010 0000",
      first_name: "Jane",
      last_name: "Doe",
    },
  });

Event name

These are standard events, matched exactly, case included: PageView, ViewContent, Search, AddToCart, AddToWishlist, InitiateCheckout, AddPaymentInfo, Purchase, Lead, CompleteRegistration, Contact, Schedule, SubmitApplication, StartTrial, Subscribe. Pixelary sends each platform its own name for them, for example Purchase becomes CompletePayment on TikTok and order_created on ChatGPT Ads.

Any other name is a custom event: 1 to 50 characters of letters, digits, spaces, _ and -. A name that breaks the rule is dropped, not renamed. purchase in lower case is a custom event, not a Purchase.

JavaScript
pixelary("track", "Booked call", { value: 0, currency: "EUR" });

Event data

FieldTypeRule
valuenumberFinite and 0 or more. A numeric string is accepted. Anything else drops the field.
currencystringISO 4217, three letters, any case. Required next to value.
content_idsstring[]A single string is taken as a list of one. Empty items are removed.
content_typestringUsually product or product_group.
content_namestringProduct or page name.
num_itemsinteger0 or more.
order_idstringYour order or transaction ID.
any other keystring, number, boolean or a list of themA custom parameter for platforms that accept them. Up to 25 per event, names up to 50 characters. Objects are dropped.

A Purchase without value or currency is still sent, with a warning in debug mode.

Options

OptionDescription
event_idUp to 100 characters. The browser and server copies share it on every platform. Without it, Pixelary generates one. A second track with the same ID on the page is ignored.
userCustomer details for this event only. Same keys as identify.

Pass raw customer data

Pixelary normalizes and hashes it with SHA-256 in the browser, separately for each platform, and sends it only when the visitor has granted ad_user_data. A value that is already a 64-character SHA-256 hash is passed through unchanged, but raw values match better.

PageView

Pixelary sends page views itself, including route changes in single-page apps. An explicit track("PageView") for a page that already got its automatic page view is dropped. With auto_events: false, explicit page views are always sent.

identify

JavaScript
pixelary("identify", {
  email: "jane@example.com",
  external_id: "u_123",
  country: "US",
});

Keys: email, phone, first_name, last_name, external_id, city, zip, country. Values merge with what the page already knows: a non-empty value replaces the old one, an empty one is ignored. They are attached to every following event on the page, automatic ones included. Between pages they are remembered only when the visitor granted both ad_storage and ad_user_data.

For one event, options.user wins over identify, which wins over what a form provided.

JavaScript
pixelary("consent", { ad_storage: "granted", ad_user_data: "granted" });
pixelary("consent", { ad_personalization: "denied" });

Any of the four Google Consent Mode types, each "granted" or "denied". Types you leave out don’t change. A type set this way is no longer changed by banners on this page. Events that waited for consent go out once it is granted. Consent & banners

config

JavaScript
pixelary("config", { auto_events: false });
// …then send page views yourself, for example on every route change:
pixelary("track", "PageView");

auto_events: false stops automatic page views and the form, click and booking triggers from the dashboard on this page. Your own track calls and dataLayer events keep working. true switches them back on for what happens next. The setting lasts until the visitor leaves the page.

dataLayer events

On sites with Google Tag Manager but without the Pixelary template, push an event to the dataLayer:

JavaScript
window.dataLayer = window.dataLayer || [];
dataLayer.push({
  event: "pixelary",
  pixelary_event: "Lead",
  pixelary_data: { content_name: "Demo request" },
  pixelary_user: { email: "jane@example.com" },
  pixelary_event_id: "lead-8421",   // optional
});

window.ft from the Framer plugin

Code written for the Framer plugin keeps working. window.ft points to the same API and keeps its three methods:

JavaScript
window.ft.setConsent(true);                       // all four consent types
window.ft.meta("Lead", { value: 10, currency: "EUR" }, { email: "jane@example.com" });
window.ft.tiktok("Lead");

ft.meta and ft.tiktok send to one platform only. For new code use pixelary("track", …), which reaches every connected platform.

TypeScript

pixelary.d.ts
declare global {
  interface Window {
    pixelary: (command: string, ...args: unknown[]) => void;
  }
}
export {};

Debug mode

Add ?pixelary_debug=1 to the page address, or run localStorage.pixelary_debug = "1" in the console. Pixelary then logs every command with the result: sent, waiting for consent, or dropped and why.

Common mistakes

  • Hashing customer data yourself. Pass raw values; each platform needs its own normalization.
  • A second pixel snippet on the page. A hand-pasted fbq or ttq next to Pixelary fires events without a shared ID, and they are counted twice.
  • Purchase without value and currency. The event counts, but value optimization has nothing to work with.
  • Calling during server rendering. window.pixelary exists only in the browser.

Something here doesn’t match what you see? Write to hello@pixelary.app.