Meta Ads Attribution Checker for CRM Payments
Check how many CRM payments you can trace to a Facebook or Instagram ad. Open an Ads Manager CSV and a CRM payments CSV, choose the ad ID columns, and see which payment rows match. Both files are processed in your browser.
Open the free meta Ads attribution checker ↓
On this page4 sections
Check which payment rows match a Meta ad
Meta Ads attribution checker
Use your own CSVs or try the demo with 100 fictional payments. Each file can be up to 8 MB, 20,000 data rows and 512 columns. For large exports, keep the columns needed for the check.
Files stay in your browser. Usage analytics records completed checks by input type (demo, lab or your CSVs).
[{"id":"exact-ids","title":"Exact 18-digit ad IDs","issue":"Three payment rows carry IDs that appear in the ad export.","fix":"Use this pair as the baseline before testing a changed export.","tip":"","adsFile":"exact-ids-ads.csv","paymentsFile":"exact-ids-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":3,"missing":0,"unmatched":0,"invalid":0},"adsCsv":"Ad ID,Ad name\r\n120000000000000101,Fictional ad A\r\n120000000000000102,Fictional ad B\r\n","paymentsCsv":"Payment reference,utm_content\r\nTEST-PAY-001,120000000000000101\r\nTEST-PAY-002,120000000000000102\r\nTEST-PAY-003,120000000000000101\r\n"},{"id":"missing-ad-ids","title":"The ad ID is missing from the payment","issue":"Two payment rows have an empty ID field. Their references keep the rows visible.","fix":"Follow a test lead from the landing page or form to the CRM and then to the payment export.","tip":"","adsFile":"missing-ad-ids-ads.csv","paymentsFile":"missing-ad-ids-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":1,"missing":2,"unmatched":0,"invalid":0},"adsCsv":"Ad ID,Ad name\r\n120000000000000101,Fictional ad A\r\n120000000000000102,Fictional ad B\r\n","paymentsCsv":"Payment reference,utm_content\r\nTEST-PAY-001,120000000000000101\r\nTEST-PAY-002,\r\nTEST-PAY-003,\" \"\r\n"},{"id":"outside-export","title":"The ad ID is outside this export","issue":"Two numeric IDs are present on payments but absent from the selected ad export.","fix":"Check the ad account and export dates. Include the ads that could have generated the original leads.","tip":"A missing match alone cannot tell you whether the account, date range or stored ID is wrong.","adsFile":"outside-export-ads.csv","paymentsFile":"outside-export-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":1,"missing":0,"unmatched":2,"invalid":0},"adsCsv":"Ad ID,Ad name\r\n120000000000000101,Fictional ad A\r\n","paymentsCsv":"Payment reference,utm_content\r\nTEST-PAY-001,120000000000000101\r\nTEST-PAY-002,120000000000000102\r\nTEST-PAY-003,120000000000000103\r\n"},{"id":"scientific-notation","title":"An ID became scientific notation","issue":"One payment ID is written as an exponent instead of the original digits.","fix":"Export the original ID again as text. Expanding a rounded exponent cannot recover the missing digits.","tip":"","adsFile":"scientific-notation-ads.csv","paymentsFile":"scientific-notation-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":1,"missing":0,"unmatched":1,"invalid":1},"adsCsv":"Ad ID,Ad name\r\n120000000000000101,Fictional ad A\r\n120000000000000102,Fictional ad B\r\n","paymentsCsv":"Payment reference,utm_content\r\nTEST-PAY-001,120000000000000101\r\nTEST-PAY-002,1.200000000000001E+17\r\n"},{"id":"rounded-id","title":"An ID was rounded but still looks numeric","issue":"One payment contains a different 18-digit value after a simulated spreadsheet conversion.","fix":"Compare the exact digits with the original export. Import ID columns as text before editing.","tip":"The checker can flag nonnumeric IDs. A rounded all-digit ID looks valid and appears as no matching ad.","adsFile":"rounded-id-ads.csv","paymentsFile":"rounded-id-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":1,"missing":0,"unmatched":1,"invalid":0},"adsCsv":"Ad ID,Ad name\r\n120000000000000101,Fictional ad A\r\n120000000000000102,Fictional ad B\r\n","paymentsCsv":"Payment reference,utm_content\r\nTEST-PAY-001,120000000000000101\r\nTEST-PAY-002,120000000000000100\r\n"},{"id":"unexpanded-parameter","title":"A tracking parameter was never expanded","issue":"One payment stores the literal tag {{ad.id}}.","fix":"Check the live ad link and the field passed into your CRM. Save the resolved numeric ID.","tip":"","adsFile":"unexpanded-parameter-ads.csv","paymentsFile":"unexpanded-parameter-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":1,"missing":0,"unmatched":1,"invalid":1},"adsCsv":"Ad ID,Ad name\r\n120000000000000101,Fictional ad A\r\n120000000000000102,Fictional ad B\r\n","paymentsCsv":"Payment reference,utm_content\r\nTEST-PAY-001,120000000000000101\r\nTEST-PAY-002,{{ad.id}}\r\n"},{"id":"installments","title":"One lead makes three payments","issue":"Three fictional installments carry the same ad ID.","fix":"Keep one row per payment when checking payment coverage. Use a separate customer identifier to count customers.","tip":"The result is three matched payment rows. It does not establish three customers or calculate revenue.","adsFile":"installments-ads.csv","paymentsFile":"installments-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":3,"missing":0,"unmatched":0,"invalid":0},"adsCsv":"Ad ID,Ad name\r\n120000000000000101,Fictional ad A\r\n120000000000000102,Fictional ad B\r\n","paymentsCsv":"Payment reference,utm_content,Lead reference\r\nTEST-PAY-001,120000000000000101,TEST-LEAD-001\r\nTEST-PAY-002,120000000000000101,TEST-LEAD-001\r\nTEST-PAY-003,120000000000000101,TEST-LEAD-001\r\n"},{"id":"duplicate-ads","title":"The ad export contains duplicate rows","issue":"The same ad appears twice in the ad export. Each payment still counts once.","fix":"Remove duplicated export rows when building a spend report. ID matching alone does not reconcile duplicated spend.","tip":"","adsFile":"duplicate-ads-ads.csv","paymentsFile":"duplicate-ads-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":2,"missing":0,"unmatched":1,"invalid":0},"adsCsv":"Ad ID,Ad name\r\n120000000000000101,Fictional ad A\r\n120000000000000101,Fictional ad A duplicate\r\n120000000000000102,Fictional ad B\r\n","paymentsCsv":"Payment reference,utm_content\r\nTEST-PAY-001,120000000000000101\r\nTEST-PAY-002,120000000000000102\r\nTEST-PAY-003,120000000000000103\r\n"},{"id":"semicolon-export","title":"The CSV uses semicolons","issue":"Both files use a semicolon separator, and an ad name contains a comma.","fix":"Keep the separator and quoting produced by the CSV exporter. Commas in a name do not identify the separator.","tip":"","adsFile":"semicolon-export-ads.csv","paymentsFile":"semicolon-export-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":2,"missing":1,"unmatched":0,"invalid":0},"adsCsv":"Ad ID;Ad name\r\n120000000000000101;Fictional ad, variation A\r\n120000000000000102;Fictional ad B\r\n","paymentsCsv":"Payment reference;utm_content\r\nTEST-PAY-001;120000000000000101\r\nTEST-PAY-002;120000000000000102\r\nTEST-PAY-003;\r\n"},{"id":"utf8-bom-and-quotes","title":"The export contains UTF-8, tabs and quoted text","issue":"The files have a UTF-8 byte order mark, tab separators and quoted text with a line break.","fix":"Export as UTF-8 and keep quoted cells intact. A line break inside a quoted cell stays in one record.","tip":"","adsFile":"utf8-bom-and-quotes-ads.csv","paymentsFile":"utf8-bom-and-quotes-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":2,"missing":1,"unmatched":0,"invalid":0},"adsCsv":"Ad ID\tAd name\r\n120000000000000101\tFictional ad – wersja A\r\n120000000000000102\t\"Fictional ad \"\"B\"\"\nSecond line\"\r\n","paymentsCsv":"Payment reference\tutm_content\r\nTEST-PAY-001\t120000000000000101\r\nTEST-PAY-002\t120000000000000102\r\nTEST-PAY-003\t\"\"\r\n"},{"id":"choose-id-column","title":"Two columns look like ad IDs","issue":"The payment export contains both Meta Ad ID and utm_content. This fixture stores the original ID in utm_content.","fix":"Confirm which field contains the original ad ID. For this test choose Column 2 in the payments file.","tip":"The lab selects the documented column. Choosing Column 1 would instead produce two unmatched rows.","adsFile":"choose-id-column-ads.csv","paymentsFile":"choose-id-column-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":2,"missing":0,"unmatched":0,"invalid":0},"adsCsv":"Ad ID,Ad name\r\n120000000000000101,Fictional ad A\r\n120000000000000102,Fictional ad B\r\n","paymentsCsv":"Meta Ad ID,utm_content,Payment reference\r\n120000000000000103,120000000000000101,TEST-PAY-001\r\n120000000000000103,120000000000000102,TEST-PAY-002\r\n"},{"id":"invalid-meta-export","title":"The ad export itself contains an invalid ID","issue":"The Meta Ads ID column contains scientific notation. A reliable comparison cannot start.","fix":"Export the ad IDs again as text. Then load the corrected file and run the check.","tip":"","adsFile":"invalid-meta-export-ads.csv","paymentsFile":"invalid-meta-export-payments.csv","adsColumn":0,"paymentsColumn":1,"expected":{"matched":0,"missing":0,"unmatched":0,"invalid":0,"error":"The selected Meta Ads column contains a blank or invalid ID. Choose the Ad ID column or export it as plain text."},"adsCsv":"Ad ID,Ad name\r\n1.200000000000001E+17,Fictional ad A\r\n","paymentsCsv":"Payment reference,utm_content\r\nTEST-PAY-001,120000000000000101\r\n"}]
Use the checks below to fix missing IDs or widen the date range in your Meta export.
Prepare two CSV exports
- Ads Manager. Export from the Ads tab with an Ad ID column. Use the ad account and dates that could have produced the leads behind the payments. Include older ads when leads take time to pay.
- CRM or payment system. Use one row per actual payment. Include a payment reference so rows with a blank ad ID are still visible, and a column containing the ad ID saved when the lead came in. A CRM field holding
utm_contentworks when its value is the numeric ad ID. - Keep IDs as text. Export CSV in UTF-8 with a header row. Comma, semicolon and tab separators are supported. If a spreadsheet shortened a long ID or turned it into scientific notation, export it again from the source.
To start saving IDs on new leads, follow the guide to carrying ad IDs into your CRM.
Interpret and fix the results
| Result | Demo count | What to check |
|---|---|---|
| Matched by ad ID | 72 | The same ID appears in both files. Use the match to prepare your revenue report. |
| Missing ad ID | 18 | Check where the landing page or lead form passes the original ID to the CRM. |
| No matching ad | 10 | Check the selected column, account and export dates. Re-export IDs that were shortened by a spreadsheet. |
The demo uses 100 fictional payment rows. The checker counts rows, so two installments count as two payments. Its match rate measures how many rows contain an ID found in your Meta export. For revenue and cost by cohort, use the free report template or see how the connected report works.
For captured Excel and Google Sheets exports, exact-string results and false-match analysis, read the 36-ID spreadsheet integrity study.
Want to reproduce a specific problem? Open the attribution test lab for 12 fictional CSV pairs, expected results and checks for missing, rounded or unexpanded IDs.
Questions
Can I use campaign names or campaign IDs?
Choose the numeric ad ID from both files. Campaign names and IDs belong to a different reporting level.
Why can an ad ID be present but still have no match?
The ad may be outside your Ads Manager export, or the ID may have been shortened, replaced with an ad name or stored as an unexpanded tracking tag. Check the account, dates and the original CSV.
Does this checker upload my CSV files?
Both CSVs are read and compared locally in your browser. The completion event records whether you used demo data, lab fixtures or your own files.
Related guides
- Meta Ads Attribution Test Lab — 12 Reproducible CSV Scenarios
- Free Meta Ads CRM revenue report template for Google Sheets
- Which Facebook ads bring paying customers: matching CRM sales to ads
- How to track Meta Ads revenue in HubSpot: from test lead to payment
- How long do leads take to pay? A case study of 1,598 CRM payments