Customer Journey Analytics API

Customer Journey Analytics API – cjapy

Hello world,

Today is the day of an expected article related to the Customer Journey Analytics API.

Customer Journey Analytics is the future of analysis with the Adobe tool stack, it has the same main interface than Adobe Analytics but with more powerful features. There are many things that would push you to have Customer Journey Analytics but also some elements that may put you to stay with Adobe Analytics for the time being.

I put an article on that topic here: Customer Journey Analytics (2021 status)?

Customer Journey Analytics at scale

I believe that if you are still reading this, you are either willing to switch from Adobe Analytics to Customer Journey Analytics, using Customer Journey Analytics already, or willing to just start with CJA.

Customer Journey Analytics (CJA) has many cool features that you can use, but for large organizations, having the capability to apply these features at scale is very important.

This is where I am usually coming, trying to make the API capabilities as easy as possible to master.

Most of the capability in CJA are the same than the Adobe Analytics API 2.0.
Therefore I could have copied most of the code that I used for the aanalytics2 python module.

Obviously, that was not my intention, since the release of the aanalytics2 module I improved on my python skills, I also had many discussions with colleagues or pairs on Adobe Analytics API use-cases, so I had many ideas on what to improve (but no time).

Also, creating a replica of the aanalytics2 module would have been too easy and not fun at all.
I decided to start again from scratch and bring you even more cool features so you can take advantage of the API to its full extend.

New Features on cjapy

cjapy is the name of the python module I developed and loaded into the pypi library.

There are few key differences on how this library works versus the aanalytics2 module and I will try to summarize it here.
Don’t worry too much as this is nothing completely different, it has the same “look & feel” that made its predecessor famous, but brings you even more capabilities.

Single Class for reporting

With aanalytics2, you would have needed to get a Login Company before starting the Analytics class.
With cjapy, once you have loaded the configuration file, you can directly call the CJA class in order to instantiate the connection.

import cjapy

cja = cjapy.CJA() ## now you are all set

Overall, you can have a look on how easy to get started with CJA by looking at the documentation focusing on get you running easily:

Logging capability included natively

It took some time for aanalytics2 to have such feature but in cjapy, you directly have a Logging capability.
It is taking its root directly from the logging module in python.

It should really help you debugging the issues or just to know what is going on when you run the different methods on the cloud.

import cjapy

 generating a logging dictionary
myLogging = cjapy.generateLoggingObject()

## using the object when instanciating the CJA class
cja = cjapy.CJA(loggingObject=myLogging)

Your object myLogging would look like this:

{'level': 'WARNING',
 'stream': True,
 'file': False,
 'format': '%(asctime)s::%(name)s::%(funcName)s::%(levelname)s::%(message)s::%(lineno)d',
 'filename': 'cjapy.log'}

The level key is the most important one I believe as most of the information are logged on the DEBUG level.

Possible values are:

  • INFO
  • EROR

Generating reporting request

After those nice elements, we are now we are getting to the juicy part of the cjapy module.

If you know the Adobe Analytics API and the official documentation, the process to retrieve report is first to generate a report request. The process is quite the same with Customer Journey Analytics.
In order to do that, you will need to go to Adobe Analytics, or Customer Journey Analytics.

Enable the debugger, in the help section.
(I have it already enabled)

help CJA
Opening debugger

Then retrieve the JSON from the appropriate:

I didn’t find that particular setup easy and convenient to realize.
The need to log in to CJA when you want to use the API is not optimal. You can have a request JSON ready to fire but when you need to change the date, the dimension, or the metrics. It is quite a hassle to handle that in the file or dictionary.

So I am very happy to present you the RequestCreator class.

Instantiating this class will provide you with an object that will have methods to generate a valid report request JSON.

You can generate that object by doing:

import cjapy
### creating an empty request 
myRequest = cjapy.RequestCreator()

Once you have this object, you can add stuffs to it:

myRequest.setDimension('dimensionId') ## setting a dimesion
myRequest.setDataViewId('dataViewId') ## set the data view
myRequest.addMetric('metricId') ## add a metric to the request

As you can see, there are different methods that you can use to create the appropriate dictionary. You can find a full documentation of that functionality here:

You will need a global filter with a dateRange for any request you are using (as well as a DataViewId, a dimension and a metric).
It basically requires to add a global filter with a dateRange specified such as: “2020-01-01T00:00:00.000/2020-02-01T00:00:00.000”

myRequest.addGlobalFilter("2020-01-01T00:00:00.000/2020-02-01T00:00:00.000") ## add a metric to the request

The format of the time period passed is important.
To make your life easier, I created several time period directly available as attriute of the object, you can access them doing the following:


That should give you the following predefined dates in a dictionary:

  • thisMonth : full month date
  • untilToday : start of the month till yesterday midnight
  • todayIncluded : start of the month, today included
  • last30daysTillToday
  • last30daysTodayIncluded
  • last7daysTillToday
  • last7daysTodayIncluded

I hope you will find this class helpful and I am looking forward to make it better, by adding support to more use-cases.

Also, last but not least, you can directly load an existing (JSON) project definition to instanciate the class.

import cjapy, json

### loading your existing request, downloaded from CJA interface
with open('mySavedRequest.json','r') as f:
    saveRequest = json.load(f)

### passing the definition to the RequestCreator
myRequest = cjapy.RequestCreator(saveRequest)

Workspace class response

A major change from the aanalytics2 report is the result returned from the getReport method.
It is a dictionary and after some times working with it, I was not satisfied with that result. It misses some interaction capabilities.

I did (do) not have time to work on it as I was pretty busy with the (massive) aepp module but I decided to start the cjapy module directly where I want to head for the aanalytics2 module.

Therefore, now the result return from the cjapy.getReport method is a Workspace class.
It provides you with more elements now, directly from attributes or methods.

You have now contextual information about the request directly in the following attributes:

  • startDate
  • endDate
  • dataframe -> the result itself is a dataframe
  • dataRequest -> a RequestCreator instance
  • globalFilters and metricsFilters : list of all filters used
  • settings: globale setting set for your report
  • pageRequested: the number of request generated to get all data
  • summaryData: the summary data when available
  • reportType: the type of report requested
  • rowNumbers: number of results
  • columns: columns returned

The same way than for the aanalytics2 module, it has the capability to return all available data in the CJA.
When you request your report, you can use the “inf” value, that is set by default, to return all data.

import cjapy

cja = cjapy.CJA()
### some data preparation

report = cja.getReport(request=myReport, n_results="inf")

There are some available methods available from the object return by the getReport method:

to_csv() and to_json() are the easy one that wrap the dataframe capability.

However, the very cool new capability that the returned object create for you is the ability to have a breakdown directly from the report.

Yes, you heard me right! You can breakdown your result directly from the result via python.
For that, you need to pass the index of the value in your return dataframe that you want to break down and the dimension you want to breakdown that value with.

##imagine you have something like:
## index | ItemId | Value    | Page views
## 0     | abc    | Home     | 1000
## 1     | def    | Category | 800

## You can break down Category such as:
myBreakdown = report.breakdown(index=1,dimension="dimensionId") 

I find this new capability really interesting, I hope you will give me feedback to improve it even more.

You can have a complete view of the possibility and value return on the documentation:

Multi Dimensional report

Another major method available on the Customer Journey Analytics API wrapper in python is the ability to realize multilevel breakdown.

I had this idea for years and never knew how to handle it in my library. Many considerations I had in mind for its implementation.
Then Jared R Smith developed it for R (cool –> R package for Adobe Analytics API 2.0) and showed me that I was overthinking it.
So here it is: the getMultidimensionalReport method is taking some limited arguments but still returns a Workspace object.

This is still beta so be careful with it and let me know if you encounter any bugs, I would not recommend to use it for more than 1 level breakdown (so one primary dimension and a children dimension).
If you have use case for more than 1 level breakdown, feel free to let me know (and also help me to develop the recursing part 🙂 )

Here is the documentation for the getMultidimensionalReport method.

Projects support

For the one of you that have been following the aanalytics2 python package, you may be familiar with my projects methods and my Project class that is able to analyze the workspace projects that you have.

Recently, Adobe Analytics API 2.0 and CJA API revealed these endpoints officially so I was able to port these methods over to the cjapy module.

It means that from a single Project (or for all projects, with the getAllProjectDetails method) you can now these different information:

  • Number of dimensions used
  • Which dimensions used
  • Number of segments filters used
  • Which Segments used
  • Data Views Id and names
  • Number of Freeform
  • Type of elements used

This is going to give you a lot of insights on how people are using your implementation, what do they use and with the combination of the audit Logs, how often do they use it.

Obviously, I also migrated the findComponentUsage method that helps you to find where a specific dimension, filter or calculated metric is being used.

You can have find all documentation here: Project class in cjapy

I hope you liked the preview I made for this new module, you will be able to find videos explaining these usages soon.

You can find the complete list of the methods available on the main CJA class here:

Leave a Reply

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