Appearance
Watcher Summary
Query watcher observations scoped to your authorized networks. Two endpoints are available: a paginated JSON endpoint for app integration and a streaming CSV endpoint for bulk export.
GET /api/v1/watcher-summary
Returns watcher observations as paginated JSON.
Query parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
from | ISO 8601 date or datetime | Yes | — | Start of the time window (inclusive). Date-only (e.g. 2026-04-01) is treated as UTC midnight. |
to | ISO 8601 date or datetime | Yes | — | End of the time window (exclusive). Date-only is treated as UTC midnight. |
site_id | integer or integer[] | No | — | Filter by one or more site IDs. Each value must be a positive integer. |
limit | integer | No | 1000 | Number of rows to return. Must be a positive integer between 1 and 5000. Values outside this range are rejected. |
sort | asc | desc | No | asc | Sort direction by observation timestamp. Must be exactly asc or desc — any other value is rejected. |
after | ISO 8601 datetime | No | — | Cursor pagination. Returns rows strictly after this timestamp. Use the next_after value from the previous response. Takes priority over offset. Must be a valid ISO 8601 timestamp. |
offset | integer | No | — | Offset pagination. Number of rows to skip. Must be a non-negative integer. Use for random page access. Ignored if after is provided. |
Date range limit
The from–to range cannot exceed 31 days.
Pagination modes
Two pagination modes are supported. Cursor mode is preferred for sequential traversal of large datasets.
Cursor-based (recommended for large datasets)
Pass next_after from the previous response as after= on the next request. When next_after is null, you have reached the last page.
Page 1: ?from=...&to=...&limit=5000
Page 2: ?from=...&to=...&limit=5000&after=<next_after from page 1>
Page 3: ?from=...&to=...&limit=5000&after=<next_after from page 2>Offset-based (random page access)
Use offset to jump directly to any page. Note that performance may degrade at large offsets.
Page 1: ?from=...&to=...&limit=5000&offset=0
Page 3: ?from=...&to=...&limit=5000&offset=10000Response 200
json
{
"status": true,
"message": "Success",
"data": {
"total": 165544,
"limit": 5000,
"next_after": "2026-04-02T08:44:21.000Z",
"count": 5000,
"rows": [
{
"WATCHERID": 500,
"GENDER": "male",
"AGE_CATEGORY": "adult",
"MOOD": "neutral",
"SITE_TIMESTAMP_SITE_TZ": "2026-04-02T08:44:21.000Z",
"SITE_TZ": "Australia/Sydney",
"HOUR_SITE_TZ": "08",
"DAY_SITE_TZ": "Wednesday",
"IS_WATCHER": 1,
"DURATION": 4.5,
"ATTENTION": 72.0,
"SITE_ID": 1,
"SITE_NAME": "Sydney CBD",
"LOCATION_ID": 3,
"LOCATION_NAME": "Entrance",
"DEVICE_ID": 12,
"DEVICE_NAME": "Camera-01",
"CAM_ID": 5,
"CAMERA_NAME": "Front Cam"
}
]
}
}Last page
When next_after is null and count is less than limit, you have reached the last page.
Client loop example
js
let after = null;
let allRows = [];
do {
const params = new URLSearchParams({ from, to, limit: 5000 });
if (after) params.set('after', after);
const { data } = await fetch(`/api/v1/watcher-summary?${params}`, {
headers: { Authorization: `Bearer ${token}` }
}).then(r => r.json());
allRows.push(...data.rows);
after = data.next_after;
} while (after !== null);Errors
| Code | Description |
|---|---|
400 | Missing from/to; date-only format (must include time); range exceeds 31 days; from is not before to; limit out of range; invalid offset, sort, site_id, or after value |
401 | Invalid or expired token; X-Network-Name header value is not authorized by the token |
403 | Token does not have access to any networks |
500 | Internal server error |
GET /api/v1/watcher-summary/download
Streams watcher observations as a CSV file. Designed for bulk data export — memory usage on the server is constant regardless of result size.
Query parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
from | ISO 8601 date or datetime | Yes | — | Start of the time window (inclusive). Date-only (e.g. 2026-04-01) is treated as UTC midnight. |
to | ISO 8601 date or datetime | Yes | — | End of the time window (exclusive). Date-only is treated as UTC midnight. |
site_id | integer or integer[] | No | — | Filter by one or more site IDs. Each value must be a positive integer. |
limit | integer | No | — | Maximum rows to include. Must be a positive integer between 1 and 5000. Values outside this range are rejected. If omitted, all matching rows are streamed. |
offset | integer | No | 0 | Number of rows to skip. Must be a non-negative integer. |
Postman
Postman displays CSV as raw text. To save the file, click Save Response → Save to a file after the request completes. For large exports, use curl instead.
curl example
API Base URL: https://prod-gcp.services.api.viana.ai
bash
curl -H "Authorization: Bearer <token>" \
"<API_BASE_URL>/api/v1/watcher-summary/download?from=2026-04-01T00:00:00Z&to=2026-04-07T23:59:59Z" \
-o watcher_summary.csvResponse
Returns a text/csv file download. The first row is the header row containing all available field names.
Field reference
| Column | Type | Description |
|---|---|---|
WATCHERID | number | Watcher identifier |
GENDER | string | Detected gender |
AGE_CATEGORY | string | Age category |
MOOD | string | Detected mood |
SITE_TIMESTAMP_SITE_TZ | timestamp | Observation timestamp (site timezone) |
SITE_TZ | string | Site timezone |
HOUR_SITE_TZ | string | Hour label (site timezone) |
DAY_SITE_TZ | string | Day label (site timezone) |
IS_WATCHER | number | 1 if watcher detected, 0 otherwise |
DURATION | float | Detection duration (seconds) |
ATTENTION | number | Attention score (0–100) |
SITE_ID | number | Site identifier |
SITE_NAME | string | Site name |
LOCATION_ID | number | Location identifier |
LOCATION_NAME | string | Location name |
DEVICE_ID | number | Device identifier |
DEVICE_NAME | string | Device name |
CAM_ID | number | Camera identifier |
CAMERA_NAME | string | Camera name |
Errors
| Code | Description |
|---|---|
400 | Missing from/to; date-only format (must include time); range exceeds 31 days; from is not before to; limit out of range; invalid offset or site_id value |
401 | Invalid or expired token; X-Network-Name header value is not authorized by the token |
403 | Token does not have access to any networks |
500 | Internal server error |