Skip to main content Link Menu Expand (external link) Copy Copied

JSON Exports API

While the GraphQL API exposes a number of interesting metrics, it wasn’t designed to export raw data efficiently.
This endpoint addresses this use case and allows exporting raw camera data.
The endpoint offers 3 variants:

  • Version 1 Accepts batches of location IDs (or reference numbers) and rejects queries containing unauthorized IDs.
  • Version 2 Accepts batches of location IDs (or reference numbers) and allows partial responses.
  • Version 3 Implements a cursor approach. You only need to specify a brand ID and locations will be returned in batches automatically.

Authentication

The authentication workflow is the same as the GraphQL API. Using your client ID and client secret, the following HTTP query will return your token:

    curl --request POST \
        --url https://tokens.analytiks.ai \
        --header 'content-type: application/json' \
        --data '{"client_id":"__YOUR_CLIENT_ID__","client_secret":"__YOUR_CLIENT_SECRET__","audience":"https://gql.analytiks.ai","grant_type":"client_credentials"}'

On success the API call will return a structure like this one:

{"access_token":"YOUR_TOKEN","expires_in":86400,"token_type":"Bearer"}

Usage

Once you have your token, you can send POST requests to https://exports.analytiks.ai/json/v1.

We are expecting the following headers:

  • Content-Type set to application/json
  • Authorization set to Bearer YOUR_TOKEN

Request body

Here’s an examplre request body.

{
    "startDate": "2023-06-08T11:30:00.000Z",
    "endDate": "2023-06-08T23:45:00.000Z",
    "interval": "15min",
    "locations": [1, 2, 3]
}

Dates are ISO 8601 and can be sent either as UTC or local time. A few notes regarding dates:

  • If dates are requested in UTC (eg. 2023-06-08T11:30:00.000Z, note the final Z), dates in the response will also be UTC.
  • If dates are requested in local time (eg. 2023-06-08T09:00:00.000, no final Z), dates in the response will also be local time.
  • Both startDate and endDate must be in the same format.
  • A maximum of 5 days can be requested at once.

Interval can be “hourly” or “15min”, by default, aggregations are written every hours.
If you’re interested in 15 minutes intervals, let us know and we will enable the feature for your account.
A maximum of 50 locations can be requested at once.
Use the GraphQL API to figure out what location IDs you can use in your queries.

In this version of the endpoint, requesting locations you are not allowed to access will cause the whole request to be rejected with a status 401.
A v2 of the endpoint that allows partial results is described at the bottom of the page.

Requests can also be made by reference numbers (which you can set to your internal IDs)

{
    "startDate": "2023-06-08T11:30:00.000Z",
    "endDate": "2023-06-08T23:45:00.000Z",
    "interval": "15min",
    "brandId": 1234,
    "referenceNumbers": ["US0658", "FR2561"]
}

The same rules apply, except here we expect a brand ID (which does not change) and a list of reference numbers.
In this mode, the response will contain a referenceNumber number fields for each requested location.

Response body

The API can return data for the following metrics. All metrics are Maps from a UTC date to Natural numbers:

  • visits: People who entered the location (excludes bounces, see below).
  • dwellTime: How long people spent inside the location, in ms.
  • groupVisits: Groups of people who entered the location within a few seconds of each other.
  • bounces: People who entered, but left within a few seconds.
  • allVisits: All visitors who entered the location (visits + bounces).
  • peakOccupancy: Maximum number of visitors within the location for a time period.
  • walkBys: People who walked past the location, includes potential visitors.

Point of interests are broken down by zones:

  • visits: People who visited a point of interest, and stayed long enough.
  • dwellTime: How long people spent in a point of interest, in ms.
  • peakVisits: Maximum number of visitors observed at a point of interest for a time period.

Again, all dates are UTC. A typical response looks like this:

[
    {
        "locationId": 1,
        "visits": {
            "2023-06-08T20:30:00Z": 1,
            "2023-06-08T20:45:00Z": 2,
            "2023-06-08T21:00:00Z": 2,
            "2023-06-08T21:15:00Z": 2,
            "2023-06-08T21:30:00Z": 4,
            "2023-06-08T21:45:00Z": 2,
            "2023-06-08T22:30:00Z": 2,
            "2023-06-08T22:45:00Z": 3,
            "2023-06-08T23:00:00Z": 1,
            "2023-06-08T23:15:00Z": 2
        },
        "dwellTime": {
            "2023-06-08T20:30:00Z": 111111,
            "2023-06-08T20:45:00Z": 111111,
            "2023-06-08T21:00:00Z": 111111,
            "2023-06-08T21:15:00Z": 111111,
            "2023-06-08T21:30:00Z": 111111,
            "2023-06-08T21:45:00Z": 111111,
            "2023-06-08T22:30:00Z": 111111,
            "2023-06-08T22:45:00Z": 111111,
            "2023-06-08T23:00:00Z": 111111,
            "2023-06-08T23:15:00Z": 111111
        },
        "groupVisits": {
            "2023-06-08T20:30:00Z": 1,
            "2023-06-08T20:45:00Z": 2,
            "2023-06-08T21:00:00Z": 2,
            "2023-06-08T21:15:00Z": 2,
            "2023-06-08T21:30:00Z": 4,
            "2023-06-08T21:45:00Z": 2,
            "2023-06-08T22:30:00Z": 2,
            "2023-06-08T22:45:00Z": 3,
            "2023-06-08T23:00:00Z": 1,
            "2023-06-08T23:15:00Z": 1
        },
        "pointOfInterest": [
            {
                "id": "11111111-1111-1111-1111-111111111111",
                "peakVisits": {
                    "2023-06-08T20:30:00Z": 1,
                    "2023-06-08T21:00:00Z": 1,
                    "2023-06-08T21:30:00Z": 1,
                    "2023-06-08T21:45:00Z": 1,
                    "2023-06-08T22:00:00Z": 1,
                    "2023-06-08T22:30:00Z": 1,
                    "2023-06-08T23:00:00Z": 1
                },
                "visits": {
                    "2023-06-08T20:30:00Z": 2,
                    "2023-06-08T21:00:00Z": 1,
                    "2023-06-08T21:30:00Z": 1,
                    "2023-06-08T21:45:00Z": 1,
                    "2023-06-08T22:00:00Z": 1,
                    "2023-06-08T22:30:00Z": 1,
                    "2023-06-08T23:00:00Z": 1
                }
            },
            {
                "id": "22222222-2222-2222-2222-222222222222",
                "peakVisits": {
                    "2023-06-08T20:30:00Z": 2,
                    "2023-06-08T20:45:00Z": 2,
                    "2023-06-08T21:00:00Z": 2,
                    "2023-06-08T21:15:00Z": 2,
                    "2023-06-08T21:30:00Z": 2,
                    "2023-06-08T21:45:00Z": 2,
                    "2023-06-08T22:15:00Z": 1,
                    "2023-06-08T22:30:00Z": 1,
                    "2023-06-08T22:45:00Z": 1,
                    "2023-06-08T23:30:00Z": 1,
                    "2023-06-08T23:45:00Z": 2
                },
                "visits": {
                    "2023-06-08T20:30:00Z": 5,
                    "2023-06-08T20:45:00Z": 2,
                    "2023-06-08T21:00:00Z": 7,
                    "2023-06-08T21:15:00Z": 5,
                    "2023-06-08T21:30:00Z": 5,
                    "2023-06-08T21:45:00Z": 4,
                    "2023-06-08T22:15:00Z": 3,
                    "2023-06-08T22:30:00Z": 3,
                    "2023-06-08T22:45:00Z": 2,
                    "2023-06-08T23:30:00Z": 1,
                    "2023-06-08T23:45:00Z": 3
                }
            }
        ]
    }
]

Exports endpoint V2

A variant of the endpoint is available at https://exports.analytiks.ai/json/v2.
In this version, requesting unauthorized locations by mistake will not cause the whole request to be rejected.
Instead, you’ll get a partial response. To achieve this, the structure of the response must be slightly different:

{
    "successes": [...], // Same structure as in V1
    "failures": {
        "description": "You are not authorized to query these locations",
        "locations": [__LOC_ID_1__, ...]
    }
}

Some additional information:

  • If all requested locations are authorized, the failures object will just be empty.
  • In case of full or partial response, the HTTP status will be set to 200
  • If all requested locations are rejected, the HTTP status will be set to 401

Exports endpoint V3

A third variant of the endpoint is available at https://exports.analytiks.ai/json/v3.
In this version, batches are done automatically using cursors. You only need to specify a brandId and the endpoint will return batches of data with an optional cursor.
When a cursor is returned in the response, you can include it in your next request to get the next batch.
A cursor set to null means eveything was fetched.

Request body:

{
    "startDate": "2023-06-08T11:30:00.000",
    "endDate": "2023-06-08T23:45:00.000",
    "interval": "hourly",
    "brandId": 1234,
    "cursor": null // Can be null or missing for the first batch
}

Response body:

{
    "cursor": "some_opaque_string" // or null when everything has been fetched
    "data": [...], // Same structure as in V1
}