Facebook Ads¶
Facebook Ads is the advertising platform that helps users to create targeted ads on Facebook, Instagram and Messenger.
omniload supports Facebook Ads as a source using Facebook Marketing API.
URI format¶
The URI format for Facebook Ads is as follows:
facebookads://?access_token=<access_token>&account_id=<account_id>
URI parameters:
access_token(required) is associated with Business Facebook App.account_id(optional) is associated with Ad manager. Can also be provided in the table name.
The URI is used to connect to Facebook Ads API for extracting data.
Setting up a Facebook Ads Integration¶
Facebook Ads requires a few steps to set up an integration, please follow the guide dltHub has built here.
Once you complete the guide, you should have an access token and an Account ID. Let’s say your access_token is abcdef and account_id is 1234, here’s a sample command that will copy the data from Facebook Ads into a DuckDB database:
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'campaigns' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.campaigns'
The result of this command will be a table in the facebook.duckdb database.
Tables¶
Facebook Ads source allows ingesting the following sources into separate tables:
Table |
PK |
Inc Key |
Inc Strategy |
Details |
|---|---|---|---|---|
|
id |
updated_time |
merge |
Retrieves campaign data with |
|
id |
updated_time |
merge |
Retrieves ad set data with |
|
id |
updated_time |
merge |
Retrieves ad data with |
|
- |
- |
replace |
Retrieves ad creative data with |
|
id, created_time |
created_time |
merge |
Retrieves lead data with fields: id, created_time, ad_id, ad_name, adset_id, adset_name, campaign_id, campaign_name, form_id, field_data. Supports |
|
date_start |
date_start |
merge |
Retrieves insights data (requires account_id in URI) |
|
date_start |
date_start |
merge |
Retrieves insights data for multiple accounts |
Use these as --source-table parameter in the omniload ingest command.
Account ID in Table Name¶
For campaigns, ad_sets, ads, ad_creatives, and leads, you can specify account ID(s) directly in the table name instead of the URI:
# Single account in table name
omniload ingest \
--source-uri 'facebookads://?access_token=your_token' \
--source-table 'campaigns:1234567890' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.campaigns'
# Multiple accounts in table name
omniload ingest \
--source-uri 'facebookads://?access_token=your_token' \
--source-table 'campaigns:1234567890,9876543210' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.campaigns'
Facebook Insights Custom Configuration¶
The facebook_insights table supports advanced configuration for breakdowns and custom fields:
Format Options¶
There are two distinct configuration modes:
Mode 1: Predefined Breakdowns
Format:
facebook_insights:breakdown_typeorfacebook_insights:breakdown_type:field1,field2,field3Uses a predefined breakdown type (see list below)
Cannot be combined with custom dimensions
Custom fields are optional - if omitted, uses default fields for that breakdown
Mode 2: Custom Dimensions
Format:
facebook_insights:dimension1,dimension2:field1,field2,field3orfacebook_insights:level,dimension1,dimension2:field1,field2,field3Uses custom dimensions (not predefined breakdown names)
Fields are required - you must always provide fields after the second colon
Can optionally specify a level (account, campaign, adset, ad) as the first dimension
[!TIP] You can include
campaign_id,adset_id, andad_idin your fields list alongside your metrics if you want to have these as part of the output.E.g.
facebook_insights:ad:campaign_id,adset_id,ad_id,spend,impressions,clicks
Available Predefined Breakdown Types¶
ads_insights- Basic insights without breakdownsads_insights_age_and_gender- Breakdown by age and genderads_insights_country- Breakdown by countryads_insights_platform_and_device- Breakdown by platform and deviceads_insights_region- Breakdown by regionads_insights_dma- Breakdown by DMA (Designated Market Area)ads_insights_hourly_advertiser- Breakdown by hour (advertiser time zone)
Available Levels¶
When using custom dimensions (not predefined breakdowns), you can specify one of these levels as the first dimension:
account- Account level insightscampaign- Campaign level insightsadset- Ad set level insightsad- Ad level insights
Note:
Levels can only be used with custom dimensions, not with predefined breakdowns
If multiple levels are specified in the dimensions list, the last valid level will be used and removed from the dimensions list
Common Dimensions¶
When using custom dimensions (not predefined breakdowns), you can use any valid Facebook Ads dimension. Some commonly used dimensions include:
age- Age rangesgender- Gender breakdowncountry- Country breakdownregion- Region breakdownplatform_position- Platform positionpublisher_platform- Publisher platformimpression_device- Device typeplacement- Ad placement
Important Notes:
Custom dimensions must always be accompanied by fields (after the second colon)
Predefined breakdown names (like
ads_insights_age_and_gender) cannot be used as custom dimensionsNot all dimension combinations are valid according to Facebook’s API. Refer to Facebook’s Marketing API documentation for valid dimension combinations
Examples¶
# Predefined breakdown: Basic insights without breakdowns
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'facebook_insights:ads_insights' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.insights_basic'
# Predefined breakdown: Age and gender with default fields
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'facebook_insights:ads_insights_age_and_gender' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.insights_demographics'
# Predefined breakdown: Country with custom fields
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'facebook_insights:ads_insights_country:campaign_id,adset_id,ad_id,impressions,clicks,spend,reach,cpm,ctr' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.insights_by_country'
# Predefined breakdown: Platform and device with default fields
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'facebook_insights:ads_insights_platform_and_device' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.insights_platform_device'
# Custom dimensions: Age and gender with custom fields (fields required)
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'facebook_insights:age,gender:campaign_id,adset_id,ad_id,impressions,clicks,spend' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.insights_custom_dimensions'
# Campaign level with custom dimensions and fields
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'facebook_insights:campaign,age,gender:campaign_id,adset_id,ad_id,impressions,clicks,spend,reach' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.campaign_insights_demographics'
# Ad level with geographic dimensions
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'facebook_insights:ad,country,age:campaign_id,adset_id,ad_id,clicks,impressions,spend' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.ad_insights_geographic'
# Account level insights only (no additional dimensions, fields required)
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'facebook_insights:account:campaign_id,adset_id,ad_id,impressions,clicks,spend,reach' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.account_level_insights'
# Adset level with single dimension
omniload ingest \
--source-uri 'facebookads://?access_token=easdyh&account_id=1234' \
--source-table 'facebook_insights:adset,gender:campaign_id,adset_id,ad_id,spend' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.adset_gender_insights'
Facebook Insights with Multiple Accounts¶
Use facebook_insights_with_account_ids to fetch insights from multiple accounts in a single request. The account IDs are specified in the table name.
Format¶
facebook_insights_with_account_ids:account_id1,account_id2
facebook_insights_with_account_ids:account_id1,account_id2:breakdown_type
facebook_insights_with_account_ids:account_id1,account_id2:breakdown_type:field1,field2
Examples¶
# Basic insights from multiple accounts
omniload ingest \
--source-uri 'facebookads://?access_token=your_token' \
--source-table 'facebook_insights_with_account_ids:1234567890,9876543210' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.multi_account_insights' \
--interval-start 2024-12-01 \
--interval-end 2024-12-31
# Multiple accounts with predefined breakdown
omniload ingest \
--source-uri 'facebookads://?access_token=your_token' \
--source-table 'facebook_insights_with_account_ids:1234567890,9876543210:ads_insights_age_and_gender' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.multi_account_demographics' \
--interval-start 2024-12-01 \
--interval-end 2024-12-31
# Multiple accounts with breakdown and custom fields
omniload ingest \
--source-uri 'facebookads://?access_token=your_token' \
--source-table 'facebook_insights_with_account_ids:1234567890,9876543210:ads_insights_country:impressions,clicks,spend' \
--dest-uri 'duckdb:///facebook.duckdb' \
--dest-table 'dest.multi_account_by_country' \
--interval-start 2024-12-01 \
--interval-end 2024-12-31
[!NOTE] When using
facebook_insights_with_account_ids, theaccount_idparameter in the URI is ignored. Account IDs must be provided in the table name.