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

  1. Go to developers.facebook.comMy Apps → Create App.
  2. Choose Business as the app type.
  3. Fill in the app name (e.g. "Compass by Launchpad") and contact email.
  4. Under Settings → Basic:
    • Note the App IDMETA_APP_ID
    • Note the App SecretMETA_APP_SECRET
  5. 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
  6. Under Permissions and Features, request:
    • ads_read — read ad spend and ad account data
    • business_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

  1. Tenant clicks Connect on Settings → Integrations → Meta CAPI.
  2. Compass redirects to https://www.facebook.com/v18.0/dialog/oauth with the App ID, requested scopes, and a CSRF state nonce.
  3. Tenant logs in to their Facebook account and authorizes Compass.
  4. Meta redirects back to /api/connect/meta/callback?code=...&state=....
  5. Compass exchanges the short-lived code for a long-lived token (60-day TTL) via the server-side exchange.
  6. Compass fetches the tenant's ad accounts from GET /me/adaccounts and stores them in Integration.config.
  7. Long-lived token is stored in IntegrationCredential (key = access_token).
  8. 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