Server-side Download Tracking

28 Mar 2021 » Analytics Tips , Server Side

You all know that Adobe Analytics has an out-of-the-box solution to track download links. It just works and few people even care about it. You may not know that you can even extend its functionality, by adding additional eVars/props/events to the server call. Not very common, but I had to do it for one client. However, what happens when someone downloads content through a direct link or you have a server-side implementation?

Before continuing, I would like to thank my colleague Himanshu Pathak. This post is based on an internal presentation he gave.

Typical client-side configuration

Let me explain a bit more the situation by starting with the normal client-side implementation. Imagine you have a website that offers content for download. This content can be anything: white papers, instructions, software, videos… Obviously, you have web pages where you offer links to download these assets. You have also configured AppMeasurement to track the downloads. This is how it would like like in Launch:

Launch Track Downloads

Upon clicking on any link to a downloadable asset, a server call is sent, with minimal information about the content to be downloaded. This is how it looks like in the Chrome developer tools:

Analytics Call Track Download

The important parameters in this image request are:

  • pe: lnk_d: this is how Adobe Analytics knows this image request refers to a download
  • pev1: <URL to downloaded file>: this is the value that will be added to the “File Downloads” report

How is this possible, if you have not added any code to the links? Well, the AppMeasurement library places a listener to detect any click on the HTML page. If the click is on a link and the URL of that link ends with any of the extensions that you have configured, it will assume that it is a download and will fire this image request. Clever, isn’t it?

Now, imagine that someone finds a link to one of your assets directly in a search engine. Try this web search, for example. Or people share links to your assets via email or chat or 3rd party websites. In all these situations, your AppMeasurment library will not be aware of these links and the downloads will not be tracked. If you are OK with that, you do not need to continue reading this post. But if you do need to track them, read on!

The only solution is to do a minimal server-side implementation. If you already have an Adobe Analytics server-side implementation, the following explanation also applies. You will need the collaboration of your colleagues in the Content Management System (CMS) world. The CMS needs to intercept all requests to the assets and run some code. The algorithm of this code should look similar to:


Let me explain these steps:

  • Is direct link? There is no guaranteed method to detect whether it is a direct link or not. The most accurate one is to check the HTTP header Referer . If it is not present or the domain is not yours, you can assume that it is a direct download request.
  • Do nothing. We are assuming that the AppMeasurement library will take care of tracking the download.
  • Is AMCV cookie? This is the cookie where the ECID is set. Since it is set as a 1st party cookie when a visitor visits your website, it should be part of the HTTP request, in the HTTP header Cookie . As long as you store the assets under the same main domain or a subdomain, this method will work.
  • Serve file. Send the requested contents back to the visitor.
  • Request ECID. In theory, you could try to generate it locally, but I recommend you call the ECID service server-side. You do not need to store the value permantently, as I explained in that post.
  • Serve file setting AMCV cookie. Ideally, we would like to connect this download with any further visits to the website. To do that, we will set the AMCV cookie with a Set-Cookie HTTP header, when serving the file. The content of this cookie should be MCMID|<ECID>, URL-encoded. It goes without saying that you should replace <ECID> with the value you have received in the previous step. In case you are wondering, although the AMCV cookie has much more information, this is the minimal information it can carry. When the visitor comes to your website in the future, the ECID service will regenerate all missing parameters. Himanshu suggests setting the s_ecid cookie instead.
  • Track download. Finally, you need to make the call to Analytics, as I documented in my server-side Analytics post. Choose any of the methods I describe, with this data:
    • The <marketingCloudVisitorID> or mid parameter will come from, either the existing AMCV cookie or the ECID request.
    • Set the <linkType> or pe parameter to lnk_d.
    • Set the <linkURL> or pev1 to the URL of the downloaded file.
    • Feel free to add additional eVars, props or events, if your requirements say so. I would use a prop to capture that the download was tracked server-side.
    • Set any of the other minimal data that you would also need: Analytics domain, RSID, ORG ID… You may want to check the parameters in a download tracked by AppMeasurement.


Before you embark in this implementation, you should consider the main drawback of this solution: it will Increment your number of visits and visitors.

  • A new visit will be counted if the visitor has left your website more than 30 minutes ago or the ECID is new
  • A new visitor will be counted if:
    • The ECID is new
    • The AMCV cookie already exists, depending on the last time the visitor came to your website

There are some solutions to mitigate this issue:

  • You may want to send these server calls to a separate report suite, which you will only use to track server-side downloads.
  • You could accumulate the information server-side and, regularly, upload the information to Analytics using data sources. In this case, the explanation in this post does not apply. If you would like to know how I would do it, let me know in the comments and I will write a post on this point.
  • Create a virtual report suite and play with the visit definition.

Also, due the inaccuracy of the “is direct link” step of the algorithm, the numbers of the reports will also be inaccurate. Browsers are free to send whatever information they want. If that was not enough, each browser is different. If you want more details, see this Wikipedia page. The best mitigation action is to use a report suite only for download tracking.

Finally, this solution only works if the assets are served from the same domain as the website, or from a subdomain. If you use a completely different top-level domain, then this solution will not work. In fact, I am not sure there is any alternative. There are two reasons for this limitation:

  • Browsers only send cookies from the same domain and, if the cookie allows so, subdomains. You will never get a cookie from a different domain, even if you own both. Therefore, you will never get the AMCV cookie, if it exists.
  • It is more likely that the browser deletes the HTTP header Referer across domains. In this case, you would double-count all downloads coming directly from your website:
    • The AppMeasurment library will count once.
    • The above will always think it is a direct link, so a second count will happen


If your CMS is AEM, you can use the permission sensitive caching feature. Although this feature is primarily for authentication and authorisation of content access, nothing prevents you from writing any arbitrary code in the authorisation servlet and always allow access to the content. You may need to swap the last 2 steps of the algorithm and track the download before serving the file. Remember to also configure correctly the dispatcher.


Image by

Related Posts