"ROI 120%" on a screenshot in a chat is one of the most misleading numbers in affiliate marketing. Behind it there may be hold that has not been approved yet, spend entered for half a day, or five leads you cannot conclude anything from. Let's look at how to calculate ROI and profit so that the number can be trusted.
The ROI formula
ROI (return on investment) shows what percentage of profit each invested dollar brought in:
ROI = (revenue − spend) / spend × 100%
Profit is simply the difference:
profit = revenue − spend
Example. Say you spent 500 $ on ads, and the affiliate network approved payouts of 650 $.
- profit = 650 − 500 = 150 $;
- ROI = 150 / 500 × 100% = 30%.
Every dollar came back and brought another 30 cents.
| Revenue | Spend | Profit | ROI |
|---|---|---|---|
| 650 $ | 500 $ | 150 $ | 30% |
| 500 $ | 500 $ | 0 $ | 0% |
| 300 $ | 500 $ | −200 $ | −40% |
| 1,000 $ | 500 $ | 500 $ | 100% |
An ROI of 100% means doubling your money, not "getting back what you put in". Zero is the break-even point.
ROI vs ROAS
Do not confuse ROI with ROAS (return on ad spend):
ROAS = revenue / spend × 100%
In the example above ROAS = 650 / 500 × 100% = 130%, while ROI = 30%. E-commerce tends to talk about ROAS, affiliate marketing about ROI. All the other metrics with formulas are collected in affiliate marketing metrics: ROI, ROAS, EPC, CR.
What counts as revenue
This is where the subtleties begin. Revenue in affiliate marketing means payouts from the affiliate network for approved conversions, not everything that arrived in postbacks.
| Conversion status | Counts as revenue? | Why |
|---|---|---|
| Sale, approved | Yes | The network confirmed it and will pay |
| Hold | No | Still under review, may be rejected |
| Lead without a status | Depends on the payout model | On CPL offers yes, on CPA wait for approval |
| Rejected, refund | No | There will be no payout |
| Trash, fraud, duplicate | No | There will be no payout |
The most common mistake is adding hold to approved payouts. In nutra and COD e-commerce, approval can take days, and part of the leads will be rejected. If you count hold as money, ROI looks great right up until you reconcile with the network.
A sensible approach is to look at two numbers: confirmed ROI (approved only) and projected ROI (approved + hold × expected approval rate). More on statuses in conversion statuses: lead, hold, approved, rejected, trash.
Payout currency
If the network pays in euros and the ad platform charges in dollars, convert everything to one currency at the rate on the conversion date. Otherwise ROI will drift along with the exchange rate.
What counts as spend
Spend is the money charged by the ad platform. It can be recorded in several ways:
| Model | How it is calculated | When it fits |
|---|---|---|
| CPC | Price × number of clicks | Fixed click price |
| CPM | Price per 1,000 impressions × impressions / 1,000 | Paying for impressions |
| From the link | The platform passes the click price via a macro | Push, pop, native with a cost macro |
| Manually per day | The amount from the ad account | Exact reconciliation with the ad account |
| Import from the ad account | Spend is pulled automatically | Large volumes, many campaigns |
The most accurate is the actual amount from the ad account. The average click price is handy for a quick estimate but can diverge from reality: the auction changes costs during the day.
Tip. Enter spend every day, not once a week. Campaign ROI without yesterday's spend looks great and is completely useless.
Direct and indirect costs
Campaign ROI is usually calculated on ad spend only. But affiliate marketing also has infrastructure: accounts, proxies, an antidetect browser, domains, filtering and tracking services, creatives, team salaries. These should be counted when evaluating the business as a whole:
net monthly profit = revenue − ad spend − infrastructure − team
A campaign can show 20% ROI on ads and end up in the red after subtracting the cost of burned accounts.
A worked campaign example
Say you are running a nutra offer that pays 25 $ per approved lead. Over three days:
| Metric | Value |
|---|---|
| Spend | 600 $ |
| Clicks that reached the offer | 1,500 |
| Leads | 60 |
| Approved | 24 |
| On hold | 18 |
| Rejected | 18 |
Let's calculate:
- confirmed revenue = 24 × 25 = 600 $;
- confirmed profit = 600 − 600 = 0 $, ROI = 0%;
- CR = 60 / 1,500 × 100% = 4%;
- EPC = 600 / 1,500 = 0.40 $;
- cost per approved lead = 600 / 24 = 25 $, exactly the payout.
Now the projection. Of the leads already decided (24 + 18 = 42), 24 were approved, about 57%. If the hold is approved at the same rate, roughly 18 × 0.57 ≈ 10 more leads will come in, which is another 250 $.
- projected revenue ≈ 850 $;
- projected ROI ≈ (850 − 600) / 600 × 100% ≈ 42%.
You can see how much hold changes the picture. You can decide on scaling ad campaigns based on the projection, but keep in mind that it is a projection.
Break-even point: the maximum click price
It is useful to know how much you can pay per click to break even. That number is EPC:
maximum click price = revenue / clicks = EPC
In the example above, confirmed EPC = 0.40 $. If a click costs more, the campaign is in the red on confirmed money. For judging an auction bid, this is the most convenient benchmark.
The same thing can be expressed through CR and payout:
EPC = CR × approval rate × payout
For the example: 0.04 × 0.4 × 25 = 0.40 $. The formula shows which levers a buyer has: raise CR (landing page, creatives), the approval rate (traffic quality, geo) or find an offer with a higher payout.
Which lever to pull
The EPC formula hints at where to look for profit, and each lever has its own price:
| Lever | How to raise it | What it costs |
|---|---|---|
| CR | New landing page, pre-lander, creatives | Time for tests and the spend on them |
| Approval rate | Another geo, a more honest angle, another source | Sometimes less traffic volume |
| Payout | Another network or a custom rate | You need stable volume to negotiate |
| Click price | Better CTR, other audiences and placements | Creatives and tests on the platform |
Common ROI calculation mistakes
Hold counted as revenue. The most expensive mistake: scaling decisions are made on money that does not exist.
Different dates for revenue and spend. Spend is for yesterday, while revenue is by the conversion's received date and includes leads from clicks two days ago. Attribute revenue to the click date when you are evaluating a campaign.
Missing spend for some days. ROI shoots up on the days someone forgot to enter spend.
Conclusions on small volume. An ROI of 200% on three leads is chance. Build up volume before scaling.
Bots in the denominator. If you calculate CR and EPC across all visits, including filtered bots and platform reviews, the metrics are understated, and a working campaign can look unprofitable. Calculate on the clicks that reached the offer.
Duplicate leads. One person submitted three forms, and the network will pay for one. If your tracker counts all three, CR and your projection are inflated.
How ArtisanClo calculates profit and ROI
In ArtisanClo, profit and ROI are calculated in the Reports section for flows with a tracker (Tracker and Cloaking + Tracker modes). By default, the Money by slice table shows clicks, conversions, CR, revenue, cost, profit and ROI by flow, source, day, country, offer, device and sub1–sub10 labels.
How the problems from the list above are handled:
- Hold is not counted as revenue. The On hold column shows payouts the network is still reviewing, separately from revenue.
- Revenue is attributed to the click date. The Conversions log has a Received date / Click date switch so the numbers match the reports.
- Currency is converted to dollars at the European Central Bank's daily rate; if the network did not send an amount, the lead or sale price from the offer settings is used.
- Duplicates. A repeat lead from the same visitor within the uniqueness window is recorded as Trash marked as a duplicate.
- Spend is set by the click cost model in the flow or source: CPC, CPM, From the link, CPA or RevShare. Per click, per 1,000 impressions and from the link are charged only on clicks that reached the offer, while per action and revenue share apply only to counted conversions.
- The exact amount from the ad account. The Add spend manually button: flow, day, amount in dollars. The amount is split evenly across that day's clicks that reached the offer and replaces the calculated price for that day. On the Business plan, cost for the last 3 days is imported from Meta, TikTok and Google Ads every morning; details on the pricing page.
For revenue to appear at all, you need conversion tracking: a postback from the affiliate network or code on your site. How to set it up is explained in postback URL: setting up S2S tracking. A flow in Cloaking mode without an external tracker does not receive conversions, so leads and revenue in it will be zero.
The bottom line
The ROI formula fits on one line, but an honest calculation takes discipline: revenue means approved payouts only, spend is entered every day at the actual amount, dates follow the click, and volume is large enough to draw conclusions. Keep confirmed and projected ROI side by side, and use EPC to decide on bids. If you want all this calculated automatically, start with a tracker for affiliate marketing, and for split-testing your campaigns see split testing offers and landing pages.



