Pixels and Tracking Tags
One API for every ad platform's pixel or site tag: list, create, update, read stats, share, manage conversion events and install on Shopify or WordPress.
A tracking tag is the measurement tag an ad platform gives you to put on a website: the Meta Pixel, the TikTok Pixel, the Google tag, the LinkedIn Insight Tag, the Pinterest tag, the X Pixel or the OpenAI Ads pixel. It is what a site fires events to, what server-side conversions deduplicate against, and what conversion campaigns and website audiences point at. Zernio exposes every platform's tag under one platform-neutral API at /v1/accounts/{accountId}/tracking-tags, and can install any of them on a connected Shopify store or WordPress site without theme edits.
These are not the click-URL parameters an ad appends to its link (utm_*, {{ad.id}}), which several platforms also call "tracking tags". Those live on each ad: see the URL tracking tags pages for Meta, Google and LinkedIn.
The id model
| Field | What it is |
|---|---|
accountId (path) | The ads connection: the SocialAccount the Ads connect flow created (metaads, tiktokads, googleads, linkedinads, pinterestads, xads, openaiads), never a posting account. The platform of that account picks the adapter. |
tagId (path) / tag.id | The id the platform's API uses for the tag. Pass it to every per-tag call. |
tag.siteTagId | The id the on-site code carries. It differs from id on TikTok, Google, X and OpenAI (table below). Store installs and the tag's code use this one. |
adAccountId | The ad account inside the connection. Required on create. On per-tag calls it is an optional scope for platforms whose tags or events live inside an ad account (TikTok advertisers, LinkedIn conversion rules); the others ignore it. |
event.id / event.siteEventId | A conversion event's API id, and the per-event id the site sends to fire it (Google conversion label, LinkedIn conversion rule id, X tw- event id, OpenAI event name). |
| Platform | accountId platform | tagId | siteTagId | adAccountId |
|---|---|---|---|---|
| Meta | metaads | Pixel id (numeric) | Same as tagId | act_<n> |
| TikTok | tiktokads | pixel_id (numeric) | pixel_code (for example D00IKHRC77UE0J0RTNHG) | Advertiser id; without it the pixel is searched across the connection's advertisers |
googleads | Customer id (10 digits, dashes allowed) | AW-<conversion tracking id> (the manager's under cross-account tracking) | The customer id | |
linkedinads | Insight Tag partner id (numeric) | Same as tagId | Ad account id, numeric or urn:li:sponsoredAccount:<id>; defaults to the tag's owner | |
pinterestads | Tag id (numeric) | Same as tagId | Ad account id; without it the tag's owner is found across the readable ad accounts | |
| X | xads | Ad account id (one X Pixel per ad account) | The pixel id from the account's web event tags | The ad account id |
| OpenAI | openaiads | cds_... API id (the pixel_id is accepted too) | pixel_id (also returned as pixelId) | Ignored: one API key is one ad account |
Capability matrix
Yes means the platform's API allows it and Zernio implements it. Anything marked 501 answers 501 platform_not_supported, and the error message says why and what to do instead, so you can surface it to a user as is.
| Operation | Meta | TikTok | X | OpenAI | |||
|---|---|---|---|---|---|---|---|
| List tags | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
Get tag (with code) | Yes | Yes (with events) | Yes (with events) | Yes (with events) | Yes | Yes (with events) | Yes (with events) |
| Create tag | Yes, not idempotent | Yes, not idempotent | Yes, idempotent (switches conversion tracking on) | Yes, idempotent (returns the account's tag) | Yes, not idempotent | 501: create it in X Events Manager | Yes, one per account, not idempotent |
| Update tag | Yes | Yes | autoTagging only | First-party tracking only | 501: v5 has no update | 501: no settings in the API | 501: no update endpoint |
| Stats | Aggregated counts | Per event (7 days default, 30 max) | Per conversion action (30 days default) | Last callback per domain and rule | Last fired, seen events, Event Quality Score | Status and last tracked time | Last 15 minutes only |
| Share with ad accounts | Yes (Business Manager pixels) | 501: Business Center only | 501: manager accounts, UI only | Yes (USE_ONLY) | 501: one ad account per tag | 501: one account per pixel | 501: one account per pixel |
| List events | Yes (custom conversions) | 501 (inline on get) | Yes (conversion actions) | Yes | 501 | 501 (inline on get) | Yes |
| Create event | Yes, idempotent by name | 501 | Yes (duplicate names refused) | Yes, not idempotent | 501 | 501 | Yes, not idempotent |
| Update event | Name and default value | 501 | Yes | Yes | 501 | 501 | 501: no endpoint |
| Delete event | Archives | 501 | Archives (restorable) | Disables the rule | 501 | 501 | 501: no endpoint |
| Diagnostics | Yes (Events Manager checks) | 501 | 501 | 501 | 501 | 501 | 501 |
| Delete tag | No | No | No | No | No | No | No |
| Install on Shopify | Yes | Yes | Mapped conversions only | Page views plus mapped rules | Yes | Page views plus mapped events | Yes |
| Install on WordPress | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
No platform's API deletes a tag, so there is no DELETE on a tag: Meta, TikTok, LinkedIn, Pinterest and OpenAI have no delete endpoint, and Google and X model the tag as part of the ad account. Retire a tag by uninstalling it from the site.
An operation a platform lacks answers:
{
"error": "Updating a tracking tag is not supported for platform \"pinterestads\". Pinterest API v5 only creates, lists and reads conversion tags; rename a tag or change its enhanced match settings in Pinterest Ads Manager (Conversions).",
"type": "invalid_request_error",
"code": "platform_not_supported",
"platform": "pinterestads"
}List and read tags
GET /v1/accounts/{accountId}/tracking-tags lists every tag the connection can see, and ?adAccountId= scopes it to one ad account. The list view leaves out code and events; GET .../tracking-tags/{tagId} returns them.
import Zernio from '@zernio/node';
const zernio = new Zernio();
const { data } = await zernio.trackingtags.getTrackingTag({
path: { accountId: '66b2e19d8c3f5a7e9d0b1c2d', tagId: '7412345678901234567' },
query: { adAccountId: '7301234567890123456' }
});Response (200), a TikTok Pixel:
{
"platform": "tiktokads",
"tag": {
"id": "7412345678901234567",
"siteTagId": "D00IKHRC77UE0J0RTNHG",
"name": "Storefront pixel",
"platform": "tiktokads",
"kind": "pixel",
"status": "active",
"creationTime": 1804064400,
"ownerAdAccountId": "7301234567890123456",
"code": "<script>!function (w, d, t) {...}</script>",
"events": [
{ "id": "1804567", "name": "Purchase", "type": "SHOPPING", "siteEvent": "purchase" }
]
}
}kind is pixel on Meta, TikTok, X and OpenAI, tag on Google and Pinterest and insight_tag on LinkedIn. status is active or inactive, lastFiredTime (Unix seconds, null when it never fired) and installed appear where the platform reports a last fire (Meta, LinkedIn, Pinterest, X), and ownerBusinessId is Meta's Business Manager owner.
Create and update
POST /v1/accounts/{accountId}/tracking-tags takes adAccountId and name (plus defaultEventType on OpenAI). It answers 201 with the tag.
Creating a tag is not idempotent on Meta, TikTok, Pinterest and OpenAI: every call makes another tag, and none of them can be deleted afterwards. LinkedIn and Google are the exceptions: a LinkedIn ad account holds one Insight Tag and a create returns it, and a Google create returns the account's tag, creating a first conversion action only when the account does not track conversions yet. Never auto-retry a create. After a timeout or a 502, list the tags before sending it again.
PATCH /v1/accounts/{accountId}/tracking-tags/{tagId} takes at least one of name, enableAutomaticMatching, automaticMatchingFields, firstPartyCookieStatus and dataUseSetting. Each platform accepts a subset and answers 400 naming the supported fields for the rest:
| Field | Meta | TikTok | |
|---|---|---|---|
name | Yes | Yes (40 characters, no emojis) | No (tags have no name) |
enableAutomaticMatching | Advanced Matching | Automatic advanced matching | No |
automaticMatchingFields | Meta codes (em, ph, fn, ...) | Folded onto TikTok's email, phone, address, first and last name switches | No |
firstPartyCookieStatus | Yes | First-party cookies on or off | First-party tracking on or off (empty answers 400) |
dataUseSetting | Yes | No | No |
Google takes only autoTagging (gclid auto-tagging on or off) and answers 400 for the fields above.
Stats
GET /v1/accounts/{accountId}/tracking-tags/{tagId}/stats takes optional startTime and endTime (Unix seconds) and returns { platform, stats: { startTime, endTime, rows } }. Rows are the platform's own data, so read the keys you get:
| Platform | Rows | Window |
|---|---|---|
| Meta | AdsPixelStatsResult for aggregation (default event; Meta only) | Meta's default when omitted |
| TikTok | Per-event counts from /pixel/event/stats | 7 days by default, at most 30, whole UTC days |
conversionActionId, conversionActionName, category, allConversions, allConversionsValue per conversion action | Last 30 days by default, in the account's time zone | |
One row per domain (domainName, lastFiredTime, blocked) and per conversion rule (status, lastFiredTime); no counts | None | |
The tag's lastFiredTime, status and enhancedMatchStatus, the events seen on it, and the ad account's Event Quality Score (1 and 14 days) | None: startTime/endTime answer 400 | |
| X | Each web event tag's status, lastTrackedTime and eventId (X has no counts) | None |
| OpenAI | The latest Pixel events received (at most 50) | Fixed to the last 15 minutes; startTime/endTime answer 400 |
Diagnostics
GET /v1/accounts/{accountId}/tracking-tags/{tagId}/diagnostics returns the platform's health checks for the tag as checks[] (key, title, description, result, actionUrl). Only Meta has them (Meta diagnostics); the others answer 501.
Conversion events
On platforms where each conversion is its own object tied to the tag, .../tracking-tags/{tagId}/events manages them. Today that is Meta (custom conversions: delete archives), Google (WEBPAGE conversion actions: delete archives, enabled: true restores), LinkedIn (conversion rules: delete disables) and OpenAI (event settings: list and create); the other platforms answer 501, and TikTok and X list their events inline on GET .../tracking-tags/{tagId}.
| Method | Path | Operation |
|---|---|---|
GET | .../tracking-tags/{tagId}/events | List conversion events |
POST | .../tracking-tags/{tagId}/events | Create a conversion event (201) |
PATCH | .../tracking-tags/{tagId}/events/{eventId} | Update a conversion event |
DELETE | .../tracking-tags/{tagId}/events/{eventId} | Delete a conversion event |
The body takes name (required on create), the platform's own event type in type or a neutral siteEvent, and the optional enabled, defaultValue, currency, clickWindowDays, viewWindowDays, urlContains (Meta URL rule), primary, countingType and alwaysUseDefaultValue (Google). A field the platform does not store answers 400 naming the ones it does. DELETE answers { platform, eventId, state }, where state is deleted, archived or disabled depending on what the platform can do. Creating an event is not idempotent: never retry it blindly.
siteEvent is Zernio's neutral storefront vocabulary, the same one the store installs speak: page_view, view_content, add_to_cart, search, initiate_checkout, add_payment_info and purchase.
const { data } = await zernio.trackingtags.createTrackingTagEvent({
path: { accountId: '66b2e19d8c3f5a7e9d0b1c2f', tagId: 'cds_68e4f0a1b2c3d4e5f6a7b8c9' },
body: { name: 'Purchases', siteEvent: 'purchase' }
});Response (201), an OpenAI event setting:
{
"platform": "openaiads",
"event": {
"id": "ces_68e4f0c9d8e7",
"name": "Purchases",
"type": "order_created",
"siteEvent": "purchase",
"siteEventId": "order_created",
"status": "active",
"clickWindowDays": 30
}
}Install on a store
POST /v1/accounts/{accountId}/tracking-tags/{tagId}/install with a connected store's storeAccountId puts the tag on the site, GET with ?storeAccountId= reads the install status and DELETE with ?storeAccountId= removes it. All three are idempotent.
- Shopify: Zernio's web pixel app extension fires one tag per platform from a single Zernio web pixel per store, mapping Shopify's customer events to each platform's events. See Shopify tracking pixels for the event mapping per platform.
- WordPress: one marked Custom HTML widget per tag with the platform's base code, read back to confirm the script survived. See WordPress tracking tags.
The install responses carry tagPlatform and siteTagId (the tag you asked about), installed and tags, every Zernio tag on the store across platforms.
Common errors
| Error | Cause | Fix |
|---|---|---|
400 naming accountId | The account is a posting account, or a platform without tracking tags | Pass the ads connection's account id. |
400 naming the supported fields | A field this platform does not store was sent on update or on an event | Send only the fields the message lists. |
403 insufficient_permissions | The platform refused the token, or the connection predates a permission (TikTok Pixel Management) | Reconnect the ads account. |
404 tracking_tag_not_found | The tag is not on this connection, or not in adAccountId | List the tags to find a current id. |
400 on sharing | LinkedIn: the target ad account already uses another Insight Tag, or it is the tag's last account | Revoke the other tag first, or share before revoking. |
409 | OpenAI: the account already has a Zernio pixel. Shopify: the store must re-approve (reconnect_required), or fires a different tag of the platform on uninstall (invalid_resource_state) | See the platform page. |
422 feature_not_available | OpenAI: the ad account is not enabled for pixel management or the event stream | Ask the OpenAI partner representative. |
422 tracking_tag_install_blocked | WordPress cannot run the script | See the reasons. |
501 platform_not_supported | The platform's API has no such operation | The message names the alternative. |
Related
- Meta Pixels, TikTok Pixel, Google tag, LinkedIn Insight Tag, Pinterest tag, X Pixel and OpenAI pixel: each platform's ids, operations and limits.
- Send conversions: server-side events that deduplicate against the browser events.
- Pixels & Tracking Tags reference: every field and response.