Woopra Docs

The Woopra Developer Hub

Welcome to the Woopra Developer Docs developer hub. You'll find comprehensive guides and documentation to help you start working with Woopra as quickly as possible.

Get Started      Documentation Reference
Suggest Edits

Intro: Javascript API

 

The Javascript Tracking API is the primary way to get data into Woopra from your website. The API code is loaded in the browser as the result of running the Javascript Snippet.

In order to use and master this simple but crucial API, you should perform this list of tasks to complete, and topics to understand:

  • Learn about the snippet, and get it placed in your page code appropriately.
  • Determine what should go in your tracker config and place a call to woopra.config() right under your snippet. At the minimum this must include your project name.
  • Learn the woopra.track() function, and how to use it to track your own custom events. This may include determining what events it is important for your business to track. See What do I track?.
  • Learn the woopra.identify() function, and how to use it to set visitor properties on your visitor profiles, and to associate each return session with a previously-seen visitor's profile, using the features of Woopra's ID system.

The Woopra JavaScript tracking code is designed for easy customization. It can be tailored to identify your website visitors and track any customer action on your site.

The functions available return the Woopra tracking object in the browser, so you can chain methods:

window.woopra.identify('testEmail@emails.com').track('my_event', {
  eventProp1: 'event prop value'
})
Suggest Edits

The Javascript Snippet

 

The javascript snippet is a small function that you place in your webpage to initialize the Woopra tracking object, and to asynchronously load the Woopra tracker code. It is typically placed in the <head> of your document. It loads the tracker script asynchronously and does not block. It also defines the tracker's methods so that you can immediately set the configuration and call track() and identify(), and it will queue those calls and run them when the tracker loads.

Using the Snippet

The Pure Snippet Function

There are many ways you can customize your use of the snippet. We will go over the general best-practices.

Here is the raw javascript snippet:

!function(){var a,b,c,d=window,e=document,f=arguments,g="script",h=["config","track","trackForm","trackClick","identify","visit","push","call"],i=function(){var a,b=this,c=function(a){b[a]=function(){return b._e.push([a].concat(Array.prototype.slice.call(arguments,0))),b}};for(b._e=[],a=0;a<h.length;a++)c(h[a])};for(d.__woo=d.__woo||{},a=0;a<f.length;a++)d.__woo[f[a]]=d[f[a]]=d[f[a]]||new i;b=e.createElement(g),b.async=1,b.src="//static.woopra.com/js/w.js",c=e.getElementsByTagName(g)[0],c.parentNode.insertBefore(b,c)}("woopra");

The snippet is an immediately-invoked function expression that asynchronously loads the javascript tracking SDK code into the browser. It also prepares some queueing so that you can make calls to the methods before the tracking code finishes loading, and it will evaluate those calls when it finishes loading.

This is the minimum of what you need to paste into your webpage code to make the Woopra tracker available to you. This will not track any events, however. Rather, it will expose the config(), track(), identify(), and push() functions for you to use in your client side javascript. To see any data in Woopra, you will also at minimum need to make a call to woopra.config() to tell the tracker object the name of your project, and a call to woopra.track() to actually track an event in Woopra.

A typical snippet + tracking implementation

Here is an example installation inside the <head> of a normal website. It will install the tracker on every page load, and track a standard built-in pageview event as well. (See woopra.track() for more on sending the default pageview event, and Built-in Events for more on built-in events in general.) One thing to note is that if you have a Single Page Application, the <head> section of the page may only be rendered once, thus only tracking a single pageview when in fact your visitor may perform many different app views in your web app. See SPAs for more info on this.

<head>
  <!-- ... Your head code -->
  <script>
    //WOOPRA SNIPPET:
    //initialize tracker object on page and create queues for funciton calls
    //and async load tracker.
    !function(){var a,b,c,d=window,e=document,f=arguments,g="script",h=["config","track","trackForm","trackClick","identify","visit","push","call"],i=function(){var a,b=this,c=function(a){b[a]=function(){return b._e.push([a].concat(Array.prototype.slice.call(arguments,0))),b}};for(b._e=[],a=0;a<h.length;a++)c(h[a])};for(d.__woo=d.__woo||{},a=0;a<f.length;a++)d.__woo[f[a]]=d[f[a]]=d[f[a]]||new i;b=e.createElement(g),b.async=1,b.src="//static.woopra.com/js/w.js",c=e.getElementsByTagName(g)[0],c.parentNode.insertBefore(b,c)}("woopra"); /*This function is invoked with the tracker object name.  You can change this if you like. See below*/

    //WOOPRA TRACKER:
    // configure tracker
    //There are many options you can pass here to configure the tracker.
    //All options have sane defaults.
    //The only REQUIERD option to set is your 
    //  project name in the "domain" property
    woopra.config({
     domain: "mybusiness.com" //This is the minimum required config
    });

    // track pageview
    woopra.track(); //With no arguments, the track funciton will track a default pageview event. See docs for woopra.track() function
  </script>
  
  <!-- ... More of Your head code ... -->
</head>

Remember, the snippet on line 6 above is what loads the woopra object onto the window. The calls to woopra.track() etc. are using the woopra object that the snippet loaded.

After the first call to woopra.track(), the ping will start. The ping sends requests to the Woopra tracking servers on an interval so that Woopra can determine the duration of a pageview, the length of a session/visit, etc. For more on the ping, see The Ping.

What is the difference between the snippet and the tracker?

It is important to understand the difference between the Snippet and the Tracker. The Snippet is a short simple function that loads the Tracker. The Tracker Object itself is the javascript code that sends events into Woopra.

Once installed, the snippet should never need to be changed or be updated. The snippet loads the Tracker code itself from the Woopra servers. The Tracker code may change at times based on new security concerns on the web, or new features that we may add. But when this happens, you don't have to change anything in your page to get the new tracker and features, becasue the snippet code loads the newest version of the tracker every time the web page is loaded on a visitor's browser.

Changing the name of the tracker object

The Snippet function takes one parameter: a string which will be the name of the tracker object on the window object. In the examples above, the string "woopra" is passed as the argument. This means that your tracker will be available on the browser at window.woopra. You can alter this if you wish. You can pass any valid javascript object parameter key string here. For example, if you want to access the tracker at window.tracker, you can invoke your snippet with `"tracker" as the argument.

When Can I Call `woopra.track()`

The snippet begins the asynchronous task of downloading the latest Woopra tracker object, and installing it onto the window object. Becasue this is asynchronous, the next line that runs after the snippet is guaranteed to be executed before the tracker is loaded. That is why part of what the snippet does is prepare a set of task queues to be run once the tracker loads.

So you can call woopra.track() immediately after the line in which you place the snippet. But the tracking data will not be sent before the Woopra tracker is loaded.

If you need a callback to know when the tracker has actually completed loading, you should put a callback in your first call to woopra.track(). See the woopra.track() docs for more info.

Suggest Edits

woopra.config()

 

The config function is used to tell the tracker what project you are tracking. It also allows you to set a number of options that can affect your default pageview tracking (woopra.track() No Args!!), the behavior, domains, and locations of cookies, how the ping works, etc.

The config function supports key/value singleton argument:

woopra.config("cookie_name", "my_business_cookie");

Or an object of keys and values:

woopra.config({
    download_tracking: true,
    outgoing_tracking: true,
    ping_interval: 30000
});

Configuring your Tracker

The Woopra tracker can be customized using the config function. Find the list of options below:

Option
Default
Description

domain

Website domain

Project Name in Woopra

cookie_name

wooTracker

Name of the cookie used to identify the visitor

cookie_domain

Website domain

Domain scope of the Woopra cookie

cookie_path

/

Directory scope of the Woopra cookie

cookie_expire

2 years from last action

Expiration date (Date object) of the Woopra cookie

ping

true

Ping woopra servers to ensure that the visitor is still on the webpage

ping_interval

12000

Time interval in milliseconds between each ping

idle_timeout

300000

Idle time after which the user is considered offline

download_tracking

false

Track downloads on the web page

outgoing_tracking

false

Track external links clicks on the web page

outgoing_ignore_subdomain

true

Do not include links to subdomains as outgoing links

download_pause

200

Time in millisecond to pause the browser to ensure that the event is tracked when visitor clicks on a download url.

outgoing_pause

400

Time in millisecond to pause the browser to ensure that the event is tracked when visitor clicks on an outgoing url.

ignore_query_url

true

Ignores the query part of the url when the standard pageviews tracking function (track() with no args) is called

map_query_params

{}

Object with URL parameter keys mapped to action property names. (e.g. { ref: "campaign_name" })

hide_campaign

false

Enabling this option will remove campaign properties from the URL when they’re captured (using HTML5 pushState).

Suggest Edits

woopra.track()

 

The Woopra JavaScript tracking code is designed for easy customization. It can be tailored to identify your website visitors and track any customer action on your site.

In order to activate tracking by Woopra’s servers you must insert the javascript snippet into the <head> element on each page you wish to be tracked. Tracking occurs when a visitor’s Web browser executes the Woopra javascript and pings the Woopra servers. Custom visitor data, or custom events, can be added to Woopra and the reference below will demonstrate how this is done.

Javascript code is asynchronous and should be inserted in the <head> tag rather than always needing to be inserted in the page footer. By placing it in the header, that pageview is going to be tracked before the visitor leaves the page.

Default Pageview Event

Calling woopra.track() with no arguments sends the default built-in "pageview" event. Some of the options that you set in the tracker config are for this built-in event.

woopra.track() (No Arguments)

window.woopra.track();
 
// The line above is equivalent to:
woopra.track("pv", {
    url: window.location.pathname,
    title: document.title
});

Tracking Custom Events

Woopra also allows you to track Custom Actions in addition to simple pageviews. Let’s say you are running a website where people can signup. You can track these actions using Woopra’s Custom Events. To track custom actions, you can define the action name string and the properties associated with that action object:

woopra.track(eventName<lowercase string>, [properties]<object>, [callback]<function>)

Argument
Type
Description
eventName

String

The name of the event that you are tracking. Should be lower case

properties

Object

An object of any properties you want to track with the event

callback

Function

A callback function to run after the tracking function has been successfully received by Woopra

All event names and properties should be lowercase.

It is best practice to use _s instead of spaces.

But don't worry, you can set up display names for events in your schemas. You can even create sentence templates using event property values for when an instance of the event is shown in the Woopra interface. Think: "James Kirk Purchased a Starship for 1000 bitcoin" from your template: ${visitor.full_name} Purchased ${action.product_name} for ${action.item_price} ${action.currency}

The Callback

Optionally, you can pass, as the last argument to woopra.track() a callback function that will be called after the tracker has received the response from the tracking server.

This can be useful if you need to access woopra labels data (at window.woopra.labels) but only after it has been evaluated and updated by the tracking server.

You can also use this as a callback to know not only when the snippet has loaded the tracker object, but when the very first woopra tracking action has successfully completed. Essentially it guarantees that the woopra tracker object has been loaded which may be important even though you can in fact call woopra.track() and the other methods as soon as the snippet code has run.

Example

woopra.track("signup", {
    company: "My Business",
    username: "johndoe",
    plan: "Gold"
});

The code above will track a custom event titled “signup”, and provides some more information like the username and company of the account created. Just imagine all of the custom events that can be tracked on your website: payment, comment, logout, email, etc…

What’s even more important about custom events is that you can always run custom reports about the data you pass to Woopra, so for the example given above, you could get the number of signups by company.

Don't Forget Your Schemas

When you track custom events, remember to update your schema on Woopra. Woopra will auto-generate a schema for the first event of that name that comes in, but you can add a display name and declare the types of values passed as event properties. That will help the rest your team to identify the events being tracked and Woopra will automatically build reports out of the box based on the event properties.

Below is another example to track when people click on the play button with id="play-button":

document.getElementById("play-button").onclick = function() {
    woopra.track("play", {
        artist: "Dave Brubeck",
        song: "Take Five",
        genre: "Jazz"
    });
};
Suggest Edits

woopra.identify()

 

Identifying Customers

In order to identify a customer, you need to send their email address to Woopra as a custom visitor property. Calling identify() does not send anything to Woopra, in order to send the properties and identify the visitor, you need to call track() after you identify(), or if you do not wish to track an event, you may call woopra.push() to send a call strictly with identifying information.

All visitor properties should be lowercase

woopra.identify(visitor-properties<object>)

Argument
Type
Description
properties

Object

An object of any properties you want to save for this current visitor.

Example

// configure
woopra.config(...);
 
// Identify customer
woopra.identify({
    email: "johndoe@mybusiness.com",
    name: "John Doe",
    company: "My Business"
});
 
// track
woopra.track();

Standard attributes which will be displayed in the Woopra live visitor data include:

  • id – used as a primary identifier.
  • email – displays the visitor’s email address and it will be used as a secondary unique identifier.
  • name – displays the visitor’s full name
  • company – displays the company name or account of your customer
  • avatar – is a URL link to a visitor avatar

But you can define any attribute you like and have that detail passed from within the visitor live stream data when viewing Woopra.

Note that if you wish to identify a visitor without sending a tracking event, you can call the function push().

Suggest Edits

woopra.push()

 

When you run woopra.identify(), the SDK assigns the properties you pass to the visitor object for the next track request. The track() function will send the request with any visitor properties that have been set, and with the event name and event properties as well in the same request.

Sometimes, however, you do not want to track an event by a visitor, but only to set a property on that visitor's profile, or identify the visitor by email, ID, or phone number. In this case, you should use woopra.push()

woopra.push([callback])

Argument
Type
Description

callback

Function

A callback function to run after the tracking function has been successfully received by Woopra

Example

woopra.identify("email", "johndoe@mybusiness.com").push();
 

Running Javascript Triggers

Label Membership Information

Suggest Edits

Intro: Tracking SDK's

 

The tracking SDK's are small packages with convenience functions written in different languages. Essentially what they do is wrap the HTTP Tracking API, which is the core to all tracking in Woopra.

The most detailed general tutorial for using tracking sdks can be found in the Browser Javascript API. Though it has some functionalities, such as the ping, that are not supported in the serverside SDKs.

The SDK's listed on the left in this section are all links to the github repositories. The most up-to-date docs are in the README.md file in the base directory of those repositories. You can get there by clicking the appropriate SDK in the list on the left.

Contributing

Please do contribute! We are a fairly small developer team here at Woopra, and sometimes there are no experts in house in, say PHP or Objective-C. We may not be able to quickly update our Python SDK for Python 3, or to get our iOS SDK tracking the new device types correctly. So yeah, we love merging pull requests! (Including updating the README!) And since everything is basically an abstraction above the tracking api, developing on the SDK's is very simple and easy.

Issues? Last Resort:

If your use case just isn't supported in our SDK's or it is but the SDK just wont work with your setup or for your needs, the last resort should always be to simply use the HTTP Tracking API directly.

Suggest Edits

Intro: HTTP Tracking API

The most basic way to get data into the Woopra system

 

The HTTP tracking API is the most fundamental way to track events and visitor properties into Woopra. All of the tracking SDKs use this API. It is also fairly simple. If you have any issues with one of the SDK's and its compatibility or anything else, it is quite trivial to use the HTTP Tracking API instead, and gain full control of the tracking requests that you are sending to Woopra.

Types of Tracking Data

Custom Events and Event Properties

One of the key features of Woopra is the ability to track Custom Events. Understanding custom events and custom event properties is crucial to getting a good tracking implementation, and to realizing the full power of Woopra. Custom events are tracked using the /track/ce endpoint. These properties are sent with the key prefix: ce_

Custom Visitor Data

Woopra allows you to store custom visitor data on the profiles of your visitors. You can add and set visitor properties on the visitor who performs the action you are tracking. This can be done when tracking a custom event via /track/ce , or without tracking an event by calling /track/identify. These properties are sent with the key prefix: cv_

Custom Visit Data

Woopra also allows you to set metadata that span multiple events, but are not saved on the visitor's profile. This is session or visit data. Examples of this would be device_type, browser, user-agent, etc. While these properties are built-in and thus are not prefixed, and in some cases are in fact generated from http headers, etc., you can also create custom session/visit properties by using the prefix. These properties are sent with the key prefix: cs_

Custom Data Property Prefixes: ce_, cv_, and cs_

In order to allow for fast encoding, and a flat data structure, the GET request parameters are prefixed with cX_ to denote if the item is a custom event property, a custom visitor property, or a custom session property. We do try to respond to track requests within 300ms after all.

  • Custom Event properties are prefixed with ce_
  • Custom Visitor properties are prefixed with cv_
  • Custom Session properties are prefixed with cs_

Special Fields

Parameters that do not have these prefixes are non-custom, built-in or required event metadata such as the event name itself, the timeout (how long before the session is considered over before another event occurs), the project you want to send this event to, the event timestamp, the referer, etc. For legacy reasons, the cookie (aka device id) is also sent without a prefix.

Conventional Fields

Some fields can be sent as custom event properties but will be treated specially by the woopra system. The clearest example of this is the campaign data fields. Sending cv_campaign_name will actually cause the Woopra system to recognize and display the campaign data for that event in a special way. It will also use this data in attribution reports.

Another example is the url property of a pageview event. Woopra will use this to look for utm_ tags and treat them the same as campaign_name and campaign_source event properties. For more information on these fields, see TODO.

For More

Url Encoding

Don't forget to url encode your property keys and values.
Note: all examples omit encoding for legibility!


Example:

Consider these request query parameters:
Percent encoding has been removed for legibility, but you must precent encode each element! (In this case it's just the spaces that need to be encoded)

?project=myProject.com
  &event=bark
  &timestamp= 1492030800000
  &cv_name=Rio
  &ce_campaign_name=Teach Speak Command
  &ce_bark_volume=loud
  &cs_is_post_nap=true

The project, event and timestamp parameters all cary necessary or overriding event metadata. The event name, the destination project, the event timestamp to use instead of the time of receipt, etc.

The cv_name will turn into a property on the visitor's profile. That property will be called "name", and will have the value on this visitor profile of "Rio". The prefix is removed before it is actually put into your data.

The ce_bark_volume on the other hand, will be a property of this particular bark event. It will show up when you expand the event in a visitor's event timeline as "bark_volume", and will have the value set as: "loud." Similarly, the ce_campaign_name will also show up as an event property, but additionally, it will be used to report on attribution and for some UI conveniences in the Woopra app.

Finally, the cs_is_post_nap session property will apply to all events in this session, and can be viewed in the interface when expanding a session in a profile's activity list. In this case, we can see that this set of events occurred post nap.


Event and Session Timeout

The timeout parameter (not prefixed), represents the elapsed time, starting from when this event is tracked, after which the visitor's session or visit should be considered over if no further events are tracked. It takes an integer value in milliseconds. You can prevent a session from ending without tracking another event if you send a /ping or /update request for the same visitor.

Responses

Response Codes

You will get a 2xx as a response code immediately unless your request is dropped for one of the three reasons in the "Dropped Requests" section below.

  • 200 -- Processed. Request has been received and logged
  • 202 -- Queued. Request could not be processed within 300 ms due to load, so it has been queued.
  • 401 -- Unauthorized: you have secure tracking enabled, but the request is not authenticated
  • 403 -- Forbidden: Your project is not registered, or you have defined exclusions for this visitor
  • 5XX -- There has been a server error. Please double check your request format, then report to support@woopra.com.

Response Bodies

The tracking servers will usually respond with a string of javascript to be run on the browser of the visitor if possible. The Javascript client-side API, for example runs this string of code, which can invoke trigger actions from the system or AppConnect apps, as well as set metadata on the tracker object itself for access by these triggers, such as the visitors's label membership information.

Dropped Requests

Woopra's tracking servers are as forgiving as they can possibly be. There are very few reasons for which a request sent to a tracking server will be dropped and not tracked. Here they are:

  1. If there is no project in the request, or the project does not exist, the Woopra Tracking servers do no know on which Woopra instance to apply the data. In this case, the request will be dropped. The preferred parameter to send your project name in a tracking request is project, but for legacy and flexibility reasons, it will also check these parameters for a project title: domain, website, host, and alias. The Server will return a 403.

  2. If Secure Tracking is enabled and the tracking request is not secure, the tracking servers will refuse to track the event in the request. The Server will return a 401.

  3. If the visitor is excluded for instance by ip or by user-agent in your settings, Woopra will drop the request. See Excluding Visitors. The server will return a code 403.

Missing Visitor Identifiers

If there are no Visitor Identifiers for the visitor, the tracking servers do not know on which visitor profile to apply this action. Identifiers include but are not limited to: id, email, and cookie. See Woopra's Profile ID System for more-in depth discussion on visitor identifiers, and the id hierarchy.

In this case, the tracking server will usually accept the request, but will generate a random value and place it in the cookie field of the visitor. (Woopra cookies are the lowest level of id in the id hierarchy. Think of woopra cookies as a device_id).

If this happens, you will never be able to identify the user who performed the action, nor will you be able to assign more actions or visitor properties to this user.

Sending Event Timestamps

Historical Events

You may send any timestamp in the past with your event. Sending future timestamps will not work reliably. Sending old timestamps will work, and the data will be considered in it's true place in time. However, please note that sending events older than your data retention window will result in an apparent loss of those events.

Future Events

Sending events with timestamps in the future can work, but can also cause unexpected behavior. The event will be logged in the log file of the time of receipt. The data will not show up in the Woopra UI until the timestamp has passed, ie: until the event "happens."

In both cases, the larger the difference between the timestamp of the event itself and the date of the transactional db log file in which it was recorded, the more likely the event will be missed in analytics, and segment reporting. This generally happens becasue certain time constraints of a report cause the system to only evaluate log files of that date range. If you think you may be missing out on data that is in your woopra when you run certain reports, reach out to support@woopra.com to get more details on this with regards to your specific situation.

Old Events

Note, that while the tracking servers will accept a well-formed request in which the timestamp is older than your data retention policy limit, you will likely never see those events in the interface.

Maximum Data Sizes

Tid Bits

  • There is no limit on the number of the parameters, as long as your browser can handle the size of the resulting GET request.
  • It is recommended to use non-blocking http clients, especially for high volume traffic.
  • The Http client used to start the tracking requests should be able to handle 301, 302 redirects, and should preferably handle cookies.
Suggest Edits

/track/ce

To track events in Woopra, send Http GET requests to this endpoint

 

Endpoint: http(s)://www.woopra.com/track/ce

Track Requests

Track requests track an event performed by a visitor. This is the main endpoint to use, and may very well end up being the only endpoint you need to use.

GET Request Parameters

Parameter
Required
Type
Example
Description

project

Required

<string>

"my-project.com"

The name of your project in Woopra.

cookie

Optional (Recommended. See Description)

<string>

"kDei34gy3h25F"

The Cookie should be thought of as a device id. It can also be used for anonymous ids. Required if no cv_{Visitor Identifier}. See The Cookie

event

Required

<string> lowercase

"form_submit"

The name of the custom event that you are tracking. See Custom Events.

timestamp

Optional

<integer> unix ms timestamp

1489704275615

Event timestamp – time in milliseconds since the UNIX epoch that the event occurred. (this can be back-dated, but not in the future.)

cv_{Visitor Identifier}

Optional (Required to identify a user)

<string>

cv_email: "tigi@woopra.com"

An identifier or multiple identifiers to associate with this visitor. Required if no cookie. See Visitor Identifiers

cv_{Visitor Property}

Optional

Various (See Description)

cv_first_name: "Tigi"

Properties to set on the visitor's profile. These can be strings, numbers, dates, etc. See Visitor Properties

ce_{Event Property}

Optional

Various (See Description)

ce_total_value: 54

Properties to set on the custom event. These can be strings, numbers, dates, etc. See Custom Events.

cs_{Visit Property}

Optional

Various (See Description)

cs_is_work_computer: false

Properties to set on the visit/session. These can be strings, numbers, dates, etc. See Visit/Session Properties

referer

Optional

<string> valid url

"www.google.com"

Visit’s referring URL, Woopra servers will match the URL against a database of referrers and will generate a referrer type and search terms when applicable. The referrers data will be automatically accessible from the Woopra interface

ip

Optional

<string> Valid IP Address

"127.0.0.1"

IP address of the visitor. If defined, it overrides the physical IP address of the connection.

timeout

Optional

<integer> milliseconds

Default: 30000 //30 seconds

In milliseconds, defaults to 30000 (equivalent to 30 seconds) after which the event will expire and the visit will be marked as over, and the visitor as offline.

browser

Optional

<string>

"chrome"

User’s browser. If defined, it overrides the auto-detected browser from the request's user-agent. You can also build your custom user-agent.

os

Optional

<string>

"Windows 10"

User’s operating system. If defined, it overrides the auto-detected operating system from user-agent.

device

Optional

<string>

eg: "mobile" or "i-phone"

User’s device type. If defined, it overrides the auto-detected device type from user-agent. Common values are mobile, tablet and desktop.

Pageviews

Woopra has a default pageview event that the Javascript Client Tracker send when there are no arguments sent to the track function. It automatically adds certain visit and event properties such as page title, url, device resolution, etc. Here is an example of request parameters sent from the SDK for a built-in pageview event:


{
  project: "dev.woopra.com"
  instance: "woopra"
  screen: "2560x1440"
  language: "en-US"
  app: "js-client"
  referer:"www.google.com"
  cookie: "5e0saOzmYfgh4q"
  event: "pv"
  ce_title: "Real-time Customer Analytics - Woopra"
  ce_domain: "www.woopra.com"
  ce_url: "/welcome-page"
	ce_uri: "https://www.woopra.com/welcome-page"
}

To track similar pageview events via this API, it is recommended that at least ce_url is used for the page path, and ce_title is used for the page title. This will integrate seamlessly with the Woopra interface and built-in pageview event reporting.

Example

To track a payment by John Smith of $149.95 for a Titanium package, you should issue a tracking request similar to the following:

http://www.woopra.com/track/ce/
  ?host=mywebsite.com
  &response=json
  &cookie=AH47DHS5SF182DIQZJD
  &timeout=300000
  &cv_username=John+Smith
  &cv_email=john@mail.com
  &event=payment
  &ce_amount=149.95
  &ce_type=blog
  &ce_package=Titanium
Suggest Edits

/track/identify

To update visitor properties in Woopra, send Http GET requests to this endpoint

 

Endpoint: http(s)://www.woopra.com/track/identify

Identify requests

Identify requests can be used to ID a visitor and/or add properties to that visitor. The endpoint is: http(s)://www.woopra.com/track/identify and the parameters are the same as a regular tracking request (event data will be ignored)

GET Request Parameters

Parameter
Required
Type
Example
Description

project

Required

<string>

"my-project.com"

The name of your project in Woopra.

cookie

Optional (Recommended. See Description)

<string>

"kDei34gy3h25F"

The Cookie should be thought of as a device id. It can also be used for anonymous ids. Required if no cv_{Visitor Identifier}. See The Cookie

cv_{Visitor Identifier}

Optional (Required to identify a user)

<string>

cv_email: "tigi@woopra.com"

An identifier or multiple identifiers to associate with this visitor. Required if no cookie. See Visitor Identifiers

cv_{Visitor Property}

Required

Various (See Description)

cv_first_name: "Tigi"

Properties to set on the visitor's profile. These can be strings, numbers, dates, etc. See Visitor Properties

Example

curl http://www.woopra.com/track/identify\
?host=mywebsite.com\
&cookie=AH47DHS5SF182DIQZJD\
&cv_email=tigi@brembo.com\
&cv_name=Tigi\
&cv_age=31
Suggest Edits

/track/update

Used to update event properties on a previous event in this un-expired session

 

Endpoint: http(s)://www.woopra.com/track/update

Event Update Requests

It is possible to add/modify an event property after the event has been tracked. This can be useful when tracking ongoing activity such as watching a video.

http://www.woopra.com/track/update
  ?host=mywebsite.com
  &event_id=aq3IUy7489d
  &ce_duration=32
  &ce_unit=seconds

Which event is updated?

There is a order of priority for finding the event to update

  1. You can send your own uid for the original event as event_id (no prefix) when you send it and use that id to reference it in the update request.
  2. You can send the event name as event, just like you did on the original event, and the update will apply to the last event by that name that occurred in this session.
  3. Otherwise, the update will apply to the last event sent.
Suggest Edits

/track/ping

Used to reset the session timeout counter, keeping this session alive

 

Ping requests

Optionally, ping requests can be periodically sent to Woopra servers to refresh the visitor timeout counter for the session/visit. This is used if it’s important to keep a visitor status ‘online’ when she’s inactive for a long time (for cases such as watching a long video). The javascript SDK will automatically start sending pings after the first event is sent.

http://www.woopra.com/track/ping
  ?host=mywebsite.com
  &cookie=AH47DHS5SF182DIQZJD
  &timeout=300000
  • There is no need to have custom parameters in the ping request.
  • It is recommend to send ping requests at intervals slightly less than the timeout value. If the timeout is 60 seconds, consider pinging the servers every 55 seconds, otherwise you will be sending unnecessary requests.
Suggest Edits

Examples

Examples of tracking code

 

Tracking Request Examples

Track a purchase event with some visitor data, and purchase event properties

http://www.woopra.com/track/ce
  ?host=mywebsite.com
  &response=json
  &cookie=AH47DHS5SF182DIQZJD
  &timeout=300000
  &cv_name=John+Smith 
  &cv_email=john@mail.com
  &event=purchase
  &ce_item=Coffee+Machine 
  &ce_category=Electric+Appliances
  &ce_sku=K5236532
Suggest Edits

Advanced

Advanced Tracking API usage concepts and examples.

 

Custom Email Tracking

One inventive way to use our HTTP Tracking API is to use it to track your campaign email opens. You probably need to have some development experience to get this working.

Typically, to track marketing email lifecycle events, one would simply install the Woopra integration for the relevant email provider in the Integrations Interface in Woopra. But we haven't integrated with every email platform, and some email marketing tools that we have integrated with, don't have this functionality either in the tool, or in our integration specifically.

So one solution is to use our HTTP Tracking API to do some of what a fully-featured email marketing automation platform does as far as tracking email lifecycle events.

TL;DR

In short, what you will be doing is creating a an <img> tag with a source url that will in fact send data to Woopra's tracking servers. Basically a webhook to Woopra from each individual email you send.

Details

So let's say we want to track an event with this basic information in it when someone opens an email:

{
  project: "<your-woopra-project>",
  name: ,
  visitor: {
    email: "*|EMAIL|*", //example merge tag from madril/mailchimp
  	fname: "*|FNAME|*"
  },
  event: {
    name: "email_opened",
    params: {
      email_subject: "*|MC:SUBJECT|*",
      list_name: "*|LIST:NAME|*",
    	campaign_name: "*|CAMPAIGN_NAME|*",
      campaign_id: "*|CAMPAIGN_UID|*",
      campaign_source: "email",
      //etc.
    }
  }
}

We have used merge tags from mailchimp as examples of how to get the data from your email provider. It may be via templated values like merge tags in mandrill or mailchimp, or it may work in some other way, and you'll have to figure this out as part of gettign the data into the email.

Once you know how to get all the data you want, compose the above event into a url that hits the Woopra HTTP Tracking API. The above data would look like this:

https://www.woopra.com/track/ce?
	project=woopra-project.com
  &event=email_opened
  &cv_email=*|EMAIL|*
  &cv_fname=*|FNAME|*
  &ce_email_subject=*|MC:SUBJECT|*
  &ce_list_name=*|LIST:NAME|*
  &ce_campaign_name=*|CAMPAIGN_NAME|*
  &ce_campaign_id=*|CAMPAIGN_UID|*
  &ce_campaign_source=email

Finally, You would put this into an html image tag and place that raw html into your emails (perhaps in the signature so that it is always there).

The image tag may look like this:

<img src="https://www.woopra.com/track/ce?project=woopra-project.com&event=email_opened&cv_email=*|EMAIL|*&cv_fname=*|FNAME|*&ce_email_subject=*|MC:SUBJECT|*&ce_list_name=*|LIST:NAME|*&ce_campaign_name=*|CAMPAIGN_NAME|*&ce_campaign_id=*|CAMPAIGN_UID|*&ce_campaign_source=email"/>
Suggest Edits

Intro: HTTP APIs

 

The Woopra API is mostly RESTful. We call it RESTish. API calls can be made with HTTP POST or GET to https://www.woopra.com/rest/[version]/[endpoint].

Authentication

The Woopra RESTish APIs use basic http authorization. Generate API keys on a per-user basis from the Access Keys tab in the Member's Area.

Rate Limits

There is currently a global per-project limit on API calls:
300 per minute, 600 per hour and 3000 per day.

This is subject to change as we tune the system.

Rate limited requests will receive a status code of 429

Versioning

The only supported version currently is version 3.0. So all urls should start with:
https://www.woopra.com/rest/3.0/{ENDPOINT}

Suggest Edits

Building Segments

How to Build Your Own Segmentation Filters to Use With, e.g.: The Reporting API

 

Analytics are great because they provide answers to all sorts of questions:

  • How many people visited my Website?
  • When did they visit?
  • Where did they come from?

But while analytics give us some answers, they also create many more questions:

  • Of the people who came to the site, how many visited from the US?
  • Of the US visitors, how many came from search engines?
  • And how much items were purchased by just those visitors?
  • Segmentation allows you to narrowly focus attention on only the visitors you want to analyze, and probe deeper to make better decisions.

Segments

Segments consist of two parameters: are (who they are, i.e: visitor Properties) and did (what they did i.e: visitor actions) and each segment contains an operator and a list of filters. Reports and Searches support a segments and they consist of an array of the segments defined below.

{
  "are": {
    "operator": "AND", // AND or OR
    "filters": []
  },
  "did": {
    "operator": "AND", // AND, OR or THEN
    "filters": []
  }
}

"Are" Filters

The are filters are simple constraints that cover the Custom Visitor Data. This filter below will narrow the query response down to those from companies that have more than 300 employees and are at the trial stage.

{
  are: {
      "operator": "AND",
      "filters": [{
          "scope": "visitors",
          "key": "company size",
          "match": "gte",
          "value": 300 
      }, {
          "scope": "visitors",
          "key": "stage",
          "match": "match",
          "value": "trial"
      }]
  }
}

"Did" Filters

Every did filter consists of 4 objects:

  • action
  • aggregation
  • timeframe
  • visit

action

Action defines the action targetd in this behavioral filter. For example, if you want to filter people who made a payment, the action object should define the action payment and its constrains.

action:{
  "operator": "AND",
  "filters": [{
    "scope": "actions",
    "key": "name",
    "match": "match",
    "value": "payment"
  }, {
    "scope": "actions",
    "key": "amount",
    "match": "gt",
    "value": "10"
  }]
}

aggregation

The action constraints are extended with aggregation rules which must be matched. For example, you may want to spot people who committed the action payment at least 3 times, or those people who committed the action payment where the sum of amount (which is a property inside every payment action) to be greater than $100.

Count aggregation example

The method count takes scope as an extra parameter which is action by default. It enabled you to count occurrences by actions or limiting the count to one per visit.

aggregation: {
  "method": "count",
  "scope": "actions", // or visits (to count once per visit)
  "match": "gte", // equivalent to "greater than or equals" or "at least"
  "value": 3
}

Sum aggregation example

The method sum takes an extra parameter titled by which is the target key that should be used to sum amounts. For example, in a payment event, you need to use the amount key.

aggregation: {
  "method": "sum",
  "by": "amount", // property of the action matching in "actions"
  "match": "gte", // equivalent to "greater than or equals" or "at least"
  "value": 100
}

timeframe

You must define a time frame for every behavioral filter. Time frames can be defined using one of 2 methods: relative dates (days ago) and absolute dates.

Example of a relative time frame

The example below defines a timeframe relative to the time you’re querying the Woopra engines: From 29 to 0 days ago. Which means last 30 days including today.

timeframe: {
    "method": "relative",
    "from": 29,
    "to": 0
}

Example of an absolute time frame

The example below defines a timeframe that is absolute. You must define two dates in the format of yyyy-mm-dd.

timeframe: {
    "method": "absolute",
    "from": "2013-01-01",
    "to": "2013-01-31"
}

visit

The visit parameter defines the visit constraints that should be matched. If a visit that contains a matching action but does not match with the visit constraints, the matching actions will be ignored. The visit constraints object consists of two properties: operator and filters.

visit: {
    "operator": "AND",
    "filters": [{
        "scope": "visits",
        "key": "browser", 
        "match": "contains",
        "value": "chrome"
    }]
}

Match Comparators

Key
Description
Data Type

match

Exactly Matches

string

starts

Starts With

string

contains

Contains

string

ends

Ends With

string

notmatch

Does Not Match

string

notstarts

Does Not Start With

string

notends

Does Not End With

string

notcontains

Does Not Contain

string

regexp

Entire String Matches Regular Expression

string

empty

Empty

string/any

notempty

Not Empty

string/any

eq

Equals

number

lt

Less Than

number

gt

Greater than

number

gte

Greater Than or Equals

number

lte

Less Than or Equals

number

neq

Not equals

number

Full Segments Example

segments: [{
    "are": {
        "operator": "AND",
        "filters": [{
            "scope": "visitors",
            "key": "company size",
            "match": "gte",
            "value": 300
        }, {
            "scope": "visitors",
            "key": "stage",
            "match": "match",
            "value": "trial"
        }]
    },
    "did": {
        "operator": "AND",
        "filters": [{
            action: {
                "operator": "AND",
                "filters": [{
                    "scope": "actions",
                    "key": "name",
                    "match": "match",
                    "value": "payment"
                }]
            },
            aggregation: {
                "method": "sum",
                "by": "amount", // property of the action matching in "actions"
                "match": "gte", // equivalent to "greater than or equals" or "at least"
                "value": 100
            },
            timeframe: {
                "method": "relative",
                "from": 29,
                "to": 0
            },
            visit: {
                "operator": "AND",
                "filters": [{
                    "scope": "visits",
                    "key": "city",
                    "match": "match",
                    "value": "San Francisco"
                }]
            }
        }]
    }
}]
Suggest Edits

The Reporting API

This is the API to use if you want to programmatically query your Woopra data as it appears in Woopra reports.

 

INCOMPLETE DOCUMENTATION

Warning: the documentation for the reporting endpoints is not complete. please refer to woopra.com/docs/ for more details on accepted and required fields.

Common Parameters

skip_drilldown

Sending skip_drilldown:false will have servers include in the response, the segment definitions (expressed in Woopra's segmentation DSL for each group of visitors that are in a funnel step in a given cohort (usually this cohort is days.) In simpler terms, this data can show you WHO is in each cell in a funnel report that you wee in the woopra interface, and is how the interface can allow you to drill down to the visitors in each cell in a report.

segments

Advanced users can programmatically define segments by which to filter their reports via the API. See Building Segments for details on creating this definition.

Suggest Edits

/analytics

Load analytics reports from your account.

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://www.woopra.com/rest/3.0/analytics
curl https://www.woopra.com/rest/3.0/analytics \
--user QSBEUTTEZ8J5CEUVIUECQK99PWVH7TLE:wmaH6Oqk9THl7gW3nouRBSsIHyM8d9YJjIhwRgTLbUI1Spnnqb4bqMEP7CuBJQ7C \
-X POST -d \
  '{
     "website": "mybusiness.com",
     "start_day": "2017-4-12",
     "end_day": "2017-5-19",
     "limit": 100,
     "offset": 0,
     "report_id": "cF8NPf971A", "skip_drilldown": true
}'
A binary file was returned

You couldn't be authenticated

{
   "request":{
      "end_day":"2017-04-17",
      "website":"woopra.com",
      "offset":0,
      "start_day":"2017-04-12",
      "project":"woopra.com",
      "skip_drilldown":true,
      "report_id":"cF8NPf971A",
      "limit":100,
      "report":{
         "@":{

         },
         "columns":[
            {
               "hide":false,
               "method":"count",
               "scope":"visitors",
               "name":"New",
               "_format":"#,##0",
               "constraints":{
                  "filters":[
                     {
                        "scope":"visits",
                        "match":"eq",
                        "value":"1",
                        "key":"number"
                     }
                  ],
                  "operator":"AND"
               },
               "render":"number_format(cell('New'), '#,##0')"
            },
            {
               "hide":false,
               "method":"count",
               "scope":"visitors",
               "name":"Returning",
               "_format":"#,##0",
               "constraints":{
                  "filters":[
                     {
                        "scope":"visits",
                        "match":"gt",
                        "value":"1",
                        "key":"number"
                     }
                  ],
                  "operator":"AND"
               },
               "render":"number_format(cell('Returning'), '#,##0')"
            },
            {
               "hide":false,
               "method":"count",
               "scope":"visitors",
               "name":"Total",
               "_format":"#,##0",
               "render":"number_format(cell('Total'), '#,##0')"
            },
            {
               "valid":true,
               "method":"count",
               "scope":"actions",
               "name":"Action Count",
               "_format":"string",
               "render":"",
               "constraints":{
                  "filters":[

                  ],
                  "operator":"and"
               }
            }
         ],
         "_appdata":{

         },
         "title":"New vs. Returning",
         "constraints":{
            "filters":[
               {
                  "scope":"actions",
                  "match":"empty",
                  "value":"",
                  "key":"~z"
               }
            ],
            "operator":"AND"
         },
         "limit":50,
         "name":"New vs. Returning",
         "group_by":[
            {
               "_alias":"day",
               "scope":"visits",
               "transforms":[
                  {
                     "function":"date_format",
                     "params":[
                        "yyyy-DDDD"
                     ]
                  }
               ],
               "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
               "key":"time"
            }
         ],
         "order_by":"",
         "metrics":[
            {
               "hide":false,
               "method":"unique",
               "splice":false,
               "scope":"visits",
               "name":"New",
               "_format":"#,##0",
               "constraints":{
                  "filters":[
                     {
                        "scope":"visits",
                        "match":"eq",
                        "value":"1",
                        "key":"number"
                     }
                  ],
                  "operator":"AND"
               },
               "render":"number_format(cell('New'), '#,##0')",
               "key":"~id"
            },
            {
               "hide":false,
               "method":"unique",
               "splice":false,
               "scope":"visits",
               "name":"Returning",
               "_format":"#,##0",
               "constraints":{
                  "filters":[
                     {
                        "scope":"visits",
                        "match":"gt",
                        "value":"1",
                        "key":"number"
                     }
                  ],
                  "operator":"AND"
               },
               "render":"number_format(cell('Returning'), '#,##0')",
               "key":"~id"
            },
            {
               "hide":false,
               "method":"unique",
               "splice":false,
               "scope":"visits",
               "name":"Total",
               "_format":"#,##0",
               "render":"number_format(cell('Total'), '#,##0')",
               "key":"~id"
            },
            {
               "valid":true,
               "method":"count",
               "scope":"actions",
               "name":"Action Count",
               "_format":"string",
               "render":"",
               "constraints":{
                  "filters":[

                  ],
                  "operator":"and"
               },
               "key":"~m"
            }
         ],
         "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
         "desc":true,
         "dimensions":[
            {
               "_alias":"day",
               "scope":"actions",
               "transforms":[
                  {
                     "function":"date_format",
                     "params":[
                        "yyyy-DDDD"
                     ]
                  }
               ],
               "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
               "key":"~m"
            }
         ]
      },
      "order_by":"",
      "definition":{
         "uid":"cF8NPf971A",
         "meta":{
            "@":{

            },
            "columns":[
               {
                  "hide":false,
                  "method":"count",
                  "scope":"visitors",
                  "name":"New",
                  "_format":"#,##0",
                  "constraints":{
                     "filters":[
                        {
                           "scope":"visits",
                           "match":"eq",
                           "value":"1",
                           "key":"number"
                        }
                     ],
                     "operator":"AND"
                  },
                  "render":"number_format(cell('New'), '#,##0')"
               },
               {
                  "hide":false,
                  "method":"count",
                  "scope":"visitors",
                  "name":"Returning",
                  "_format":"#,##0",
                  "constraints":{
                     "filters":[
                        {
                           "scope":"visits",
                           "match":"gt",
                           "value":"1",
                           "key":"number"
                        }
                     ],
                     "operator":"AND"
                  },
                  "render":"number_format(cell('Returning'), '#,##0')"
               },
               {
                  "hide":false,
                  "method":"count",
                  "scope":"visitors",
                  "name":"Total",
                  "_format":"#,##0",
                  "render":"number_format(cell('Total'), '#,##0')"
               },
               {
                  "valid":true,
                  "method":"count",
                  "scope":"actions",
                  "name":"Action Count",
                  "_format":"string",
                  "render":"",
                  "constraints":{
                     "filters":[

                     ],
                     "operator":"and"
                  }
               }
            ],
            "_appdata":{

            },
            "title":"New vs. Returning",
            "constraints":{
               "filters":[
                  {
                     "scope":"actions",
                     "match":"empty",
                     "value":"",
                     "key":"~z"
                  }
               ],
               "operator":"AND"
            },
            "limit":50,
            "name":"New vs. Returning",
            "group_by":[
               {
                  "_alias":"day",
                  "scope":"visits",
                  "transforms":[
                     {
                        "function":"date_format",
                        "params":[
                           "yyyy-DDDD"
                        ]
                     }
                  ],
                  "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
                  "key":"time"
               }
            ],
            "order_by":"",
            "metrics":[
               {
                  "hide":false,
                  "method":"unique",
                  "splice":false,
                  "scope":"visits",
                  "name":"New",
                  "_format":"#,##0",
                  "constraints":{
                     "filters":[
                        {
                           "scope":"visits",
                           "match":"eq",
                           "value":"1",
                           "key":"number"
                        }
                     ],
                     "operator":"AND"
                  },
                  "render":"number_format(cell('New'), '#,##0')",
                  "key":"~id"
               },
               {
                  "hide":false,
                  "method":"unique",
                  "splice":false,
                  "scope":"visits",
                  "name":"Returning",
                  "_format":"#,##0",
                  "constraints":{
                     "filters":[
                        {
                           "scope":"visits",
                           "match":"gt",
                           "value":"1",
                           "key":"number"
                        }
                     ],
                     "operator":"AND"
                  },
                  "render":"number_format(cell('Returning'), '#,##0')",
                  "key":"~id"
               },
               {
                  "hide":false,
                  "method":"unique",
                  "splice":false,
                  "scope":"visits",
                  "name":"Total",
                  "_format":"#,##0",
                  "render":"number_format(cell('Total'), '#,##0')",
                  "key":"~id"
               },
               {
                  "valid":true,
                  "method":"count",
                  "scope":"actions",
                  "name":"Action Count",
                  "_format":"string",
                  "render":"",
                  "constraints":{
                     "filters":[

                     ],
                     "operator":"and"
                  },
                  "key":"~m"
               }
            ],
            "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
            "desc":true,
            "dimensions":[
               {
                  "_alias":"day",
                  "scope":"actions",
                  "transforms":[
                     {
                        "function":"date_format",
                        "params":[
                           "yyyy-DDDD"
                        ]
                     }
                  ],
                  "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
                  "key":"~m"
               }
            ]
         },
         "owner_id":"220613",
         "created":1483585033000,
         "name":"New vs. Returning",
         "rank":143,
         "type":"reports",
         "updated":1484530417000,
         "properties":{
            "172899":{

            }
         }
      },
      "date_format":"yyyy-MM-dd",
      "exp":"TRUE()",
      "desc":"true"
   },
   "total":[
      6,
      "3,368",
      "5,671",
      "145,957",
      ""
   ],
   "success":true,
   "@report-id":"kpviw7uyaljo",
   "model":{
      "website":"woopra.com",
      "offset":0,
      "report":{
         "@":{

         },
         "columns":[
            {
               "hide":false,
               "method":"count",
               "scope":"visitors",
               "name":"New",
               "_format":"#,##0",
               "constraints":{
                  "filters":[
                     {
                        "scope":"visits",
                        "match":"eq",
                        "value":"1",
                        "key":"number"
                     }
                  ],
                  "operator":"AND"
               },
               "render":"number_format(cell('New'), '#,##0')"
            },
            {
               "hide":false,
               "method":"count",
               "scope":"visitors",
               "name":"Returning",
               "_format":"#,##0",
               "constraints":{
                  "filters":[
                     {
                        "scope":"visits",
                        "match":"gt",
                        "value":"1",
                        "key":"number"
                     }
                  ],
                  "operator":"AND"
               },
               "render":"number_format(cell('Returning'), '#,##0')"
            },
            {
               "hide":false,
               "method":"count",
               "scope":"visitors",
               "name":"Total",
               "_format":"#,##0",
               "render":"number_format(cell('Total'), '#,##0')"
            },
            {
               "valid":true,
               "method":"count",
               "scope":"actions",
               "name":"Action Count",
               "_format":"string",
               "render":"",
               "constraints":{
                  "filters":[

                  ],
                  "operator":"and"
               }
            }
         ],
         "_appdata":{

         },
         "title":"New vs. Returning",
         "constraints":{
            "filters":[
               {
                  "scope":"actions",
                  "match":"empty",
                  "value":"",
                  "key":"~z"
               }
            ],
            "operator":"AND"
         },
         "limit":50,
         "name":"New vs. Returning",
         "group_by":[
            {
               "_alias":"day",
               "scope":"visits",
               "transforms":[
                  {
                     "function":"date_format",
                     "params":[
                        "yyyy-DDDD"
                     ]
                  }
               ],
               "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
               "key":"time"
            }
         ],
         "order_by":"",
         "metrics":[
            {
               "hide":false,
               "method":"unique",
               "splice":false,
               "scope":"visits",
               "name":"New",
               "_format":"#,##0",
               "constraints":{
                  "filters":[
                     {
                        "scope":"visits",
                        "match":"eq",
                        "value":"1",
                        "key":"number"
                     }
                  ],
                  "operator":"AND"
               },
               "render":"number_format(cell('New'), '#,##0')",
               "key":"~id"
            },
            {
               "hide":false,
               "method":"unique",
               "splice":false,
               "scope":"visits",
               "name":"Returning",
               "_format":"#,##0",
               "constraints":{
                  "filters":[
                     {
                        "scope":"visits",
                        "match":"gt",
                        "value":"1",
                        "key":"number"
                     }
                  ],
                  "operator":"AND"
               },
               "render":"number_format(cell('Returning'), '#,##0')",
               "key":"~id"
            },
            {
               "hide":false,
               "method":"unique",
               "splice":false,
               "scope":"visits",
               "name":"Total",
               "_format":"#,##0",
               "render":"number_format(cell('Total'), '#,##0')",
               "key":"~id"
            },
            {
               "valid":true,
               "method":"count",
               "scope":"actions",
               "name":"Action Count",
               "_format":"string",
               "render":"",
               "constraints":{
                  "filters":[

                  ],
                  "operator":"and"
               },
               "key":"~m"
            }
         ],
         "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
         "desc":true,
         "dimensions":[
            {
               "_alias":"day",
               "scope":"actions",
               "transforms":[
                  {
                     "function":"date_format",
                     "params":[
                        "yyyy-DDDD"
                     ]
                  }
               ],
               "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
               "key":"~m"
            }
         ]
      },
      "limit":1,
      "order_by":"",
      "group_by":[

      ],
      "desc":"true"
   },
   "rows":[
      [
         "2017-0107",
         "503",
         "1,294",
         "1,716",
         27939
      ],
      [
         "2017-0106",
         "335",
         "857",
         "1,143",
         12524
      ],
      [
         "2017-0105",
         "288",
         "833",
         "1,081",
         10781
      ],
      [
         "2017-0104",
         "481",
         "1,158",
         "1,573",
         21287
      ],
      [
         "2017-0103",
         "549",
         "1,438",
         "1,901",
         33407
      ],
      [
         "2017-0102",
         "622",
         "1,546",
         "2,075",
         40019
      ]
   ]
}

Body Params

website
string

Your Woopra Project eg: mybusiness.com

report_id
string

Report ID – can be found by retrieving the last part of the URL path when loading a report in the web app. Ex: for the report https://www.woopra.com/live/project/mybusiness.com/funnels/6d9hqssf37 the report ID is: “6d9hqssf37”

start_day
string

The start date in the format YYYY-MM-DD eg: 2017-04-12

end_day
string

The start date in the format YYYY-MM-DD eg: 2017-04-12

segments
string
limit
string

max number of records to return

offset
string

number of records to skip

skip_drilldown
string

Skip the individual segment definitions for drilldowns for each cell in the table

 
Suggest Edits

/retention

Load retention reports from your account.

 

Basic Auth

 Authentication is required for this endpoint.
posthttps://www.woopra.com/rest/3.0/retention
curl https://www.woopra.com/rest/3.0/retention \
--user QSBEUTTEZ8J5CEUVIUECQK99PWVH7TLE:wmaH6Oqk9THl7gW3nouRBSsIHyM8d9YJjIhwRgTLbUI1Spnnqb4bqMEP7CuBJQ7C \
-X POST -d \
  '{
     "website": "mybusiness.com",
     "start_day": "2017-4-12",
     "end_day": "2017-5-19",
     "limit": 100,
     "offset": 0,
     "report_id": "83mYcoe6jX", "skip_drilldown": true
}'
A binary file was returned

You couldn't be authenticated

{
   "request":{
      "end_day":"2017-04-23",
      "website":"woopra.com",
      "offset":0,
      "start_day":"2017-04-12",
      "initial":{
         "filters":[
            {
               "_uikey":"actions:mobile install",
               "scope":"actions",
               "match":"match",
               "value":"mobile install",
               "key":"~n"
            }
         ],
         "operator":"and"
      },
      "tz":"sun.util.calendar.ZoneInfo[id=\"America/Los_Angeles\",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]",
      "count":7,
      "project":"woopra.com",
      "skip_drilldown":true,
      "unit":"day",
      "later":{
         "filters":[
            {
               "_uikey":"actions:mobileview",
               "scope":"actions",
               "match":"match",
               "value":"mobileview",
               "key":"~n"
            }
         ],
         "operator":"and"
      },
      "report_id":"83mYcoe6jX",
      "limit":100,
      "order_by":"",
      "definition":{
         "uid":"83mYcoe6jX",
         "meta":{
            "@":{

            },
            "later":{
               "filters":[
                  {
                     "_uikey":"actions:mobileview",
                     "scope":"actions",
                     "match":"match",
                     "value":"mobileview",
                     "key":"~n"
                  }
               ],
               "operator":"and"
            },
            "initial":{
               "filters":[
                  {
                     "_uikey":"actions:mobile install",
                     "scope":"actions",
                     "match":"match",
                     "value":"mobile install",
                     "key":"~n"
                  }
               ],
               "operator":"and"
            },
            "name":"Mobile Retention",
            "_appdata":{

            }
         },
         "owner_id":"6",
         "created":1483585033000,
         "name":"Mobile Retention",
         "rank":99,
         "type":"retention",
         "updated":1490338411826,
         "properties":{
            "6":{

            },
            ":site":{

            }
         }
      },
      "date_format":"yyyy-MM-dd",
      "exp":"TRUE()",
      "all_dates":[
         "20170412",
         "20170413",
         "20170414",
         "20170415",
         "20170416",
         "20170417",
         "20170418",
         "20170419",
         "20170420",
         "20170421",
         "20170422",
         "20170423"
      ],
      "desc":"true"
   },
   "success":true,
   "model":{
      "unit":"day",
      "columns":6
   },
   "items":[
      {
         "key":"Mon, Apr 17, 2017",
         "goals":[
            {
               "visitors":7,
               "percent":"100"
            },
            {
               "visitors":4,
               "percent":"57.14"
            },
            {
               "visitors":2,
               "percent":"28.57"
            },
            {
               "visitors":1,
               "percent":"14.29"
            },
            {
               "visitors":1,
               "percent":"14.29"
            },
            {
               "visitors":1,
               "percent":"14.29"
            },
            {
               "visitors":1,
               "percent":"14.29"
            }
         ]
      },
      {
         "key":"Sun, Apr 16, 2017",
         "goals":[
            {
               "visitors":2,
               "percent":"100"
            },
            {
               "visitors":0,
               "percent":"0"
            },
            {
               "visitors":1,
               "percent":"50"
            },
            {
               "visitors":0,
               "percent":"0"
            },
            {
               "visitors":0,
               "percent":"0"
            },
            {
               "visitors":0,
               "percent":"0"
            },
            {
               "visitors":0,
               "percent":"0"
            }
         ]
      },
      {
         "key":"Sat, Apr 15, 2017",
         "goals":[
            {
               "visitors":4,
               "percent":"100"
            },
            {
               "visitors":2,
               "percent":"50"
            },
            {
               "visitors":1,
               "percent":"25"
            },
            {
               "visitors":1,
               "percent":"25"
            },
            {
               "visitors":1,
               "percent":"25"
            },
            {
               "visitors":0,
               "percent":"0"
            },
            {
               "visitors":1,
               "percent":"25"
            }
         ]
      },
      {
         "key":"Fri, Apr 14, 2017",
         "goals":[
            {
               "visitors":5,
               "percent":"100"
            },
            {
               "visitors":1,
               "percent":"20"
            },
            {
               "visitors":0,
               "percent":"0"
            },
            {
               "visitors":2,
               "percent":"40"
            },
            {
               "visitors":2,
               "percent":"40"
            },
            {
               "visitors":3,
               "percent":"60"
            },
            {
               "visitors":1,
               "percent":"20"
            }
         ]
      },
      {
         "key":"Thu, Apr 13, 2017",
         "goals":[
            {
               "visitors":9,
               "percent":"100"
            },
            {
               "visitors":3,
               "percent":"33.33"
            },
            {
               "visitors":3,
               "percent":"33.33"
            },
            {
               "visitors":6,
               "percent":"66.67"
            },
            {
               "visitors":3,
               "percent":"33.33"
            },
            {
               "visitors":2,
               "percent":"22.22"
            },
            {
               "visitors":4,
               "percent":"44.44"
            }
         ]
      },
      {
         "key":"Wed, Apr 12, 2017",
         "goals":[
            {
               "visitors":3,
               "percent":"100"
            },
            {
               "visitors":1,
               "percent":"33.33"
            },
            {
               "visitors":0,
               "percent":"0"
            },
            {
               "visitors":0,
               "percent":"0"
            },
            {
               "visitors":0,
               "percent":"0"
            },
            {
               "visitors":1,
               "percent":"33.33"
            },
            {
               "visitors":0,
               "percent":"0"
            }
         ]
      }
   ],
   "goals":[
      {
         "visitors":1,
         "initialvisitors":1,
         "percent":100
      },
      {
         "visitors":1,
         "initialvisitors":1,
         "percent":"36.67"
      },
      {
         "visitors":1,
         "initialvisitors":1,
         "percent":"23.33"
      },
      {
         "visitors":1,
         "initialvisitors":1,
         "percent":"33.33"
      },
      {
         "visitors":1,
         "initialvisitors":1,
         "percent":"23.33"
      },
      {
         "visitors":1,
         "initialvisitors":1,
         "percent":"23.33"
      },
      {
         "visitors":1,
         "initialvisitors":1,
         "percent":"23.33"
      }
   ]
}

Body Params

website
string

Your Woopra Project eg: mybusiness.com

report_id
string

Report ID – can be found by retrieving the last part of the URL path when loading a report in the web app. Ex: for the report https://www.woopra.com/live/project/mybusiness.com/funnels/6d9hqssf37 the report ID is: “6d9hqssf37”

start_day
string

The start date in the format YYYY-MM-DD eg: 2017-04-12

end_day
string

The start date in the format YYYY-MM-DD eg: 2017-04-12

segments
string
limit
string

max number of records to return

offset
string

number of records to skip

skip_drilldown
string

Skip the individual segment definitions for drilldowns for each cell in the table

 
 

Basic Auth

 Authentication is required for this endpoint.
posthttps://www.woopra.com/rest/3.0/retention
curl https://www.woopra.com/rest/3.0/funnels \
--user QSBEUTTEZ8J5CEUVIUECQK99PWVH7TLE:wmaH6Oqk9THl7gW3nouRBSsIHyM8d9YJjIhwRgTLbUI1Spnnqb4bqMEP7CuBJQ7C \
-X POST -d \
  '{
     "website": "mybusiness.com",
     "start_day": "2017-4-12",
     "end_day": "2017-5-19",
     "limit": 100,
     "offset": 0,
     "report_id": "5ux9oj3rjc", "skip_drilldown": true
}'
A binary file was returned

You couldn't be authenticated

{
   "request":{
      "end_day":"2017-04-19",
      "website":"woopra.com",
      "offset":0,
      "start_day":"2017-04-12",
      "project":"woopra.com",
      "skip_drilldown":true,
      "report_id":"5ux9oj8rjc",
      "limit":10,
      "order_by":"",
      "group_by":{
         "scope":"actions",
         "transforms":[
            {
               "function":"date_format",
               "params":[
                  "yyyy-DDDD"
               ]
            }
         ],
         "name":"Days",
         "order_by":0,
         "menu":"Cohorts",
         "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
         "key":"~m"
      },
      "definition":{
         "uid":"5ux9oj8rjc",
         "meta":{
            "@":{

            },
            "name":"EXAMPLE",
            "_appdata":{

            },
            "goals":[
               {
                  "name":"Initial Action",
                  "optional":false,
                  "filters":[
                     {
                        "scope":"actions",
                        "match":"match",
                        "value":"signup",
                        "key":"~n"
                     }
                  ],
                  "operator":"AND"
               },
               {
                  "name":"Login",
                  "optional":false,
                  "filters":[
                     {
                        "scope":"actions",
                        "match":"match",
                        "value":"login",
                        "key":"~n"
                     }
                  ],
                  "operator":"AND"
               }
            ]
         },
         "owner_id":"211312",
         "created":1495662773475,
         "name":"EXAMPLE",
         "rank":1,
         "type":"funnels",
         "updated":1495663043485,
         "properties":{
            "211312":{

            }
         }
      },
      "date_format":"yyyy-MM-dd",
      "exp":"TRUE()",
      "render":"date_format(group_by(0) ,'E, MMM dd, yyyy')",
      "desc":"true",
      "goals":[
         {
            "name":"Initial Action",
            "optional":false,
            "filters":[
               {
                  "scope":"actions",
                  "match":"match",
                  "value":"signup",
                  "key":"~n"
               }
            ],
            "operator":"AND"
         },
         {
            "name":"Login",
            "optional":false,
            "filters":[
               {
                  "scope":"actions",
                  "match":"match",
                  "value":"login",
                  "key":"~n"
               }
            ],
            "operator":"AND"
         }
      ]
   },
   "nodes":[
      {
         "total":240,
         "meta":{
            "visits":0,
            "time":0
         },
         "optional":false,
         "links":[
            {
               "total":11,
               "meta":{
                  "visits":82,
                  "time":54191
               },
               "id":1
            }
         ],
         "id":0,
         "title":"Initial Action"
      },
      {
         "total":11,
         "meta":{
            "visits":82,
            "time":54191
         },
         "optional":false,
         "links":[

         ],
         "id":1,
         "title":"Login"
      }
   ],
   "success":true,
   "model":{
      "total":13,
      "offset":0,
      "limit":10
   },
   "items":[
      {
         "key":"Wed, Apr 19, 2017",
         "goals":[
            {
               "visitors":46,
               "visits":0,
               "total":46,
               "meta":{
                  "visits":0,
                  "time":0
               },
               "optional":false,
               "links":[

               ],
               "id":0,
               "time":0,
               "title":"Initial Action"
            },
            {
               "visitors":0,
               "visits":0,
               "total":0,
               "optional":false,
               "links":[

               ],
               "id":1,
               "time":0,
               "title":"Login"
            }
         ]
      },
      {
         "key":"Tue, Apr 18, 2017",
         "goals":[
            {
               "visitors":28,
               "visits":0,
               "total":28,
               "meta":{
                  "visits":0,
                  "time":0
               },
               "optional":false,
               "links":[

               ],
               "id":0,
               "time":0,
               "title":"Initial Action"
            },
            {
               "visitors":0,
               "visits":0,
               "total":0,
               "optional":false,
               "links":[

               ],
               "id":1,
               "time":0,
               "title":"Login"
            }
         ]
      },
      {
         "key":"Mon, Apr 17, 2017",
         "goals":[
            {
               "visitors":33,
               "visits":0,
               "total":33,
               "meta":{
                  "visits":0,
                  "time":0
               },
               "optional":false,
               "links":[
                  {
                     "total":2,
                     "meta":{
                        "visits":5,
                        "time":436
                     },
                     "id":1
                  }
               ],
               "id":0,
               "time":0,
               "title":"Initial Action"
            },
            {
               "visitors":2,
               "visits":0,
               "total":2,
               "meta":{
                  "visits":5,
                  "time":436
               },
               "optional":false,
               "links":[

               ],
               "id":1,
               "time":0,
               "title":"Login"
            }
         ]
      },
      {
         "key":"Sun, Apr 16, 2017",
         "goals":[
            {
               "visitors":19,
               "visits":0,
               "total":19,
               "meta":{
                  "visits":0,
                  "time":0
               },
               "optional":false,
               "links":[
                  {
                     "total":2,
                     "meta":{
                        "visits":128,
                        "time":17700
                     },
                     "id":1
                  }
               ],
               "id":0,
               "time":0,
               "title":"Initial Action"
            },
            {
               "visitors":2,
               "visits":0,
               "total":2,
               "meta":{
                  "visits":128,
                  "time":17700
               },
               "optional":false,
               "links":[

               ],
               "id":1,
               "time":0,
               "title":"Login"
            }
         ]
      },
      {
         "key":"Sat, Apr 15, 2017",
         "goals":[
            {
               "visitors":16,
               "visits":0,
               "total":16,
               "meta":{
                  "visits":0,
                  "time":0
               },
               "optional":false,
               "links":[
                  {
                     "total":1,
                     "meta":{
                        "visits":5,
                        "time":523
                     },
                     "id":1
                  }
               ],
               "id":0,
               "time":0,
               "title":"Initial Action"
            },
            {
               "visitors":1,
               "visits":0,
               "total":1,
               "meta":{
                  "visits":5,
                  "time":523
               },
               "optional":false,
               "links":[

               ],
               "id":1,
               "time":0,
               "title":"Login"
            }
         ]
      },
      {
         "key":"Fri, Apr 14, 2017",
         "goals":[
            {
               "visitors":22,
               "visits":0,
               "total":22,
               "meta":{
                  "visits":0,
                  "time":0
               },
               "optional":false,
               "links":[
                  {
                     "total":1,
                     "meta":{
                        "visits":102,
                        "time":2070
                     },
                     "id":1
                  }
               ],
               "id":0,
               "time":0,
               "title":"Initial Action"
            },
            {
               "visitors":1,
               "visits":0,
               "total":1,
               "meta":{
                  "visits":102,
                  "time":2070
               },
               "optional":false,
               "links":[

               ],
               "id":1,
               "time":0,
               "title":"Login"
            }
         ]
      },
      {
         "key":"Thu, Apr 13, 2017",
         "goals":[
            {
               "visitors":34,
               "visits":0,
               "total":34,
               "meta":{
                  "visits":0,
                  "time":0
               },
               "optional":false,
               "links":[
                  {
                     "total":3,
                     "meta":{
                        "visits":47,
                        "time":7863
                     },
                     "id":1
                  }
               ],
               "id":0,
               "time":0,
               "title":"Initial Action"
            },
            {
               "visitors":3,
               "visits":0,
               "total":3,
               "meta":{
                  "visits":47,
                  "time":7863
               },
               "optional":false,
               "links":[

               ],
               "id":1,
               "time":0,
               "title":"Login"
            }
         ]
      },
      {
         "key":"Wed, Apr 12, 2017",
         "goals":[
            {
               "visitors":42,
               "visits":0,
               "total":42,
               "meta":{
                  "visits":0,
                  "time":0
               },
               "optional":false,
               "links":[
                  {
                     "total":2,
                     "meta":{
                        "visits":197,
                        "time":266823
                     },
                     "id":1
                  }
               ],
               "id":0,
               "time":0,
               "title":"Initial Action"
            },
            {
               "visitors":2,
               "visits":0,
               "total":2,
               "meta":{
                  "visits":197,
                  "time":266823
               },
               "optional":false,
               "links":[

               ],
               "id":1,
               "time":0,
               "title":"Login"
            }
         ]
      }
   ]
}

Body Params

website
string

Your Woopra Project eg: mybusiness.com

report_id
string

Report ID – can be found by retrieving the last part of the URL path when loading a report in the web app. Ex: for the report https://www.woopra.com/live/project/mybusiness.com/funnels/6d9hqssf37 the report ID is: “6d9hqssf37”

start_day
string

The start date in the format YYYY-MM-DD eg: 2017-04-12

end_day
string

The start date in the format YYYY-MM-DD eg: 2017-04-12

segments
string
limit
string

max number of records to return

offset
string

number of records to skip

skip_drilldown
string

Skip the individual segment definitions for drilldowns for each cell in the table

 
Suggest Edits

Labels API

Manage your Woopra project labels (saved visitor segments)

 

Overview

Labels are a way of saving customer segments that are important to you. For example, you may want to save your “rock star” customer segment or your “at-risk of leaving” customer segment in order to monitor, analyze, and compare these customers.

Once you create a Label, you will be able to use it for quick segmentation in many other Woopra features, such as Analytics Reports and the People View. You will also see your Labels on your dashboard.

JSON Format of a Label

{
        "name": "Purchased (US)",
        "color": "#0844a4",
        "filterObject": [{
        "are": {
                "operator": "AND",
                "filters": []
         },
         "did": {
            "operator": "AND",
            "filters": [{
                   "aggregation": {
                        "value": 1,
                        "method": "count",
                        "match": "gte"
                    },
                    "action": {
                        "operator": "AND",
                        "filters": [{
                            "scope": "actions",
                            "value": "checkout",
                            "match": "contains",
                            "key": "name"
                        }]
                    },
                    "timeframe": {
                        "to": 0,
                        "method": "relative",
                        "from": 29
                    },
                    "visit": {
                         "operator": "AND",
                         "filters": [{
                            "scope": "visits",
                            "value": "US",
                            "match": "match",
                            "key": "country"
                    }]
                }
            }]
        }
    }]
}

For more on how to populate the filterObject data, see Building Segments.

CRUD Operations

Create

Endpoint: http(s)://www.woopra.com/rest/[version]/userdata/add

Parameters

Name
Description

project

project as registered in Woopra

type

labels

properties

user-specific JSON properties ex: {“enabled”:true}

meta

JSON content (example above)

Read

Endpoint: http(s)://www.woopra.com/rest/[version]/userdata/list

Parameters

Name
Description

project

project as registered in Woopra

type

Use Value: labels

Update

Endpoint: http(s)://www.woopra.com/rest/[version]/userdata/update

Parameters

Name
Description

project

project as registered in Woopra

uid

object unique ID (generated by woopra when created)

meta

JSON content (example above)

Delete

Endpoint: http(s)://www.woopra.com/rest/[version]/userdata/delete

Parameters

project

project as registered in Woopra

uid

object unique ID (generated by woopra when created)

Suggest Edits

Schemas API

Manage your Projects visitor and action schemas

 

Action Schema JSON Format

{
        "template": "**${visitor.name}** viewed [${action.title}](http://${action.d}${action.url})",
        "icon": "files/document---generic.png",
        "details": {
            "title": "Page View",
            "description": "Visitor loaded a page"
        },
        "eventName": "pv",
        "fields": [{
            "aggregate": "group",
            "type": "string",
            "key": "url"
             },
              {
            "aggregate": "group",
            "type": "string",
            "key": "title"
    }]
}

Visitor Property Schema JSON Format

{
        "propertyName": "email",
        "aggregate": "unique",
        "details": {
            "title": "Email",
            "order": 1,
            "description": "Visitor email address"
        },
        "type": "string"
}

CRUD Operations

Create

Endpoint: http(s)://www.woopra.com/rest/[version]/schemata/[visitor|action]/add

Parameters

Name
Description

project

project as registered in Woopra

schema

JSON schema object as exemplified above

Read

Read all schemata, regardless of type.

Endpoint: http(s)://www.woopra.com/rest/[version]/schemata/get

Parameters

Name
Description

project

project as registered in Woopra

Delete

Endpoint: http(s)://www.woopra.com/rest/[version]/schemata/[visitor|action]/delete

Parameters

project

project as registered in Woopra

name

Visitor Schema’s or Action Schema's "name"

Suggest Edits

The Export API

Export raw daily visit data

 

The Export API exports a raw list of visits as line-separated JSON visit objects. You request the files by the log day in the America/Pacific timezone.

Line Types

Each line in the response is a single contained JSON object. There are a few types of objects that you will find. The type of object is available on the "type" key in the JSON object on each line.

Visit Lines

Visit lines represent a single session/visit. They contain visit-level metadata, a visitor object with any updated properties for that visitor during this session, as well as an array of actions that occurred in this visit, each has it's own event name, timestamp, properties, etc.

The visit also has a profile id ("pid") on which to include this visit and all of its actions. The profile id is an ephemeral reandomly-generated uuid for a profile for one person--do not rely on it to stay the same for the same person (see deletes below).

To process a visit line, find or create a profile in your own database with the given pid, set the keys and values from the visitor object on to this profile, then add all of the actions in the actions array to this profile.

Delete Lines

Probably the most important thing to note about this API is that, becasue it closely mirrors our own, home-rolled transactional database, it will include DELETE lines that are intended to nullify all previous visits for a given profile. After a DELETE line, these visits and their actions are re-logged (with their original timestamps) under a new profile id.

Delete lines are marked by type: "delete"

To Process a delete line, find the profile in your database that you created for that pid, and delete it. It's scary, I know, but the coming lines will contain all the data you just deleted, and likely more. The delete line will also contain a new_id with the new pid that will be used to re-log these actions, along with any actions from other merged profiles, as well as the new action that caused the merge.

Deletes? (yes, deletes.)

Deleting in a transaction type database is usually done by writing a delete directive. In practice, this often never results in data being erased, but rather the delete line is read as a directive to ignore this or that that happened in the past from now on when reading relevant data. There are many reasons for this, and Wikipedia or Stack Overflow will surely help figure them out.

So why are there so many delete actions still in our particular case? Well, we often have anonymous users come back over and over to our site or interact with us in other ways, but who are never identified. This would result in each of these sessions being attributed to it's own pid. Consider this example:

DELETES EXAMPLE:

Let's say a user who has three anonymous profiles--one from her desktop two weeks ago when she first discovered your site, one from her mobile phone where she clicked an add a few days ago, and one on her work laptop today--decides to identify herself to you today. On her work laptop, she submits your call to action form and gives you her email address. You, of course, forward that email address to Woopra to put on her profile. The export logs would now see a DELETE for the old anonymous profile id and a new one would be created that is (more or less) permanently mapped to this email address.

So now let's say that this evening, the user in question is on the train home and decides to sign in with her new email/account from her phone. Now the profile that had pointed to the phone's cookie, will get a DELETE, and all of those actions will be re-logged onto the new pid that was generated when she gave us her email. This is called a profile merge, and you can learn more about these concepts as they pertain to visitor identifiers in the Woopra's Profile ID System document. The same thing will happen again when she logs in from her desktop.

The database sometimes seems to have a mind of it's own when it comes to deleting. For instance the first identify in the previous example may not have a delete after it, but just a new visitor property added to the visitor object in a "type: visit" line. There is no way to predict exact behavior, but it is guaranteed to be consistent if you follow the rules of deleting when it tells you to, and trusting that you will get the data re-logged.

Suggest Edits

/logs/export

 

Basic Auth

 Authentication is required for this endpoint.
gethttps://www.woopra.com/rest/2.4/logs/export
curl https://www.woopra.com/rest/2.4/logs/export\
?project=test.woopra.com\
&file=2015-02-01\
&pos=0
A binary file was returned

You couldn't be authenticated

...
{"continent":"NA","date":"2017-04-20","country":"US","city":"San Francisco","timezone":"America/Los_Angeles","screen":"","description":"","language":"English","pid":"UqKtG234us4Trh","type":"visit","resolution":"","second":0,"duration":11,"number":0,"post":"94110","browser":"Chrome","id":"ceWlJtWMc234fz","lat":37.7484,"hour_of_day":18,"os":"Mac","lng":-122.4156,"offset":"-08:00","method":"","org":"","ip":"93.245.196.152","h":"UqK23fuM4Trh","minute":15,"ct":"cable_dsl","referrer":{"query":"","type":"direct","url":""},"time":1492737300712,"region":"California","visitor":{"first_visit_time":"1492737300712","email":"test@woopra.com","first_referrer_type":"direct"},"device":"desktop","actions":[{"duration":0,"date":"6:15:12 PM","exit":true,"system":true,"domain":"test.woopra.com","name":"property update","id":"tgV9k5LlGg","time":1492737312033,"passive":false,"properties":{"name":"property update","value":"1492737312031","key":"last_email_sent_at"}},{"duration":-1492737300,"date":"6:15:00 PM","system":true,"domain":"test.woopra.com","name":"label join","id":"S0AkHmWFmT","time":1492737300712,"passive":false,"properties":{"name":"Heavy Users","id":"GAT3vFrqd0"}},{"duration":0,"date":"6:15:00 PM","system":false,"landing":true,"domain":"test.woopra.com","name":"email_view","id":"ceWlJtWMc1cz","time":1492737300712,"passive":false,"properties":{"name":"email_view"}}]}

{"continent":"","date":"2017-04-20","country":"","city":"","timezone":"","screen":"","description":"this is a system log. This visitor has been deleted and replaced with a new profile id:nv2PwAIFEFC4. You can safely delete this visitor from your database.","language":"","pid":"854265404","type":"delete","resolution":"","second":3,"duration":0,"number":0,"post":"","browser":"","id":"PSz5V9wNIki5","lat":0,"hour_of_day":18,"new_id":"nv2PwAIFEFC4","os":"","lng":0,"offset":"","org":"","ip":"","h":"854265404","minute":18,"ct":"","referrer":{"query":"","type":"","url":""},"time":1492737483381,"region":"","visitor":{},"device":"","actions":[]}

{"continent":"NA","date":"2017-04-20","country":"US","city":"San Francisco","timezone":"America/Los_Angeles","screen":"","description":"","language":"English","pid":"nv2PwAIFEFC4","type":"visit","resolution":"","second":3,"duration":12,"number":0,"post":"94110","browser":"Chrome","id":"vQlIUtJDKWRP","lat":37.7484,"hour_of_day":18,"os":"Mac","lng":-122.4156,"offset":"-08:00","method":"","org":"","ip":"93.245.196.152","h":"nv2PwAIFEFC4","minute":18,"ct":"cable_dsl","referrer":{"query":"","type":"direct","url":""},"time":1492737483339,"region":"California","visitor":{"social_updated_at":"1492737495433","first_visit_time":"1492737483339","email":"test@woopra.com","first_referrer_type":"direct"},"device":"desktop","actions":[{"duration":0,"date":"6:18:15 PM","exit":true,"system":true,"domain":"test.woopra.com","name":"property update","id":"IyNnR57K94","time":1492737495436,"passive":false,"properties":{"name":"property update","value":"1492737495433","key":"last_email_sent_at"}},{"duration":-1492737483,"date":"6:18:03 PM","system":true,"domain":"test.woopra.com","name":"label join","id":"c9hw8JZBBv","time":1492737483339,"passive":false,"properties":{"name":"Social Media Engaged","id":"GAT3vFrqd0"}},{"duration":0,"date":"6:18:03 PM","system":false,"landing":true,"domain":"test.woopra.com","name":"tweet","id":"vQlIUtJDKWRP","time":1492737483339,"passive":false,"properties":{"name":"tweet"}}]}
...

Query Params

project
string

The name of your Woopra project.

file
string
pos
string

The position of the log file in question, only relevant if getting today's logs

 

Parameters

file

To tell Woopra which file you would like to export, you simply send it the name of the log file. This is also the PST date of the log file having the format yyyy-MM-dd. Ex: 2015-02-01 is the log file for Feb 1st, 2015. Log files are rotated at midnight PST. It is a good practice to send an http HEAD request to the same endpoint to get the current log file name.

pos (Paging or Streaming)

Each response will contain two headers: X-Woopra-NextFile and X-Woopra-NextPos You can use these to programmatically determine what parameters to use for your next call so as to avoid any duplicate lines coming in.

If you are exporting today's file, you will definitely need to use the pos key to ensure that you can get data starting at the correct cursor when you make the next call. Otherwise you could get duplicate or missed events.

Suggest Edits

The Import API

Import raw visit data with actions and visitor properties

 

The Import API allow you to bulk fill events and visitor properties into your Woopra instance in a single transaction.

This endpoint accepts an http body of line-separated JSON. This means, a single JSON object represented as a string (without the outer quotes) on each line. For Example:

{"visitor":{"email":"test1@mail.com"}, "actions":[{"time":1444077951001, "name":"purchase", "properties":{"price":20, "currency":"$"}]}
{"visitor":{"email":"test2@mail.com", "username": "test2"}, "actions":[{"time":1444077951891, "name":"signup", "properties":{"campaign": true}]}
...

Importing Visits

Each line in the body that you POST to /import should be a visit, a.k.a. session. The visit object should include a nested actions array, and a visitor object. At minimum, the visitor object should have an identifier so that Woopra knows to which person profile this visit belongs. The actions array is an array of event objects, each of which has a name, a time (in UNIX milliseconds), and a properties object with the custom event properties.

It is very conceivable that a visitor will have multiple lines in this file as they have done a number of visits, each expressed on its own line, and each containing an array of actions performed on this visit.

Bulk Updating Visitor Properties

You can bulk update visitor properties without tracking any actions by only including visitor information on each line. So each line would omit the actions array, and other visit properties, and look like:

{
  "visitor": {
  	"email": "<email>",
    "account_level": "enterprise",
    "property1": "prop1Value"
  }
}

A note on generated visit properties

NOTE: while you cannot send generated visit properties when doing real-time tracking (becasue they are generated) the tracking servers do not generate these fields on imports, and thus, you can send them. Imports go straight into the events database as is (more or less) and the logic that we run before write time at the end of a normal session in real-time tracking, is not run in the case of imported sessions via this endpoint. They are written as is.

A note on Engagement

Similarly, the Woopra system does not run engagement on imported data. This means that labels, triggers, and other automations are not evaluated for imported events.

Suggest Edits

/logs/import

 

Basic Auth

 Authentication is required for this endpoint.
puthttps://www.woopra.com/rest/2.4/logs/import
curl -X PUT --user appID:secretKey 'https://www.woopra.com/rest/2.4/logs/import?project=mybusiness.com' -d '{
  "visitor": {
    "email": "tigi@brembo.com"
  },
  "actions": [{
    "name": "article view",
    "time": 1450808259000,
    "properties": { 
      "campaign_name": "EN_2014",
      "campaign_medium": "Social",
      "campaign_source": "twitter" 
      "uri": "http://www.my-website.com/blog/welcome",
      "title": "welcome!"
    }
  }]
}'
A binary file was returned

You couldn't be authenticated

Try the API to see results

Query Params

project
string

The project into which you would like to import logs

 
Suggest Edits

The Segmentation DSL

A Domain Specific Language for Defining Visitor Segments in Woopra