# Pixels and tracking tags

One API for every ad platform's pixel or site tag: list, create, update, read stats, share, manage users and conversion events, and install on Shopify, WordPress, Wix or Webflow.

import { Tab, Tabs } from 'fumadocs-ui/components/tabs';

Manage every ad platform's pixel or site tag under one platform-neutral API at `/v1/accounts/{accountId}/tracking-tags`, and install it on a connected store or site without theme edits.

## Before you start

A tracking tag is an ad platform's measurement tag for a website: sites fire events to it, server-side conversions deduplicate against it, conversion campaigns and website audiences point at it.

- **Covered:** the Meta Pixel, the TikTok Pixel, the Google tag, the LinkedIn Insight Tag, the Pinterest tag, the X Pixel and the OpenAI Ads pixel.
- **Installs:** on a connected [Shopify](/platforms/shopify/tracking-pixels) store, [WordPress](/platforms/wordpress/tracking-pixels), [Wix](/platforms/wix/tracking-pixels) or [Webflow](/platforms/webflow/tracking-pixels) site.
- **Not Reddit:** these endpoints answer `400` for a `redditads` account. Create the pixel in Reddit Ads Manager and send server-side events with the [Reddit Ads Conversions API](/platforms/reddit-ads/conversions).
- **Not click-URL parameters** (`utm_*`, `{{ad.id}}`). Those live on each ad: see URL tracking tags for [Meta](/platforms/meta-ads/url-tracking), [Google](/platforms/google-ads/url-tracking) and [LinkedIn](/platforms/linkedin-ads/url-tracking).

| 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. Its platform picks the adapter. |
| `tagId` (path) / `tag.id` | The id the platform's API uses for the tag. |
| `tag.siteTagId` | The id the on-site code carries, used by store installs and `code`. It differs from `id` on TikTok, Google, X and OpenAI. |
| `adAccountId` | The ad account inside the connection. Required on create, an optional scope on per-tag calls. |
| `event.id` / `event.siteEventId` | A conversion event's API id, and the id the site sends to fire it. |

Each platform page lists its own id formats.

## List and read tags

`GET /v1/accounts/{accountId}/tracking-tags` lists every tag the connection can see (`?adAccountId=` scopes it). `GET .../tracking-tags/{tagId}` adds `code` and `events`.

<Tabs items={['Node.js', 'Python', 'curl']}>
<Tab value="Node.js">
```typescript
import Zernio from '@zernio/node';

const zernio = new Zernio();

const { data } = await zernio.trackingtags.getTrackingTag({
  path: { accountId: '66b2e19d8c3f5a7e9d0b1c2d', tagId: '7412345678901234567' },
  query: { adAccountId: '7301234567890123456' }
});
```
</Tab>
<Tab value="Python">
```python
from zernio import Zernio

client = Zernio()

data = client.tracking_tags.get_tracking_tag(
    account_id="66b2e19d8c3f5a7e9d0b1c2d",
    tag_id="7412345678901234567",
    ad_account_id="7301234567890123456",
)
```
</Tab>
<Tab value="curl">
```bash
curl "https://zernio.com/api/v1/accounts/66b2e19d8c3f5a7e9d0b1c2d/tracking-tags/7412345678901234567?adAccountId=7301234567890123456" \
  -H "Authorization: Bearer $ZERNIO_API_KEY"
```
</Tab>
</Tabs>

Response (`200`), a TikTok Pixel:

```json
{
  "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" }
    ]
  }
}
```

`status` is `active` or `inactive`. `kind` and `lastFiredTime` (Unix seconds) vary by platform: see the [capability table](#capability-matrix).

## Create a tag

`POST /v1/accounts/{accountId}/tracking-tags` takes `adAccountId` and `name`, and answers `201` with the tag. `defaultEventType` ([OpenAI](/platforms/openai-ads/tracking-tag)) and `automaticMatchingFields` ([Pinterest](/platforms/pinterest-ads/tracking-tag)) are extras; other platforms answer `400` to them.

<Callout type="warn">
Most creates are not idempotent and no tag can be deleted. After a `502`, list the tags before creating again.
</Callout>

## Update a tag

`PATCH /v1/accounts/{accountId}/tracking-tags/{tagId}` takes at least one of `name`, `enableAutomaticMatching`, `automaticMatchingFields`, `firstPartyCookieStatus`, `enableFirstPartyCookies`, `dataUseSetting` or `autoTagging`.

Each platform accepts a subset and answers `400` naming its supported fields for the rest.

## Read stats and diagnostics

`GET .../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.

`GET .../tracking-tags/{tagId}/diagnostics` returns health checks as `checks[]` (`key`, `title`, `description`, `result`, `actionUrl`), on [Meta only](/platforms/meta-ads/tracking-tag#diagnostics).

## Share a tag with other ad accounts

`GET`, `POST` and `DELETE` on `.../tracking-tags/{tagId}/shared-accounts` list, add and remove shared ad accounts. The `POST` body and the `DELETE` `?adAccountId=` name the ad account.

## Manage conversion events

`.../tracking-tags/{tagId}/events` manages a tag's conversion events. The body takes `name` (required on create) and the platform's event type in `type` or a neutral `siteEvent`.

<Tabs items={['Node.js', 'Python', 'curl']}>
<Tab value="Node.js">
```typescript
const { data } = await zernio.trackingtags.createTrackingTagEvent({
  path: { accountId: '66b2e19d8c3f5a7e9d0b1c2f', tagId: 'cds_68e4f0a1b2c3d4e5f6a7b8c9' },
  body: { name: 'Purchases', siteEvent: 'purchase' }
});
```
</Tab>
<Tab value="Python">
```python
data = client.tracking_tags.create_tracking_tag_event(
    account_id="66b2e19d8c3f5a7e9d0b1c2f",
    tag_id="cds_68e4f0a1b2c3d4e5f6a7b8c9",
    name="Purchases",
    site_event="purchase",
)
```
</Tab>
<Tab value="curl">
```bash
curl -X POST "https://zernio.com/api/v1/accounts/66b2e19d8c3f5a7e9d0b1c2f/tracking-tags/cds_68e4f0a1b2c3d4e5f6a7b8c9/events" \
  -H "Authorization: Bearer $ZERNIO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Purchases", "siteEvent": "purchase" }'
```
</Tab>
</Tabs>

Response (`201`), an OpenAI event setting:

```json
{
  "platform": "openaiads",
  "event": {
    "id": "ces_68e4f0c9d8e7",
    "name": "Purchases",
    "type": "order_created",
    "siteEvent": "purchase",
    "siteEventId": "order_created",
    "status": "active",
    "clickWindowDays": 30
  }
}
```

| Method | Path | Operation |
|--------|------|-----------|
| `GET` | `.../tracking-tags/{tagId}/events` | [List conversion events](/tracking-tags/list-tracking-tag-events) |
| `POST` | `.../tracking-tags/{tagId}/events` | [Create a conversion event](/tracking-tags/create-tracking-tag-event) (`201`) |
| `PATCH` | `.../tracking-tags/{tagId}/events/{eventId}` | [Update a conversion event](/tracking-tags/update-tracking-tag-event) |
| `DELETE` | `.../tracking-tags/{tagId}/events/{eventId}` | [Delete a conversion event](/tracking-tags/delete-tracking-tag-event); answers `{ platform, eventId, state }` |

`siteEvent` is Zernio's neutral storefront vocabulary, the one the store installs speak: `page_view`, `view_content`, `add_to_cart`, `search`, `initiate_checkout`, `add_payment_info`, `purchase`.

## Manage users and partners

Meta pixels have people with access and partner businesses ([Meta pixel users and partners](/platforms/meta-ads/tracking-tag#users-and-partners)). Other platforms answer `501`.

| Method | Path | Operation |
|--------|------|-----------|
| `GET` | `.../tracking-tags/{tagId}/users` | [List the tag's users](/tracking-tags/list-tracking-tag-users) |
| `POST` | `.../tracking-tags/{tagId}/users` | [Assign a user](/tracking-tags/assign-tracking-tag-user) with `{ userId, tasks }`, replacing an assigned user's tasks |
| `DELETE` | `.../tracking-tags/{tagId}/users/{userId}` | [Remove a user](/tracking-tags/remove-tracking-tag-user): `501` on Meta |
| `GET` | `.../tracking-tags/{tagId}/partners` | [List partner businesses](/tracking-tags/list-tracking-tag-partners), read only |

## 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` reads the status and `DELETE` removes it, both with `?storeAccountId=`.

Responses carry `tagPlatform`, `siteTagId`, `installed`, and `tags` (every Zernio tag on the store).

| Store | How the tag goes on |
|-------|---------------------|
| [Shopify](/platforms/shopify/tracking-pixels) | One Zernio web pixel per store (a web pixel app extension) fires one tag per platform, mapping Shopify's customer events |
| [WordPress](/platforms/wordpress/tracking-pixels) | One marked Custom HTML widget per tag, read back to confirm the script survived |
| [Wix](/platforms/wix/tracking-pixels) | One Zernio script per site loads each tag's base code |
| [Webflow](/platforms/webflow/tracking-pixels) | One Zernio script in the site's custom code, live after the next publish; needs the Zernio Webflow app |

## Check what each platform supports [#capability-matrix]

`Yes` means the platform's API allows it and Zernio implements it. `No` means the API cannot do it, and `501` that Zernio does not expose it. Both answer `501 platform_not_supported` with a message naming the alternative.

| Operation | [Meta](/platforms/meta-ads/tracking-tag) | [TikTok](/platforms/tiktok-ads/tracking-tag) | [Google](/platforms/google-ads/tracking-tag) | [LinkedIn](/platforms/linkedin-ads/tracking-tag) | [Pinterest](/platforms/pinterest-ads/tracking-tag) | [X](/platforms/x-ads/tracking-tag) | [OpenAI](/platforms/openai-ads/tracking-tag) |
|-----------|------|--------|--------|----------|-----------|---|--------|
| `kind` | `pixel` | `pixel` | `tag` | `insight_tag` | `tag` | `pixel` | `pixel` |
| `lastFiredTime`, `installed` | Yes | No | No | Yes | Yes | Yes | No |
| Create tag | Not idempotent | Not idempotent | Idempotent | Idempotent | Not idempotent | One per ad account (`409`) | One per account (`409`), not idempotent |
| Update tag | Yes | Yes | `autoTagging` only | First-party tracking only | No | First-party cookies only | No |
| Delete tag | No | No | No | No | No | No | No |
| Stats | Aggregated counts | Per event, 7 days default, 30 max | Per conversion action, 30 days default | Last fire per domain and rule | Last fired, Event Quality Score | Last tracked, no counts | Last 15 minutes |
| Diagnostics | Yes | No | No | 501 | 501 | 501 | 501 |
| Share | Business Manager pixels | Business Center pixels | No | `USE_ONLY` | No | No | No |
| Users, partners | Yes (no user removal) | 501 | 501 | 501 | 501 | 501 | 501 |
| List events | Custom conversions | Pixel events | Conversion actions | Conversion rules | Advertiser defined events | Web event tags | Event settings |
| Create event | Idempotent by name | Not idempotent | Duplicate names refused | Not idempotent | Keyed by name | Not idempotent | Not idempotent |
| Update event | Name, value | Name, value, currency | Yes | Yes | Type only | Name, type, windows | No |
| Delete event | Archives | No | Archives (restorable) | Disables | Stops tracking | Deletes | No |
| Install on Shopify | Yes | Yes | Mapped conversions only | Page views, mapped rules | Yes | Page views, mapped events | Yes |
| Install on WordPress, Wix, Webflow | Yes | Yes | Yes | Yes | Yes | Yes | Yes |

An operation a platform lacks answers:

```json
{
  "error": "Updating a tracking tag is not supported for platform \"pinterestads\". Pinterest API v5 has no endpoint to edit a tag: its spec lists only POST and GET on /conversion_tags and GET on /conversion_tags/{id}, and PATCH or PUT on /conversion_tags/{id} answer 405 \"Method not allowed\" (code 5). Rename a tag or change its enhanced match settings in Pinterest Ads Manager (Conversions); enhanced match can be set when creating it.",
  "type": "invalid_request_error",
  "code": "platform_not_supported",
  "platform": "pinterestads"
}
```

## How it behaves

- **No tag deletes.** No platform's API deletes a tag, so there is no `DELETE` on a tag. Retire a tag by uninstalling it from the site.
- **Event creates are not idempotent** on TikTok, LinkedIn, X and OpenAI. Never retry one blindly.
- **Unknown fields are refused.** A field the platform does not store answers `400` naming the ones it does.
- **Installs are idempotent.** Repeating an install, status read or uninstall changes nothing more.

## If it fails

| Error | Cause | Fix |
|-------|-------|-----|
| `400` naming `accountId` | 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 | Send only the fields the message lists. |
| `400` on sharing | The platform's share condition is not met | See the platform page. |
| `403 insufficient_permissions` | The platform refused the token, or the connection predates a permission | 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. |
| `409` | The account already has a pixel, or the store must reconnect (`reconnect_required`) or fires another tag (`invalid_resource_state`) | See the platform page. |
| `422 feature_not_available` | OpenAI has not enabled the ad account | Ask the OpenAI partner representative. |
| `422 tracking_tag_install_blocked` | WordPress cannot run the script | See [the reasons](/platforms/wordpress/tracking-pixels#when-wordpress-cannot-run-the-tag). |
| `501 platform_not_supported` | The platform's API has no such operation | The message names the alternative. |

## Related

- [Meta Pixels](/platforms/meta-ads/tracking-tag), [TikTok Pixel](/platforms/tiktok-ads/tracking-tag), [Google tag](/platforms/google-ads/tracking-tag), [LinkedIn Insight Tag](/platforms/linkedin-ads/tracking-tag), [Pinterest tag](/platforms/pinterest-ads/tracking-tag), [X Pixel](/platforms/x-ads/tracking-tag) and [OpenAI pixel](/platforms/openai-ads/tracking-tag): each platform's ids, operations and limits.
- [Send events](/conversions/send-events): server-side events that deduplicate against the browser events.
- [Pixels & Tracking Tags reference](/tracking-tags/list-tracking-tags): every field and response.