Facebook Ads model

Ad performance daily

Daily delivery and purchase results per ad, the Ads Manager "Ads" tab by day.

Grain
date_day x account_id x ad_id
Built from
  1. 8
    Raw tables
  2. 8
    Staging
  3. 1
    Core
  4. 1
    Analytics
Reads from Facebook Ads
accountadad_roas_insightad_roas_insight_action_valuesad_roas_insight_actionsad_setad_set_attributioncampaign
Ships as
Weld and dbt SQL, open source on GitHub
core.facebook_ads.ad_performance_daily
1-- core.facebook_ads.ad_performance_daily
2-- Daily delivery and purchase results per ad, the Ads Manager "Ads" tab by day.
3--
4-- Grain: date_day x account_id x ad_id. Currency: the ad account's.
5-- Depends on: staging.facebook_ads.ad_roas_insight, .ad_roas_insight_actions,
6-- .ad_roas_insight_action_values, .ad, .ad_set, .campaign, .account,
7-- .ad_set_attribution
8--
9-- The leading columns follow the cross-channel ad contract shared with the other
10-- paid ads templates in this repo, so the models can be stacked with UNION ALL.
11--
12-- clicks is link clicks (Ads Manager "Link clicks"), the closest match to a
13-- click on a search or display ad; Meta's "Clicks (all)", which also counts
14-- likes, comments and profile clicks, is in clicks_all.
15--
16-- conversions is purchases: Meta's omni_purchase action (the Ads Manager
17-- "Purchases" column, de-duplicated across website, app and offline), falling
18-- back to the purchase action where omni_purchase is absent. Never both, so a
19-- purchase is not counted twice. conversion_value is the matching purchase value.
20-- Both use the attribution windows the connector requests (7-day click and
21-- 1-day view by default) and are dated on the day the purchase happened, not the
22-- day of the ad impression. For other conversion events, see
23-- conversions_by_action_type_daily.
24
25WITH purchases AS (
26    -- One row per ad and day: pick the purchase action types out of the
27    -- one-row-per-action-type tables before joining, so the join cannot fan out.
28    SELECT
29        date_day,
30        account_id,
31        ad_id,
32        COALESCE(SUM(IF(action_type = 'omni_purchase', action_count, NULL)),
33                 SUM(IF(action_type = 'purchase', action_count, NULL)))          AS purchases
34    FROM {{staging.facebook_ads.ad_roas_insight_actions}}
35    WHERE action_type IN ('omni_purchase', 'purchase')
36    GROUP BY 1, 2, 3
37),
38
39purchase_values AS (
40    SELECT

This model and the 9 it depends on. Deploy them together; refs like {{staging.…}} resolve to the matching folders in Weld, and the dbt view uses source() and ref().

Notes

How it counts. And where it stops.

The leading columns follow the cross-channel ad contract shared with the other paid ads templates in this repo, so the models can be stacked with UNION ALL. clicks is link clicks (Ads Manager "Link clicks"), the closest match to a click on a search or display ad; Meta's "Clicks (all)", which also counts likes, comments and profile clicks, is in clicks_all. conversions is purchases: Meta's omni_purchase action (the Ads Manager "Purchases" column, de-duplicated across website, app and offline), falling back to the purchase action where omni_purchase is absent. Never both, so a purchase is not counted twice. conversion_value is the matching purchase value. Both use the attribution windows the connector requests (7-day click and 1-day view by default) and are dated on the day the purchase happened, not the day of the ad impression. For other conversion events, see conversions_by_action_type_daily.

Raw tables it reads

  • raw.facebook_ads.account
  • raw.facebook_ads.ad
  • raw.facebook_ads.ad_roas_insight
  • raw.facebook_ads.ad_roas_insight_action_values
  • raw.facebook_ads.ad_roas_insight_actions
  • raw.facebook_ads.ad_set
  • raw.facebook_ads.ad_set_attribution
  • raw.facebook_ads.campaign

Put Facebook Ads in front
of your agents.

Connect Facebook Ads, deploy the models, and ask questions in Claude, Cursor or ChatGPT. Free for 14 days, no credit card.