roitrack Start tracking

Self-hosted tracking for Facebook buyers

Every ad account in one table.

Keep the data from all your Facebook campaigns in one place. Cost, revenue, profit and ROI per campaign, pulled in daily and kept on a server Facebook can't switch off.

14 days, no card, set up over Telegram.

Six Facebook ad accounts across three business managers, read through one ads_read token into a single row of totals in US dollars. Six ad accounts sit under three business managers. BM 1 holds a personal account billed in rupees, INR 79,200, worth 900 dollars, and a BM-owned account billed in dollars, USD 5,410. BM 2 holds an agency account, USD 1,275, and a rented account billed in reais, BRL 8,262, worth 1,530 dollars. BM 3 holds a personal account, INR 52,800, worth 600 dollars, and a rented account, BRL 4,590, worth 850 dollars. All six feed a single ads_read token, whichever business manager they sit under. That token reads 6 of 6 accounts, needs no ad account IDs, and pulls spend daily. Rates are pinned per day at 88.0000 rupees and 5.4000 reais to the dollar. The six converted amounts sum to one row of totals: cost 10,565 dollars, revenue 13,946 dollars, profit 3,381 dollars, ROI plus 32.0 percent. BM 1 personalINR 79,200$900 bm-ownedUSD 5,410$5,410 BM 2 agencyUSD 1,275$1,275 rentedBRL 8,262$1,530 BM 3 personalINR 52,800$600 rentedBRL 4,590$850 one ads_read token accounts read6 of 6 ad account IDsnone spend pulleddaily INR → USD88.0000 BRL → USD5.4000 cost$10,565 revenue$13,946 profit$3,381 ROI+32.0% Six Facebook ad accounts across three business managers, read through one ads_read token into a single row of totals in US dollars. Six ad accounts sit under three business managers. BM 1 holds a personal account billed in rupees, INR 79,200, worth 900 dollars, and a BM-owned account billed in dollars, USD 5,410. BM 2 holds an agency account, USD 1,275, and a rented account billed in reais, BRL 8,262, worth 1,530 dollars. BM 3 holds a personal account, INR 52,800, worth 600 dollars, and a rented account, BRL 4,590, worth 850 dollars. All six feed a single ads_read token, whichever business manager they sit under. That token reads 6 of 6 accounts, needs no ad account IDs, and pulls spend daily. Rates are pinned per day at 88.0000 rupees and 5.4000 reais to the dollar. The six converted amounts sum to one row of totals: cost 10,565 dollars, revenue 13,946 dollars, profit 3,381 dollars, ROI plus 32.0 percent. BM 1 personalINR 79,200$900 bm-ownedUSD 5,410$5,410 BM 2 agencyUSD 1,275$1,275 rentedBRL 8,262$1,530 BM 3 personalINR 52,800$600 rentedBRL 4,590$850 one ads_read token INR → USD88.0000 BRL → USD5.4000 cost$10,565 revenue$13,946 profit$3,381 ROI+32.0% accounts read6 of 6 ad account IDsnone spend pulleddaily
Six accounts, three business managers, three currencies, one token. The converted amounts sum to the cost shown.
Roitrack campaigns table: 22 campaigns across Facebook, TikTok, Push and Native, with clicks, conversions, cost, revenue, profit and ROI per campaign.
Every campaign, every account, every source. Totals at the bottom, profit and ROI per row.

Spend is in eight places. Revenue is in three.

Ads Manager knows what you paid. The network knows what it paid you. Every evening you move both into a spreadsheet, in three currencies, and hope you typed it right.

The accounts multiply

Personal, BM, agency, rented. Connecting them one at a time is a job, and half won't be yours next month.

The pixel learns the wrong thing

Facebook optimises toward a click on your lander, because the sale lands on the network's server hours later.

Then an account dies

Access goes and every number with it. The campaign you were about to scale is now a thing you half remember.

Teach the pixel what actually paid.

Send Facebook button clicks and it finds people who click buttons. Send it the deposits and approved leads your network paid for, and it goes looking for those.

The conversion loop in five steps: a Facebook click goes out, and the real payout comes back to the pixel that aimed it. A closed loop in five steps. A Facebook ad carries the pixel id in ?pixel= on its URL. The click hits your tracker, which stores fbclid to match on, and the visitor goes to a lander, where an optional fbp snippet can run, or straight to the offer. The conversion happens on the network, hours to weeks later. roitrack maps it to a Facebook event, per campaign, taking the campaign conversion or any of event1 to event10, with write-only tokens. The pixel receives a real payout rather than a button click, and the return leg carries that back to the ad, which aims better next time. Facebook ad?pixel= on the ad URL Click hits the tracker fbclid stored to match lander or direct to offer fbp optional on lander Conversion happenson the network hours to weeks later Mapped to a Facebook event per campaign: conversion or event1–event10 Pixel gets a real payouttokens are write-only the next ad aims better The conversion loop in five steps: a Facebook click goes out, and the real payout comes back to the pixel that aimed it. A closed loop in five steps. A Facebook ad carries the pixel id in ?pixel= on its URL. The click hits your tracker, which stores fbclid to match on, and the visitor goes to a lander, where an optional fbp snippet can run, or straight to the offer. The conversion happens on the network, hours to weeks later. roitrack maps it to a Facebook event, per campaign, taking the campaign conversion or any of event1 to event10, with write-only tokens. The pixel receives a real payout rather than a button click, and the return leg carries that back to the ad, which aims better next time. Facebook ad?pixel= on the ad URL Click hits the tracker fbclid stored to match lander or direct to offer fbp optional on lander Conversion happenson the network hours to weeks later Mapped to a Facebook event per campaign: conversion or event1–event10 Pixel gets a real payouttokens are write-only the next ad aims better The pixel is trained on the payout, not on the click.
The pixel is trained on the payout, not on the click.

Why this compounds

Every conversion you send is a training example. Thin or delayed signal keeps a campaign in learning, spending budget on exploration. Real payouts get it out sooner and into the pockets that convert, so cost per paid conversion falls as volume climbs.

What you configure

Event mapping is per campaign: your conversion, or any of event1event10, to any standard Facebook event. The pixel comes from ?pixel= on the ad URL. Matching uses fbclid automatically, fbp optional via a lander snippet.

Signal, not magic. A working offer scales further and a bad one fails faster.

Accounts die. The numbers don't.

Spend is pulled daily into your own database. Lose the BM and you still have the spend, clicks, conversions and profit, per campaign, for as long as you keep the server.

On your box, not ours

Roitrack runs on your VPS. We can't see your campaigns or your numbers. Only the licence check talks to us.

Domains you can burn

Unlimited domains on one price. SSL issues itself, DNS goes in over the Cloudflare API, bulk-add when a batch dies.

Backups you control

To disk or R2, on your schedule. Cancel and nothing is deleted, because nothing was ever on our servers.

Two questions that need two reports.

“What did I make today?” and “did last month's traffic ever pay off?” have different answers, and one report can't give you both.

Click-date report grouped by week: the week of 22 June shows 107.8% ROI.
Click date. Revenue credited to the week the traffic arrived.
Conversion-date report for the same campaign and weeks: the week of 22 June shows 3.9% ROI.
Conversion date. Revenue credited to the day the payout landed.

Same campaign, same five weeks, the same 30.1% overall — and week by week the verdicts barely agree. The week of 22 June reads +107.8% on click date and +3.9% on payout date.

Columns that match the vertical.

iGaming counts registrations and first deposits. Nutra counts lander CTR, leads and approvals. Build columns from your own formulas and save them as a preset per vertical.

iGaming campaigns with registrations, cost per registration, first deposits and cost per first deposit columns.
iGaming: regs, cost per reg, FDs, cost per FD, straight through to profit.
Nutra campaigns with lander clicks, lander CTR, leads, approved leads and cost per lead columns.
Nutra: lander clicks, LP CTR, leads, approved, CPL.

Routing, without a flowchart to learn.

Split how you like

Weighted split across offers and landers with a fallback. Fixed or random rotation, sticky per visitor.

Target on what you have

Country, OS and device allow-block lists, plus sub conditions combined with everything else.

Keep junk out of the maths

Bots to a 404, a blank or a safe page. Duplicate clicks deduped so postbacks attribute correctly.

Fresh server to first tracked click, about fifteen minutes.

  1. Point a domain at your VPS.
  2. Grab your install link — licence and domain already baked in.
  3. Paste the one command into a clean Ubuntu 24 server.
  4. Authorise the Facebook token, add a source and an offer, launch.

First time through, budget 30–45 minutes: DNS and your network's postback take most of it. Every domain after that is under two minutes.

Who builds this.

Six years buying traffic. We built Roitrack because self-hosted trackers wanted $130+ a month the moment we needed more than one user and ten domains. We run our own campaigns on it, and support reaches the people who wrote it, not a ticket queue.

It is early. No customer count, no case studies, because there aren't any yet. The trial is issued by hand over Telegram or email for the same reason: we want to hear what's missing from everyone who tries it, and the people who start now decide what gets built next.

One plan, everything included.

$69per month

Typical self-hosted trackers ask $130+ once you pass one user and ten domains. This is the whole price, at any size.

One licence per server. Add a VPS from any provider, roughly $10–15 a month.

  • Unlimited ad accounts and business managers
  • Unlimited domains, users and clicks
  • Facebook spend sync and Conversions API
  • Users, groups and permissions
  • Cloudflare integration and self-serve SSL
  • Cancel any month

The things buyers ask first.

Do I have to connect every ad account one by one?

No. One ads_read token covers the whole portfolio, read per campaign node. No ad account ID, no enumeration, and accounts you add later need no reconnection.

An account got banned. Do I lose its history?

No. Spend is pulled daily into your own database, so everything up to the ban is already on your server. You lose Ads Manager, not your record of what that campaign did.

My accounts bill in different currencies. What do I see?

Each is read in its own currency and converted to USD at a rate pinned to that day. If one can't be priced, Roitrack writes nothing rather than a partial total that looks complete.

How do conversions get back to Facebook?

Through the Conversions API. Your network's postback becomes a Facebook event, mapped per campaign — your conversion or any of event1event10 to any standard event — matched on fbclid. Tokens are write-only.

Does it cloak?

Yes. You can send invalid traffic to a 404, a blank page or a safe page you set, so it stays out of your numbers.

Can you see my campaigns?

No. Campaigns, sources and numbers live on your VPS. The licence check is the only thing that talks to us and it carries no campaign data.

I already run a tracker. What does moving cost?

A couple of minutes per campaign. Any network works through URL templates and macros, so if it fires an S2S postback it works here. Run both in parallel for a week and compare.

What happens if I cancel?

Your data stays on your server. The licence stops validating after a short grace period, so the app stops working until you resubscribe. Nothing is deleted.

Every account, one table, on your server.

Fourteen days, the full version, no card.