CJM
PixelManual tracking

Send custom events

Use track, trackPage, getIdentity, and shared options.

Use these functions when your website knows the exact moment of an action, such as a confirmed request. Call them from the action handler after validation. First check Pixel loading.

track(name, data?, options?)

ArgumentTypeRequiredBehavior
namestringYesChoose a stable, nonempty event name.
dataobjectNoJSON-serializable details; defaults to {}. Do not put credentials or contact details here; use trackLead for forms.
optionsobjectNoClassification and destinations for this event.
options.tagsarrayNoThe supported public tag is lead. It does not replace trackLead data.
options.destinations.metaobjectNoEnables Meta forwarding.
options.destinations.meta.eventNamestringNoMeta name; defaults to name.
options.destinations.meta.isStandardbooleanNotrue uses a standard event; false or omitted uses a custom event.
options.destinations.gtmobjectNoEnables dataLayer forwarding.
options.destinations.gtm.eventNamestringNodataLayer name; defaults to name.

Complete example, called once after the request is confirmed:

window.CJMPixel.track('demo_requested', {
  plan: 'pro',
  source: 'pricing',
  teamSize: 12
}, {
  tags: ['lead'],
  destinations: {
    meta: { eventName: 'Lead', isStandard: true },
    gtm: { eventName: 'cjm_demo_requested' }
  }
});

Options do not install the integrations. Forwarding requires available destinations and all consent signals; see Meta and GTM. Omit options to send only to CJM.

The function does not return delivery confirmation. await track() does not prove receipt. Repeated calls with the same name are not automatically deduplicated.

trackPage(data?)

data is an optional page metadata object, defaulting to {}. This starts a page lifecycle for the current URL only if its path or query changed since the last tracked page. The Pixel already observes pushState, replaceState, and popstate.

Use this inside the navigation handler after the actual URL has changed:

window.CJMPixel.trackPage({ section: 'pricing' });

{ path: '/pricing' } would only add metadata, not change the address. The same page, hash-only changes, and repeated calls for one URL do not generate new visits. Calls within the same operation are coalesced; only configured page events run. No destination options or delivery confirmation are provided.

getIdentity()

Immediately returns { cid, sid }, both strings. Visitor ID cid requires adStorage; session ID sid requires analyticsStorage. Either can independently be ''. Before initialization the result may not yet be usable.

To populate two hidden form inputs, assign IDs contact-cid and contact-sid and run after Pixel loading:

function updateIdentityFields() {
  const { cid, sid } = window.CJMPixel.getIdentity();
  const cidInput = document.querySelector('#contact-cid');
  const sidInput = document.querySelector('#contact-sid');
  if (cidInput) cidInput.value = cid;
  if (sidInput) sidInput.value = sid;
}
updateIdentityFields();
window.CJMPixel.onConsentChange(updateIdentityFields);

This also updates the inputs on consent withdrawal. Do not manually include these identifiers in trackLead: the Pixel handles them. CRM matching requires the CRM to receive and use the corresponding fields.

Verify

Check event names and data with the verification guide. Calling track for an action already configured in the dashboard may create a second event. Use trackEcommerce for sales and trackLead for contacts.

On this page