Creating Campaigns Cost in Adobe Analytics

Hello world,
on this blog post, I would like to share an idea that I had recently (but never been tested in the field) about creating / importing the costs of campaigns in Adobe Analytics.

Not Genesis, not classification

As discussing cost import with other consultants, this idea is not very new and there are (were) already several ways to achieve that. However, the method I am going to give you is not the official Adobe one, it may be better as it fixes several issue of the current method(s) but it is probably hard for people to scale it efficiently. We’ll see that together.

First, let’s discuss the official ways to realize that.

Numeric Classification

Numeric classifications have been discountinued for some years and seasoned professional are probably asking themselves why I bring back this capability in 2021.

2 reasons:

  • Because I never lost an opportunity to tell the Product Manager(s) of Adobe Analytics how bad this decision was. I understand they had their reasons for that (too much cost, too complex to maintain, etc…) but in my opinion it was a KEY functionality of AA.
  • Because Product Managers are not evil and this functionality is coming back with CJA (Customer Journey Analytics). It is on the roadmap and I am super excited about it.

Unfortunately, not everyone will have CJA in 2021, even in 2022, so you are stuck with Analytics and no numeric classication.

Data Connectors / Advertising Analytics

There is still a way to import your campaigns costs in Adobe Analytics and it goes through either a Data connector (genesis) or Advertising Analytics. The latter being a genesis connector maintained by Adobe and directly integrated in the product.

This kind of connection works as a sort of classification at the end as you are creating this connector on a key and then, instead of you, a service import data into Adobe Analytics.

For more information about the data connector :

There are several reasons why I don’t like this service: The setup can be painful, there is often a cost associated from either Adobe or the partner that have developed the integration and the data are not stitch to your users.

So you cannot calculate the ROI of a visitor, or his CPL / CPA.

There is a way to do some sort of calculation and Lukas Oldenburg went through his experience here.

The Calculated Metrics way

Most of the people reading this already realized that we will go on the Calculated Metrics route. This is the reason why I am thinking that this idea may not be so new for a lot of advanced analytics users, I just never really tought through about it.

Prerequisites / Limitations

There are some prerequisites and limitations with this method that may be enough to be discouraged you from going further, so as a good consultant, I am going to manage the expectations here.

This is about cost of campaigns, not impressions.
Because Adobe Analytics is based on data from users that have been to your website / application, there is no way to import impressions of your campaign (I mean technically there is but not to link them with your visitors).

It requires past data or some level of expected performance.
We will be basing CPC or CPV information into Adobe Analytics, some type of campaign (Paid Search) are really good on having this information. Some other (Affiliation) less and require aposteriori analysis.

This is about reporting and have some real-time limitation.
For completely new campaign with uncertain performance, there may be a limitation to use that technique.

This will not give you exact numbers.
What I am going to demonstrate is a (good?) idea in Adobe Analytics, it is not the recommended practice for exact cost calculation.


The usage of that report requires some preparation on your side and some understanding of how Adobe Analytics works.
As explained previously, Adobe Analytics based its numbers on the number of users that have reached your website. Therefore, to import the cost of your campaign, we need to find a way to report the cost on the number of visitors.

There are 2 ways to imagine doing that:

  • Calculate aposteriori a cost per visitor on your campaign. That is most accurate calculation that you can do. You take the total cost of your campaign and count the number of visits that they have lead to and then we will be able to have a cost per visit.
    However, it may be a bit tricky as you may have allocation period of your campaign running for 30 days as a last touch channel*. That means you will received more than one visit attributed to a specific campaign in Adobe Analytics. We will account for that but it add another complexity layer.
  • Calculate (aposteriori) a cost per click to all campaign (even the non-CPC ones). Fortunately, the digital marketing field is starting to makes customers pay per click and not per view or post-view (scam-alert !! ). If they do not, there may be a way for you to calculate that number based on the number of clicks realized for a specific campaign.
    This is the easiest way to go but it has the disadvantage to be hard to guess for completely new campaigns.

You would also need to have the s.campaign tracking parameter in place so it will capture the campaing on the landing, and it will be better if it is captured only on the landing page. Not on every page or hit because saved in a cookie.**

Having a classification of your campaign based on the ID is preferred, if not required. Depending on the level of granularity you want to report the cost on, you can use a different layer of granularity.

Adobe Analytics setup

Now that we have our information, we are ready to start building our Analytics setup. For this use-case I will use my own Adobe Analytics and fortunately for you, I am tracking some campaigns I am making when posting articles (like this one) and we will use that to fake campaign import.

To give you an overview, I have several campaign medium that I am using for tracking my article post on social media:

You can see that majority of my tracking is done via SEO most probably (I am not that well known to have a good “Direct Traffic” element). But I still managed to capture some visits on the different social media.

I have a more granular view on my campaign, so per example on LinkedIn, I can see the following blog post shared.

Online Advertising in 2022 was big hit (side note : I am happy that my “predictions” turns out to be true as Google will offer segment-based audiences) and you can see how much each compaign bring me in visit.

In my case, I do not pay for any of this but I am spending my time doing these article and some article require more time than others.

Online-Ad took me a couple of hours, but Adobe Analytics API per example is more about months work (any python module article require understanding the API + coding + writing – sometimes twice with the github documentation). So I could imagine putting a cost of time in each of my campaign based on time spent.
So let’s do the exercise.

Download data from Analytics

I first need to define which campaign have been running during the last 52 weeks. For me it is easy as I ran something like 40 article in the last year.
If you are a company that has thousands of campaign, you may consider doing a classification export of the key and their value. (As I said, having classification for your campaign ids is a requirement).

Download Cost Data from Platforms (Google Adwords, etc…)

This is where my exercise will differ from yours as I don’t have cost per say but I will imagine one. Also, the idea is definitely better suited for CPC campaigns. You could take the average CPC over the last year and define that as your cost per visit per user.

For non-cpc campaign, again, you need to evaluate the number of visit generated per that campaign and do the calculation.

What if my campaign is still running ? I do not have a final cost yet.
In my opinion, I would advise to take a month of data and extrapolate that data. If it is for future campaign, takes a general calculation based on previous similar campaigns.

On my side, I will have a CSV file that would look like this:

Cost per visit file preparation

As you can see, I paid a small effort to do the “online-ad-2022” campaign but paid a big time (x6) for doing my “python-video-tutorial”. I really hope you enjoyed it.

Create your calculated metric

This is where the fun start, I would do a 2 step process in the UI and you may want to jump directly in the 2nd step if you already have the idea now on how I want to proceed. I will just explain a trick first on what to not do when creating the calculated metric(s).

The idea is to attribute a value on each visit so we reflect the price we pay for each.
So we can start like this:

First step

I simply drag and drop the Campaign Audience (v0) and select a specific condition (= my audience).

However, this has a problem of over estimating the cost of the campaign running. (Yes I don’t have to have the “Unspecified” but maybe I want to quantify the brand advertising into the “Unspecified”, so I let myself an option to add a cost to it… just an idea 😉 )
I am pretty sure that you have a 30 days attribution period on your campaign tracking. Therefore, each subsequent visit coming from Direct will again come at a cost, which is not really true.

We could imagine doing a decrease cost attribution by number of visits but that would be another long post. So we need to add an extra something in order to account for your attribution logic (30, 60, 90 days….).

We will create a segment that is Hit based and that only consider the Hit where a campaign instance has been detected.

Campaign instance

And we will add this segment on top of our campaign cost assignment calculated metrics.

Adding the segment on top

Scaling the solution

So far, you may be please with the article but still unsure if this is really scalable.
There are 2 main questions that needs remain to be answered.

How do I proceed with thousands of campaigns ?

Has Julien done an article without talking about python ? 😀

There are 2 ways to scale it. Either by giving the creation of this metric to a bunch of people for a week but by now, you know that I am always trying to do something that is less manual and more like I would need to click few times to repeat the task.
You “may” also have heard of my different python wrappers and many of my friends think that I am bit insistent on that but Python can solve a lot of challenges for you.
Now we will need to see how it can solve this one.

— DISCLAIMER : I would recommend to know python to continue reading this part —-

I will use the aanalytics2 module to connect to my Adobe Analytics instance and retrieve the specific calculated metrics definition. (Side note: I discovered that I didn’t have a specific function to retrieve a specific calculated metrics – no one never asked for it anyway. It is solved with the version 0.2.5 of the module)

I will spare you the beginning as you are probably familiar with it or you can see one of my video to see how to connect to the Adobe Analytics API. But at the end, you can look at your calculated metrics “formula” and it looks like this:

You see that we have a pattern here. For some reasone we have col2 that is called several times and more importantly, it seems that the condition is based on an id. This id, because it starts with a s can be identified as a segment.

Wait – are you telling me that in the background, Adobe create segments for my calculated metric? Yes, sir.
Looking at one specific segment, we can see how it is built:

Segment definition

It was/is my long time wish to create a segment creation class in my aanalytics2 module so you can easily create segment from it.
Because it is not my job, because it is hard, and because it requires a lot of time to develop that, it (will?) never come(s). Maybe one day, a client will ask for this and I will be able to spend some time on this kind of feature.

In the meantime, if we want to scale that solution, we will need to stop whinning and start working on a way to build this at scale.

Looking at the segment API guide, it seems pretty straight forward to see what we need to establish as base dictionary.
We just need to have the different values in key places and we already downloaded the different values from Workspace (or Data Warehouse if you have a big amount of data).

You can then import them in a dataframe easily:

My Values

We know that the Segment definition should look something this:

and that my definition (“myDef”) dictionary should look something like this:

At the end, there are only 2 values to fill with a loop:
– the name
– the value of the equal sign

And as you can imagine, the value and the name will be pretty similar.
As this is a test and I do not really care if the segment ends up being mine, you have seend that I put my name into it, I would recommend that you put the API account owners of that segments. So you can clearly identify the segments that have been created through that mean.

You can test your segment with the validate option in the API (or with my module 😉 )

After creation (if it works), they will appear on your Adobe Analytics component.

When looking at the calculated metric, there is obvioulsy a pattern that you could re-use as explained before. As for me, it goes like this:

I will need to create as many dictionary as require to match the number of segment. I will also need to attached the ID of the segments created with the cost of the Campaign.
I will manage to do that easily as I have saved each response from the segment in a list that will match the dataframe order. Otherwise, be sure to be able to catch them by either naming convention or tags.

Now my dataFrame looks like this:

This will help on the creation of the calculated metrics component.
However, the creation of the calculated metrics via API is not that easy (big understatement detected) and I believe I already shared a large amount of python code. So I will not pass all the details but you need to know that apparently, a Calculated Metrics cannot have more than 2 elements to its component. So you need to nest element if more than 2, and this indefinitely.

Just a pick on how it looks like

At the end, I need to add this massive nested dictionary into my final container definition for that metrics that set the Hit segment ensuring we are counting only the visit when a click happen (click through exists)

This is our final definition that we can use in the Calculated Metrics JSON object:

The function to create is not that easy in python and as I said, it will depend on how granular you want to be, but you can always validate that with the ‘createCalculatedMetricValidate’ method and it will give the reason why it fails, or how it will succeed:

I have now created my new calculated at scale with 39 different campaigns.
I have never done that on client with 1000 different campaigns, the python script will work but I don’t know if Adobe calculated metrics will support it.

To be fair, the definition starts to look barbaric:

metric overview definition

But now we can scale that to any number of elements (if Adobe supports it).
And I have a cost per article, which in my case represents more the value of my articles (cost to create that article * number of people clicking on my campaign).

And apparently, I should spend more time on AEP stuffs and python videos 😀

I hope you enjoyed that article and learned some things (or two) on Adobe Analytics, especially calculatede metrics. Obviously, let me know if you think that was helpful, that always drive more content.

* In my previous company, we ended up believing that the allocation of the campaign should always be linked to a visit (not 30 days). The 30 days attribution is over representing the last touch channels and play in the cards of the converters. Campaign such as Social or Display are important but may not convert. But that is a story of another time (let me know if you want to know more about it)

** My previous company was storing the campaign value in a cookie and when I started, it was writting the campaign value on every hit. That was inflating the number of campaign instance. They had good idea but not everything was perfect in my previous company 😉

Leave a Reply

Your email address will not be published. Required fields are marked *