---
id: agencias/resultado-meta-por-objetivo
industry: Marketing agencies
usage: widely used
effort: low
grain: Ad x day
---

# Meta Ads results by objective

The cost per result of each campaign measured by its real objective, without double-counting leads and matching Ads Manager.

## Executive summary

**For:** Agencies that report paid media results to their clients.

**What it solves**

- The CPL and cost per result in the report match Ads Manager.
- Each campaign is evaluated by the objective it was created for, not by a single lead yardstick.
- "Campaign with no results" alerts stop firing for no reason on reach, conversation or sales campaigns.

**Why it matters:** A wrong CPL leads to the wrong budget reallocation and, when the client compares it with the CRM, to a loss of trust in the agency. It is also the foundation for every other media case: the funnel down to the sale, alerts and automated reports.

**Business questions it answers**

- How much did each result cost, by client and by campaign, this month?
- Which campaigns are delivering the objective they were created for?
- Which client has a cost per result above target?
- How many leads came from Meta forms and how many from the website?
- Does it make sense to move budget from reach to conversion for this client?

**What you need**

- Meta Ads connected to Nekt (one account per client, if multi-client)
- The objective agreed with each client: lead, conversation, purchase or reach

**What you get**

- A table by ad and day with result, result type and cost
- A client dashboard with a cost per result that matches Ads Manager
- An AI agent that answers media questions with the right rule
- Alerts only for campaigns that have a conversion to measure

## Detailed

### The problem

For each ad and day, Meta returns a list of actions with dozens of types, and the same lead shows up in several of them. Anyone who adds up the types that look like leads reports a CPL at half the real value. Anyone who expects leads from a reach campaign or a WhatsApp conversation campaign fires false alerts about campaigns with no results.

### Business rules

1. **The result comes from the ad set objective.** Read the ad set's optimization_goal and, for website conversions, the optimized event (promoted_object.custom_event_type). Never classify by campaign name or by the presence of some action. (Avoid: Classifying the campaign by its name or by the first action that appears.)
2. **Use the objective to result map.** Each objective has a single action_type that counts as the result. Reach objectives have no conversion to measure. (Avoid: Using lead as a universal result.)
3. **A lead is the lead action_type, and only that.** lead is already the sum of onsite_conversion.lead_grouped (instant form) and offsite_conversion.fb_pixel_lead (website pixel). Use those two to break down by origin, never add all three. (Avoid: lead + lead_grouped + fb_pixel_lead)
4. **Ignore the mirror types.** offsite_search_add_meta_leads, offsite_content_view_add_meta_leads, offsite_complete_registration_add_meta_leads and onsite_web_lead repeat leads already counted. (Avoid: Filtering action_types that contain lead.)
5. **A click is the link_click from the actions.** The insight's native clicks column includes clicks outside the link and does not match Ads Manager. (Avoid: Using the insight's clicks column.)
6. **Each campaign is judged by its own objective.** A reach campaign has no CPL; a conversation campaign has a cost per conversation. Say reach objective, no conversion to measure, never zero leads. (Avoid: A zero leads alert on a reach campaign.)
7. **A conversation started is not a sale.** It is the top of the WhatsApp funnel. Qualification comes from the CRM or the customer service tool. (Avoid: Reporting a conversation as a qualified lead.)
8. **A time on page pixel is not a lead.** If the Lead event fires based on time on page (for example, 20 seconds), the valid result is the form's custom conversion. This is a per-client rule. (Avoid: Trusting the pixel's standard Lead event.)
9. **Declare the tax on the budget.** If the agency passes on tax on the Meta budget (for example, 12.15% or 13.83%), state whether the cost includes tax or not and keep the criterion consistent. (Avoid: Mixing cost with and without tax across reports.)

### What counts as a result

Based on the ad set's optimization objective.

- **LEAD_GENERATION, QUALITY_LEAD** → Lead (`lead`)
- **OFFSITE_CONVERSIONS · LEAD** → Lead (`lead`)
- **OFFSITE_CONVERSIONS · PURCHASE** → Purchase (`offsite_conversion.fb_pixel_purchase`)
- **OFFSITE_CONVERSIONS · COMPLETE_REGISTRATION** → Registration (`offsite_conversion.fb_pixel_complete_registration`)
- **OFFSITE_CONVERSIONS · custom** → Custom conversion (`offsite_conversion.custom.<id>`)
- **VALUE** → Purchase, with revenue (`offsite_conversion.fb_pixel_purchase`)
- **CONVERSATIONS, REPLIES** → Conversation started (`onsite_conversion.messaging_conversation_started_7d`)
- **LINK_CLICKS** → Link click (`link_click`)
- **LANDING_PAGE_VIEWS** → Landing page view (`landing_page_view`)
- **THRUPLAY** → ThruPlay (`video_thruplay_watched_actions`)
- **REACH, IMPRESSIONS, VISIT_INSTAGRAM_PROFILE** → No conversion to measure (`no action_type`)

### Definitions

| Metric | Definition |
|---|---|
| Spend | sum of spend |
| Result | value of the action_type for the ad set's objective |
| Cost per result | sum of spend / sum of results in the period, dividing only once |
| Form leads | onsite_conversion.lead_grouped |
| Website leads | offsite_conversion.fb_pixel_lead |
| CPL | spend of lead objective campaigns / lead |
| Cost per conversation | spend of conversation objective campaigns / conversations started |

### Pitfalls

- **CPL at half the real value.** Adding lead, lead_grouped and fb_pixel_lead counts each lead twice. How to avoid: Use only lead for the total.
- **Duplicated ad set.** The ad sets table stores more than one version per id and the join duplicates spend. How to avoid: Keep the most recent version of each ad set.
- **Average of daily costs.** Averaging each day's cost distorts the monthly number. How to avoid: Sum spend and results and divide once.
- **False dropped-to-zero alert.** Delivery, travel and e-commerce clients were measured by leads and triggered alerts every day. How to avoid: Evaluate by the campaign's objective.
- **The conversion changes everything.** In a real account, CPA went from R$ 8.39 (lead, purchase and conversation added together) to R$ 90.57 (only the objective's conversion). How to avoid: Agree on the result with the client before the first report.
- **Lead Ads without UTMs.** The instant form does not go through the website, so the lead reaches the CRM without UTMs. How to avoid: Join to the CRM by form id or ad id.

Validated on real data: In Nekt's own Meta Ads account, on every day with leads, lead was exactly lead_grouped + fb_pixel_lead. Adding all three would double the leads.

### Acceptance test

- [ ] For one client and one closed month, each campaign's result and cost per result match the Results column in Ads Manager (difference below 1%).
- [ ] Total leads equal form leads + website leads.
- [ ] No reach, conversation or traffic campaign shows a CPL.
- [ ] The final table has one row per ad and day.

### Context document

```text
Meta Ads results
- Each campaign's result is the one for the ad set's optimization objective (optimization_goal and promoted_object.custom_event_type). Never classify by campaign name.
- Lead = action_type 'lead'. Do not add it to onsite_conversion.lead_grouped or offsite_conversion.fb_pixel_lead; those are its components (form and website).
- Ignore action_types *_add_meta_leads and onsite_web_lead.
- Click = action_type 'link_click'.
- Reach, impressions and profile visit campaigns have no conversion: evaluate them by CPM, reach and frequency.
- Conversation campaigns: result = onsite_conversion.messaging_conversation_started_7d. A conversation is not a sale.
- Cost per result = sum of spend / sum of results in the period.
- If a client's objective is not confirmed, say "objective not confirmed" instead of assuming lead.
Per-client exceptions:
- <client>: the valid result is the custom conversion <name>; the pixel's Lead fires based on time on page and does not count.
- <client>: cost reported including <x>% tax on the budget.
```

### Variations

- **Multi-client:** One Meta Ads source per client, unified with the account to client mapping.
- **Revenue and ROAS:** For VALUE or purchase objectives, use action_values for the same action_type.
- **LinkedIn and Google:** LinkedIn: MAX_LEAD counts form leads, without view-through. Google: the primary conversion of the conversion action.
