curl --request GET \
--url https://www.closient.com/analytics/api/v1/traffic \
--header 'X-API-Key: <api-key>'import requests
url = "https://www.closient.com/analytics/api/v1/traffic"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://www.closient.com/analytics/api/v1/traffic', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.closient.com/analytics/api/v1/traffic",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://www.closient.com/analytics/api/v1/traffic"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.closient.com/analytics/api/v1/traffic")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/analytics/api/v1/traffic")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"breadcrumb": [
{
"name": "Salsa Fresca Foods",
"type": "organization"
},
{
"id": "8kPq2mWvNc4RtYuIoPaSdF",
"name": "Salsa Fresca",
"type": "brand"
}
],
"interval": "day",
"metric": "scans",
"period": {
"end": "2026-07-08T00:00:00Z",
"start": "2026-07-01T00:00:00Z"
},
"previous_period_total": 142,
"scope": {
"id": "8kPq2mWvNc4RtYuIoPaSdF",
"name": "Salsa Fresca",
"type": "brand"
},
"series": [
{
"data": [
12,
19,
7,
0,
23,
31,
18
],
"has_children": true,
"id": "3nRt7yUiOpAsDfGhJkLzXc",
"name": "Salsa Fresca Medium 16oz",
"total": 110,
"type": "product"
},
{
"data": [
8,
11,
4,
0,
14,
19,
12
],
"has_children": true,
"id": "5vBnM3qWeRtYuIoPaSdFgH",
"name": "Salsa Fresca Hot 16oz",
"total": 68,
"type": "product"
}
],
"timestamps": [
"2026-07-01",
"2026-07-02",
"2026-07-03",
"2026-07-04",
"2026-07-05",
"2026-07-06",
"2026-07-07"
],
"total": 178
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}Hierarchical traffic time series for a scope
Returns a stacked time series suitable for an ECharts stacked area / bar chart, plus a breadcrumb describing the drill-down path. The shape mirrors the Customer Analytics Dashboard contract (C-1045).
Scopes form a hierarchy organization → brand → product (optional) → trade_item; the response’s series[*].type discriminator tells the frontend whether clicking a stacked segment should drill into another product, an ungrouped trade item, or stop.
Data comes from the pre-aggregated ScanDailySummary table — no raw event scans are queried at request time. Today’s partial day is excluded; pre-aggregation runs nightly.
Caller must be a member of organization_id or a 404 is returned. scope_id (when supplied) must belong to that organization or a 404 is returned.
curl --request GET \
--url https://www.closient.com/analytics/api/v1/traffic \
--header 'X-API-Key: <api-key>'import requests
url = "https://www.closient.com/analytics/api/v1/traffic"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://www.closient.com/analytics/api/v1/traffic', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.closient.com/analytics/api/v1/traffic",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://www.closient.com/analytics/api/v1/traffic"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://www.closient.com/analytics/api/v1/traffic")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://www.closient.com/analytics/api/v1/traffic")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"breadcrumb": [
{
"name": "Salsa Fresca Foods",
"type": "organization"
},
{
"id": "8kPq2mWvNc4RtYuIoPaSdF",
"name": "Salsa Fresca",
"type": "brand"
}
],
"interval": "day",
"metric": "scans",
"period": {
"end": "2026-07-08T00:00:00Z",
"start": "2026-07-01T00:00:00Z"
},
"previous_period_total": 142,
"scope": {
"id": "8kPq2mWvNc4RtYuIoPaSdF",
"name": "Salsa Fresca",
"type": "brand"
},
"series": [
{
"data": [
12,
19,
7,
0,
23,
31,
18
],
"has_children": true,
"id": "3nRt7yUiOpAsDfGhJkLzXc",
"name": "Salsa Fresca Medium 16oz",
"total": 110,
"type": "product"
},
{
"data": [
8,
11,
4,
0,
14,
19,
12
],
"has_children": true,
"id": "5vBnM3qWeRtYuIoPaSdFgH",
"name": "Salsa Fresca Hot 16oz",
"total": 68,
"type": "product"
}
],
"timestamps": [
"2026-07-01",
"2026-07-02",
"2026-07-03",
"2026-07-04",
"2026-07-05",
"2026-07-06",
"2026-07-07"
],
"total": 178
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}{
"detail": "The requested resource was not found.",
"error_code": "not_found",
"retryable": false,
"status": 404,
"timestamp": "2026-03-31T12:00:00+00:00",
"title": "Not Found",
"type": "https://closient.com/docs/errors/not_found"
}Authorizations
Query Parameters
UUID of the organization to query (caller must be a member).
22^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$Hierarchy level being viewed. Defaults to organization (the top-level entry view).
organization, brand, product, trade_item UUID of the brand / product / trade item to scope to. Required for every scope_type other than organization.
22^[23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{22}$Override the default child grouping. Most callers leave this blank — the service derives it from scope_type (org → brand, brand → product_and_trade_item, product → trade_item).
brand, product_and_trade_item, trade_item Time bucket size for the X-axis.
day, week, month Window start (UTC, inclusive). Defaults to 30 days before end.
Window end (UTC, exclusive). Defaults to now.
Counter to plot on the Y-axis. resolves = every scan the resolver served; page_visits = the hosted-page subset.
resolves, page_visits Cap on distinct stacked series. The remainder collapses into a single Others series so the chart stays readable.
1 <= x <= 50Response
OK
Stacked traffic time series for a scope, ready for ECharts.
Shape mirrors the ticket's Response shape example. The frontend feeds
timestamps to the X-axis and each :class:SeriesEntryOut to a
stacked series; total / previous_period_total power the summary
cards above the chart.
Entity the chart is currently zoomed into.
Show child attributes
Show child attributes
{
"id": "8kPq2mWvNc4RtYuIoPaSdF",
"name": "Salsa Fresca",
"type": "brand"
}
Drill-down path from the org root to the current scope. The frontend renders this as a click-to-navigate trail.
Show child attributes
Show child attributes
Time bucket size used to build timestamps.
day, week, month Which counter the data arrays report.
resolves, page_visits Window covered by timestamps.
Show child attributes
Show child attributes
{
"end": "2026-07-08T00:00:00Z",
"start": "2026-07-01T00:00:00Z"
}
Sum of every series total within period — top summary card.
x >= 0Sum for the immediately preceding equal-length window. Used to compute the delta-vs-previous summary and per-series trend indicator. Zero when no historical data exists.
x >= 0Children of the current scope, ranked by total descending. High-cardinality scopes apply a Top N + Others collapse — see top_n query param.
Show child attributes
Show child attributes
X-axis bucket starts, ISO date / datetime. Length matches every series' data array.