Importing Spend and Calculating ROI in AlterCPA

Importing Spend and Calculating ROI in AlterCPA

Xoxo, everyone — it’s Reznik, and today we’re going to count the cash.

Starting with version 3.17, AlterCPA Pro got a genuinely handy new feature: you feed it your ad campaign spend data, and it hands you back deep spend and ROI analytics broken down across every one of AlterCPA’s multi-level reports. I’ll walk you through how to use this tool and what pitfalls are waiting for you on the road to full financial accounting.

How It Works

The new version of AlterCPA added useful statistics columns that let you gauge the real success of your ad campaigns. You turn them on in the system’s “Advanced” settings. Here’s what we added to the “Traffic” block:

  • Clicks – the number of paid clicks counted by the system. Not every click counts as paid — a page refresh or a jump from the pre-landing page to the landing page definitely shouldn’t be counted.
  • CPC – the average cost of a single click, from the column above.
  • Spend – total traffic spend, the product of the first two columns
  • Profit – the difference between spend and the total revenue from accepted leads and leads on hold. Since we count hold leads (leads with delayed confirmation) toward revenue, you can safely add them to your income.
  • ROI – the ratio of revenue to spend, shown as a percentage. An ROI below 100 is a sign of total failure.

First, a quick moment of disappointment. What’s implemented in AlterCPA is specifically an import of spend data, not an export of it. In other words, you have to go knock on the system’s door yourself and tell it: “I done did it!” – specifying how much was spent and against which criteria. AlterCPA won’t go pull anything from anywhere on its own, because there are plenty of ad networks out there and only one AlterCPA. Just like the Russian Post.

Here’s another important detail – the specifics of how paid clicks get counted out of the total click count. A click only counts as paid if it meets a few conditions. First, the click has to be unique. The system doesn’t track whether a click came in from outside or was just a page refresh or a jump to one of the landing page’s internal pages, so for simplicity, it only counts unique clicks. Second, the click on the landing page has to be direct, not arriving from a pre-landing page. Every click coming through a pre-lander, unique or not, won’t count as paid. That’s why it’s best to send the price not for a single click, but for the entire volume of clicks at once – AlterCPA will spread the price tag across all the clicks it likes, on its own.

The Technical Side of the Process

Sending price data is handled by the wm/cost function, which will look something like this for you:

https://altercpa.site/api/wm/cost.json?id=123-abc

The most important parameters this function expects are the click prices:

  • cpc – the price per single click, not recommended
  • cost – the price for the entire selected volume of clicks, recommended
  • currency or curr – the three-letter ISO currency code the click price is given in.

It’s best to send cost specifically, ideally paired with currency. If no currency code is sent, the clicks are assumed to be priced in the system’s default currency.

Besides the price, you also need to send at least one filter – or all of them at once, if you like. Here are the filter parameters available for clicks:

  • flow – the Flow ID.
  • utms – the utm_source tag
  • utmc – the utm_campaign tag
  • utmn – the utm_content tag
  • utmt – the utm_term tag
  • utmm – the utm_medium tag
  • from – the date and time to start selecting clicks from, exclusive.
  • to – the date and time to end the click selection, inclusive.

The from and to parameters come with a few interesting life hacks.

  1. You can pass integers in these parameters, and they’ll be read as a UNIX timestamp. That’s the optimal choice when importing data from some smart system built by programmers who actually know what they’re doing. In that case, the selection period will be strictly greater than from and less than or equal to to.
  2. You can pass the date and time in a format an actual human can read – YYYY-MM-DD HH:MM:SS – instead of resorting to scary, incomprehensible strings of digits. AlterCPA will read a date like that relative to the time zone set in the system.
  3. You can also stuff any old nonsense into these parameters, as long as the strtotime function understands it. You can read more about these formats in the PHP documentation – it’s all laid out there in plenty of detail. For example, to send clicks from the last 24 hours, you could use “-24 hours” for from and just pass “now” for to.

The parameters themselves can be sent in either the GET or POST part of the request. It’s very important that you don’t split them – sending some parameters via GET and some via POST – the system will treat that as two separate requests and process each one on its own. If you want to send data for a whole bunch of clicks in one go, you can stuff them into an array under a single batch parameter, so you end up with something like this:

{
    "batch": [
        {
            "flow": 42,
            "cost": 1984,
            "currency": "usd"
        },
        {
            "from": "2020-04-04 00:00:00",
            "to": "2020-04-07 23:59:59",
            "cpc": 1.337,
            "currency": "eur"
        }
    ]
}

Now that we’re steeped in the technical side of things, let’s work through a few examples and see how this actually plays out in reality.

Practical Examples

For convenience, let’s assume we’re passing the traffic source in the utm_source parameter, the ad campaign ID goes into utm_campaign, and the specific creative’s code goes into utm_content.

Total Spend by Flow

Say we use one Flow per ad campaign, and the ad network can periodically send us a postback with the total amount spent on that campaign to date.

In that case, we just pass the Flow ID in the postback’s flow parameter, and pass the total spend amount – given by the matching macro, say {spend} – into the cost parameter.

That gives you a postback that looks like this:

https://altercpa.site/api/wm/cost.json?id=123-abc&flow=777&cost={spend}

Flow Spend for a Fixed Period

Say the ad network from the example above can send a postback every hour, stating the amount spent during that specific hour. In that case, the postback will include a from parameter with the value “-1 hour”, matching the reporting period. You don’t need to specify to here, since by default it matches the current moment.

https://altercpa.site/api/wm/cost.json?id=123-abc&flow=777&cost={spend}&from=-1hour

Flow Spend for an Arbitrary Period

Say our ad network can’t send a postback once an hour, but it can send one for an arbitrary period instead. And it can state the start of that period in the {start} macro, in whatever format is convenient. In that case, we’ll pass the {start} macro straight into the from parameter:

https://altercpa.site/api/wm/cost.json?id=123-abc&flow=777&cost={spend}&from={start}

And if the ad network can indicate not just the start of the period but its end too, in an {end} macro, we’ll add that to the to parameter.

https://altercpa.site/api/wm/cost.json?id=123-abc&flow=777&cost={spend}&from={start}&to={end}

Spend by Ad Campaign

Say our network uses a single global postback, and we don’t tie a Flow to any specific ad campaign. In that case, we need to filter clicks by utm_campaign – no point setting it up in the link otherwise.

Odds are we’re using more than just one network, so for our made-up network, Pedobear Advert, we already set the utm_source parameter to pedadvert in the Flow ahead of time. Which means we add that same filter to the postback in the utms parameter. Meanwhile, the ad campaign ID comes through in the {campaign} macro and gets sent in the utmc parameter.

In that case, our smartest postback yet ends up looking like this:

https://altercpa.site/api/wm/cost.json?id=123-abc&utms=pedadvert&utmc={campaign}&cost={spend}&from={start}&to={end}

This will set the click price across every Flow from the selected ad network, splitting it across ad campaigns and tying it to the right period. That said, it’s crucial that the UTM tags are actually present in your Flow URLs.

Integration with Well-Known Systems

This section will keep growing as we integrate with existing traffic sources, ad networks, trackers, and analytics systems.

It’s empty here for now, since the ROI calculation feature hasn’t even been officially announced yet. Send us your integration ideas, and we’ll add them all right here!

That’s it from Reznik — xoxo, everyone!