Meta Pixel for the Climber App
Capitan has a built-in Meta Pixel integration for the Climber App. Once you add your Meta Pixel ID / Dataset ID to your organization settings, Capitan automatically does two things on every page of your Climber App:
- Tracks page views, so Meta can see when someone who clicked one of your ads (or saw one on Facebook or Instagram) lands on your Climber App and browses it.
- Tracks purchase-funnel events, so Meta can see your customers move through the buying journey: viewing a product, starting checkout, and completing a purchase, along with the revenue from each sale.
No code, tags, or scripts are required. You paste one ID into Capitan, click Save, and both kinds of tracking turn on across the entire Climber App.
Three settings sit alongside the Pixel ID and change what Meta receives: advanced matching, which attaches hashed customer identifiers to each event; the privacy notices the Climber App shows visitors, which can stop the pixel entirely; and a Conversions API access token, which sends a second copy of each purchase-funnel event from Capitan's servers for the visits where the pixel is blocked.
New to the Meta Pixel? The Meta Pixel (formerly the Facebook Pixel) is Meta's free conversion-tracking tool for Facebook and Instagram advertising. It reports what visitors do on your Climber App back to your Meta ad account, so Meta can attribute purchases to the ads that drove them, optimize ad delivery toward people who buy, and build retargeting audiences. This article assumes you already have (or can create) a Meta Business account.
Before you begin
You'll need a Meta Pixel ID (Meta now also calls this a Dataset ID; they are the same number). It is a long string of digits, for example 1406003404508736.
To get one:
- In Meta Events Manager, create a pixel/dataset for your business (or use an existing one).
- Copy its Dataset ID (shown on the dataset's Settings tab; older accounts label it Pixel ID).
Meta's own walkthrough is here: Create and install a Meta Pixel.
It must be the numeric ID, not a code snippet. Capitan builds and installs the full pixel code for you, so all it needs is the ID itself. Capitan validates the format and rejects anything that is not entirely digits.
Getting Started: Add your Pixel ID in Capitan
- On the Staff Site, go to Organization Settings.
- Find the Meta Pixel ID / Dataset ID field.
- Paste in your numeric ID.
- Click Save.
That's the entire setup. From this point on, every Climber App page automatically loads Meta's official pixel script and begins sending events to your Meta dataset.
Leave the "Tracking/Analytics Script" field empty for the Meta Pixel. That field is a separate, advanced tool for trackers where Capitan has no dedicated integration; see the Google Analytics article's explanation of that field. For the Meta Pixel, the ID field alone is all you need. Pasting a Meta Pixel snippet into both places would cause double-counting.
Send customer info to Meta for advanced matching
Advanced matching attaches identifiers for the person buying to every pixel event, so Meta can match a conversion to a real account instead of matching on cookie and browser signals alone. It is what Meta's Event Match Quality score measures, and raising that score improves how accurately your Climber App sales are attributed to the ads that produced them.
Once a Meta Pixel ID is saved, a checkbox appears beneath it in Organization Settings:
- Find Send customer info to Meta for advanced matching, directly under the Meta Pixel ID / Dataset ID field.
- Turn it on.
- Click Save.
What Capitan sends, when the setting is on:
- The customer's email address, first name, last name, and customer ID, with every tracked event.
- Their phone number, only when they are signed in.
Every value is hashed in the browser before it reaches Meta, in the one-way form Meta's manual advanced matching accepts (see the technical reference for the exact keys and hash). Meta compares those hashes against its own; it does not receive a readable email address or phone number from Capitan.
Why a guest purchase sends no phone number: someone buying without signing in is matched to an existing customer record on name and birthday, so the phone number on that record is not something the visitor typed. A hashed phone number is short enough to recover by brute force, so publishing one into the page would expose a number the visitor never supplied. Everything else sent for a guest is either what they just entered or opaque.
Nobody is identified in these cases, and the events still fire with no match data attached:
- The visitor is browsing without signing in and has not entered purchaser details yet.
- A staff user is using the Climber App on behalf of a customer. That session runs in the staff user's own browser, so matching would tie the staff browser's Meta cookies to the customer's identity.
- The page is running in kiosk mode.
- The visitor has not granted consent for tracking. See Privacy notices and what they change.
Example use case: a location running Instagram ads for its intro class sees Meta credit far fewer bookings than the Capitan reports show. Turning advanced matching on lets Meta match the hashed email of the person who booked against the account that saw the ad, so the bookings Meta was previously unable to attribute start appearing against the campaign that drove them.
Disclosing this in your privacy policy is your responsibility. Capitan shows visitors a privacy notice and records their choice, but the policy describing what your location shares with Meta is yours to write and maintain.
Send events from the server with the Conversions API
Ad blockers and browser privacy settings stop the pixel on certain visits, so Meta never hears about some of the purchases Capitan processes. The Conversions API closes that gap: with an access token saved, Capitan sends a second copy of each purchase-funnel event from its own servers, carrying the same event ID as the browser's copy. Meta counts the two copies as one conversion, and still records it when the browser copy never arrived.
To turn it on:
- In Meta Events Manager, open your dataset's Settings tab and generate an access token under Conversions API. Meta's own instructions are in the Conversions API documentation.
- On the Staff Site, go to Organization Settings and paste the token into the Conversions API Access Token field, below the Meta Pixel ID / Dataset ID field.
- Click Save.
Clearing the token turns server-side sending off again. The pixel keeps working on its own.
What the server sends: "ViewContent", "InitiateCheckout", and "Purchase", for the same products and values as the browser events. "PageView" stays browser-only. Each server event carries the visitor's IP address and browser user agent, Meta's browser cookies and ad click ID where the pixel was able to set them, and, when advanced matching is on, the same hashed identifiers the pixel sends. With advanced matching off, no customer identifiers leave the server.
The privacy notice applies to both copies. A visitor who has not granted consent, a staff user acting on a customer's behalf, and a kiosk session produce no server event, just as they produce no pixel event. Server-side sending never reports anyone the pixel would not.
"Purchase" no longer depends on the confirmation page. The server copy is sent when the payment completes, so a customer who pays and closes the tab before the confirmation screen appears is still counted. Purchases that never pass through the Climber App checkout (the Sell Screen, your POS, and automatic membership renewals) are still not sent.
Delivery and retries: events leave within a minute or two of the action and are retried for about a day if Meta cannot be reached. Meta only deduplicates a server event against the browser's copy for 48 hours, so an event older than that is dropped rather than risk counting a purchase twice.
If the token stops working, for example because it was revoked in Meta or the pixel it belongs to no longer exists, Capitan pauses server-side sending and shows This integration needs attention under the token field in Organization Settings, with Meta's reason and when it happened. Enter a new access token to resume. Events from the paused period that are still inside the 48-hour window are sent once sending resumes.
Example use case: a location running Instagram ads sees Ads Manager credit far fewer purchases than the Capitan Revenue report shows, and a check of its own staff browsers finds an ad blocker on most of them. After the owner adds a Conversions API token, the purchases from blocked browsers start reaching Meta, and the campaign's cost per purchase drops to reflect the sales it was already driving.
Privacy notices and what they change
The Climber App asks visitors about analytics and advertising tracking, and the pixel obeys the answer. Which notice a visitor sees depends on where they are:
| Where the visitor is | What they see | What happens before they answer |
|---|---|---|
| The EU, the wider EEA, and the UK | A banner with Reject and Accept | Tracking stays off until they choose Accept |
| The United States | A notice with Do Not Sell or Share My Personal Information and OK | Tracking runs, and stays on unless they opt out |
| Everywhere else | No notice | Tracking runs |
When a visitor has not granted consent, the pixel sends nothing, and no server-side event is sent either. Capitan issues Meta's consent revoke call before the pixel initializes, so events raised on the page are held in the pixel's queue rather than transmitted, the no-script tracking image is left out of the page, and no advanced matching data is attached. Granting consent later releases the queued events.
Staff-on-behalf sessions and kiosks are never asked and never tracked. A staff user helping a customer, or a shared kiosk device, sees no notice, and Capitan records no decision on that device.
A visitor can change their mind at any time from the Climber App settings page, in the Privacy card: the Allow analytics and advertising cookies checkbox, then Save Preferences.
Expect lower event volume in the EU and the UK. Every visitor there who declines, or who never answers the banner, is a visitor the pixel does not report. This is the tradeoff the notice exists to make, and it applies to page views, funnel events, and advanced matching alike.
For the full picture of how the notices behave, including what Google receives in the same circumstances, see Google Analytics for the Climber App.
What gets tracked automatically
Page views
Because you provided a Pixel ID, Capitan injects the Meta Pixel into every Climber App page, and the pixel records a "PageView" event each time a customer loads any page: the login page, the schedule, a membership purchase page, the confirmation screen, and so on.
Page views are what let Meta connect an ad click to what happened afterward. When someone clicks your ad and lands on the Climber App, the pixel picks up the click identifier Meta appends to the link and ties that visitor's later activity (including their purchase) back to the ad.
Purchase-funnel events
On top of page views, Capitan sends three standard Meta Pixel events as customers move through a purchase in the Climber App. Together they form a funnel:
| Funnel stage | Meta event | When it fires in the Climber App |
|---|---|---|
| 👀 Browsing | "ViewContent" | The customer opens a specific product and is choosing who it's for / how many participants. |
| 🛒 Checkout started | "InitiateCheckout" | The customer reaches the payment page for that product. |
| ✅ Purchase complete | "Purchase" | The customer reaches the confirmation page after paying. |
These events fire for every type of product a customer can buy through the Climber App. With a Conversions API access token saved, each of the three is also sent from Capitan's servers under the same event ID, so Meta counts the two copies once.
What information each event carries
- "ViewContent": the product's name, a unique content ID, and a quantity of 1. On the pages where the price is already settled it also carries the currency, the value, and the item's price. See Where a price is included below.
- "InitiateCheckout": the product, the currency, and the value (the invoice total at checkout).
- "Purchase": everything in "InitiateCheckout", plus the Capitan invoice number in two places: an
order_idparameter, and a unique event ID that prevents the same sale from being counted twice. This is the event that drives conversion and return-on-ad-spend reporting in Meta Ads Manager.
The currency is your organization's configured currency (e.g. USD, GBP), and the value is the full invoice amount, including any applicable taxes and fees.
All three events carry their content IDs in Meta's content_ids parameter and declare a content_type of "product", which is the shape Meta's catalog matching and dynamic ads read. The same products are also listed in the "contents" array, with a per-item price and quantity.
Where a price is included
"ViewContent" fires while the customer is still choosing options, so on most product pages the final price is not settled yet. Where the page already knows it, the event carries the currency, the value, and the item's price. That amount is tax-inclusive, so it matches the value the later "InitiateCheckout" and "Purchase" events read off the invoice.
A price is included on:
- The gift pages for a membership, an entry pass, and a voucher pack, where the price is the product's own fee plus tax at the purchaser's location.
- The voucher pack purchase page, where one list price and one tax rate apply to everyone.
No price is included on:
- The gift card page, where the visitor types the amount.
- Membership and entry pass pages bought for a specific member, where the price depends on that member's tier or home location.
- Event and session booking pages, where the price comes from a pricing matrix and the number of participants.
What this changes for your campaigns: a "ViewContent" with no value still registers the product view, so retargeting audiences built on it behave the same. Value-based bidding still rests on "InitiateCheckout" and "Purchase", which have carried a value all along.
Understanding the content IDs
Each tracked product is sent to Meta with a human-readable name (e.g. "Adult Annual Membership") and a structured content ID. The content ID uses a consistent prefix so you can tell product types apart:
| Content ID format | What it represents |
|---|---|
| membership-{id} | A membership |
| pass-{id} | An entry pass |
| voucher-pack-{id} | A voucher pack |
| event-{id} | A session or event booking |
| membership-gift-{id} | A gifted membership |
| entry-pass-gift-{id} | A gifted entry pass |
| voucher-pack-gift-{id} | A gifted voucher pack |
| gift-card | A gift card |
These are the same product IDs the Google Analytics integration uses, so if you run both, a product's activity lines up across the two platforms.
A note on gift cards: gift cards have no per-product IDs, so every gift card event uses the fixed ID "gift-card" on the product page, and on the checkout and confirmation pages, which also carry the amount paid.
How to use this data in Meta
A few of the most useful things you can do once events are flowing:
1. Confirm it's working (Events Manager). In Meta Events Manager, open your dataset and use the Test events tab, then open your Climber App in another browser tab and click around. You should see "PageView" events appear, and if you start a purchase, "ViewContent" and "InitiateCheckout" follow. The Overview tab shows totals for each event over time.
2. Optimize ad delivery for purchases. In your campaigns, choose the "Purchase" event as the conversion event. Meta then shows your ads to the people most likely to buy, not just to click, and reports cost per purchase and return on ad spend using the real revenue values Capitan sends.
3. Re-engage shoppers who didn't finish (Custom Audiences). Build a Custom Audience of people who triggered "InitiateCheckout" but not "Purchase" (they started buying but didn't complete) and run a retargeting campaign to bring them back.
4. Find new customers who look like your buyers (Lookalike Audiences). Build a Lookalike Audience from people who triggered "Purchase". Meta finds people with similar profiles who haven't visited your Climber App yet.
5. Compare interest vs. sales per product. Because both "ViewContent" and "Purchase" carry the product name, you can compare views to purchases for each product and spot items with lots of interest but weak conversion.
Good to know (limitations & details)
- It's not retroactive. Meta only collects data from the moment you add your Pixel ID. It can't show you traffic or sales from before setup.
- Only Climber App purchases are tracked. Sales made by staff using the Staff Site Sell Screen or through your POS, and automatic recurring membership renewals, do not go through the Climber App checkout pages, so they are not sent to Meta. Treat these numbers as "customer online activity," not your full revenue. Your Capitan reports remain the source of truth for total revenue.
- Without the Conversions API, a purchase is counted when the confirmation page loads. If a customer pays but closes the tab before the confirmation screen appears, that purchase does not reach Meta. A Conversions API access token removes this gap, since the server copy is sent when the payment completes. Small discrepancies between Meta and your Capitan revenue reports remain normal.
- Each sale is one line item at the full invoice total. A purchase is reported with a quantity of 1 and a price equal to the whole invoice, even when it covers several people (like a group membership) or multiple participants (like a group booking). Your total purchase value in Meta will be right; the per-item quantity breakdown is not itemized per person.
- Purchases are de-duplicated. The "Purchase" event's ID is built from the Capitan invoice number, so a customer refreshing the confirmation page won't double-count the sale.
- Without the Conversions API, all events are sent from the visitor's browser. Visitors whose browsers block trackers (ad blockers, strict privacy settings) are not tracked, which is another reason Meta's purchase counts run below your Capitan reports; the Conversions API is the fix for that. Visitors who decline the privacy notice are not tracked either way.
- Domain verification stays with Capitan. Your Climber App pages live on Capitan's shared domain (climber.hellocapitan.com), so that domain can't be verified under an individual business's Meta Business portfolio. Verification isn't required for the tracking described in this article.
Technical reference (optional)
For the technically curious or your marketing agency. Non-technical users can stop here.
When a Pixel ID is set, Capitan adds Meta's standard pixel loader to every Climber App page, followed by:
fbq('init', 'YOUR_PIXEL_ID');
fbq('track', 'PageView');
With advanced matching on and a customer to identify, the init call carries a third argument of pre-hashed values, using Meta's manual advanced matching keys:
fbq('init', 'YOUR_PIXEL_ID', {
em: '<sha256 of the lowercased, trimmed email>',
ph: '<sha256 of the digits, with country calling code>',
fn: '<sha256 of the lowercased first name>',
ln: '<sha256 of the lowercased last name>',
external_id: '<sha256 of the Capitan customer ID>'
});
The ph key is present only for a signed-in customer. Where consent has not been granted, Capitan emits fbq('consent', 'revoke') before the init call and the whole match-data argument is left out.
The standard noscript image-tag fallback is included as well, except where consent has not been granted: a plain image request has no consent API to obey, so the only way to hold it back is to leave it out of the page. Because this is the standard Meta script, the pixel's built-in behavior all applies: it sets and reads the _fbp and _fbc cookies and captures the fbclid click identifier from inbound ad URLs on its own.
The funnel events are emitted on the relevant pages. Example payloads:
// On a product page where the price is not settled yet
fbq('track', 'ViewContent', {
content_ids: ['membership-12'],
content_type: 'product',
contents: [{ id: 'membership-12', name: 'Adult Annual Membership', quantity: 1 }]
}, { eventID: '9f1c2b7e4d0a4c6f8e3b1a5d7c9e2f40' }); // a random ID for this page load
// On a product page where it is (the three gift pages, and the voucher pack page)
fbq('track', 'ViewContent', {
content_ids: ['membership-gift-12'],
content_type: 'product',
currency: 'USD',
value: 75,
contents: [{ id: 'membership-gift-12', name: 'Adult Annual Membership', item_price: 75, quantity: 1 }]
}, { eventID: '4b8d3e1f2a7c4d9e8f1b6c3a5d2e7f81' });
// On the payment page
fbq('track', 'InitiateCheckout', {
content_ids: ['membership-12'],
content_type: 'product',
currency: 'USD',
value: 75,
contents: [{ id: 'membership-12', name: 'Adult Annual Membership', item_price: 75, quantity: 1 }]
}, { eventID: 'initcheckout.48213' }); // 48213 = the Capitan invoice number
// On the confirmation page
fbq('track', 'Purchase', {
content_ids: ['membership-12'],
content_type: 'product',
order_id: '48213',
currency: 'USD',
value: 75,
contents: [{ id: 'membership-12', name: 'Adult Annual Membership', item_price: 75, quantity: 1 }]
}, { eventID: 'purchase.48213' });
With a Conversions API access token saved, Capitan also POSTs each of the three events to Meta's Conversions API with action_source "website", the page URL as event_source_url , an event_id equal to the browser event's "eventID", the same custom_data , and a user_data object holding client_ip_address , client_user_agent , fbp , and fbc , plus the hashed advanced-matching keys above when that setting is on.
Four details worth knowing if you're configuring campaigns or auditing events:
- Product information travels twice: in the
content_ids/content_typeparameters, and in the "contents" array (withid,name,item_price,quantityper item). Meta's parameter reference does not treat the two as mutually exclusive. - "Purchase" carries the Capitan invoice number in both
order_idand the event's "eventID" (Meta's deduplication key). "InitiateCheckout" carries it in the "eventID" only. - "ViewContent" carries a random "eventID" generated for that page load, so a server copy can pair with it, and carries a value only on the pages listed under Where a price is included. "InitiateCheckout" and "Purchase" always carry both, their event IDs prefixed "initcheckout." and "purchase." respectively.
- The per-item price key changed. Entries in "contents" previously used a
pricekey, which is not one of the four fields Meta documents for that array (id,quantity,item_price,delivery_category), so Meta never recorded it. The key is nowitem_price. Event-level value was always named correctly, so your reported conversion values and return on ad spend are unaffected; what changes is that a per-item price is now recorded alongside them. The Google Analytics integration keepsprice, because that is Google's own documented key for the same field.