Login
ZappushZappush Docs
Reference

SDK

The window.zappush API. Send standard and custom events with the full payload, manage consent, and read shopper identity.

Once a Zappush script is installed it exposes window.zappush. Your own code calls it to send events, manage consent, and read the current shopper identity.

Use the SDK when you do not have a data layer, when the event has no GA4 equivalent, or when you want contact details to stay out of window.dataLayer, where every other script on the page can read them.

What is available where

Zappush serves two scripts and they expose different methods. The tracker runs on your store, the gate runs on a compliant page.

MethodTrackerGate
trackYesYes
setConsent, withdrawConsentYesNo
getIdentityNoYes
redirectNoYes

track is safe to call at any time. The install snippet buffers calls made before the script loads and replays them once it is ready. Every other method needs the script loaded first. If you have not installed it yet, follow Install the tracker.

Payload shape

window.zappush.track(eventName, metadata);

Everything goes in one flat object. There is no ecommerce or user_data wrapper, unlike a data layer push.

window.zappush.track("checkout_started", {
  currency: "USD",          // conversion value
  value: 158.0,
  email: "alex@example.com", // who the shopper is
  phone: "+61400000000",
  items: [ ... ],            // which products
});
GroupKeys
Valuevalue, currency, transaction_id, coupon
Contactemail, phone, first_name, and the rest below
Productsitems
Anything elsePassed through as event metadata

value must be a number greater than zero, and currency an ISO 4217 code. The conversion value Meta receives is the value you send. It is never summed from item prices, so an event without one reports a conversion worth nothing.

Event names

This is the one place the SDK differs from the data layer. A data layer push accepts the GA4 name and translates it. track does not translate anything, so pass the Zappush name. Leads are the exception: a captured lead follows the GA4 schema, so send generate_lead.

window.zappush.track("checkout_completed", { ... });  // correct
window.zappush.track("purchase", { ... });            // a custom event named "purchase"

Calling track("purchase") is not an error and the event will arrive, but it does not become an order, and it reaches Meta as a custom event rather than the standard Purchase.

Zappush eventMeta CAPI eventFire when
product_viewedViewContentA product page or prominent product modal opens
product_added_to_cartAddToCartA product is added to the cart
cart_viewedcustomThe cart page or drawer opens
checkout_startedInitiateCheckoutThe shopper reaches the first checkout step
checkout_shipping_info_submittedAddShippingInfoShipping details are submitted
payment_info_submittedAddPaymentInfoPayment details are submitted
checkout_completedPurchasePayment succeeded
order_refundedcustomAn order is refunded
generate_leadLeadContact details are captured
scheduleScheduleA call or appointment is booked
verify_leadLeadA captured lead is confirmed or qualified
search_performedSearchA search is run
user_signed_upCompleteRegistrationAn account is created

lead_generated and verify_lead are legacy events. They still work exactly as before, but they will be deprecated. Use generate_lead in place of lead_generated in anything new.

The full list, including the GA4 name each one maps from, is in the event name reference.

Contact fields

These decide whether a conversion matches a real person in Meta. Email and phone do most of the work. Send them flat, on every event that has them.

FieldAlso accepted as
email
phonephone_number
first_namefirstName
last_namelastName
city
stateregion
zippostal_code, zipcode
countrycountry_code
date_of_birthdob
gender
external_idexternal_customer_id

All optional, send whatever you have. Phone in E.164 with the country code, country as ISO 3166-1 alpha-2. Zappush persists them for the session, so later events in that session attribute to the same person without resending.

A nested user_data object is also accepted, for when you are porting a data layer payload, but flat keys are the recommended shape.

Items

FieldRequiredWhat it does
item_idYesIdentifies the product. Sent to Meta as content_ids.
item_nameNoProduct name in your dashboard. Used as the identity if item_id is missing.
quantityNoSummed into Meta's num_items. Defaults to 1.
priceNoUnit price in your dashboard and on order lines.
item_variantNoVariant name in your dashboard.
item_categoryNoProduct type in your dashboard.

Ecommerce events

Product viewed

window.zappush.track("product_viewed", {
  currency: "USD",
  value: 79.0,
  items: [
    {
      item_id: "SKU-001",
      item_name: "Running Shoes",
      item_variant: "Blue / 10",
      item_category: "Footwear",
      price: 79.0,
      quantity: 1,
    },
  ],
});

Added to cart

window.zappush.track("product_added_to_cart", {
  currency: "USD",
  value: 79.0,
  items: [
    { item_id: "SKU-001", item_name: "Running Shoes", price: 79.0, quantity: 1 },
  ],
});

Checkout started

window.zappush.track("checkout_started", {
  currency: "USD",
  value: 158.0,
  coupon: "SUMMER10",
  items: [
    { item_id: "SKU-001", item_name: "Running Shoes", price: 79.0, quantity: 2 },
  ],
});

Payment info submitted

window.zappush.track("payment_info_submitted", {
  currency: "USD",
  value: 158.0,
  email: "alex@example.com",
  phone: "+61400000000",
  items: [
    { item_id: "SKU-001", item_name: "Running Shoes", price: 79.0, quantity: 2 },
  ],
});

Purchase

Fire on the order confirmation page, after payment succeeds.

window.zappush.track("checkout_completed", {
  transaction_id: "T-1234",
  currency: "USD",
  value: 158.0,
  coupon: "SUMMER10",
  email: "alex@example.com",
  phone: "+61400000000",
  first_name: "Alex",
  last_name: "Smith",
  city: "Sydney",
  state: "NSW",
  zip: "2000",
  country: "AU",
  items: [
    {
      item_id: "SKU-001",
      item_name: "Running Shoes",
      item_variant: "Blue / 10",
      item_category: "Footwear",
      price: 79.0,
      quantity: 2,
    },
  ],
});
  • value must be a number greater than zero. Without it the purchase does not become an order in your dashboard and reports no revenue.
  • transaction_id identifies the order. It is what stops a refreshed confirmation page from counting twice, and it is sent to Meta as order_id.
  • Contact details matter most here. Without them Zappush cannot match the order to a shopper, and the conversion will not attribute in Meta.

Lead events

Lead captured

window.zappush.track("generate_lead", {
  lead_source: "Quiz",
  email: "alex@example.com",
  phone: "+61400000000",
  first_name: "Alex",
  last_name: "Smith",
});

Appointment booked

Fire schedule when someone books a call or an appointment. It is a stronger signal than a form submit.

window.zappush.track("schedule", {
  email: "alex@example.com",
  phone: "+61400000000",
  first_name: "Alex",
  last_name: "Smith",
});

Lead contact fields

Use generate_lead when you want a Lead event to go to Meta. Send the four contact fields and nothing else:

FieldFormat
first_nameThe first word of the name the person entered
last_nameEverything after the first word
emailAs entered. Leave the key out if the form has no email field
phoneE.164, with + and the country code

Do not add the service, treatment, consultation type, offer, or any other description of what the lead asked for. Meta has rules on what a lead event may say about a person, and Zappush filters those fields before sending. Extra fields make that filtering less predictable. Contact fields are all Meta needs to match the lead.

Custom events

Any name that is not a standard event passes through as a custom event. Nothing to register first.

window.zappush.track("quiz_completed", {
  quiz_id: "skin-type",
  result: "combination",
});

Custom events appear in your dashboard once the first one arrives. They start unclassified, so give them a funnel stage on the analytics configure page to make them count in your funnel.

They reach Meta as a custom event under the same name, carrying every key you sent except items, which is dropped, and contact fields, which Zappush forwards separately as user data. So quiz_id and result above arrive as custom properties you can build an audience on.

Attach value and currency if the action is worth something, and the custom event can be optimized against like any other conversion.

Keep names lowercase with underscores, like quiz_completed, and stay consistent so the same action always reports under one name. A name is created the first time it arrives, so a typo becomes a second event you then have to ignore.

From a third-party tool

If you send events from a script that loads independently of Zappush, a quiz platform or a booking widget for example, call track from its custom JavaScript field. Buffered calls are replayed, so there is no readiness check to write.

window.zappush.track("quiz_completed", { result: "type-a" });

From a Kommo web form

Kommo forms post straight to Kommo, so the lead arrives there with nothing tying it to the visit that produced it. When a Kommo form is present on the page, Zappush notices the submission and records it as a lead automatically. There is nothing to add to the page and nothing to configure.

Only successful submissions count. A validation error is not a lead, so it is not recorded as one.

Tracker only, and only on a store with Consent management turned on.

Most consent banners, Cookiebot for example, support Google Consent Mode v2, Google's standard format for passing on a shopper's cookie choices. If yours does, Zappush picks up each shopper's choice on its own and you do not need these methods. Use them only when your banner does not support it. Both take effect immediately.

window.zappush.setConsent({
  analytics_storage: "granted",
  ad_storage: "granted",
  ad_user_data: "granted",
  ad_personalization: "granted",
});

window.zappush.withdrawConsent();

setConsent takes the four Google Consent Mode v2 choices: analytics_storage, ad_storage, ad_user_data, and ad_personalization. Set each one to "granted" or "denied" to match what the shopper agreed to on your banner. You can pass only the choices that changed, and the others keep their previous value.

withdrawConsent is the same as calling setConsent with all four set to "denied". From then on, Zappush follows your After a shopper withdraws setting on this page and on the shopper's later visits, until they agree again. Anything recorded before the withdrawal is kept.

Only call setConsent once the shopper has actually agreed. Calling it without real consent defeats the purpose of the banner.

Read the current identity

Gate only. Returns what Zappush has resolved for the visitor on a compliant page.

const identity = window.zappush.getIdentity();
FieldWhat it is
persistent_idLong-lived ID for this shopper
session_idID for the current session
route_idThe route this compliant page belongs to
fbc, fbp, fbclidMeta click and browser identifiers
click_idsAd click identifiers picked up from the landing page (Google, Microsoft, TikTok, and others)
consentCurrent analytics and marketing grants

Contact fields, page URL, referrer, and user agent are also on the object. Any field Zappush has not resolved yet is null.

Trigger a compliant redirect

Gate only. Sends the visitor to your store and carries their identity across, including any ad click identifiers picked up on the landing page. The gate script already wires this to the page's call to action, so most stores never call it. Use it if you build your own button.

window.zappush.redirect("https://your-store.example/products/best-seller");

Repeat calls within half a second are ignored, so a double click cannot fire two redirects. If building the identity-carrying URL fails for any reason, the visitor is still sent to the plain destination URL rather than being stranded.

On this page