JSON Exports API for Camera data
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 toapplication/json
Authorization
set toBearer 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 finalZ
), dates in the response will also be UTC. - If dates are requested in local time (eg.
2023-06-08T09:00:00.000
, no finalZ
), dates in the response will also be local time. - Both
startDate
andendDate
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 (excludesbounces
, see below).dwellTime
: How long people spent inside the location, in ms. Note that this metric is only available if a camera can be calibrated for it, a good field of view of the entire place is required in order to do so.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
}