Google Tag Manager
One Custom HTML tag loads pb.js on every page. Conversion events are more Custom HTML tags on your existing triggers.
Install pb.js
- GTM workspace → Tags → New → Custom HTML.
- Name it
AdsPing — pb.jsand paste:
<script async src="https://api.adsping.io/pb.js" data-pixel-id="YOUR_PIXEL_ID"></script>- Trigger: Initialization — All Pages (loads before your other tags).
- Save → Submit → Publish.
Fire events from GTM
Conversion events are additional Custom HTML tags calling adsping('track', …), attached to the GTM triggers you already have. Example — a Purchase tag triggered on your order-confirmation page, pulling values from GTM variables:
<script>
adsping("track", "Purchase", {
value: {{Order Total}},
currency: "USD",
order_id: "{{Order ID}}",
event_id: "{{Order ID}}-purchase",
});
</script>The event_id matters more here than anywhere else. A GTM tag fires off a trigger, and the same trigger often reaches us by a second road — read the next section before you publish.
Every event works this way — see the event pages for the full payload of each.
Avoid double-counting
AdsPing listens to window.dataLayer and turns the standard GA4 e-commerce pushes into events on its own. That is the trap in the setup above: your Purchase tag fires off the purchase push, and we already read that push. One sale, two events. A Meta or TikTok tag on the same trigger makes it three, because we mirror those calls too.
Every copy is a real conversion as far as the ad platform is concerned, so revenue and conversion count both inflate. Two ways to stop it, and the first is usually right.
Give every road the same event id
Put a stable id on the tag — the order number works, since one order is one sale — and pass the same value to any pixel tag firing beside it. We drop the second arrival for 24 hours, and Meta deduplicates the browser copy against the server one.
<script>
var eid = "{{Order ID}}-purchase";
adsping("track", "Purchase", {
value: {{Order Total}}, currency: "USD",
order_id: "{{Order ID}}", event_id: eid,
});
// if a Meta Pixel tag fires on this trigger too:
fbq("track", "Purchase", { value: {{Order Total}}, currency: "USD" },
{ eventID: eid });
</script>{{Order ID}}-purchase, {{Order ID}}-payment.Or switch the bridge off
If your container already reports everything you need, take our reader out of the picture entirely:
<script async src="https://api.adsping.io/pb.js"
data-pixel-id="YOUR_PIXEL_ID"
data-ignore-datalayer="true"></script>Your dataLayer is untouched — GA4 and every other consumer keep working. AdsPing just stops reading it, so the only events we record are the ones your own adsping('track', …) tags send, plus the browser pixels we mirror with a shared event id.
add_payment_info or view_item push with no tag of its own is an event you were getting for free and will stop getting. Open Diagnostics, list the event types you receive today, and make sure each one has a Custom HTML tag before you publish this.Identity from the dataLayer
When a push carries user_data, we read the email and phone out of it. But window.dataLayer is a shared array — your container, an agency's tags, a chat widget and an A/B tool all write to the same place, and a push carries no proof of who wrote it.
So by default we treat what we find there as a guess: it rides the event it came with, it fills a field nothing else supplied, and it never overwrites an identity you sent with adsping('identify', …). It is also not kept for the visitor's next visit.
If your own container is the only writer, say so and those pushes count as statements — kept for the visitor, applied to later events, exactly like an identify call:
<script async src="https://api.adsping.io/pb.js"
data-pixel-id="YOUR_PIXEL_ID"
data-trust-datalayer="true"></script>identify call written, and match quality flat between visits. Leave it off when another company's tags live in the same container. Either way a constant placeholder address is refused: a container that fills the field with [email protected] when it has no real address hands every visitor one identity, so we drop it and tell you in the response.Verify
- Use GTM Preview mode — the AdsPing tag shows under Tags Fired on page load.
- The pixel detail page in AdsPing shows
Last event: a few seconds ago.