Campaign Performance Trend
Weekly engaged known contacts and campaign MQLs · source-normalized and deduplicated
Audience Journey
Distinct identified people, then qualified downstream stages
Engaged Audience by Channel
Unique known contacts, assigned to a first qualifying engagement source
Visibility vs. Response
Different units shown separately — not summed
Leadership Interpretation
What the executive page is designed to answer
Event impact · who was in the room from Dallas cohort analysis
Turnout, the accounts and ARR in the room, and the pipeline that was already open at those accounts on the day · one row per AI Pillar event
| Event | Registered | Attended | External show rate | Accounts in the room | ARR in the room | Open pipeline in the room illustrative | Pipeline created ≤90 days after illustrative |
|---|---|---|---|---|---|---|---|
| Illuminate Dallas 2026 | 936 | 570 | 54% | 140 of 202 | $302M | $48.6M · 212 opps | $6.1M · 37 opps |
| Next AI Pillar events | Populate automatically once each event campaign sits under an AI Pillar sub-theme in Salesforce | ||||||
Unique Identifiable Reach by Channel
De-duplicated contact IDs; excludes anonymous pageviews and impressions
Share of Voice Trend
Bentley AI-term mentions / Bentley plus monitored competitor mentions
Web Discoverability
GA4 AI Hub and AI blog activity (not unique people)
LLM Discoverability
AI mentions, citations and referrals as distinct components
PR / Analyst Context
Visibility diagnostics only; never part of unique-person reach
Content Engagement Actions by Channel
Interaction count, including anonymous social interactions · separate from known contact counts
Qualified Engagement Over Time
Content actions versus distinct engaged contacts (two different measures)
Content / Experience Performance
Illustrative assets and event themes across linked touchpoints
Email & Event Diagnostics
Operational metrics feeding the journey without inflating the executive reach count
Reached → Engaged → Progressed → MQL
Contact-level sequence; MQLs deduplicated across Salesforce AI Pillar subcampaigns
Progression by First Engagement Source
Progressed contacts / engaged contacts in each source
Journey Conversion
Conversion rates are people-based, not counts of repeated activities
Required Business Rules
Proposed data-layer logic applied in this demo
Qualified Intent by Request Type
Distinct people in the headline KPI; requests can appear in multiple diagnostic types
Influenced Pipeline by Opportunity Stage
One opportunity counted once after an eligible prior campaign touch
Example Salesforce Opportunities
Synthetic opportunity rows and campaign-influence links; dollar values are not actual pipeline
eStore / Completed Commercial Results
Separate from requests, campaign influence, and pipeline
Who showed up, and who didn’t from Dallas cohort analysis
Registered = attended + no-show · Bentley staff reported apart from external
| Cohort | Registered | Attended | No-show | Show rate | Share of no-shows |
|---|---|---|---|---|---|
| External | 754 | 408 | 346 | 54% | 95% |
| Bentley | 182 | 162 | 20 | 89% | 5% |
| Total | 936 | 570 | 366 | 61% | 100% |
What drives no-shows? from Dallas cohort analysis
External registrants · show rate by registrant profile (average 54%; orange = below average)
| Registrant profile | Registered | Show rate |
|---|---|---|
| Based outside the US | 72 | |
| Registered with a personal email | 82 | |
| Account unknown or <$50K ARR | 273 | |
| Small segment account | 59 | |
| Only person from their company | 173 | |
| Lead (new prospect), not Contact | 283 | |
| Company sent a team of 2–3 | 184 | |
| Account with $250K–$1M ARR | 169 |
Which kinds of accounts were in the room from Dallas cohort analysis
Industry derived from account name · 97% US · 75% Enterprise · 69% existing customer contacts
| Industry | Registered | Attended | Show rate |
|---|---|---|---|
| Engineering & design firms | 466 | 271 | |
| Construction & contractors | 52 | 32 | |
| Technology, industrial & other | 67 | 31 | |
| Utilities & energy | 30 | 20 | |
| Government & public agencies | 26 | 14 | |
| Rail, transit & ports | 16 | 12 | |
| Education | 15 | 9 | |
| Unknown (personal email) | 82 | 19 |
Account turnout and ARR from Dallas cohort analysis
Accounts grouped by how many of their registrants came · ARR on the ultimate-parent account
| Account turnout | Accounts | Attended | ARR (est.) | Share of ARR |
|---|---|---|---|---|
| Full: everyone came | 83 | 153 of 153 | $89.8M | 25% |
| Partial: some no-shows | 57 | 189 of 338 | $212.0M | 60% |
| None: no one came | 62 | 0 of 78 | $51.7M | 15% |
| Total registered | 202 | 342 of 569 | $353.6M | 100% |
Open pipeline in the room, by stage illustrative
Opportunities created before the event date and still open on it · attending accounts vs registered no-show accounts
Top accounts in the room
Ranked by attendees · ARR from the Dallas analysis; open pipeline illustrative until the query runs
| Account | Industry | ARR (est.) | Attended / reg. | Show rate | Open pipeline illustrative |
|---|---|---|---|---|---|
| Kiewit | Construction | $4.6M | 10 / 11 | 91% | $3.2M |
| Lina T. Ramey & Assoc. | Engineering | $348K | 10 / 14 | 71% | $0.4M |
| BNSF Railway | Rail & transit | $267K | 10 / 10 | 100% | $0.9M |
| Ferrovial | Construction | $1.0M | 9 / 20 | 45% | $1.6M |
| Black & Veatch | Engineering | $7.9M | 8 / 12 | 67% | $4.1M |
| AtkinsRéalis | Engineering | $11.0M | 8 / 15 | 53% | $5.3M |
| STV | Engineering | $3.9M | 7 / 11 | 64% | $1.2M |
| Jacobs | Engineering | $18.2M | 7 / 13 | 54% | $6.8M |
| AECOM | Engineering | $20.1M | 6 / 15 | 40% | $7.4M |
| Burns & McDonnell | Engineering | $7.4M | 6 / 8 | 75% | $2.2M |
How the event numbers are defined
Same rules for every AI Pillar event so results compare
01 · Source Systems
Raw observations and transactional records
02 · Snowflake PRESENTATION
Verified objects the model reads today
03 · Power BI Semantic Model
Native SQL per table · campaign tree · guardrails in DAX
04 · Executive / Diagnostic Views
Measures in Power BI, consistent across pages
Data flow · source to report
What feeds each Power BI table, and where it lands in Snowflake first
Campaign hierarchy · how everything rolls up to the AI Pillar
Salesforce campaigns are the spine; every other system attaches to a child campaign
How each system attaches to the hierarchy
The join key that ties each source to a child campaign, and the KPIs it feeds
| System | How it attaches | Key | Feeds | Status |
|---|---|---|---|---|
| Salesforce events (Cvent / Splash upload) | Child campaign under a sub-theme; attendees uploaded as members with status | Campaign Parent ID → sub-theme | Members, Reach, Engaged, New/Existing, MQLs, Pipeline | Needs set-up |
| Marketo email programs | Mailing IDs listed in {{EmailIds}} today; target: program synced to an SFDC child campaign | Mailing ID (today) → SFDC Campaign ID (target) | Email, Reach, Email CTO/CTR, AAG reach | Ready |
| Marketo gated content / forms | Form campaign as SFDC child; Responded flag set on fill | SFDC Campaign ID | Content form fills, TLE, Engaged, Progression | Needs set-up |
| ON24 webinars | Event IDs in {{WebinarEventIds}}; target: ON24 event linked to an SFDC child campaign | Event ID → SFDC Campaign ID | Webinar registrations / attendance, TLE | Ready · none scheduled |
| GA4 web | Page-path rules for AI Hub / AI blog; utm_campaign carries the child campaign key on campaign links | Path rules · utm_campaign | LLM & web visibility, AI referrals, top content, TLE | Ready |
| Paid media | Row in the paid campaign Microsoft List: Campaign Alignment = “Pillar - AI” + SFDC Child Campaign ID | Platform campaign ID → list → SFDC child | Paid impressions / clicks / conversions (diagnostic) | Ready |
| Opportunities | Primary campaign in the tree, or account member touch before creation; later Salesforce Campaign Influence | Primary campaign key · ultimate account key | Influenced pipeline & opportunities | Needs definition |
| PR / SOV, analyst briefings, social, PIKC, ClickUp (events, UG, CAB) | No feed yet — placeholder measures show “—” | — | Share of voice, PR impressions, social, video, PIKC, activity counts | Manual entry |
Connection & parameters
Power Query parameters used by every query (shown as {{Name}} in the SQL)
| Parameter | Current value | Purpose |
|---|---|---|
SnowflakeServer | vkelqpo-bird_prod.snowflakecomputing.com | Snowflake account |
SnowflakeWarehouse | REPORTING_WH__XS | Warehouse used by the refresh |
StartDate | 2024-07-01 | Earliest date loaded (gives prior-period history) |
PillarRootId | 701Wj00001uusRZIAY | AI Pillar root campaign (reference) |
SubThemeIds | '701Wj00001x4BSLIA2', '701Wj00001x5JE3IAM', '701Wj00001x4pG1IAI', '701Wj00001x5VofIAE' | The four sub-themes the tree starts from |
EmailIds | 31004,31138 | Marketo mailing IDs in scope |
WebinarEventIds | 0 | ON24 event IDs in scope (none scheduled yet) |
PaidAlignment | Pillar - AI | Campaign Alignment value in the paid campaign list |
Model, refresh & access
How the published model behaves
| Storage | Import for every Snowflake table; DirectQuery for Paid Campaigns (composite model) |
| Relationships | All facts → Date[Date] (single direction) · Members → Campaign Tree on campaign ID · Paid Daily → Paid Campaigns on platform campaign ID |
| Calculated tables | Date (1 Jul 2024 → today), Metric Catalog, Funnel Stage, Team Headline, TLE Type |
| Report filter | Campaign window: Date ≥ 1 Oct 2025 (earlier data kept for prior-period comparisons) |
| Refresh | Daily ~7 AM CT on the published dataset in My workspace |
| Credentials | Snowflake: OAuth2 (Maurice) · Paid Media updated: OAuth2 — both signed in on the dataset settings page |
| Native queries | Desktop asks to approve each new SQL text once; the service runs them without prompting |
| Project files | Power BI project (.pbip): report in PBIR folders, model in TMDL — diffable and versionable |
Power BI tables · grain, source and logic
One line per model table; full SQL below
| Table | Grain | Snowflake objects | Logic | Status |
|---|---|---|---|---|
| Campaign Tree | One row per campaign in the AI Pillar tree (sub-themes + every child below them) | MART.DIM_CAMPAIGN | Recursive CTE from the four sub-theme IDs down the Campaign Parent ID chain (max 6 levels). Tags each node with its sub-theme, level and Sub-theme / Tactic. | Ready · 0 rows today |
| Members | One row per campaign member on any campaign in the tree | MART.FCT_CAMPAIGN_MEMBERSHIP · DIM_CAMPAIGN_MEMBER_STATUS · DIM_CONTACT · DIM_LEAD · FCT_LEAD | Same tree CTE, joined to membership. Responded = 1 when Has Campaign Member Responded is TRUE/YES/1. New vs Existing = person created between 1 day before and 14 days after the member record. Region from contact or lead. | Ready · 0 rows today |
| Pipeline | One row per opportunity influenced by the pillar | MART.FCT_OPPORTUNITY · DIM_OPPORTUNITY · FCT_CAMPAIGN_MEMBERSHIP · DIM_CAMPAIGN | Influenced when (a) the opportunity’s primary campaign is in the tree, or (b) any member of the same ultimate account joined a tree campaign on or before the opportunity create date. Records which rule fired and the touch campaign. | Ready · 0 rows today |
| One row per recipient × email | EDW.MARKETO_ACTIVITIES_EMAIL_SEND / DELIVERED / OPEN / CLICK · MARKETO_EMAILS · MARKETO_LEADS | Mailings filtered to {{EmailIds}}. Delivered / opened / clicked flags per recipient (bot clicks excluded). Segment = Internal enablement when the email address is @bentley.com, otherwise External market. | Ready | |
| Webinar | One row per registrant × webinar | EDW.EVENT · REGISTRANT · ATTENDEE (ON24) | Events filtered to {{WebinarEventIds}} (current rows only). Attended when the registrant email appears in ATTENDEE; minutes = live + archive. | Ready · none scheduled |
| Web Daily | One row per day × page × source × campaign | MART_MARKETING.DAILY_GA4_PAGES_REPORT | AI pages = path contains infrastructure-ai, /category/ai/, or a /news/ or /blog/ path with -ai- / artificial-intelligence. Page group = AI Hub vs AI Blog & News. AI referral = session source ChatGPT/OpenAI, Gemini, Perplexity, Copilot or Claude. | Ready |
| Paid Daily | One row per day × platform campaign | EDW.MEDIA_GOOGLE / BING / LINKEDIN / FB_AD_ANALYTICS · MEDIA_LOOKUPS | All four platforms unioned from {{StartDate}}. The AI Pillar filter is applied in the measures through the live Paid Campaigns list (Campaign Alignment = “Pillar - AI”), joined on platform campaign ID. | Ready |
| Paid Campaigns | One row per paid platform campaign (DirectQuery) | Power BI semantic model “Paid Media updated” (Marketing Analytics Dashboards) · table Paid Media Campaign Metadata | Read live with the viewer’s sign-in — no copy, no XMLA needed. Columns: CAMPAIGNID, Platform, Campaign Name, Campaign Alignment, SFDC Child Campaign ID, Funnel Stage, Region. | Live (DirectQuery) |
Campaign Tree Ready · 0 rows today
- Grain
- One row per campaign in the AI Pillar tree (sub-themes + every child below them)
- Reads
- MART.DIM_CAMPAIGN
- Logic
- Recursive CTE from the four sub-theme IDs down the Campaign Parent ID chain (max 6 levels). Tags each node with its sub-theme, level and Sub-theme / Tactic.
Members Ready · 0 rows today
- Grain
- One row per campaign member on any campaign in the tree
- Reads
- MART.FCT_CAMPAIGN_MEMBERSHIP · DIM_CAMPAIGN_MEMBER_STATUS · DIM_CONTACT · DIM_LEAD · FCT_LEAD
- Logic
- Same tree CTE, joined to membership. Responded = 1 when Has Campaign Member Responded is TRUE/YES/1. New vs Existing = person created between 1 day before and 14 days after the member record. Region from contact or lead.
Pipeline Ready · 0 rows today
- Grain
- One row per opportunity influenced by the pillar
- Reads
- MART.FCT_OPPORTUNITY · DIM_OPPORTUNITY · FCT_CAMPAIGN_MEMBERSHIP · DIM_CAMPAIGN
- Logic
- Influenced when (a) the opportunity’s primary campaign is in the tree, or (b) any member of the same ultimate account joined a tree campaign on or before the opportunity create date. Records which rule fired and the touch campaign.
Email Ready
- Grain
- One row per recipient × email
- Reads
- EDW.MARKETO_ACTIVITIES_EMAIL_SEND / DELIVERED / OPEN / CLICK · MARKETO_EMAILS · MARKETO_LEADS
- Logic
- Mailings filtered to {{EmailIds}}. Delivered / opened / clicked flags per recipient (bot clicks excluded). Segment = Internal enablement when the email address is @bentley.com, otherwise External market.
Webinar Ready · none scheduled
- Grain
- One row per registrant × webinar
- Reads
- EDW.EVENT · REGISTRANT · ATTENDEE (ON24)
- Logic
- Events filtered to {{WebinarEventIds}} (current rows only). Attended when the registrant email appears in ATTENDEE; minutes = live + archive.
Web Daily Ready
- Grain
- One row per day × page × source × campaign
- Reads
- MART_MARKETING.DAILY_GA4_PAGES_REPORT
- Logic
- AI pages = path contains infrastructure-ai, /category/ai/, or a /news/ or /blog/ path with -ai- / artificial-intelligence. Page group = AI Hub vs AI Blog & News. AI referral = session source ChatGPT/OpenAI, Gemini, Perplexity, Copilot or Claude.
Paid Daily Ready
- Grain
- One row per day × platform campaign
- Reads
- EDW.MEDIA_GOOGLE / BING / LINKEDIN / FB_AD_ANALYTICS · MEDIA_LOOKUPS
- Logic
- All four platforms unioned from {{StartDate}}. The AI Pillar filter is applied in the measures through the live Paid Campaigns list (Campaign Alignment = “Pillar - AI”), joined on platform campaign ID.
Paid Campaigns Live (DirectQuery)
- Source
- Power BI semantic model Paid Media updated in Marketing Analytics Dashboards (owner: Nischal)
- Mode
- DirectQuery (composite model) — the AI Pillar model holds no copy
- Upstream list
- SharePoint Microsoft List Paid Media Campaign Metadata (site 2020MarketingPlans) — open list. Media owners keep Campaign Alignment and SFDC Child Campaign ID filled in there; that ID is what places a paid campaign in the AI Pillar campaign tree.
- Why not SQL
- The list is maintained in a Microsoft List behind Nischal’s model; that workspace is not on Premium capacity, so an import refresh through XMLA fails in the service. DirectQuery works on Pro.
Event impact · open pipeline in the room Needs set-up
- Grain
- Event × account turnout × opportunity stage
- Reads
- MART.DIM_CAMPAIGN · FCT_CAMPAIGN_MEMBERSHIP · DIM_CAMPAIGN_MEMBER_STATUS · FCT_OPPORTUNITY · DIM_OPPORTUNITY
- Logic
- Accounts = ultimate parents of the event’s members (attended if any member attended). Open in the room = created before the event date and not closed by it. Stage/amount are current values until opportunity history lands in Snowflake.