Guide

How to track the Facebook ad ID in your CRM

Track the Facebook ad ID in your CRM: put {{ad.id}} in the URL, keep it in hidden form fields, store it on the lead, then join it to spend for CPL per ad.

By Simone Manto, founder of DropCPL · Published

To track the Facebook ad ID in your CRM, make the click carry it and the form keep it:

  1. Add {{ad.id}}, {{adset.id}} and {{campaign.id}} to the ad’s URL parameters.
  2. Copy them from the URL into hidden form fields on the landing page.
  3. Save them on the lead in your CRM.
  4. Join leads to spend by Ad ID: CPL per ad.

Store IDs, not names. A name is a label anyone can edit; the ID is the key Meta uses when it reports spend per ad.

Step 1: put the Facebook ad ID in the URL

In Ads Manager, open the ad, scroll to Tracking and paste this into the URL parameters field:

ad_id={{ad.id}}&adset_id={{adset.id}}&campaign_id={{campaign.id}}

All three are among Meta’s documented dynamic URL parameters. Meta fills them in with the IDs of the ad, ad set and campaign, so each click arrives carrying its own. The Facebook URL parameters guide has the full list and a UTM version of the template.

If your form tool or CRM already captures UTM fields, reuse them instead of adding new ones:

utm_source={{site_source_name}}&utm_medium=paid&utm_campaign={{campaign.id}}&utm_term={{adset.id}}&utm_content={{ad.id}}

utm_content={{ad.id}} puts the ad ID into a field your stack already stores. Whatever keys you pick, use the same ones on every ad.

Step 2: copy the IDs into hidden form fields

The parameters sit in the address bar; the form has to pick them up. Add one hidden input per value and a few lines of script that fill them from the query string:

<form method="post" action="/lead">
  <!-- visible fields: name, email, phone -->
  <input type="hidden" name="ad_id">
  <input type="hidden" name="adset_id">
  <input type="hidden" name="campaign_id">
  <input type="hidden" name="fbclid">
  <button type="submit">Send</button>
</form>

<script>
  const keys = ['ad_id', 'adset_id', 'campaign_id', 'fbclid'];
  const params = new URLSearchParams(window.location.search);
  for (const key of keys) {
    const fromUrl = params.get(key);
    if (fromUrl) sessionStorage.setItem(key, fromUrl);
    const value = fromUrl || sessionStorage.getItem(key);
    const field = document.querySelector(`input[name="${key}"]`);
    if (field && value) field.value = value;
  }
</script>

A few things that decide whether this works:

  • The script comes after the form in the HTML, so the inputs exist when it looks for them.
  • Name the inputs exactly like the CRM properties they map to.
  • sessionStorage keeps the values when a multi-step form moves to a second URL in the same tab. It ends when the tab closes, so it won’t rescue a return visit days later.
  • A form embedded in an iframe from another domain can’t read the landing page’s address bar. Pass the values into the iframe’s URL, or use your form tool’s own hidden-field option.
  • fbclid isn’t needed for the join, but keep it for the Conversions API; the fbclid glossary entry explains what it can and can’t do.

Step 3: store the Facebook ad ID in your CRM

  • Create custom fields for ad ID, ad set ID and campaign ID, as text. An 18-digit ID stored as a number gets rounded in some systems, and a rounded ID matches nothing; the ad_id glossary entry explains why.
  • Map each hidden input to its field in your form tool, integration or webhook.
  • Decide what a repeat submission does. My rule: the ad that created the lead keeps it. Later submissions from the same contact are logged as activity, with their own ad ID, and never overwrite the original.
  • If leads reach your CRM by webhook, check that the IDs are in the payload. DropCPL’s lead routing sends the Meta ad ID, the landing page, the click ID and the UTM values with every lead.

Step 4: join leads to spend by ad ID

Spend comes from Ads Manager, per ad:

  1. Open the Ads tab in Ads Manager.
  2. Go to Columns, Customize columns and add Ad ID, which Meta lists in the Settings category of columns. Keep Amount spent.
  3. Set the same date range as your CRM export, then export the table as a CSV.
  4. In a spreadsheet, count the CRM leads per ad ID (a COUNTIF on the ID column does it) and divide each ad’s spend by its count.

Example, one week:

Ad ID (example)SpendLeads in CRMCPL
…0033€80040€20.00
…0044€65013€50.00
…0055€3000no leads yet
no ad IDnone9unattributed

The last row is your tracking loss. Nine leads arrived without an ad ID, so something between the click and the CRM dropped the parameters; the last section lists where to look. Watch that row over time. If it grows, fix it before you trust any CPL above it.

Two cautions from measuring CPL by creative: spend and leads must cover the same window, and the current day’s spend isn’t final. Ads Manager’s own cost per result per ad uses Meta’s attributed count, so it rarely matches this table; Meta attribution settings explains the gap.

DropCPL does this join for you, because the ads are created from DropCPL and the ad_id is logged at the click. The click lands on the tracking domain that serves your landing page, spend per ad is synced from the Meta Ads API, and each lead reaches your CRM by webhook with its ad_id, landing page and click ID attached. Start free →

What about Instant Forms leads?

Lead ads with Instant Forms skip the landing page: the lead is created on Meta’s side, with the ad already attached. According to Meta’s documentation on retrieving leads:

  • The leadgen webhook Meta sends when a lead is created includes ad_id, together with leadgen_id, form_id, page_id and created_time.
  • Reading ad-specific fields such as ad_id or campaign_id through the API requires a token from someone who can advertise on the ad account and on the Facebook Page, plus permissions such as ads_management.
  • When entries come without ad IDs, Meta lists three causes: the lead came from organic reach (is_organic shows 1), it was submitted from an ad preview, or whoever pulled the leads lacks advertiser privileges on the ad account.

So a CRM integration that reads leads through Meta’s API can store the ad ID without any URL parameter. Check that yours maps it to a field, and step 4 works the same way. Whether Instant Forms or a landing page suits your offer is a separate decision, covered in Facebook lead ads vs landing page.

Where the Facebook ad ID gets lost

Multi-step forms

Step two loads on a new URL without the query string, and the values are gone unless step one saved them. The sessionStorage lines in the snippet cover this; so does carrying the parameters into the step-two URL. A form that reloads after a validation error has the same problem.

Redirects

A redirect between the ad and the landing page (a link shortener, an http-to-https rule, a consent or geo redirect) can rebuild the URL without its query string. Check what arrives after a real click on a live ad, not what you typed in Ads Manager.

Ad names instead of IDs

Meta fills name parameters with the name the ad had when it was first published. Rename the ad later and your CRM keeps the old name while the spend export shows the new one, so the join fails on every renamed ad.

Duplicated ads

A duplicate is a new ad. Meta’s API reference for ad copies describes copying as creating an ad, returned with its own copied_ad_id. With {{ad.id}} in the template, each copy reports its own ID and joins to its own spend. With a hard-coded value, say utm_content=video_a typed by hand, ten duplicates of a winning ad all arrive as video_a, and copies that keep the original name merge the same way if you join on names.

Return visits without the parameters

Meta’s help article on URL parameters says they apply to the visit that came from the ad: someone who leaves and comes back later on their own arrives without them. sessionStorage won’t help, because it ends with the tab. Only an identifier stored on the first visit, in a first-party cookie, ties the return to the original click, and the tracking identifiers entry explains why it should be set server-side.

FAQ

How do I find a Facebook ad ID?+

In Ads Manager, open the Ads tab, then Columns, Customize columns, and add Ad ID from the Settings category. For leads, the reliable source is the click itself: put {{ad.id}} in the URL parameters so every visit carries the ID of the ad that was clicked.

Do Facebook lead ads include the ad ID?+

Yes. The leadgen webhook Meta sends for each new lead includes ad_id, and the API returns ad fields such as ad_id and campaign_id when the token belongs to someone who can advertise on the ad account and the Facebook Page, with the right permissions. Leads from organic reach, from an ad preview, or pulled without advertiser privileges can come without an ad ID.

Should I store the ad name or the ad ID in my CRM?+

The ID. Meta fills name parameters with the name the ad had when it was first published, so a later rename splits your CRM data from the spend export, and duplicates often share a name. Keep the name as a readable label if you like, but join on the ID.

Why are the ad ID fields empty in my CRM?+

Usually the parameters were in the URL but never reached the form: a redirect dropped the query string, a multi-step form lost it, or the person came back later without it. Click a live ad, check the URL that loads, and check the hidden fields before submitting a test lead.

Can I see CPL per ad in Ads Manager?+

Ads Manager shows cost per result for each ad, but the result count is Meta's attributed number, not your CRM's. For the CPL of leads you actually received, join CRM leads by ad ID with spend exported by Ad ID.

Ready to find out what
converts, for real?

Free to start.

Start free →