Apps API

With Exponea Apps API it is possible to create custom apps that are integrated with Exponea. Creation of custom apps is not allowed for public yet. The input and output format specified here is used by version 1 of our API. Since this API is still in beta version some breaking changes could occur. After releasing it as stable no breaking changes will be done later on.

Getting started

The easiest way to start developing Exponea Apps is to use our Python Flask Apps SDK and see our example app. For authentication we use OAuth2 which is encapsulated in our SDK. You don’t have to handle it by yourself.

Calculating analyses

With Exponea Apps API you can calculate analyses on demand. This documentation summarizes input and output formats of different types of analyses.
To calculate an analysis a following POST request should be made:

POST https://cloud.exponea.com/api/v1/analytics/<analysis-type>/calculate?project_id=project_id

or using SDK

exponea.post(project_id, 'analytics/<analysis-type>/calculate', data)

The body of the POST request should be a JSON containing following data:

{
    // unix timestamp for which you want to calculate the analysis
    // optional (default: now)
    "execution_time": 1454333342, 

    // adds global filters which will be applied while calculating analysis 
    // optional (default: {}), for more details see Global Filters
    "global_filters": {},

    // required, the structure depends on type of analysis you are calculating
    // you can find the input formats of analyses below
    "data": {
        ...
    }  
}

Trends

POST https://cloud.exponea.com/api/v1/analytics/trends/calculate?project_id=project_id

or using SDK

exponea.post(project_id, 'analytics/trends/calculate', data)

Input

{
    "data": {
        // series to be calculated
        "event_types": [{            
            // required descriptive name, not used for calculation
            "display_name": "Session start",
            "type": "session_start",

            // filters to apply for the event
            // for more details see Event Attributes Filter
            // optional (default: [])
            "filter": [] 
        }, {            
            "display_name": "Session end",
            "type": "session_end"
        }],

        // required, if set to true the count of customers having specified 
        // events will be calculated, otherwise count of events will be
        // calculated
        "unique_per_customer": false,
        
        // required, see Date Filter the only exception to regular date 
        // filter is that this one has to be always turned on (no need for  
        // enabled option) and it has to be bounded from the left side (from
        // date is required if set to absolute)
        "date_filter": {  
            "absolute": false,
            "duration": {
                "count": 30,
                "units": "days"
            }
        },

        // required, how X series is grouped
        // available choices: seconds, minutes, hours, 
        // days, weeks, months, years
        "group_by": "days",

        // decides for which customers trend should be calculated
        // optional (default: {}), for more details see Customer Filter
        "customer_filter": {}
    }
}

Output

{
    // separate series
    "data": [{
        // data points for first serie, first item is unix timestamp 
        // of beginning of given period second is count
        "data": [[1451865600, 1813], [1452470400, 1578], [1453075200, 1415]],
        "name": "Session start",  // specified display name
        "type": "line",  // whether should be rendered as line or column
        "visible": true
    }, {
        "data": [[1451865600, 1813], [1452470400, 1576], [1453075200, 1418]],
        "name": "Session end", 
        "type": "line", 
        "visible": true        
    }], 
    "success": true
}

Funnels

POST https://cloud.exponea.com/api/v1/analytics/funnels/calculate?project_id=project_id

or using SDK

exponea.post(project_id, 'analytics/funnels/calculate', data)

Minimal example

{
    "data": {
        "funnel_steps": {
            "steps": [{
                "name": "Session",
                "type": "session_start"
            }, {
                "name": "First purchase",
                "type": "purchase"
            }, {
                "name": "Second purchase",
                "type": "purchase"
            }]
        }
    }
}

Input

{
    "execution_time": 1454333342,
    "data": {
        "funnel_steps": {  // required

            // actual list of funnel steps
            "steps": [{

                // descriptive name of step (not used for actual calculation)
                // required 
                "name": "Session",  
                "type": "session_start",  // type of event, required
                
                // filters to apply for the event
                // for more details see Event Attributes Filter
                // optional (default: [])
                "filter": []

            }, {
                "name": "Purchase",
                "type": "purchase"
            }],

            // specifies date filter to apply for all the events 
            // before considering them to be part of funnel
            // for more details see Date Filter, optional (default: {})
            "date_filter": {},
            
            // specifies time range starting from first step within which
            // customer have to complete the funnel
            // optional (default: {"enabled": False})
            "duration_filter": {
                "enabled": true,
                "duration": {  // required if enabled
                    "count": 30,  // integer >= 1
                    
                    // available choices: seconds, minutes, hours, 
                    // days, weeks, months, years
                    "units": "days"  
                }
            }
        },

        // whether drill down should be calculated
        // for more details see Funnel Drill Down
        // optional (default: {"type": "none"})
        "drill_down": {"type": "none"},

        // when specified a sum of event attribute will be calculated 
        // and returned for given step
        // for more details see Funnel Metric, optional (default: null)
        "metric": null,

        // decides for which customers funnel should be calculated
        // optional (default: {}), for more details see Customer Filter
        "customer_filter": {}
    }   
}
Funnel Drill Down

There are 3 types of drill downs that can be applied to funnels:

  • No drill down
  • By customer attribute
  • By funnel step
No drill down
{"type": "none"}
By customer attribute
{
    "type": "customer", 

    // customer attribute by which drill down should be calculated
    // required, for more details see Customer Attribute
    "attribute": { 
        "type": "property",
        "property": "first_name"
    }
}
By funnel step
{
    "type": "step",

    // number of step (indexed from 0) on which drill down should be applied,
    // required, integer < number of steps in funnel
    "step": 0,  

    // event attribute by which drill down should be calculated
    // required, for more details see Event Attribute
    "attribute": { 
        "type": "property",
        "property": "browser"
    }
}
Funnel Metric

When specified, calculates sum of given attribute of one particular event step for every drill down series.

{
    // number of step (indexed from 0) on which will be metric calculated,
    // required, integer < number of steps in funnel
    "step": 2,

    // event attribute which will be summed for each drill down series
    // required, for more details see Event Attribute
    "attribute": { 
        "type": "property",
        "property": "price"
    }
}

Output

{
    "data": {
        "total": {
            "counts": [150, 140, 10],  // number of users for every step

            // average time in seconds from previous step
            // if unavailable -1 is present 
            // (note: first step will always have -1)
            "times": [-1, 3687, 45987],             

            "metric": 0  // calculated sum of metric if specified
        },

        // drill down series 
        "drill_down": [{   
            "key": "Internet Explorer",  // drill down value
            "counts": [80, 70, 0], 
            "times": [-1, 4000, 50000],
            "metric": 0
        }, {
            "key": "Google Chrome", 
            "counts": [70, 70, 10], 
            "times": [-1, 3374, 41974],
            "metric": 0
        }]
    }, 
    "success": true
}

Reports

POST https://cloud.exponea.com/api/v1/analytics/reports/calculate?project_id=project_id

or using SDK

exponea.post(project_id, 'analytics/reports/calculate', data)

Minimal example

{
    "data": {
        "server": {
            "metrics": [{
                "type": "embedded_metric",
                "members": [{
                    "type": "customer",
                    "aggregation": "count"
                }],
                "formula": "A"
            }]
        }
    }
}

Input

{
    "data": {
        "server": {
            // for more details see Report Attribute
            // optional (default: [])
            "rows": [{
                "type": "event",
                "attribute": {"type": "timestamp"},
                "format": "year month day"
            }],
            // optional (default: []), same format as rows
            "columns": [],      
            "metrics": [{
                // for more details see Metrics
                "type": "embedded_metric",
                "members": [{
                    "type": "customer",
                    "aggregation": "count"
                }],
                "formula": "A"
            }],

            // decides for which customers report should be calculated
            // optional (default: {}), for more details see Customer Filter
            "customer_filter": {},

            // decides for which events report should be calculated
            // optional (default: {})
            "event_filters": {
                // list of filters for used event types
                // optional (default: [])
                "attributes": [{
                    "type": "session_start",

                    // filters to apply for the event
                    // for more details see Event Attributes Filter
                    // optional (default: [])
                    "filter": []
                }]                

                // specifies date filter to apply for all the events 
                // before considering them to be part of report
                // for more details see Date Filter, optional (default: {})
                "date_filter": {"enabled": false}
            }
        }
    }
}
Report Attribute
{
    // whether report attribute belongs to customer or event
    // required, allowed choices: customer, event
    "type": "customer",
            
    // required, type depends on field type, it could be 
    // Customer Attribute or Optionally Typed Event Attribute
    "attribute": {  
        "type": "property",
        "property": "first_name"
    },

    // how should report value be processed
    // allowed values:
    //
    // round(4), floor(2), ceil(3) - specify precision as an integer in 
    // brackets
    //
    // euro, dollar, percent - aliases for round(2)
    // none - no conversion
    //
    // year, year month, year month day, year month monday, 
    // year month day hour, year month day hour minute 
    // - rounding of unix timestamp will be performed for these
    //
    // month, week, day of year, day of month, weekday, hour, minute 
    // - extracts date part from unix timestamp as string / double
    //
    // years ago, months ago, days ago, hours ago, minutes ago, seconds ago
    // - extracts integer with time difference according to execution time
    //
    // numeric - forces number value
    // optional (default: none)
    //
    // string, capitalize, lowercase, uppercase - forces string value
    "format": "none",

    // whether multiple different values should be grouped together
    // for more details see Report Grouping
    // optional (default: {type: none})
    "grouping": {"type": "none"},

    // array of modifiers that will be applied to value
    // for more details see Report Modifiers
    // optional (default: [])
    "modifiers": [],

    // whether empty values should be hidden
    // optional (default: true)
    "hide_null": true
}
Report Grouping

There are several types of value grouping in reports:

  • none – no grouping applied (default value)
  • auto – uses black magic to decide which grouping method will be used
  • custom – specify boundaries between values manually
  • discretization – group to given number of groups with approximately same number of items each
  • top – group according to value of first metric to several groups, rest will be put to separate group (others)
  • histogram – group to several groups by the same range
No grouping
{
    "type": "none"
}
Auto grouping
{
    "type": "auto",
    // whether grouped value should be considered numeric
    // optional (default: true)
    "numeric": true  
}
Custom grouping
{
    "type": "custom",
     // groups values to:
     // (-infinity, 4), <4, 6), <6, 8), <8, 12), <12, infinity)
    "boundaries": [4, 6, 8, 12]  // 1 <= length <= 49
}
Discretization
{
    "type": "discretization",
    // threshold, if number of unique value is smaller than this value
    // no grouping will take place
    // optional (default: 10)
    "when_above": 65,
    // number of groups, optional (default: 10)
    "to": 10,
    // whether value should be considered to be numeric
    // required
    "numeric": true
}
Top
{
    "type": "top",
    // how many top items according to first metric will be picked 
    // without other
    // optional (default: 9)
    "number": 10,  
    // if false items with largest first metric value will be kept
    // if true items with smallest first metric value will be kept
    // optional (default: false)
    "ascending": false
}
Histogram
{
    "type": "histogram",
    // threshold, if number of unique value is smaller than this value
    // no grouping will take place
    "when_above": 65,
    // number of groups, optional (default: 10)
    "to": 10,
    // whether value should be considered to be numeric
    // required   
    "numeric": true
}
Report Modifiers

Modifiers are applied to extracted value in the same order in which they are specified in array.

[{

    // merges multiple values to one
    "type": "merge",  

    // which values should be merged
    "targets": [{ 
        // this is a single value - this occurs when no grouping is used
        "type": "single",
        "value": "Safari"
    }, {
        "type": "single",
        "value": "iOS"
    }]

    // new value after merging
    "new_name": "Apple"

}, {

    // replace value
    "type": "rename",  

    // which value should be renamed    
    "target": {
        // this is a range - this occurs e.g. when histogram is used
        "type": "range",
        "from": 4
        "to": 6
        // this is an index of this value in rows or columns, required
        "index": 1 
    },

    // new value after replacing
    "new_name": "Internet Explorer"
}, {

    // ignore value
    "type": "delete",  

    // which value should be ignored    
    "target": {
        // this is an other group value from top grouping
        "type": "other"
    } 
}]

Output

{
    "data": {
        "column_count": 4, // number of columns

        // hierarchical tree structure, the depth depends on number of items in columns in input
        // let say that original report had in columns two things: Gender, Age category
        "columns": [{
            // generated identifier used in rows for optimizations
            "id": "0", 

            // type of value (single, range, other)
            // for more information see Report Modifiers
            "type": "single", 
            "value": "Male" // actual value

            // present only if next column was specified in definition
            // contains nested column values and their identifiers
            "sub": [{
                "id": "0",
                "type": "single",
                "value": "Young"
            }, {
                "id": "1",
                "type": "single",
                "value": "Old"
            }]
        }, {
            "id": "1", 
            "type": "single", 
            "value": "Female",
            "sub": [{
                "id": "0",
                "type": "single",
                "value": "Young"
            }, {
                "id": "1",
                "type": "single",
                "value": "Old"
            }]
        }],
                 
        "groupings": {
            // types of groupings that were actually used for rows and columns
            // useful when auto grouping is turned on
            "rows": ["none", "none"],  
            "columns": ["none", "none"]
        }, 
        "row_count": 4, // number of rows

        // hierarchical tree structure, the depth depends on number of items 
        // in rows in input + number of items in columns in input 
        // lets say we have in rows two things: Continent, Device
        "rows": [{
            "type": "single",
            "value": "Europe",
            "sub": [{  // similar to columns
                "type": "single",
                "value": "PC",
                "data": {
                    // keys are ids of columns
                    // on first level is first column
                    // on second level is second column
                    // on last level is array of metrics for given row / column path
                    "0": {"1": [1, 5, 6]},
                    "1": {"0": [2, 3, 4]}
                }
            }, {
                "type": "single",
                "value": "Mobile",
                "data": {
                    "0": {
                        "0": [2, 3, 4], 
                        "1": [1, 2, 3]
                    }
                }
            }]
        }, {
            "type": "single",
            "value": "America",
            "sub": [{  
                "type": "single",
                "value": "PC",
                "data": {
                    "0": {"0": [2, 8, 6]}
                }
            }, {
                "type": "single",
                "value": "Mobile",
                "data": {
                    "1": {"0": [3, 8, 9]}
                }
            }]
        }],

        // contains statistic values such min, max, avg,
        // standard deviation if numeric histogram is calculated
        // for more information see Statistics For Histogram
        "stats": [],
 
        // false if report output is too large and only 
        // partial (probably incorrect) result is returned
        "valid": true 
    }, 
    "success": true
}
Statistics for histogram
[{
    // for which item was histogram calculated
    "field": {
        "attribute_type": "rows",  // rows or columns
        "index": 0  // index of rows or columns value
    },
    "stats": {
        "avg": 172.889569864,  
        "max": 2919, 
        "min": 0, 

        // standard deviation
        "stddev": 333.354602944,  

        "sum": 92498859, 
        "total_count": 535017
    }
}]

Retentions

POST https://cloud.exponea.com/api/v1/analytics/retentions/calculate?project_id=project_id

or using SDK

exponea.post(project_id, 'analytics/retentions/calculate', data)

Input

{
    // specify event filter matching events that should 
    // be counted as initial step
    "initial_step": {
        "type": "session_start",

        // filters to apply for the event
        // for more details see Event Attributes Filter
        // optional (default: [])
        "filter": [] 
    }, 

    // event filter specifying returning step events
    "returning_step": {
        "type": "purchase"
    },

    // required, see Date Filter the only exception to regular date 
    // filter is that this one has to be always turned on (no need for  
    // enabled option) and it has to be bounded from the left side (from
    // date is required if set to absolute)
    "date_filter": {  
        "absolute": false,
        "duration": {
            "count": 30,
            "units": "days"
        }
    },

    // available choices: 
    // - uniform - all the steps have same length
    // - custom - length of steps is specified for each step
    // optional (default: uniform)
    "steps_type": "uniform",

    // number of periods when steps type is set to uniform
    // optional (default: 8) 
    "steps": 8,

    // period indexes when steps type is set to custom
    // required if step types is set tu custom
    "steps_custom": [0, 4, 8, 120],

    // where is return event calculated
    // - exact - only given period
    // - left - all periods before
    // - right - all periods after
    // allowed values: left, exact, right
    // optional (default: exact)
    "return_type": "exact",  

    // available choices: seconds, minutes, hours, 
    // days, weeks, months, years
    // optional (default: days)
    "group_by": "days",

    // array of rows that should be grouped
    "grouped_rows": [{
        "start": 0,  // index of first row in group
        "end": 2     // index of last row in group
    }],
    
    // decides for which customers retention should be calculated
    // optional (default: {}), for more details see Customer Filter
    "customer_filter": {}     
}

Output

{
    // rows of retention table
    "data": [{
        "cells": [26, 12, 5],  // columns of retention table
        "date": 1451865600,    // unix timestamp of initial date
        "initial_step": 244    // how many customers have done initial step
    }, {
        "cells": [24, 10], 
        "date": 1451952000,
        "initial_step": 120
    }, {
        "cells": [15], 
        "date": 1452038400,
        "initial_step": 18
    }], 
    "success": true
}

Segmentations

POST https://cloud.exponea.com/api/v1/analytics/segmentations/calculate?project_id=project_id

or using SDK

exponea.post(project_id, 'analytics/segmentations/calculate', data)

Input

{
    // array of segments
    "segments": [{

        // name of segment, required
        "name": "Has session start",
      
        // decides for which customers should be contained in this segment
        // optional (default: {}), for more details see Customer Filter
        "customer_filter": {
            "or_filter": [{
                "and_filters": [{
                    "filter": {
                        "type": "funnel_steps",
                        "steps": [{
                           "name": "Session start",
                           "type": "session_start"
                        }]                
                    }
                }]
            }]
       } 

    }, {
        "name": "Rest"
    }],

    // array of metrics that will be calculated for each segment
    // for more details see Metrics
    // optional (default: [])
    "metrics": [],  

    // decides for which customers segmentation should be calculated
    // optional (default: {}), for more details see Customer Filter
    "customer_filter": {} 
}

Output

{
    "data": {
        "segments": [{  // array of segments
            "count": 120687,   // number of customers in segment
            "metrics": [1, 5], // calculated metric values
            "name": "Payers"   // segment name
        }, {
            "count": 387156,  
            "metrics": [66, 2],
            "name": "Non Payers" 
        }]
    },
    "success": true
}

Flows

POST https://cloud.exponea.com/api/v1/analytics/flows/calculate?project_id=project_id

or using SDK

exponea.post(project_id, 'analytics/flows/calculate', data)

Input

{
    // specify event filter matching events that should 
    // be counted as source
    "source_event": {
        "type": "session_start",

        // filters to apply for the event
        // for more details see Event Attributes Filter
        // optional (default: [])
        "filter": [] 
    }, 

    // if set true, only first occurence of source event will 
    // be counted for a single customer
    // optional (default: false)
    "only_first_source_occurrence": false,

    // if set to true the count of customers having specified 
    // events will be calculated, otherwise count of events will be
    // calculated, optional (default: false)
    "unique_per_customer": false,

    // how many levels should be autoexpanded
    // 0 <= levels <= 5
    // optional (default: 2)
    "levels": 3,

    // if set to true events will be processed backwards 
    // (source will be last event)
    // optional (default: false)
    "reversed_order": false,

    // specifies date filter to apply for all the events 
    // for more details see Date Filter, optional (default: {})
    "date_filter": {"enabled": false},   

    // which nodes should be extended
    // for more details see Flow Node
    // optional (default: [])
    "extended": [],

    // which nodes should be excluded from results
    // for more details see Flow Node
    // optional (default: [])
    "hidden": [],

    // which nodes should be drilled down
    // for more details see Flow Node Drill Down
    // optional (default: [])
    "drill_down": [], 

    // how many drill down variants should be calculated (upper limit)
    // optional (default: 100)
    // this option is advanced used for optimizations
    // you probably don't want to change it
    "drill_down_limit": 100,

    // decides for which customers segmentation should be calculated
    // optional (default: {}), for more details see Customer Filter
    "customer_filter": {} 
}
Flow Node
{
    // how far is event from source
    "level": 2,  
    "event_type": "session_start",

    // optional (default: false)
    "is_drilled_down": true,  

    // required only if is drilled down
    "drill_down_value": "Chrome"  
}
Flow Node Drill Down
{
    // how far is event from source
    "level": 2,  
    "event_type": "session_start",

    // event attribute which should be drilled down
    // for more details see Event Attribute
    "attribute": { 
        "type": "property",
        "property": "browser"
    },

    // how many top drill down values
    // should be calculated
    // 1 <= top <= 20, optional (default: 5)
    "top": 5  
}

Output

{
    "data": {
        "result": {
            // array of levels, source event is on first level
            // on second level are all events that happened after
            // the source event, etc...
            "levels": [
                [{ // each level contains array of nodes within that level
                     // number of customers / events for that node
                    "count": 150  
                    "event_type": "session_start"
                    "is_drilled_down": false 
                }], [
                    {
                        "count": 120  
                        "event_type": "session_end"
                        "is_drilled_down": true,

                        // just in case that node is drilled down
                        "drill_down_value": "Chrome"  
                    }, {
                        "count": 30  
                        "event_type": "session_end"
                        "is_drilled_down": true,

                        // in case that node is drilled down and this are 
                        // grouped items that were over drill down limit
                        "is_other": true,

                        // in cases when items are grouped to other there
                        // is a chance that count is an approximation
                        // in such cases lower count is the lower bound of
                        // count and count is an upper bound
                        "lower_count": 30                
                    }
                ]
            ],

            // array of connections between nodes
            "edges": [{
                "count": 120,  // number of customers / events flowing
                "from": {      // coordinates of source node in levels
                    "level": 0,
                    "node": 0
                },
                // index of target node (level is level of from + 1) 
                "to": 0,
                // time statistics of duration between events in seconds
                "times": { 
                    "min": 125,
                    "max": 1568,
                    "avg": 785
                }
            }, {
                "count": 30,
                "from": {   
                    "level": 0,
                    "node": 0
                },
                "to": 1,
                "times": { 
                    "min": 25,
                    "max": 688,
                    "avg": 358
                }
            }]
        }
    },
    "success": true
}

Geo Analyses

POST https://cloud.exponea.com/api/v1/analytics/geoanalyses/calculate?project_id=project_id

or using SDK

exponea.post(project_id, 'analytics/geoanalyses/calculate', data)

Input

{
    // series for which will coordinates be calculated
    // optional (default: [])
    "marker_series": [{
        "name": "Serie name",  
        "color": "#ffffff",    

        // which event should be used for this serie
        // optional (default: session_start)
        "event_type": "session_start",

        // which property should be considered to be x coordinate
        // optional (default: longitude)
        "x_property": "longitude",

        // which property should be considered to be y coordinate
        // optional (default: latitude)
        "y_property": "latitude",

        // which property will be returned as label
        // optional (default: city)
        "label_property": "city",
 
        // which event occurence should be taken into account
        // available choices: first, last, all
        // optional (default: last)
        "event_set": "last",

        // specifies date filter to apply for all the events 
        // for more details see Date Filter, optional (default: {})
        "date_filter": {"enabled": false},

        // decides for which customers should be calculated in this serie
        // optional (default: {}), for more details see Customer Filter
        "customer_filter": {}
    }],
 
    // optional, if specified optimizations are made that
    // only points from given viewport will be returned
    "viewport": {
        "x1": -120,  // lower bound, required, -180 <= x1 <= 180 
        "y1" -45     // lower bound, required,  -90 <= y1 <=  90 
        "x2": 90,    // upper bound, required, -180 <= x2 <= 180 
        "y2" 45      // upper bound, required,  -90 <= y2 <=  90 
    }
}

Output

{
    "data": [{  // array of series
        "name": "Serie name",  
        "color": "#ffffff",   
  
        // array of marker coordinates
        "markers": [{

            // number of events in marker
            "count": 47,  
            "label": "Bratislava",
            
            // coordinates 
            "x": 19.5,
            "y": 48.66
        }],

        // approx. how many markers are visible
        "percentage_visible: "100"  
    }], 
    "success": true
}

Metrics

There are two ways how metrics can be used. They can be used as a part of other analysis (e.g. reports, segmentations) or on their own.
To use metric as a part of analysis you can use already persisted metric by specifying metric id:

{
    "type": "metric",
    "id": "5655a68ff551f43743aff51a"  
}

Or you can embed metric definition right into the input JSON:

{
    "type": "embedded_metric",    

    // fields from metric definition, e.g. members, formula, etc...
    ...
}

To use metric separately you can use following URL

POST https://cloud.exponea.com/api/v1/analytics/metrics/calculate?project_id=project_id

or using SDK

exponea.post(project_id, 'analytics/metrics/calculate', data)

Input

{
    // required, not used during calculation
    "name": "Name of metric",  

    // parts of metric that are combined by formula
    // max 25 members are allowed
    "members": [{

        // aggregates events
        "type": "event",

        // which event should be aggregated
        "event": {
            "type": "purchase",  // optional

            // filters to apply for the event
            // for more details see Event Attributes Filter
            // optional (default: [])
            "filter": []
        },

        // specifies date filter to apply for all the events 
        // for more details see Date Filter, optional (default: {})
        "date_filter": {"enabled": false},
        
        // event attribute which should be aggregated
        // required if aggregation is not count or exists
        // for more details see Event Attribute
        "attribute": { 
            "type": "property",
            "property": "price"
        },

        // which occurence of event should be aggregated
        // available choices: all, first, last
        // optional (default: all)
        "occurence_per_customer": "all",

        // this section is common for both event and customer members
        // required, aggregation function
        // allowed values: count, min, max, sum, avg, first, last, exists
        "aggregation": "sum",

        // decides for which customers should be aggregated
        // optional (default: {}), for more details see Customer Filter
        "customer_filter": {}
        
    }, {

        // aggregates customers
        "type": "customer",
        "aggregation": "count",

        // customer attribute which should be aggregated
        // required if aggregation is not count or exists
        // for more details see Customer Attribute
        "attribute": null
        
    }, {
        // represent numeric constant
        "type": "constant",
        "value": 100  // required if type is constant
    }],

    // expression which can contain operators + - * /
    // brackets (), large characters representing members 
    // from members array where A is first member, B is second member, etc...
    "formula": "(A+B)*C"  
}

Output

{
    "data": {"value": 26953},
    "success": true
}

Common

Following common input formats are used widely in analyses.

Event attribute

There are several types of event attributes:

  • property
  • timestamp
  • event_type
  • index
  • expression
Property

Extracts property set while tracking.

{
    "type": "property", 
    "property": "browser"  // required
}
Timestamp

Extracts date time when event was created (as unix timestamp).

{"type": "timestamp"}
Event type
{"type": "event_type"}
Index

Extracts how many events have given customer before this event.

{"type": "event_index"}
Expression

Expression value based on persisted expression.

{
    "type": "expression", 

    // id of persisted expression which should be calculated, required
    "id": "5655a68ff551f43743aff51a"  
}

Optionally typed event attribute

Wraps event attribute with optional event type.

{
    "event_type": "purchase"  // optional, type of event

    // required, see Event Attribute
    // note, if no event_type is present only following event attribute
    // types are allowed: timestamp, event_type, index
    "attribute": {  
        "type": "property",
        "property": "price"
    }
}

Customer attribute

There are many types of customer attributes:

  • property
  • id
  • aggregate
  • embedded_aggregate
  • segmentation
  • expression
Property

Customer property explicitly tracked, imported or set.

{
    "type": "property", 
    "property": "first_name"  // which property to extract, required
}
Identifier

Customer id set while tracking or importing.

{
    "type": "id", 
    "id": "registered"  // which id to extract, required
}
Persisted Aggregate

Aggregated value based on persisted aggregate.

{
    "type": "aggregate", 

    // id of persisted aggregate which should be calculated, required
    "id": "5655a68ff551f43743aff51a"  
}
Embedded Aggregate

Aggregated value based on aggregate defined inline.

{
    "type": "embedded_aggregate", 
    "aggregate": {  // required
        // type of aggregation, required
        // allowed values: count, min, max, sum, avg, first, last, exists
        "type": "sum", 

        // required, specifies which events should be aggregated
        // for more information see Generic Event Filter
        "event": {"type": "purchase"}, 

        // which event attribute should be aggregated
        // required only if aggregation type is not count or exists
        "attribute": {  
            "type": "property", 
            "property": "price"
        },

        // date range for which events will be aggregated
        // optional, disabled by default, for more information see Date Filter
        "date_filter": {"enabled": false}
    }
}
Segmentation

Segment name based on persisted segmentation.

{
    "type": "segmentation", 

    // id of persisted segmentation which should be calculated, required
    "id": "5655a68ff551f43743aff51a"  
}
Expression

Expression value based on persisted expression.

{
    "type": "expression", 

    // id of persisted expression which should be calculated, required
    "id": "5655a68ff551f43743aff51a"  
}

Date Filter

There are three ways how to use a date filter:

No date filtering (default)
{
    "enabled": false
}
Absolute Date Filter
{
    "enabled": true,
    "absolute": true,

    // unix timestamp of first valid date time, optional
    "from_date": 1432476145,  

    // unix timestamp of last valid date time, optional
    "to_date": 1454333342     
}
Relative Date Filter
{
    "enabled": true,
    "absolute": false,

    // specifies period of time - length of time frame from which events will 
    // pass the filter, required
    "duration": {
        "count": 7,  // integer >=1

        // available choices: seconds, minutes, hours, 
        // days, weeks, months, years
        "unit": "days" 
    },  

    // if not specified the time frame duration will end at analysis 
    // execution time, if specified the time frame duration will end at 
    // (analysis execution time - length of offset)
    "offset": {
        "count": 2,
        "unit": "months"
    }
}

Customer Filter

Note: It is not currently possible to reorder 'and', 'or' and 'not' filters, the structure me be always the same: or filters contains and filters which can be negated.

{
    // required, specifies list of filters which are combined
    // with or operator
    "or_filters": [{

        // required, specifies list of filters which are 
        // combined with and operator
        "and_filters": [{

            // optional (default: false)
            // if set to true the nested filter will be negated
            "negate": true,
            "filter": {  // required
                // required: allowed values: attribute, funnel_steps
                "type": "attribute",  

                // which attribute should be matched
                // for more details see Customer Attribute
                "attribute": {  
                    "type": "property",
                    "property": "first_name"
                } 

                // which condition should attribute match
                // for more details see Constraint                   
                "constraint": {
                    "type": "string",
                    "operator": "equals",
                    "operands": ["Joe"]
                }
            }

        }]

    }, {
        "and_filters": [{
            "filter": {
                "type": "funnel_steps",
                // the rest of JSON for funnel steps filter is 
                // the same as in Funnels
                "steps": [{
                   "name": "Session start",
                   "type": "session_start"
                }]                
            }
        }]
    }]
}

Event Attributes Filter

Event attribute filters are specified by array. The filters are combined with 'and' operator.

[{
    // required, for more details see Event Attribute
    "attribute": {
       "type": "property",
       "property": "browser"
    },
    // required, for more details see Constraint
    "constraint": {
        "type": "string",
        "operator": "contains",
        "operands": ["explorer"]
    }
}]

Constraint

Constraints are used by filters to match values extracted by attributes. There are several types of constraints, according to data type:

  • string
  • number
  • boolean
  • date
  • list

All the constraint types support following operators that don't require any operands: is set, is not set, has value, has no value.

String
{
    "type": "string",

    // required, accepted values: equals, does not equal, in, 
    // not in, contains, does not contain
    "operator": "equals",

    // required, array of operands that are applied to operator
    // the length of array depends on type of operator
    //
    // for equals, does not equal, contains and does not contain
    // only one operand is used
    //
    // for in and not in multiple operands can be specified    
    "operands": ["joe"] 
}
Number
{
    "type": "number",

    // required, accepted values: equal to, in between, not between, 
    // less than, greater than
    "operator": "in between",

    // required, array of operands that are applied to operator
    // the length of array depends on type of operator
    //
    // for equal to, less than and greater than only one operand is used
    // for in between and not between two operands are used
    "operands": [4, 6] 
}
Boolean
{
    "type": "boolean",
    "operator": "is",  // required, accepted values: is
    "value": "true"    // accepted values: true, false
}
Date
{
    "type": "date",

    // allowed choices more than, less than, 
    // matches current day, matches current month, matches current year
    "operator": "more than", 

    // following attributes should be set only when operator 
    // is set to more than or less than
    "amount": 5,  // integer >= 1

    // available choices: seconds, minutes, hours, days, weeks, months, years
    "units": "minutes",      

    // available choices: ago, ahead
    "tense": "ago"  
}
List
{ 
    "type": "list",
    "operator": "contains"  // required, accepted values

    // required, item that should be contained in 
    // list to match the filter
    "value": "item"         
}

Advanced

These models are quite specialized and probably won't be used from Apps. Anyway documentation for them is here.

Global Filters

{ 
    // date filter to apply, for more details see Date Filter input
    // optional (default: {})
    "date_filter": {},  

    // if true date filters will be replaced with date filter specified above
    // otherwise an intersection will be calculated
    // optional (default: false)
    "date_filter_override": false,  
        
    // array of filters to be applied
    // optional: (default: [])
    "attributes": [{
        // required, currently only type of global filters that are available
        "type": "pick_values",

        // whether filter should be applied or not, optional (default: false)
        "enabled": true,  

        // descriptive name of filter (not used in calculations)
        // required
        "name": "By name",  
        
        // which attribute should be filtered, required
        "attribute": {
            // whether filtered attribute belongs to customer or event
            // required, allowed choices: customer, event
            "type": "customer",
            
            // required, type depends on field type, it could be 
            // Customer Attribute or Optionally Typed Event Attribute
            "attribute": {  
                "type": "property",
                "property": "first_name"
            }
        }

        // list of values that matches the filter, required 
        "values": ["Joe", "John", "Jacob"]  
    }]  
}