Connectors
Meta Conversions API (CAPI)
Category: Attribution
What it does: Tenants connect their Meta Business Manager via OAuth so Compass can send server-side conversion events (purchases, leads, checkouts) directly to Meta — improving ad targeting and measurement without relying on the browser pixel.
Prerequisites
You need a Meta App registered in Meta for Developers. The app acts as the OAuth client; each tenant grants it access to their Business Manager.
Step 1 — Create the Meta App
- Go to developers.facebook.com → My Apps → Create App.
- Choose Business as the app type.
- Fill in the app name (e.g. "Compass by Launchpad") and contact email.
- Under Settings → Basic:
- Note the App ID →
META_APP_ID - Note the App Secret →
META_APP_SECRET
- Note the App ID →
- Under Facebook Login → Settings:
- Add Valid OAuth Redirect URIs:
https://joincompass.ai/api/connect/meta/callback - For local development, also add:
http://localhost:3000/api/connect/meta/callback
- Add Valid OAuth Redirect URIs:
- Under Permissions and Features, request:
ads_read— read ad spend and ad account databusiness_management— access Business Manager assets
Step 2 — Set environment variables
META_APP_ID="123456789"
META_APP_SECRET="abc123..."
META_API_VERSION="v18.0"
OAUTH_REDIRECT_BASE_URL="https://joincompass.ai"
Step 3 — How the OAuth flow works
- Tenant clicks Connect on Settings → Integrations → Meta CAPI.
- Compass redirects to
https://www.facebook.com/v18.0/dialog/oauthwith the App ID, requested scopes, and a CSRF state nonce. - Tenant logs in to their Facebook account and authorizes Compass.
- Meta redirects back to
/api/connect/meta/callback?code=...&state=.... - Compass exchanges the short-lived code for a long-lived token (60-day TTL) via the server-side exchange.
- Compass fetches the tenant's ad accounts from
GET /me/adaccountsand stores them inIntegration.config. - Long-lived token is stored in
IntegrationCredential(key =access_token). - Tenant is redirected to
/settings/integrations?connected=meta.
Token refresh: Long-lived tokens expire after ~60 days. A scheduled job to refresh them is a future improvement (TODO).
Step 4 — Configure the Pixel
After connecting, the tenant must set their Pixel ID in Integration.config.pixelId before events can be pushed. This is currently done by editing the DB directly — a UI picker is a planned follow-up.
Step 5 — Sending events
The ingest pipeline calls sendCAPIEvent(tenantId, event) from lib/connectors/meta-capi.ts when an event has a Meta-related traffic source. Example:
import { sendCAPIEvent } from "@/lib/connectors/meta-capi";
await sendCAPIEvent(tenantId, {
eventName: "Purchase",
eventTime: Math.floor(Date.now() / 1000),
actionSource: "website",
userData: { em: hashedEmail },
customData: { value: orderTotalCents / 100, currency: "USD" },
});
Disconnect
Clicking Disconnect in the UI deletes the Integration and IntegrationCredential rows.
TODO: Revoke the token at Meta via the Graph API before deletion.
Ad account picker (future)
After the OAuth callback, Integration.config.adAccounts contains the list of ad accounts the tenant authorized. A UI for the tenant to select which ad account to associate with Compass (and to input their Pixel ID) is planned as a follow-up feature.
Troubleshooting
| Error param | Cause |
|---|---|
meta_denied |
Tenant clicked "Cancel" on the Meta authorization page |
meta_state_invalid |
CSRF state nonce expired (10-min TTL) or was tampered with |
meta_exchange_failed |
Meta Graph API error — verify META_APP_ID and META_APP_SECRET |