CRM stages and sales, page tracking data
Window per destination, identifiers and event_id
Events and audiences ready to send
Meta Conversions API and Google Ads
What it solves
- Platforms start optimizing for qualified leads, meetings or sales, not for filled forms.
- Each event arrives once, within the deadline the platform accepts.
- Disqualified leads and current customers leave prospecting through exclusion audiences.
Business questions it answers
Ask your agent these questions once the case is live.
What you need
- Each client's CRM connected to Nekt, with the date of each stage
- The stages that become events and each one's value, agreed with the client
- Meta Conversions and Google Ads destinations set up per account, with the conversion action created on the platform
What you get
- One table per destination and per client with the current window's events
- Normalized identifiers: email, phone, fbc and external ID
- Customer and disqualified audiences kept up to date
- A monitor that compares the table produced with the send made
Where to activate
Qualification, meeting and sale events, several times a day when volume calls for it.
Won sales with a valid email, once a day.
Customers and disqualified leads as lookalike and exclusion audiences.
One pipeline per client and per destination. The logic repeats; the care is in the window, deduplication and checking that the send was counted. The detailed view has the business rules, the pitfalls and the acceptance test. Or send everything straight to your agent with the Nekt MCP.
The same sale must reach Meta and Google in different formats and deadlines. Meta rejects events older than 7 days or dated in the future; Google accepts up to 90 days from the click but rejects empty identifiers. The destination resends the whole table at every run, so whoever does not control the window sends the same event several times. And a successful run in Nekt does not prove the platform matched the sale to a click.
How it is usually done, and the rule
Each row is a mistake that already happened in practice.
Meta and Google require different columns, windows and identifiers for the same sale. Build one transformation per client and per destination, already in the destination's format. Never a single table serving both.
The Meta Conversions API rejects event_time older than 7 days: use a 6-day or 132-hour window, never exactly 7. Google Ads Click Conversions accepts up to 90 days after the click (63 days for enhanced conversions for leads): real pipelines use 55 days to leave a margin. An event dated in the future makes Meta reject the batch: cap event_time at the run time.
The destination resends the whole table at every run. So the table carries only the current window's events, tied to the run time, with disjoint windows when it runs several times a day. Each update goes out once and the daily count matches Events Manager.
Build event_id from the lead or deal ID and the event name (<id>-<event>). If the same deal comes back in a later window, it goes out with the same event_id and Meta's deduplication absorbs it. On Google, use order_id on the same principle.
Email lowercase, no spaces and with an @. Phone digits only, with 55 in front when it has 10 or 11 digits, valid with 12 or 13. First name letters only. fbc in the format fb.1.<timestamp in ms>.<fbclid> when the landing URL has an fbclid; fbp, IP and user agent from the page when they exist. A row with no email and no phone does not go out.
Each client defines which stages become events (qualified lead, meeting booked, proposal, sale) and each one's value. A sale carries the won deal value; an intermediate stage may carry an agreed fixed value. Events from the CRM alone go as system_generated (offline); events with page data go as website, the only kind that gets a match quality score.
If the pixel, an automation or another tool already sends an event (calendar booking, form lead), the CRM pipeline does not send the same fact under another name. Use a flag on the lead to avoid firing again and keep event names distinct between pipelines.
Send the conversions that may have a click on the destination: when the client asks, only deals with a Meta source go to the Conversions API. Never send imported bases, test contacts or emails from the client's or the agency's team.
Check both sides: the transformation ran, the destination is active and ran after it. A recent transformation with an inactive destination is a signal never delivered. And even when the send is accepted, without a matching click in the window the sale does not become a conversion: the sign that it works is the offline conversion action showing conversions in the ad account.
Customer audiences (Customer Match, Custom Audiences) and exclusion audiences (disqualified, current customers, another business line's base) use the same email and phone normalization, with no test or team contacts, deduplicated by phone. Disqualified is the disqualification stage or a loss for profile reasons, agreed with the client.
Limits of each destination
What each platform accepts and what the pipeline does to fit.
Definitions
Pitfalls that already happened
The transformation ran every day and the table was right, but the destination had been inactive for weeks. Google kept optimizing for leads.
A monitor comparing the table produced with the send made.
One event dated a few minutes in the future made Meta reject the whole batch.
Cap event_time at the run time.
The cumulative table was resent at every run and the same lead showed up several times a day.
Disjoint window tied to the run time.
Complete and partial form responses had IDs from different spaces; deduplicating by response ID removed nothing and the lead went out twice.
Deduplicate by normalized phone within a 7-day window.
The sale conversion in the ad account was data sent by the agency itself and was presented to the client as platform measurement.
Label offline conversions as sent by the agency.
Months of successful sends and no offline conversion attributed, because the emails did not match clicks within the window.
Track the offline action in the account, not the send status.
Acceptance test
The case is done when every item passes.
- No event_time in the Meta table is older than 7 days or in the future at send time.
- Across 7 consecutive runs, each event_id appears in a single window, and the daily count in Events Manager equals the table's.
- Every row has a normalized email or phone, and every phone has 12 or 13 digits starting with 55.
- For each active conversion table there is an active destination that ran after it within the last 24 hours.
- In a closed month, sales sent to Google show up in the account's offline action, or the difference is explained.
Agent package
Paste into Claude, ChatGPT or any client with the Nekt MCP connected.
CRM conversions to the platforms - Each client has one table per destination. Conversion tables are outputs for Meta and Google, not a source for results analysis. - Meta Conversions API: event_time up to 7 days (6-day or 132-hour window) and never in the future. Deduplication by event_id within 48 hours. - Google Ads Click Conversions: up to 90 days from the click (63 for enhanced conversions for leads); rows with no identifier are rejected. - event_id = record ID + event name. The table holds only the current window. - CRM-only events go as system_generated (offline, no match quality score). Events with page data go as website. - A table produced is not a send made: confirm an active destination and a run after the transformation. A send accepted is not a counted conversion: check the offline action in the account. - A sale conversion showing on the platform was sent by the agency. Do not present it as independent measurement. Per-client exceptions: - <client>: events <LeadQualificado>, <ReuniaoMarcada> and <Purchase>; LeadQualificado = lead still open <n> days after creation. - <client>: only deals with a Meta source go to the Conversions API. - <client>: fixed value of <x> for stage <stage> on Google.
Build the "CRM conversions back to Meta and Google" case in my Nekt workspace following the rules at https://academy.nekt.com/en/industrias/agencias/conversoes-offline-crm.md. 1) Find the source tables and confirm the columns the rules use. 2) Create a transformation at the stated grain applying every rule. 3) Run the acceptance test and show me the result of each item. 4) Create the case's context document in the workspace, leaving my clients' exceptions open for me to fill in.
Variations
Partial and complete go out under the same event name, the partial event_id gets its own suffix and deduplication is by phone.
Agencies with dozens of clinics or franchises generate one table and one destination per form, from a template.
An approved sale on an info product platform sent per transaction, with a validated email.