Black Friday series

CAPI for Black Friday: Checklist Before Scaling

Key takeaways

  • Accepted event, matched event, attributed sale and confirmed sale are four different things; check each one separately.
  • Only a confirmed sale becomes a Purchase; a stage change, a link sent or "I'll pay" are not a purchase.
  • The event_id must be the same on every resend of the same order and different for every new order; that is how Meta deduplicates.
  • Value and currency travel together, and different currencies are never added up in the report.
  • Reconcile daily: events sent, accepted, rejected and deduplicated against the CRM's orders, before raising the budget.

What does the Conversions API do in a WhatsApp campaign on Black Friday?

The Conversions API (CAPI) sends server-side events to Meta, such as Purchase, with deduplication by event_id when the same event also arrives through the pixel, according to Meta's documentation. In WhatsApp sales there is no pixel in the conversation: the sale only exists for Meta if the CRM sends the event.

That matters because a campaign with a messages objective optimizes for conversations started. Without Purchase coming back, Meta never knows which conversations became sales, and the media buyer decides budget on CPL. With Purchase, Meta receives a sales signal and shows, within the attribution window, sales per campaign. The basics of the Conversions API for WhatsApp sales are covered elsewhere; here the focus is not scaling with a broken send.

Four states that must not be confused:

StateWhat it meansWho confirms itWhat it does NOT prove
Accepted eventMeta received a valid payloadEvents ManagerThat the sale happened
Matched eventMeta linked the event to a userEvents ManagerThat the ad caused the sale
Attributed saleMeta credited the sale to an ad within the windowMeta's reportThat the value is right
Confirmed salePayment approved and recorded in the CRM with value and currencyCRM / financeThat Meta received the event

What is the CAPI checklist before scaling?

The checklist has ten items, and any "no" holds back the budget expansion. Test before the event with Meta's test mechanism, without simulating real purchases in production.

  1. Event source defined: which dataset receives the event and which system sends it. If two tools are sending, one has to stop.
  2. Right trigger: Purchase goes out only when the sale is confirmed in the CRM. A funnel stage change, a payment link sent and "closed on voice note" do not fire Purchase.
  3. Value and currency: numeric value and currency in ISO format (BRL). Without a currency the value is useless; with the wrong currency the ROAS is fiction.
  4. Stable event_id: generated from the order identifier, the same on every resend of the same order, different for a new order.
  5. event_time of the payment: the confirmation time, not the batch send time. A late batch pushes the sale outside the attribution window.
  6. Matching data: the identification fields the channel provides follow the format Meta's documentation requires; without them the event arrives and links to no one.
  7. Deduplication tested: send the same order twice in the test environment and check that Meta counts one.
  8. Controlled resend: a network failure triggers a retry with the same event_id, with a retry limit and a log.
  9. Owner of rejections: one person looks at rejected events every day and knows to stop the send if the payload is wrong.
  10. Reconciliation: events accepted per day match orders confirmed in the CRM per day; a difference above the tolerance (hypothetical: 5%) blocks scaling.

Decision rule: if items 2, 3, 4 or 10 fail, do not scale. The others can be fixed with the validation budget running.

How does deduplication by event_id work in practice?

Meta receives events with the same event_name and the same event_id within an interval and counts only one. That protects against resends after a failure and against the same event arriving through two paths. Hypothetical example:

  1. Order 7781 confirmed at 2:02 pm, R$ 240.00 BRL. The CRM generates event_id "purchase-7781" and sends Purchase.
  2. The network fails and the CRM gets no confirmation. At 2:04 pm it resends the same payload with event_id "purchase-7781". Meta counts one Purchase.
  3. Order 7782 confirmed at 2:10 pm, R$ 240.00 BRL, the same customer buying a second item. event_id "purchase-7782". Meta counts the second Purchase.
  4. The mistake that destroys the report: the CRM generates the event_id from the customer's phone number. Orders 7781 and 7782 get the same event_id, Meta deduplicates, and the report shows R$ 240 instead of R$ 480.
  5. The opposite mistake: the CRM generates the event_id with a timestamp. The 2:04 pm resend gets a new id and Meta counts two Purchases of R$ 240 for one order: inflated ROAS.

The day's reconciliation: CRM with 2 orders (R$ 480); Meta with 2 accepted events (R$ 480). Three events point to an unstable id; one event points to an id collision. A CRM with attribution that sends Purchase with duplicate control, such as RASTRO, takes care of that part; the media buyer still checks the reconciliation.

Which CAPI mistakes show up most on Black Friday?

The most frequent mistakes are about trigger, identity and timing:

  • Turning a funnel stage into Purchase. A lead in "negotiating" has not bought. A Purchase there teaches Meta to look for people who negotiate, not people who pay, and inflates ROAS.
  • Copying an e-commerce payload. A website with a pixel has fields the conversation does not; the event arrives with empty data and matching drops. Build the payload from what the channel provides and declare what is not available.
  • Sending in an overnight batch. The batched event_time throws the sale onto another day and, near the end of the attribution window, outside it. Meta's report and the CRM's stop matching.
  • Adding up currencies. A client selling to Brazil in BRL and abroad in USD needs two ROAS reports. A Purchase in USD added to one in BRL produces a meaningless number.
  • Forgetting cancellations. Article 49 of the CDC (Brazil's Consumer Protection Code) gives a 7-day cooling-off right for purchases made outside the store, including WhatsApp. A cancelled sale is flagged in the CRM and deducted from the report; the Purchase already sent stays as a declared limitation.

The source of truth is the CRM with value and currency, not Events Manager. If what you send is wrong, optimization learns the wrong thing in the most competitive auction of the year; in November, compare cost with the account's own previous November.

What should you measure daily during Black Week to keep CAPI reliable?

Measure events sent, accepted, rejected, deduplicated and reconciled, and cross them with the CRM's attribution coverage. Formulas and ranges:

  • Acceptance rate = accepted events ÷ events sent. Good: close to 100%. Bad: below 95% (hypothetical); investigate the payload the same day.
  • Duplicate rate = deduplicated events ÷ events sent. Good: equal to the rate of resends after failures. Bad: far above it (unstable id) or zero despite resends (colliding id).
  • Reconciliation = accepted events ÷ orders confirmed in the CRM. Good: between 0.95 and 1.05 (hypothetical). Bad: outside that for two days.
  • Attribution coverage = sales with origin ÷ total sales in the CRM. Purchase goes out for every confirmed sale, with or without origin; coverage tells you how much Meta will be able to attribute. Below 70% (hypothetical), Meta's per-campaign report becomes partial and scaling per ad loses its basis.
  • Value difference = revenue from accepted events − revenue confirmed in the CRM, per currency. Good: zero. Bad: any recurring difference.

Compare by cohort (sales from the leads that came in that day), not by cash; the attribution window follows the click, not the payment. The tracking that feeds those sales is in tracking from the ad to WhatsApp, and the budget decision based on them in Meta Ads budget for Black Friday.

How do you present CAPI numbers to the client without promising what does not exist?

Present the four states separately, with coverage alongside, and write down what the channel does not provide. Meta's ROAS and the CRM's ROAS are different readings, not someone's mistake. Suggested structure:

  1. Sales confirmed in the CRM, per currency, with the total and the unattributed on their own line.
  2. Purchase events sent, accepted and deduplicated in the period.
  3. Sales attributed by Meta within the window, per campaign.
  4. The difference between 1 and 3 explained by window, coverage and matching.
  5. Declared limitations: cancellations after the send and entry paths with no origin.

A number that cannot be explained line by line should not be in the report. The full format is in a report that helps the client decide.

Action plan: what to do this week

Use this schedule to validate CAPI before scaling.

WhenActionOwnerDone when
TodayConfirm which system sends Purchase and to which datasetMedia buyerA single tool sending
By FridayFire Purchase only on confirmed sales, with value, currency, and an event_id from the order numberCRM ownerTest payload with value, ISO currency, and the order's event_id
D-14Send the same order twice and a second order from the same customer in the test environmentCRM ownerDeduplication counts 1 event for 2 sends of the same order and 2 events for 2 orders
D-7Name who checks rejected events every day and can stop sendingMedia buyer and clientOwner's name written into the brief
D-7 to D-1Reconcile accepted events with confirmed orders in the CRM, per dayMedia buyerReconciliation between 0.95 and 1.05 (hypothetical) before scaling
Event dayCheck acceptance rate and value difference per currencyMedia buyerAcceptance close to 100% and zero value difference
D+7Mark sales canceled within the cooling-off period in the CRMCustomer serviceCancellations deducted from the report

Frequently asked questions

Sources

Does an event accepted by Meta guarantee the sale was attributed to the ad?

No. Acceptance means the payload was valid. Attribution requires Meta to find the user (matching) and the sale to fall within the click's attribution window. A confirmed sale is yet another thing: only the CRM and finance confirm it. Check the four states separately.

Should I send Purchase when the lead says they will pay?

No. Purchase only for confirmed payment, with value and currency. Sending it earlier teaches Meta to look for people who promise, not people who pay, and inflates ROAS. If you want an intermediate signal, use a custom event for qualified lead, separate from Purchase.

What happens if I resend the same order twice?

If the event_id is the same, Meta deduplicates and counts one Purchase. If the event_id changes on every send (for example, with a timestamp), Meta counts two and the ROAS is inflated. Test the resend in the test environment before Black Friday and check the count.

How do I test CAPI without generating fake purchases?

Use the test events mechanism in Meta's Events Manager, with an order flagged as a test in the CRM. Check value, currency, event_id, event_time and deduplication. Then flag or delete the test order so it does not enter the report.