Login
ZappushZappush Docs
Reference

Data layer

The exact payload Zappush reads from window.dataLayer, with a copy-paste example for every ecommerce and lead event.

Once the tracker loads it wraps window.dataLayer.push and reads every push. One push reaches both GA4 and Zappush. There is no extra call and no GTM tag to add.

Zappush follows the GA4 recommended events schema. If you already send GA4 ecommerce, you are already sending Zappush ecommerce. If you do not use a data layer, call zappush.track() instead, which takes the same fields flattened and the Zappush event name rather than the GA4 one.

Push shape

window.dataLayer.push({
  event: "purchase",   // required, must be a string
  user_data: { ... },  // who the shopper is
  ecommerce: { ... },  // what it was worth, and which products
});
KeyWhat it carries
eventThe event name. A push without a string event is ignored.
user_dataContact details, used to match the conversion to a person.
ecommercevalue, currency, transaction_id, coupon, items.
Anything elsePassed through as event metadata.

Zappush flattens all three into one object. If the same key appears twice, the later one wins in this order: user_data, then top-level keys, then ecommerce.

Pushes made before the tracker finishes loading are replayed, so you never need a readiness check. On a visitor's first page load that replay happens once their consent state resolves, which takes a moment longer than the script loading. page_view is ignored, because the tracker fires its own page view. Anything starting with gtm. is ignored.

Contact fields

This is the part that decides whether a conversion matches a real person in Meta. Email and phone do most of the work. Send them on every event that has them.

Inside user_data, exactly these keys are read. This is the GA4 Enhanced Conversions shape.

KeyExampleNotes
emailalex@example.com
phone_number+61400000000E.164, including country code
address.first_nameAlex
address.last_nameSmith
address.citySydney
address.regionNSWState or province
address.postal_code2000
address.countryAUISO 3166-1 alpha-2

address is a single object, never an array. Keys inside user_data that are not on this list are dropped. To send anything else, put it at the top level of the push, where these names and aliases are read:

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

Send whatever you have, all fields are optional. Zappush persists them for the session and attributes later events in that session to the same person, so you only need to send them once.

Anything pushed to window.dataLayer is readable by every other script on the page. To keep contact details out of the shared data layer, call zappush.track() directly instead.

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.

Other GA4 item fields (item_brand, coupon, discount, index, affiliation, item_category2 and up) are accepted and stored on the event, but Zappush does not read them and does not forward them to Meta.

Put value and currency on ecommerce, not on items. The conversion value Meta receives is ecommerce.value exactly as you send it. It is never summed from item prices, so an event without a value reports a conversion worth nothing.

Ecommerce events

Fire these in order as the shopper moves through your funnel.

Product viewed

window.dataLayer.push({
  event: "view_item",
  ecommerce: {
    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.dataLayer.push({
  event: "add_to_cart",
  ecommerce: {
    currency: "USD",
    value: 79.0,
    items: [
      { item_id: "SKU-001", item_name: "Running Shoes", price: 79.0, quantity: 1 },
    ],
  },
});

Checkout started

window.dataLayer.push({
  event: "begin_checkout",
  ecommerce: {
    currency: "USD",
    value: 158.0,
    coupon: "SUMMER10",
    items: [
      { item_id: "SKU-001", item_name: "Running Shoes", price: 79.0, quantity: 2 },
    ],
  },
});

Shipping info submitted

window.dataLayer.push({
  event: "add_shipping_info",
  user_data: { email: "alex@example.com", phone_number: "+61400000000" },
  ecommerce: {
    currency: "USD",
    value: 158.0,
    shipping_tier: "Ground",
    items: [
      { item_id: "SKU-001", item_name: "Running Shoes", price: 79.0, quantity: 2 },
    ],
  },
});

Payment info submitted

window.dataLayer.push({
  event: "add_payment_info",
  user_data: { email: "alex@example.com", phone_number: "+61400000000" },
  ecommerce: {
    currency: "USD",
    value: 158.0,
    payment_type: "Credit Card",
    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.dataLayer.push({
  event: "purchase",
  user_data: {
    email: "alex@example.com",
    phone_number: "+61400000000",
    address: {
      first_name: "Alex",
      last_name: "Smith",
      city: "Sydney",
      region: "NSW",
      postal_code: "2000",
      country: "AU",
    },
  },
  ecommerce: {
    transaction_id: "T-1234",
    currency: "USD",
    value: 158.0,
    coupon: "SUMMER10",
    items: [
      {
        item_id: "SKU-001",
        item_name: "Running Shoes",
        item_variant: "Blue / 10",
        item_category: "Footwear",
        price: 79.0,
        quantity: 2,
      },
    ],
  },
});

Two fields carry more weight here than anywhere else:

  • 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.

Always send contact details on purchase. Without them Zappush cannot match the order to a shopper, and the conversion will not attribute in Meta.

Refund

window.dataLayer.push({
  event: "refund",
  ecommerce: {
    transaction_id: "T-1234",
    currency: "USD",
    value: 79.0,
    items: [{ item_id: "SKU-001", quantity: 1 }],
  },
});

Lead events

generate_lead is a GA4 event, so push it to the data layer. schedule and verify_lead are Zappush events with no GA4 name, so GTM will never emit them. Fire those two with zappush.track(), which takes contact fields flat rather than under user_data.

Lead captured

Fire when you collect contact details: a form, a quiz result, a lead magnet, an email opt-in.

window.dataLayer.push({
  event: "generate_lead",
  lead_source: "Quiz",
  user_data: {
    email: "alex@example.com",
    phone_number: "+61400000000",
    address: { first_name: "Alex", last_name: "Smith" },
  },
});

Add value and currency if the lead has a known worth. Both or neither.

Appointment booked

Fire schedule when someone books a call or an appointment. It is a stronger signal than a form submit, and it maps to Meta's standard Schedule event.

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

Lead verified

Fire verify_lead when a lead you already captured is confirmed or qualified, for example an email or phone confirmation. The initial capture is generate_lead.

window.zappush.track("verify_lead", {
  email: "alex@example.com",
  phone: "+61400000000",
});

Send contact fields only on lead events. No value, currency, or product data unless the lead has a real monetary worth.

Event name reference

Use either the GA4 name or the Zappush name. Both resolve to the same event.

GA4 eventZappush eventMeta CAPI event
generate_leadlead_generatedSubmitApplication
view_itemproduct_viewedViewContent
add_to_cartproduct_added_to_cartAddToCart
remove_from_cartproduct_removed_from_cartcustom
view_cartcart_viewedcustom
begin_checkoutcheckout_startedInitiateCheckout
add_shipping_infocheckout_shipping_info_submittedAddShippingInfo
add_payment_infopayment_info_submittedAddPaymentInfo
purchasecheckout_completedPurchase
add_to_wishlistproduct_added_to_wishlistAddToWishlist
searchsearch_performedSearch
loginuser_logged_incustom
sign_upuser_signed_upCompleteRegistration
view_item_listitem_list_viewedcustom
view_promotionpromotion_viewedcustom
select_promotionpromotion_selectedcustom
select_itemitem_selectedcustom
refundorder_refundedcustom
select_contentcontent_selectedcustom
sharecontent_sharedcustom
view_search_resultssearch_results_viewedcustom

Two Zappush events have no GA4 name: schedule maps to Meta's Schedule, and verify_lead maps to Meta's Lead.

Any name not on this list passes through as a custom event under the name you used, and reaches Meta as a custom event. Custom names appear in your dashboard once received, and you can give them a funnel stage on the analytics configure page.

What reaches Meta

On the seven product events (view_item, add_to_cart, add_to_wishlist, begin_checkout, add_shipping_info, add_payment_info, purchase), Zappush sends a fixed set and drops the rest: value, currency, content_ids from your item_ids, num_items from your quantities, content_type, order_id from transaction_id, and coupon.

On every other event, all metadata is forwarded except contact fields, which Zappush forwards separately as Meta's user data.

To confirm a push arrived, open Analytics → Events in the dashboard. Your event shows up within a couple of minutes.

On this page