Tracking & Attribution

How Do You Run Meta CAPI for Multiple Ad Accounts on One Site?

Running two Meta ad accounts against one website? When to share a dataset, when to split, and how dedup and the eight-event domain budget behave.

Quick answer

Share one Meta dataset across the ad accounts if they are allowed to share it, and create a second dataset only when the accounts sit in Businesses that will not share assets. Either way, the site keeps one capture layer and one server-side config per dataset: each dispatch carries that dataset's own access token and its own event ID, and deduplication is compared inside a dataset, never across two. The eight-event Aggregated Event Measurement budget belongs to the verified domain, so a second pixel never buys you a ninth event.

Tell us what's broken. We'll fix your tracking — free.

Describe the tracking/attribution problem you're stuck on and we'll map it to a fix: server-side conversions to Meta, Google, TikTok and Pinterest, plus first-party tracking that survives Safari. No code required.

Share one Meta dataset across the ad accounts when they are allowed to share it, and split only when they are not. Either way the site keeps one capture layer, and every conversion is dispatched to each dataset separately, carrying that dataset’s own access token and its own event ID.

The duplication belongs in the dispatch. It should never reach the tracking.

Do you actually need more than one Meta pixel on this site?

Usually not. A Meta dataset — the object Events Manager still labels a pixel — can be shared with more than one ad account inside Business Manager. That is an asset permission, granted once, with no second line of code on the site and no second server-side integration.

You need separate datasets when the ad accounts live in different Businesses that will not share assets: two clients of the same agency, a white-label reseller, a joint venture whose data cannot legally pool. You also want them when one domain hosts genuinely separate brands whose audiences should stay apart.

Two reasons that look valid and are not: separate reporting, which ad account and campaign breakdowns already give you, and keeping an agency walled off from a client’s data, which asset permissions already do.

Every extra dataset splits conversion volume. A dataset receiving forty purchases a week learns faster than two receiving twenty each, and thin signal is expensive.

What happens when two Meta pixels fire on the same page?

Both datasets record the same visitor, and that is correct behaviour. Each dataset is its own ledger. A purchase worth $180 appears once in each, and only your own spreadsheet double-counts it — Ads Manager never sums across datasets.

Deduplication is where the real damage happens, because Meta compares events inside a dataset. A server event is matched to a browser event on the same event name plus the same event_id, and that comparison never crosses a dataset boundary. So reusing one event_id value in both datasets is harmless. Sending a fresh random ID from the server while the browser sent a different one is what double-counts — inside a single dataset, twice over, on every conversion you have.

That failure is silent. Nothing in Events Manager says “these two were the same purchase”; you just see a conversion count higher than your CRM’s. Why your Meta CAPI is not deduplicating walks the diagnosis, and what the event_id should be covers how to generate one that survives retries.

Match quality is also scored per dataset. The same lead, sent to two datasets with the same hashed email and phone, gets an Event Match Quality score in each one independently — and they can differ, because each dataset has its own history of browser events to resolve against.

Why does the eight-event limit belong to your domain, not your pixel?

Because Aggregated Event Measurement, the framework Meta built for iOS 14.5 and App Tracking Transparency, budgets conversion events per verified domain. Eight of them, ranked in priority order, configured against the domain rather than against a pixel or an ad account.

This is the constraint that surprises agencies. Two ad accounts driving traffic to the same website draw from the same eight slots, no matter how many datasets you create. Adding a second pixel to buy a ninth event does not work — the budget was never a property of the pixel.

Three practical consequences:

  • Priority order is a joint decision. For a user who opted out of tracking, the highest-priority event that fired is the one reported. If one account prioritises Purchase and the other needs Lead, that argument happens before the configuration is saved, not after.
  • Domain verification has one owner. The domain is verified inside a Business, and the event configuration lives there with it. If the agency verified the client’s domain in the agency Business, that decision follows you into every future argument about access.
  • A separate domain gets its own budget. This is the honest reason to run a second landing-page domain for a second brand — and it brings its own attribution problem, which is attributing orders across two domains.

Who should own the dataset when an agency runs the ads?

The client, and the reasoning is not political.

A dataset accumulates history — conversion volume, the audiences built from it, the optimisation learning that makes week twelve cheaper than week one. Rebuilding it inside a new Business does not carry any of that across. If the dataset lives in the agency’s Business, the client is one relationship breakdown away from starting over with an empty one.

The workable structure is boring: the client’s Business owns the dataset and verifies the domain, the agency’s ad account receives asset access to it, and the server-side access token is issued by the owning Business. Offboarding is then a permission change plus a token rotation — an afternoon, not a migration.

Rotate the token on the way out regardless of how the relationship ended: a server-side integration keeps sending conversions for exactly as long as its token stays valid.

How do you stop one account’s events from landing in the other’s dataset?

By routing on something the event already carries — the domain it happened on, the path it happened under, the campaign tags on the session — and by deciding that routing server-side, after the record exists.

Client-side routing is the common approach and the fragile one. Two base codes behind conditional logic fails on exactly the traffic that matters: single-page apps that never reload, cached pages that fire the wrong branch, tag managers with a race between containers, and blockers that kill one snippet and not the other. Server-side, the record is already written before anything decides where it goes.

Routing keys that hold up in practice:

  • Host. The cleanest rule available. Brand A’s domain feeds Brand A’s dataset, full stop.
  • Path prefix. For brands that share a domain — /pro/ to one dataset, /home/ to the other.
  • Campaign tagging. Workable only when UTM naming is disciplined; a utm_source typed by hand into a boosted post is not a routing key.
  • The offer itself. Which form, which product, which price tier — usually the most stable signal, since it changes less often than the media plan.

What does not work is the click ID. An fbclid tells you the visitor arrived from a Meta ad; it does not tell you which ad account paid for it, so it cannot separate two accounts running to the same page.

One rule to settle before you build any of this: what happens when an event matches both configs. Sending it to both is legitimate for a shared retargeting pool; doing it by accident and reconciling two sets of numbers at month end is not.

Diagram of one captured lead record fanning out to two Meta CAPI configs, each with its own pixel ID, access token, trigger rule and deterministic event ID

How does PartialLeads run Meta CAPI for multiple ad accounts?

One capture layer in front, one config per destination dataset behind it.

The tag captures once. Email and phone as they are typed, the UTMs and referrer, fbclid and the _fbp / _fbc cookies, the landing page and the geo — one record per session, written before anything decides where it is going. Adding a second ad account adds a config, not a second script.

Each Meta config holds its own pixel ID and its own access token, and each carries its own dispatch rules. The send mode decides when it fires — on a partial lead before submit, on a completed submission, on a rule match, on a booking, or only when an operator sends it by hand. The trigger rules decide whether it fires, as an AND/OR combination of field matches evaluated against the captured record. The same matcher runs for the Microsoft Conversions API, which is also where you will find the rules preview: it answers “this rule would have matched N of M capture-ready leads in the last seven days” using the dispatch matcher itself, so a routing condition can be tested before you commit to it.

Dedup is per config, by construction. The event ID is a SHA-256 of the pixel ID, event name and record ID, so the same conversion sent to two datasets produces two different IDs, and behind each config is a dedup table with a uniqueness constraint on that ID. A redelivered webhook physically cannot double-fire into either dataset, and a retry into one is not affected by the state of the other. That property is what makes running two datasets boring instead of nerve-racking — it is the same mechanism described in the Conversions API explainer, applied once per destination.

Failures are scoped per config too. An expired token flips that config to “reconnect needed” and leaves the other running; transient failures retry on the next worker cycle; permanent payload failures do not retry at all. One client’s lapsed access does not take the other client’s conversions down with it.

You see it in two places. The CAPI activity log carries one row per dispatch — event name, status, platform and timestamp — so two datasets receiving the same conversion read as two rows, not one ambiguous one. The Leads list adds an API column showing which conversion APIs a specific lead was dispatched to, which is the fastest way to answer “did this lead go to both accounts or one.” Both are part of knowing whether your Meta CAPI is working.

The honest constraints. Server-side dispatch does not replace the browser base tag. Match quality leans on _fbp and _fbc, which are set client-side, per dataset — PartialLeads reconstructs _fbc from a fbclid in the URL, but it does not synthesise _fbp from nothing, so each dataset still wants its own base code on the page. With email and phone as required form fields, PartialLeads consistently delivers EMQ 9+ across customer accounts, and the condition is load-bearing: the number comes from the identifiers you collect, and an audience Meta cannot resolve will score lower whatever the payload contains. Nothing here changes the eight-event budget or domain verification either — those are Meta-side decisions made by humans in Business Manager. We control dispatch. The platform controls matching.

Meta CAPI activity log in the PartialLeads dashboard: one row per dispatch per config, the same conversion sent to two different pixel IDs with its own account chip, status and match quality score, and one config flagged as needing reconnection

What breaks The mechanism Where you see it in the dashboard
A second pixel means a second script, a second integration and a new set of bugs One capture record per session, one dispatch config per destination dataset Integrations list, one Meta config per pixel ID
The same conversion double-counts inside one dataset Deterministic event ID (SHA-256 of pixel ID, event name and record ID) with a unique dedup table per config CAPI activity log, one row per event per config
Events meant for one account land in the other’s dataset Per-config trigger rules as AND/OR field matches, evaluated server-side against the captured record Rules preview: matched N of M capture-ready leads
One client’s expired token silently stops the other client’s conversions Per-config retry taxonomy — auth failures flag that config only, transient failures retry Config status, reconnect-needed flag
No way to tell which accounts a given lead was sent to Per-lead dispatch record for every conversion API Leads list, API column

Tell us what's broken. We'll fix your tracking — free.

Describe the tracking/attribution problem you're stuck on and we'll map it to a fix: server-side conversions to Meta, Google, TikTok and Pinterest, plus first-party tracking that survives Safari. No code required.

Sources

  1. Meta for Developers — Conversions API: https://developers.facebook.com/docs/marketing-api/conversions-api
  2. Meta for Developers — Deduplicate Pixel and server events: https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events
  3. Meta for Developers — Conversions API server event parameters: https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/server-event
  4. Meta for Developers — Aggregated Event Measurement: https://developers.facebook.com/docs/marketing-api/aggregated-event-measurement

Frequently asked questions

QCan two ad accounts share one Meta pixel?
Yes. A dataset is an asset in Business Manager and can be shared with several ad accounts, which is the simplest setup for an agency running multiple accounts against one website. Both accounts optimise against the same conversion history, which is usually an advantage — pooled volume trains faster than two thin datasets. Separate datasets are only necessary when the accounts belong to Businesses that cannot share assets.
QDo I need two Conversions API integrations if I have two pixels?
You need one dispatch config per dataset, because each dataset has its own pixel ID and its own access token, but you do not need two capture layers. The site is tracked once; the server decides which datasets each conversion goes to. If a vendor asks you to install a second snippet per ad account, that is a limitation of the vendor, not of the Conversions API.
QWill sending the same conversion to two pixels double-count it?
Not within either dataset — each one counts it once, and Ads Manager never sums across datasets. The real double-counting risk is inside a single dataset, when the browser event and the server event carry different event_id values and Meta cannot recognise them as the same event. Keep the ID consistent between browser and server for each dataset, and use a deterministic ID so retries are safe.
QDoes the eight-event limit apply per pixel or per domain?
Per verified domain. Aggregated Event Measurement budgets eight prioritised conversion events against the domain, so two ad accounts sending traffic to the same site share those eight slots regardless of how many datasets exist. Creating another pixel does not add events. A genuinely separate domain has its own budget, which is one of the few legitimate reasons to run a second landing-page domain.
QWho should own the Meta pixel, the agency or the client?
The client's Business should own the dataset and verify the domain, with the agency's ad account granted asset access. The dataset carries conversion history, audiences and optimisation learning that cannot be moved to a new Business, so ownership decides who keeps all of it when the relationship ends. Offboarding then becomes a permission change and a token rotation rather than a rebuild.
QHow do I route conversions to the right ad account automatically?
Route on something already present on the record — the host, the path prefix, disciplined campaign tags, or the specific form or offer the lead used. Decide it server-side, after the record is written, rather than with conditional snippet loading in the browser, which breaks on single-page apps, cached pages and blockers. The click ID cannot help: fbclid identifies Meta as the source, not which ad account paid.
QWhat happens if one account's access token expires?
Only that config stops. A well-built dispatcher scopes failures per config: an authentication failure flags that integration as needing reconnection, transient failures retry on the next cycle, and permanent payload errors do not retry at all. The other dataset keeps receiving events throughout. This is worth testing deliberately, because a shared failure mode across configs is exactly the bug you do not want to discover at month end.
QCan I run different events to each ad account from the same site?
Yes, and it is a common requirement — one account optimising for leads, another for purchases. Per-config rules decide which captured records dispatch to which dataset, evaluated as field matches on the record. Remember that the eight-event priority order still belongs to the domain, so the two accounts are choosing from one shared budget even when their dispatch rules are completely different.

Find the qualified leads your forms are currently throwing away.

Install PartialLeads on one landing page, send traffic, and compare what your CRM captured against what PartialLeads recovered and qualified.