City operational report - plays and screens, load, anomalies
GET /api/v1/stats/reports
https://app.tanba-ooh.kz/api/v1/stats/reports
Технический текст справочника написан на английском.
Scope read:stats. Own organisation; the authority sees the city. Answered from the hourly aggregates; days are Asia/Almaty days. series holds plays and active screens (structures with a play) per period, district and format; load the distribution of plays per screen per day; anomalies the screens to look at; reconciliation the plays an operator imported against the plays the players reported, per structure, approval and finished day.
Аутентификация
Ключ API в заголовке Authorization или сессия консоли.
Право доступа: read:stats
Параметры
| Имя | Где | Тип | Обязательный | Описание | Пример |
|---|---|---|---|---|---|
from | запрос | string (date) | нет | First day (default 29 days back). | 2026-09-08 |
to | запрос | string (date) | нет | Last day (default today). | 2026-10-06 |
grain | запрос | string | нет | Length of one period: day, week or month. day, week, month | day |
Ответы
200 The report sections.
application/json
| Имя | Тип | Обязательный | Описание | Пример |
|---|---|---|---|---|
from | string (date) | да | First day of the report. | "2026-09-08" |
to | string (date) | да | Last day of the report. | "2026-10-06" |
grain | string | да | Length of one period in series: day, week or month. | "day" |
series | array of object | да | Plays and active screens for each period, district and format. | |
series[].period | string (date) | да | First day of the period. | "2026-10-05" |
series[].district | string | да | Code of the district. | "bostandyk" |
series[].format | string | да | Code of the format. | "cityboard" |
series[].plays | integer | да | Plays in the period. | 48210 |
series[].screens | integer | да | Screens with at least one play in the period. | 36 |
load | object | да | How plays per screen per day are distributed. | |
load.screen_days | integer | да | Number of screen-days counted. | 1008 |
load.mean | integer | да | Mean plays per screen per day. | 1340 |
load.median | integer | да | Median plays per screen per day. | 1325 |
load.p10 | integer | да | Plays per screen per day that 10 % of screen-days stay under. | 980 |
load.p90 | integer | да | Plays per screen per day that 90 % of screen-days stay under. | 1710 |
load.max | integer | да | Most plays on one screen in one day. | 2010 |
load.histogram | array of object | да | Screen-days by bands of plays. | |
load.histogram[].from | integer | да | Lower edge of the band, in plays. | 1000 |
load.histogram[].to | integer | да | Upper edge of the band, in plays. | 1500 |
load.histogram[].count | integer | да | Screen-days in the band. | 412 |
anomalies | array of object | да | The screens to look at. | |
anomalies[].kind | string | да | What was found. low_plays, silent, refusal_spike | |
anomalies[].structure_id | string (uuid) | да | Identifier of the structure. | "b7e4a2c9-0d1f-4a68-8e35-91c7f2d40b16" |
anomalies[].code | string | да | Code of the structure. | "ALM-0012" |
anomalies[].address | string | да | Street address of the structure. | "Al-Farabi Ave 77/7" |
anomalies[].district | string | да | Code of the district. | "bostandyk" |
anomalies[].observed | integer | да | Plays observed on that day. | 120 |
anomalies[].baseline | integer | да | Plays expected from the structure's own history. | 1300 |
anomalies[].day | string | да | The Asia/Almaty day concerned. | "2026-10-05" |
reconciliation | array of object | да | Imported plays against reported plays, for each structure, approval and finished day. | |
reconciliation[].day | string (date) | да | The Asia/Almaty day compared. | "2026-10-05" |
reconciliation[].structure | string | да | Structure code. | "ALM-0012" |
reconciliation[].approval_number | string | да | Number of the approval compared. | "TNB-2026-000123" |
reconciliation[].imported_plays | integer | да | Plays the operator imported for that day. | 2830 |
reconciliation[].reported_plays | integer | да | Plays the players reported for that day. | 2841 |
reconciliation[].reconciled_ratio | number | null | да | Imported divided by reported; null while the players reported nothing. | 0.996 |
Пример
{
"from": "2026-09-08",
"to": "2026-10-06",
"grain": "day",
"series": [
{
"period": "2026-10-05",
"district": "bostandyk",
"format": "cityboard",
"plays": 48210,
"screens": 36
}
],
"load": {
"screen_days": 1008,
"mean": 1340,
"median": 1325,
"p10": 980,
"p90": 1710,
"max": 2010,
"histogram": [
{
"from": 1000,
"to": 1500,
"count": 412
}
]
},
"anomalies": [
{
"kind": "low_plays",
"structure_id": "b7e4a2c9-0d1f-4a68-8e35-91c7f2d40b16",
"code": "ALM-0012",
"address": "Al-Farabi Ave 77/7",
"district": "bostandyk",
"observed": 120,
"baseline": 1300,
"day": "2026-10-05"
}
],
"reconciliation": [
{
"day": "2026-10-05",
"structure": "ALM-0012",
"approval_number": "TNB-2026-000123",
"imported_plays": 2830,
"reported_plays": 2841,
"reconciled_ratio": 0.996
}
]
}
Ошибки
Ошибки приходят документом problem (application/problem+json) со стабильным полем code.
| Статус | Значение |
|---|---|
| 401 | Нет действительной сессии или ключа API (unauthenticated, session_expired, invalid_api_key). |
| 403 | Роль или право ключа этого не допускает (forbidden, key_scope_denied, key_route_denied). |
| 422 | Ошибки полей (validation_failed). |
| default | Ошибка в виде документа problem. |
Примеры кода
curl
curl 'https://app.tanba-ooh.kz/api/v1/stats/reports' \
-H 'Authorization: Bearer YOUR_API_KEY'
Python
import requests
response = requests.get(
"https://app.tanba-ooh.kz/api/v1/stats/reports",
headers={
"Authorization": "Bearer YOUR_API_KEY",
},
)
print(response.status_code, response.text)
Go
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, err := http.NewRequest("GET", "https://app.tanba-ooh.kz/api/v1/stats/reports", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(data))
}