Meta Ads Connector
Connect Meta Ads (Facebook & Instagram) to Brevo through Tajo to synchronize Custom Audiences, import conversion events via the Conversions API, and bridge paid social advertising with lifecycle marketing automation.
Overview
| Property | Value |
|---|---|
| Platform | Meta Ads (Facebook, Instagram, Messenger, WhatsApp) |
| Category | Marketing |
| Setup Complexity | Advanced |
| Official Integration | No |
| Data Synced | Audiences, Conversions, Campaigns, Leads |
| Available Skills | 8 |
| API Version | v25.0 (Graph API) |
Features
- Custom Audience sync - Upload Brevo contact lists as Meta Custom Audiences
- Conversions API (CAPI) - Send server-side conversion events for accurate attribution
- Lead form sync - Import Facebook Lead Ads submissions directly into Brevo contacts
- Campaign insights - Pull ad performance metrics into Tajo dashboards
- Lookalike audiences - Create Lookalike Audiences from synced Brevo segments
- Catalog sync - Sync product catalogs for dynamic product ads
- Multi-platform - Single integration covers Facebook, Instagram, Messenger, and WhatsApp ads
Prerequisites
Before you begin, ensure you have:
- A Meta Business Manager account
- A Facebook App with Marketing API access
- A System User with appropriate permissions
- An Access Token with
ads_managementandads_readpermissions - A Brevo account with API access
- A Tajo account with API credentials
Authentication
System User Access Token
Meta recommends using System User tokens for server-to-server integrations. These tokens do not expire.
# Required permissions for System Userads_managementads_readbusiness_managementleads_retrievalpages_read_engagementcatalog_managementApp-Level Authentication
curl -G "https://graph.facebook.com/v25.0/act_AD_ACCOUNT_ID/campaigns" \ -d "access_token=SYSTEM_USER_ACCESS_TOKEN" \ -d "fields=name,status,objective"Configuration
Basic Setup
connectors: meta_ads: enabled: true app_id: "your-facebook-app-id" app_secret: "your-facebook-app-secret" access_token: "your-system-user-access-token" ad_account_id: "act_123456789" business_id: "987654321" pixel_id: "111222333444"
# Data sync options sync: custom_audiences: true conversions_api: true lead_forms: true campaign_insights: true
# API version api_version: "v25.0"Custom Audience Configuration
Sync Brevo lists to Meta Custom Audiences:
custom_audiences: enabled: true lists: - brevo_list_id: 5 audience_name: "All Customers" subtype: "CUSTOM" - brevo_list_id: 6 audience_name: "High LTV Customers" subtype: "CUSTOM" - brevo_list_id: 7 audience_name: "Recent Purchasers" subtype: "CUSTOM"
# Matching fields match_keys: - EMAIL - PHONE - FN # First name - LN # Last name - CT # City - ST # State - ZIP - COUNTRY
schedule: "daily" sync_mode: "mirror"Conversions API Configuration
conversions_api: enabled: true pixel_id: "111222333444" test_event_code: "" # Set for testing, clear for production
events: - brevo_event: "order_completed" meta_event: "Purchase" value_field: "revenue" currency_field: "currency" - brevo_event: "cart_updated" meta_event: "AddToCart" - brevo_event: "customer_created" meta_event: "Lead" - brevo_event: "page_viewed" meta_event: "ViewContent"API Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST | /v25.0/act_{id}/customaudiences | Create a Custom Audience |
POST | /v25.0/{audience_id}/users | Add users to Custom Audience |
DELETE | /v25.0/{audience_id}/users | Remove users from Custom Audience |
POST | /v25.0/{pixel_id}/events | Send Conversions API events |
GET | /v25.0/act_{id}/campaigns | List campaigns |
GET | /v25.0/act_{id}/insights | Get campaign insights |
GET | /v25.0/{form_id}/leads | Retrieve lead form submissions |
POST | /v25.0/act_{id}/adcreatives | Create ad creatives |
GET | /v25.0/{catalog_id}/products | List catalog products |
Code Examples
Initialize Meta Ads Connector
import { TajoClient } from '@tajo/sdk';
const tajo = new TajoClient({ apiKey: process.env.TAJO_API_KEY, brevoApiKey: process.env.BREVO_API_KEY});
// Connect Meta Ads accountawait tajo.connectors.connect('meta-ads', { appId: process.env.META_APP_ID, appSecret: process.env.META_APP_SECRET, accessToken: process.env.META_ACCESS_TOKEN, adAccountId: 'act_123456789', pixelId: '111222333444'});Send Conversions API Events
// Send a purchase event via Conversions APIconst response = await fetch( `https://graph.facebook.com/v25.0/${PIXEL_ID}/events`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ data: [{ event_name: 'Purchase', event_time: Math.floor(Date.now() / 1000), action_source: 'website', user_data: { ph: [hashSHA256('+15551234567')], fn: [hashSHA256('jane')], ln: [hashSHA256('kim')], client_ip_address: '192.168.1.1', client_user_agent: 'Mozilla/5.0...', fbc: 'fb.1.1234567890.AbCdEfG', // Click ID fbp: 'fb.1.1234567890.987654321' // Browser ID }, custom_data: { value: 89.99, currency: 'USD', content_ids: ['SKU-001'], content_type: 'product' } }], access_token: process.env.META_ACCESS_TOKEN }) });Sync Custom Audience from Brevo List
// Upload a Brevo contact list as a Meta Custom Audienceawait tajo.connectors.syncAudience('meta-ads', { brevoListId: 5, audienceName: 'High Value Customers', matchKeys: ['EMAIL', 'PHONE', 'FN', 'LN'], syncMode: 'mirror'});Pull Campaign Insights
// Get campaign performance metricsconst insights = await tajo.connectors.query('meta-ads', { resource: 'campaigns', fields: ['campaign_name', 'impressions', 'clicks', 'spend', 'actions', 'cost_per_action_type'], dateRange: { since: '2024-01-01', until: '2024-01-31' }, level: 'campaign'});Rate Limits
| Resource | Limit | Details |
|---|---|---|
| Marketing API | Tier-based | Based on app access level and spend |
| Custom Audience uploads | 700 requests/hour | Per ad account |
| Conversions API | 2,000 events/sec | Per pixel |
| Insights API | 200 calls/hour | Per ad account |
| Lead retrieval | 200 calls/hour | Per page |
| Batch requests | 50 requests/batch | Per batch call |
Business Verification Required
Full Marketing API access requires business verification in Meta Business Manager. Unverified apps are limited to development mode with restricted rate limits.
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
OAuthException | Token expired or invalid | Regenerate System User access token |
| Low Custom Audience match rate | Poor data quality | Hash all PII with SHA-256, include multiple match keys |
| Conversions not attributed | Missing fbc/fbp parameters | Pass Facebook Click ID and Browser ID from cookies |
RATE_LIMIT_REACHED | Too many API calls | Implement exponential backoff, check API access tier |
| Lead forms not syncing | Missing leads_retrieval permission | Add permission to System User |
| Events in test mode | test_event_code still set | Remove test event code for production |
Best Practices
- Use System User tokens - System Users provide stable, non-expiring tokens for server integrations
- Hash all PII - SHA-256 hash all personally identifiable information before sending to Meta
- Send both CAPI and Pixel - Use both Conversions API and Meta Pixel for redundant tracking with deduplication
- Include event IDs - Set
event_idon both CAPI and Pixel events to enable deduplication - Pass
fbcandfbp- Include Facebook Click ID and Browser ID for maximum conversion attribution - Verify your business - Complete Business Verification for full API access and higher rate limits
- Use
test_event_code- Test Conversions API events in Events Manager before going live
Security
- System User tokens - Non-personal, business-scoped authentication tokens
- SHA-256 hashing - All PII hashed before transmission to Meta servers
- App Secret Proof - Optional additional layer of authentication security
- Business scoping - Permissions scoped to specific ad accounts and pages
- Meta compliance - Subject to Meta Platform Terms and advertising policies
- Data Processing Terms - Meta’s Data Processing Terms apply for EU data
Related Resources
Open-Source Implementation Map
This section is derived from official or public repository material discovered for the Meta Ads connector. Use it as the engineering companion to the setup guide above: it shows where the API surface lives, what implementation assets exist, and how Tajo should translate them into reliable Brevo sync behavior.
Repository Snapshot
| Repository | Commit | Languages / formats | Files |
|---|---|---|---|
| facebook/openapi | 4003386 | Markdown (3), license (1), YAML (1) | 5 |
Integration Shape
graph LR Source["Meta Ads API / repository"] --> Auth["Auth and scopes"] Source --> Objects["Objects, events, and schemas"] Auth --> Tajo["Tajo connector runtime"] Objects --> Tajo Tajo --> Brevo["Brevo contacts, attributes, lists, campaigns"] Tajo --> Ops["Backfill, cursor, retries, logs"]What To Reuse
- Meta OpenAPI Specifications
- Overview
- Composition
- The repository currently contains specifications for:
-
- Business Messaging - WhatsApp API OpenAPI Specification. Visit developer documentation for WhatsApp Business API here.
Tajo Revamp Checklist
- Keep authentication setup aligned with the vendor docs and the public repository’s current API shape.
- Map primary resources into explicit Tajo sync objects with stable external IDs.
- Prefer cursor-based or updated-at incremental sync where the API exposes it; otherwise document the fallback.
- Treat webhook handlers as idempotent and replay-safe, especially for order, contact, ticket, and campaign events.
- Capture pagination, rate limits, retry headers, and partial-failure behavior in connector smoke tests.
- Keep examples small and runnable against sandbox or test-mode accounts.