Tracking Pixels
Install ad platform pixels on a Shopify store's storefront and checkout with one call.
Put an ad platform's pixel on the store's storefront and checkout with one call and no theme edits:
POST /v1/accounts/{accountId}/tracking-tags/{tagId}/installaccountIdis your connected ads account (Meta, TikTok, Google, LinkedIn, Pinterest, X or OpenAI).tagIdis the tracking tag.- The body names this store's
storeAccountId.
Zernio installs its web pixel app extension on the store, which maps Shopify's customer events to each platform's events.
How the install works
A Shopify app gets one web pixel per store, so the store runs a single Zernio web pixel that holds one tag per ad platform:
- Install is idempotent. Calling it again rewrites the same settings. Installing a different tag of the same platform replaces the previous one and names it in
replacedTagId. Tags of other platforms are kept. - Status (
GETwith?storeAccountId=) says whether this tag is the one the store fires for its platform (installed). It also says which tag of that platform it fires now (installedTagId), and lists every Zernio tag on the store intags. - Uninstall (
DELETEwith?storeAccountId=) removes only this platform's tag and keeps the others. The web pixel itself is deleted when no tag remains.- Removing a tag that is not installed is a no-op.
- Removing a tag while the store fires a different tag of that platform changes nothing and answers
409 invalid_resource_state.
const { data } = await zernio.trackingtags.installTrackingTagOnStore({
path: { accountId: '66b2e19d8c3f5a7e9d0b1c2d', tagId: '7412345678901234567' },
body: { storeAccountId: '66b2e19d8c3f5a7e9d0b1c3e' }
});Response (200), a TikTok Pixel added next to a Meta pixel already on the store:
{
"platform": "tiktokads",
"install": {
"storeAccountId": "66b2e19d8c3f5a7e9d0b1c3e",
"platform": "shopify",
"shopDomain": "acme.myshopify.com",
"tagPlatform": "tiktokads",
"siteTagId": "D00IKHRC77UE0J0RTNHG",
"installed": true,
"installedTagId": "D00IKHRC77UE0J0RTNHG",
"webPixelId": "2031620387",
"tags": [
{ "platform": "metaads", "siteTagId": "1729525464415281" },
{ "platform": "tiktokads", "siteTagId": "D00IKHRC77UE0J0RTNHG" }
],
"replacedTagId": null
}
}siteTagId, installedTagId, replacedTagId and tags carry the on-site id (the TikTok pixel code, the Google AW- id, the X or OpenAI pixel id), not the API tagId.
Google, LinkedIn and X store their per-event ids (conversion labels, rule ids, event ids) at install time. Install again after you add or change conversion events on those platforms.
Older stores. Stores connected before 28 September 2026 have not granted write_pixels and read_customer_events.
On those, all three calls answer 409 reconnect_required. The fresh consent link is in details.authUrl and the missing scopes in details.missingScopes.
The account keeps its id, so retry after the merchant approves.
A store connected with a custom-app Admin token gets the same answer, because a web pixel belongs to the app that installs it.
See When the store must re-approve for the full error.
Event mapping
The pixel subscribes to 7 Shopify standard customer events. It reduces them to Zernio's neutral site events and sends each one to every installed platform:
| Shopify event | Site event | Meta | TikTok | X | OpenAI | |||
|---|---|---|---|---|---|---|---|---|
page_viewed | page_view | PageView | Pageview | PAGE_VIEW action, if one exists | Page view (base tag hit) | pagevisit | Page view (twq('config')) | page_viewed |
product_viewed | view_content | ViewContent | ViewContent | Not sent | VIEW_CONTENT rule, if one exists | viewcontent | CONTENT_VIEW event, if one exists | contents_viewed |
product_added_to_cart | add_to_cart | AddToCart | AddToCart | ADD_TO_CART action, if one exists | ADD_TO_CART rule, if one exists | addtocart | ADD_TO_CART event, if one exists | items_added |
search_submitted | search | Search | Search | Not sent | SEARCH rule, if one exists | search | SEARCH event, if one exists | Custom search |
checkout_started | initiate_checkout | InitiateCheckout | InitiateCheckout | BEGIN_CHECKOUT action, if one exists | START_CHECKOUT rule, if one exists | initiatecheckout | CHECKOUT_INITIATED event, if one exists | checkout_started |
payment_info_submitted | add_payment_info | AddPaymentInfo | AddPaymentInfo | Not sent | ADD_BILLING_INFO rule, if one exists | addpaymentinfo | ADDED_PAYMENT_INFO event, if one exists | Custom addpaymentinfo |
checkout_completed | purchase | Purchase | Purchase | PURCHASE action, if one exists | PURCHASE rule, if one exists | checkout | PURCHASE event, if one exists | order_created |
Meta, TikTok, Pinterest and OpenAI receive every event.
- Product and cart events carry the variant id, value and currency.
- Checkout events carry every line, the total and the currency.
- The purchase adds the order id.
Google counts only events that have their own conversion action. It receives page_view, add_to_cart, initiate_checkout and purchase.
Each is sent only when the account has an enabled WEBPAGE conversion action of the matching category with a label (the primary-for-goal action wins).
Google has no category for search or payment info. Sending product views to the page-view action would count every product page twice. See Google tag.
LinkedIn always receives the page view as a base Insight Tag hit.
Any other event is sent only when the ad account has an enabled conversion rule of the matching type that a page can fire, with the value, currency and order id.
That is an event-specific Insight Tag rule, not a Conversions API or URL-match rule. The most recently fired one wins.
A KEY_PAGE_VIEW rule is never fired, since it would count every page as a conversion. See Insight Tag.
X always receives the page view. Any other event is sent only when the ad account has a conversion event of the matching type (the most recently tracked one wins). See X Pixel.
OpenAI has no standard search or payment-info event. Those go out as the lowercase custom events search and addpaymentinfo, the names the OpenAI Conversions API stores for a server-side Search or AddPaymentInfo.
Search text is never sent to OpenAI.
Deduplication
Every event carries an event id: Shopify's own event id, except the purchase. The purchase id is shopify_order_<orderId> (the numeric order id).
Send a server-side purchase for the same order through POST /v1/ads/conversions with eventId: "shopify_order_<orderId>". Each platform counts it once.
The id travels as:
| Platform | Field |
|---|---|
| Meta | eventID |
| TikTok | event_id |
oid (one conversion per order id per action) | |
eventId | |
event_id | |
| X | conversion_id |
| OpenAI | event_id |
How events reach each platform
Shopify runs app pixels in a strict sandbox (a web worker with no DOM), where the platforms' own browser scripts cannot load.
The Zernio pixel therefore sends each event straight to the endpoint the platform's script would call.
It keeps the platform's click id (fbclid, ttclid, gclid/gbraid, li_fat_id, epik, twclid, oppref) in a first-party cookie, so later events stay attributed:
| Platform | Endpoint | Status |
|---|---|---|
| Meta | www.facebook.com/tr with _fbp / _fbc | Documented (the pixel's image endpoint) |
| TikTok | analytics.tiktok.com/api/v2/pixel, reusing _ttp | Undocumented: the endpoint TikTok's events.js calls |
www.googleadservices.com/pagead/conversion/<id>/ with the conversion label | Documented no-JavaScript conversion tag; gclid/gbraid kept in _gcl_aw/_gcl_gb | |
px.ads.linkedin.com/collect with li_fat_id from the landing URL | Documented image pixel (pid, conversionId, eventId), plus the parameter names insight.min.js sends | |
ct.pinterest.com/v3/ (GET, or a form POST past 2048 characters) | The endpoint Pinterest's documented noscript tag and core.js call, with core.js's parameter names; epik kept in _epik | |
| X | analytics.twitter.com/1/i/adsct | Reverse-engineered from uwt.js (X documents only the legacy image pixel) |
| OpenAI | bzr.openai.com/v1/sdk/events | Documented image tag; oppref kept in __oppref for 30 days, amounts in minor units |
The pixel follows the store's customer privacy settings. Where consent is required, it fires only for visitors who allow marketing.