PricingOpen the demo
Meta Ads logo

Meta Ads integration

Meta reports its own grades. We mark the exam.

Meta's attribution is optimised to make Meta look good — same-day view-through, in-platform conversion windows, and revenue counted before a single cost is deducted. Kepra pulls the same spend data down to ad-id level and judges it against orders we matched ourselves.

What we pull

  • Spend, impressions and clicks at ad-id level
  • Campaign → ad set → ad structure
  • Creative metadata and delivery status
  • Account-level budgets and bid strategy

OAuth · incremental sync

Profit per ad, after COGS

Every Meta ad gets a profit number with product costs, refunds and fees removed — the figure that decides whether the ad deserves more money.

Your attribution, not Meta's

First-party click-id capture matches orders back deterministically, so a purchase Meta claims and Google also claims lands on exactly one of them.

LTV instead of first order

Cohorts follow the customers an ad brought in. A campaign that fills the feed with one-time buyers stops looking like a winner by week six.

What we catch on Meta Ads

The leaks this platform is best at hiding.

01The one-time-buyer machine

A prospecting campaign hits ROAS 2.8 on first orders — and 71% of those customers never return. On lifetime value it's below break-even. It is the pattern platform ROAS is least able to see, which is why it is the one we built the profit engine around.

02Retargeting taking credit for organic

Retargeting ads shown to people already heading to checkout report gorgeous ROAS while adding almost nothing incrementally. We flag when a campaign's audience overlaps your existing traffic.

03Lookalikes cannibalising each other

Multiple lookalike ad sets bidding on overlapping audiences push your own CPMs up. The spend rises, the profit doesn't — visible immediately in the Profit Tree.

04Creative fatigue burning budget

Frequency climbs, CTR sags, cost per profitable order drifts. We watch the profit curve rather than the vanity curve, so fatigue surfaces before the month closes.

The loop, on Meta Ads
Meta Ads logo

Meta Ads → Kepra

K
  1. Reading

    spend + matched orders

  2. Deciding

    profit after COGS and LTV

  3. Your call

    nothing moves until you say so

  4. Pushing

    executed over MCP, logged

Verdict: Prospecting – Interests spends DKK 9,220/mo. Meta reports ROAS 2.8; matched against real orders it returned DKK 6,450, and 71% of those buyers never came back. After COGS it is DKK 5,200/mo underwater.

Pause campaignawaiting your approval
Show your working

The maths behind every verdict.

Every verdict on this page comes out of four lines of arithmetic. None of it is proprietary — it is the maths Meta's reported ROAS leaves out, and you can run it on your own numbers in a spreadsheet tonight.

Break-even ROAS

At a 62% margin: 1 ÷ 0.62 = 1.61. Any ad below 1.61 reported ROAS loses money on the first order — before you have paid for a single return.

1 ÷ gross margin

LTV ROAS

Meta reports ROAS 2.8 on DKK 9,220 of spend — DKK 25,800 of claimed revenue. Deterministic matching finds DKK 6,450 of it actually originated here; the rest was claimed inside a view-through window, or claimed by Google too. With 71% of those buyers never returning, six months of the campaign returns about DKK 49,800 against DKK 55,300 of spend: LTV ROAS 0.9.

(first-order revenue + repeat revenue over N days) ÷ spend

Marginal ROAS

Going from DKK 10,000 to DKK 14,000/day earned DKK 6,400 more revenue. Marginal ROAS on that increment is 1.6 — just below the 1.61 break-even, so the last DKK 4,000 a day bought volume and no profit. Average ROAS would still have read 2.6, and told you nothing about the next krone.

Δ revenue ÷ Δ spend, between two budget levels

Incremental share

If a holdout group that never saw the retargeting ad still converts at 80% of the exposed group's rate, only 20% of that campaign's reported conversions were caused by it.

1 − (conversions in holdout ÷ conversions in exposed)

Meta reports the numerator and never the denominator. That is the whole disagreement.

Do this without us

Four checks you can run in Meta Ads today.

You do not need Kepra to find out whether you have this problem. Twenty minutes in Ads Manager will tell you, and if the answer is reassuring you should keep your money.

  1. 1

    In Ads Manager, set the attribution window to 7-day click and untick 1-day view.

    Look at: Compare reported purchases before and after.

    If the number drops by more than about a fifth, that share of your reported performance was view-through — people who saw an ad and would likely have bought regardless.

  2. 2

    Add the “Purchases – first-time customers” breakdown to your top prospecting campaign.

    Look at: Divide first-time purchases by total purchases.

    Above 85% means the campaign is buying strangers who never come back. That is fine only if the first order alone clears your break-even ROAS.

  3. 3

    Export the last 90 days at ad level, then divide total spend by total orders.

    Look at: Compare that cost per order against gross profit per order, not revenue per order.

    If cost per order exceeds gross profit per order, the campaign is buying revenue with your margin. Reported ROAS will still look healthy.

  4. 4

    Check frequency on any ad set older than three weeks.

    Look at: Frequency above roughly 3.0 within a 7-day window, with CTR falling.

    You are paying more each week to reach the same people. The profit curve turns down well before the ROAS curve does.

Where this runs out: What this cannot tell you is which orders actually came from which ad once a customer touches three channels before buying, or what those customers are worth in month six. That is the part that needs matched order data — and it is the part we built.

What the agent may do in Meta Ads

Meta is exposed to the agent as typed MCP tools. It can propose pausing the bleeding campaign or moving budget to the winner — and nothing executes until you approve it.

mcp · meta-ads
  • meta.campaign.pause(campaign_id)approval required
  • meta.adset.set_budget(adset_id, amount)approval required
  • meta.adset.set_bid_cap(adset_id, cap)approval required
  • meta.audience.create(spec)approval required
Why does Kepra show lower ROAS than Meta Ads Manager?

Because we deduct what it cost to fulfil the order and only count conversions we can match to a click. Meta's number is revenue under its own attribution; ours is money you keep.

Does this replace the Meta pixel or Conversions API?

No. Keep them — they optimise delivery. Kepra is the independent scoreboard, plus the layer that acts on what the scoreboard says.

Can the AI change my campaigns on its own?

Only if you approve each change. Auto-push ships off, and every executed action is logged and revertible.

Kepra needs all four to tell the whole truth