Meta Pixel and Conversions API setup

This runbook creates a Meta Pixel (Meta calls it a dataset in Events Manager), shares it with the ad account, gives the BoostUp system user access, tests the Conversions API (CAPI) and connects everything to a brand in BoostUp. It follows the setup we ran for boostup.cloud on 2026-11-12, including the two problems we hit.

Result for boostup.cloud: pixel 28254557980886537, named boostup.cloud, owned by the Pro Level Solutions LTD business, data use setting advertising_and_analytics.

The pixel ID is public (it is in every page's HTML). Access tokens are secrets and never appear in this page, in tickets or in the repository.

Before you start

You need:

  • Admin access to the business in Meta Business Manager that owns the ad account.
  • A system user in that business with a token for your Meta app. In Business settings, Users, System users: Add, give it the Admin role, then Generate token for the app. We recommend the permissions ads_management, ads_read and business_management, plus pages_read_engagement and pages_show_list if BoostUp should read the Facebook Page. Store the token in your password manager.
  • The ad account ID and the Facebook Page ID (both in Business settings, under Accounts).

The API calls

All calls go to the Graph API at https://graph.facebook.com/<version>/ with the system user token (as the access_token parameter or an Authorization: Bearer header, left out below). Parameters on POST calls are sent as form fields.

1. Look at the existing pixels

GET https://graph.facebook.com/<version>/<business id>/owned_pixels?fields=id,name

Returned 200 with one existing pixel, Pro Level Solutions Data, and paging cursors (not needed here). Check this first so you do not create a duplicate pixel for a site that already has one.

2. Create the pixel

By hand: in Events Manager, Connect data sources, Web, name the dataset after the domain (boostup.cloud) and create it. Skip the partner integration wizard.

By API:

POST https://graph.facebook.com/<version>/<business id>/adspixels

name=boostup.cloud

Returned 200:

{ "id": "28254557980886537" }

3. Share the pixel with the ad account

By hand: in Business settings, Data sources, Datasets (or Pixels), select the pixel, then Connected assets, Add assets, and pick the ad account.

By API:

POST https://graph.facebook.com/<version>/28254557980886537/shared_accounts

account_id=<ad account id>
business=<business id>

Returned 200:

{ "success": true }

4. Give the system user access to the pixel

By API (failed):

POST https://graph.facebook.com/<version>/28254557980886537/assigned_users

user=<system user id>
tasks=['EDIT','ANALYZE']
business=<business id>

Returned 400:

{
  "error": {
    "message": "(#10) Application does not have permission for this action",
    "type": "OAuthException",
    "code": 10,
    "fbtrace_id": "<redacted>"
  }
}

The app behind the token is not allowed to change asset assignments in the business. Do not spend time on it:

By hand (the fix): in Business settings, Users, System users, select the BoostUp system user, then Assign assets. Pick the pixel (under datasets or pixels) and grant full control, or at least the permissions that match EDIT and ANALYZE. While you are there, assign the ad account and the Facebook Page to the same system user.

5. Install the browser pixel

BoostUp's web app reads the pixel ID from NEXT_PUBLIC_META_PIXEL_ID:

NEXT_PUBLIC_META_PIXEL_ID=28254557980886537

Like every NEXT_PUBLIC_ variable it is inlined when the app is built, so set it before the build (a Docker build argument for the web image). Do not set it for development or staging builds. An empty value turns the pixel off, and the pixel loads only after the visitor accepts marketing cookies in the consent banner, so accept them before you test with the Meta Pixel Helper extension.

6. Configure the Conversions API on the server

The server sends the same events through CAPI, so they still count when the browser blocks the pixel. It reads:

VariableWhereSecret
META_PIXEL_IDserver sideno
META_CAPI_TOKENserver side onlyyes

META_CAPI_TOKEN is the system user token from above, or a token generated in Events Manager under the dataset's Settings, Conversions API, Generate access token. Put it in the server's infra/.env (which is not committed) or your secret store. It never goes in the repository, in a NEXT_PUBLIC_ variable or in a browser bundle.

When the same event is sent by the browser pixel and by CAPI, give both the same event_id so Meta counts it once.

7. Send a CAPI test event

In Events Manager first: open the dataset, then the Test events tab, choose the action source you will send (Website for server events from the site) and copy the test code shown there. The code only works while that Test events session is open.

POST https://graph.facebook.com/<version>/28254557980886537/events

data=[{"event_name": "PageView", "event_time": 1794492998, "action_source": "website",
       "event_source_url": "https://boostup.cloud/",
       "user_data": {"client_ip_address": "<visitor ip>", "client_user_agent": "HermesSetup/1.0"}}]
test_event_code=TEST_HERMES

Returned 200, but with a warning:

{
  "events_received": 1,
  "messages": [
    "test_event_code \"TEST_HERMES\" does not match an active Test Events session for this dataset and the action source of these events. These events were received, but will not appear in Test Events. ..."
  ],
  "fbtrace_id": "<redacted>"
}

What went wrong. We made up the code TEST_HERMES instead of copying it from an open Test events session. The event was received (the token, the pixel ID and the payload were all fine) but it did not show in Test events.

Fix. Open the Test events tab, pick Website, copy the code it shows (it looks like TEST12345) and send again while the tab is open; the event appears within seconds. Never send test_event_code from production: events carrying it may be treated as test traffic.

8. Check the pixel

GET https://graph.facebook.com/<version>/28254557980886537?fields=id,name,last_fired_time,owner_business,data_use_setting

Returned 200:

{
  "id": "28254557980886537",
  "name": "boostup.cloud",
  "owner_business": { "id": "<business id>", "name": "Pro Level Solutions LTD" },
  "data_use_setting": "advertising_and_analytics"
}

last_fired_time is missing because the pixel had not fired yet (the only event so far was a test event). After the site is deployed with NEXT_PUBLIC_META_PIXEL_ID, it appears, and Overview in Events Manager shows browser and server events side by side.

9. Connect Meta to a brand in BoostUp

A platform admin imports the Meta assets for a brand with POST /admin/integrations/import-meta:

{
  "org_id": "<organization id>",
  "brand_id": "<brand id>",
  "access_token": "<system user access token>",
  "pixel_id": "28254557980886537",
  "ad_account_id": "<ad account id>",
  "page_id": "<facebook page id>"
}
  • access_token must be a system user token, not a personal one: personal tokens expire and stop when the person leaves the business.
  • The system user needs the pixel, the ad account and the Page assigned (step 4), or BoostUp's reads fail with permission errors.
  • Like every mutation, the call needs a signed-in admin session and the X-CSRF-Token header (see the API overview). Send the token only to this endpoint over HTTPS.