Meta Pixel Integration
Track booking funnel events to Meta Ads, with browser pixel + Conversions API for accurate attribution.
Benefits
- Funnel tracking: PageView, lead capture, qualification, and booking events sent to Meta
- Server-side conversions (CAPI): funnel events report reliably even with ad blockers or iOS privacy features, because they never depend on the browser pixel
- Hashed PII: Email, phone, and name are SHA-256 hashed before they leave your team's server
- Customizable event names: Map SalesCal events to Meta's standard events (Lead, Schedule) or your own custom event names
- Per-form exclusion: Opt specific booking pages out of pixel tracking when you don't want them in your ad data
How the Pixel Works
SalesCal fires Meta events two complementary ways:
- Browser pixel — the Meta
fbevents.jsscript loads on your public booking page and fires the page-view event - Conversions API (CAPI) — every funnel event (lead capture, qualification, booking) is sent server-side from a SalesCal edge function, carrying SHA-256-hashed prospect details (email, phone, name, location) plus the IP address, user agent, and Meta's click and browser ids
Funnel events are server-only on purpose: exactly one copy per event, always carrying the fullest match data, unaffected by ad blockers or browser privacy features, and with no dependence on a race between duplicate events (Meta deduplicates by event_id but keeps only the first copy it receives — it never merges). Page views still fire from the browser so Meta's session tooling, like the Test Events tab, can see the visit.
Connecting a Pixel
- Go to Integrations
- Find Meta Pixel and click Connect
- The "Add Meta Pixel" dialog appears. Fill in:
- Pixel Name — a label for your own reference (e.g. "Q2 Campaign Pixel")
- Pixel ID (Dataset ID) — the 15–18 digit ID from Meta Events Manager
- CAPI Access Token — generate this in Meta Events Manager → Settings → Conversions API. It's a long string, around 200 characters.
- Click Add Pixel
After the first pixel is saved, manage everything else from Integrations > Meta Pixel.
Where to find your Pixel ID and access token
In Meta Events Manager:
- Pixel ID: top of your dataset settings — labeled "Dataset ID"
- CAPI Access Token: Settings tab → Conversions API → Generate Access Token. Treat this like a password — anyone with it can write events to your pixel.
Use Meta's copy button rather than selecting the token by hand, and paste it straight into SalesCal. The token field is masked, so a password manager may offer to autofill your saved password into it — dismiss that if it appears. SalesCal rejects anything that's obviously the wrong length, but the surest check is that what you paste starts with EA and runs to roughly 200 characters.
Events SalesCal Tracks
| SalesCal trigger | Default Meta event | When it fires |
|---|---|---|
page_view | ViewContent | A prospect lands on a public booking page |
potential | Lead | Contact info captured on the booking form (fires once per lead — see below) |
qualified | SubmitApplication | Form passes qualification rules |
booked | Schedule | Meeting time confirmed |
When the Lead event fires
The potential trigger fires once per lead, with the most complete contact data available. When a prospect completes the email step, SalesCal waits up to 60 seconds for a phone number before sending the event:
- Phone captured within the window → one Lead event including the phone
- No phone within 60 seconds → one Lead event with email only
- Prospect leaves the page during the window → the event sends immediately with whatever was captured
- The form has no phone field → the event sends as soon as the email is captured
A phone number added after the Lead event has gone out doesn't re-fire it — Meta would discard a duplicate rather than merge it — but the phone still reaches Meta on the later qualified and booked events.
Calls Booked by an Admin
When an admin books a call for a lead directly from the Leads screen, the same booked conversion fires server-side — sourced as a phone call rather than a website event. Match data comes from whatever the lead's stored contact details already hold (email, phone, name, and their ad click ID if the original visit came from a Meta ad); there's no browser session to draw from for a call booked this way, so match quality depends entirely on what that original visit captured. As with every other trigger, nothing fires unless the team has a pixel configured.
Each event has two modes:
- Meta standard event — map to one of Meta's predefined events (Lead, Schedule, Purchase, etc.). Use this for ad optimization where standard events have first-class support
- Custom event — fire your own event name (e.g. "SalesCal_Lead"). Use this when you need separate data streams from other pixels firing similar events
Configuration lives at Integrations > Meta Pixel — pick the mode and event name per trigger.
Per-Form Exclusion
By default, every booking page fires the pixel. If you have internal or test forms that shouldn't pollute your ad data, exclude them:
- Open the booking event in the dashboard
- The exclusion list is team-wide — managed alongside other meta-pixel settings
- Excluded events still book normally; they just don't fire the pixel
This is useful for staging events, internal sales-team links, or low-quality channels you don't want optimizing against.
What CAPI Sends
For each event, the server-side CAPI call includes:
| Field | Value |
|---|---|
em | SHA-256(lowercase trimmed email) |
ph | SHA-256(digits-only phone) |
fn / ln | SHA-256(lowercase trimmed first/last name) |
ct / st | SHA-256(lowercase city / state, no spaces) |
country | SHA-256(2-letter ISO code) |
external_id | SHA-256(SalesCal lead UUID) |
client_ip_address | Prospect's IP from the booking request |
client_user_agent | Browser user-agent string |
fbc / fbp | Meta's click ID and browser ID cookies if present |
PII fields are hashed in your team's server before transit. Meta receives only the hashes, which it matches against its own hashed user graph for attribution.
Test Events
There are two ways to verify a pixel, both using the Test Event Code from Meta Events Manager's Test Events tab.
Quick check: send a sample event
- Go to Integrations > Meta Pixel
- Open the menu on the pixel and choose Test Pixel
- Paste the Test Event Code and click Send Test Event
SalesCal fires a single server-side event carrying that code, and it appears in the Test Events tab within a few seconds. The test event carries a full sample set of match fields — email, phone, first and last name, city, region, country, IP address, and browser user agent — so you can confirm every advanced-matching parameter arrives in Meta exactly as live booking events send them.
Full walkthrough: test a real booking
To watch a complete booking flow — browser and server events side by side, exactly as live traffic behaves — open your booking page with ?meta_test_code=YOURCODE added to the URL:
https://yourcompany.salescal.site/book-a-call?meta_test_code=TEST12345Every server event fired from that browser tab then carries your test code and shows in the Test Events tab (alongside the page-view browser event). Only your own tab is affected — other visitors' events keep reporting normally — and the test session ends when you close the tab. (A walkthrough still creates a real lead and booking, so cancel it afterwards.)
Test mode is never saved anywhere: the dialog send is one-shot and the URL flag lives only in your own browser tab. Live traffic keeps flowing to normal reporting the whole time, and there's nothing to switch off afterwards.
Troubleshooting
"No events showing up in Events Manager"
- Confirm the Pixel ID matches your dataset (not your old pixel from a different campaign)
- Check the CAPI Access Token — regenerating one in Meta will silently invalidate the previous token
- Open the pixel's ⋯ menu → View Activity to see the Activity Log — disabled triggers no-op silently and won't error
"Invalid OAuth access token - Cannot parse access token"
This appears in the Activity Log when the saved token isn't a token at all — Meta can't even read it, so it rejects every event. Nothing you change in Events Manager will fix it; the value stored in SalesCal is wrong.
The usual causes:
- Only part of the token was copied. Meta shows it in a scrolling box, so hand-selecting it often grabs a fragment.
- The wrong value was pasted — a Dataset ID, App ID, or App Secret instead of the token.
- A password manager autofilled the field. It's a masked field, so browsers can mistake it for a login box.
To fix it: generate a fresh token in Events Manager → Settings → Conversions API, copy it with Meta's copy button, then open the pixel's ⋯ menu → Edit in SalesCal and paste it in. The field shows dots and leaving it blank keeps the broken token, so you must paste the new one. Use Test Pixel to confirm the fix before relying on live traffic.
If you suspect a password was autofilled into this field, change that password — it was stored as your access token.
"Browser pixel fires but CAPI doesn't"
- The CAPI Access Token is missing or expired — re-enter it
- Your edge function logs (Supabase) will show the actual error from Meta
"Events fire but Meta says 'no match'"
Meta needs at least one user identifier to match. Make sure the booking form captures email or phone, otherwise CAPI sends an event with no matchable PII.
"Wrong events firing on a page"
Check the per-event mode and event-name configuration — a "Custom event" mode with a typo'd name will fire successfully but show up as a custom event in Meta rather than as Lead/Schedule/etc.
Disconnecting
- Go to Integrations > Meta Pixel
- Click the delete icon next to the pixel
- Confirm
The pixel record is removed and tracking stops immediately. Events already in Meta are not deleted — that's a Meta-side cleanup.
Privacy & Security
- The CAPI Access Token is stored encrypted at rest
- Prospect identifiers are SHA-256 hashed on the server before they reach Meta; the browser pixel only fires the page view and carries no personal details
- Per-form exclusion lets you keep regulated forms (e.g. healthcare, financial) out of ad tracking
- Trigger logs are pruned after 30 days
Multiple Pixels
You can connect more than one Meta Pixel per team. All active pixels fire on every event (subject to per-form exclusion). Use this when:
- You run multiple ad accounts and need attribution in each
- You're migrating from one pixel to another and want overlap during the cutover
Related Guides
- Google Tag Manager — for arbitrary tag firing (not just Meta)
- Hyros Integration — for SQL-level ad attribution across Meta, Google, TikTok
- Qualification Rules — controls when "Qualified" vs "Disqualified" fires