TAŇBA-OOH Developers

Delivery report of one approval

GET /api/v1/delivery/approvals/{number}

https://app.tanba-ooh.kz/api/v1/delivery/approvals/{number}

Scope read:delivery. What each structure of the approval played, per day or per hour, split by evidence tier, against the plays declared for it, with the gaps that explain a shortfall. The tiers are shown side by side and never added together: mtls (certificate tier), signed, attested and native (device tiers; the last three are left out when the platform runs without the signed tier), and reported, what the operator's own system asserted, which is not evidence of a play. declared and delta (plays less declared) appear on day rows only; a day on which plays were declared always has a row, also with no plays. gaps lists, per structure, minutes offline, minutes in compliance mode and in cut-off, and refusals of the player.

Who sees what: the organisation that applied for the approval and the authority see every structure; an advertiser organisation sees the approvals whose advertiser BIN equals its own verified BIN; an operator sees only its own structures, also inside an approval of someone else (view is then own_structures). Anyone else gets 404. The window is the last 30 days by default, at most 92 days, or 7 days by the hour, and ends no later than today.

Authentication

API key in the Authorization header, or a console session.

Scope: read:delivery

Parameters

NameInTypeRequiredDescriptionExample
numberpathstringyesApproval number.TNB-2026-000123
fromquerystring (date)noFirst day (default 29 days back).2026-10-01
toquerystring (date)noLast day (default today).2026-10-14
grainquerystringnoLength of one row: day or hour. day, hourday

Responses

200 The report.

application/json

DeliveryReport

NameTypeRequiredDescriptionExample
schemastringyesVersion of the document format."tanba.delivery/1"
scopeobjectyesWhat the report covers.
scope.kindstringyesWhether the report covers one approval or a campaign. approval, campaign
scope.refstringyesThe approval number, or the id of the campaign."7a1f0c2e-5b6d-4e8f-9a0b-1c2d3e4f5a6b"
scope.namestringName of the campaign."Autumn campaign"
scope.external_refstringThe organisation's own reference of the campaign."PO-2026-17"
periodobjectyesThe Asia/Almaty days the report covers.
period.fromstring (date)yesFirst day."2026-10-01"
period.tostring (date)yesLast day."2026-10-14"
grainstringyesLength of one row. day, hour
viewstringyesall when the reader sees every structure of every approval; own_structures when the report is cut to what the reader may see. all, own_structures
ownerstringWho a certificate was issued for; certificates only."Example Agency LLP"
issued_atstringWhen a certificate was issued, Almaty time; certificates only."2026-10-14T17:00:00+05:00"
tiersarray of stringyesThe tiers the report covers, strongest first.
approvalsarray of DeliveryApprovalyesThe approvals in the report, with their totals per tier.
approvals[].numberstringyesApproval number."TNB-2026-000123"
approvals[].advertiserstringyesName of the advertiser; its BIN is not part of a report."Example Advertising LLP"
approvals[].media_sha256stringyesHex SHA-256 of the approved media file."2419fe2d001c9185b3b903283894a5d955f45a57d1eaf1c6b787759650f00a17"
approvals[].valid_fromstring (date)yesFirst day of validity."2026-10-01"
approvals[].valid_untilstring (date)yesLast day of validity."2026-10-31"
approvals[].revoked_atstringWhen the approval was revoked, Almaty time; present only if it was."2026-10-12T08:00:00+05:00"
approvals[].regulationobjectyesThe regulation version the approval was issued under.
approvals[].regulation.codestringyesCode of the regulation."placement-rules"
approvals[].regulation.versionstringyesVersion of the regulation."1"
approvals[].structuresarray of stringyesCodes of the structures of the approval that the reader may see.
approvals[].totalsobjectyesPlays and on-screen time over the whole window, by tier; a tier with nothing is absent.
rowsarray of DeliveryRowyesPlays per approval, structure and day or hour.
rows[].approvalstringyesApproval number."TNB-2026-000123"
rows[].structurestringyesCode of the structure."ALM-0001"
rows[].slotstringyesThe Asia/Almaty day, or on hour rows the start of the hour with its offset."2026-10-03"
rows[].declaredintegerPlays per day the operator declared for the structure; day rows only.100
rows[].tiersobjectyesThe plays by tier. Tiers are never added together.
gapsarray of DeliveryGapyesPer structure, what may explain a shortfall; structures with nothing to report are left out.
gaps[].structurestringyesCode of the structure."ALM-0001"
gaps[].offline_minutesintegeryesMinutes the screen's player was out of contact inside the window.180
gaps[].compliance_minutesintegeryesMinutes in compliance mode; counted only where mode changes were reported.45
gaps[].cutoff_minutesintegeryesMinutes in cut-off; counted only where mode changes were reported.0
gaps[].refusalsintegeryesRecords the player refused to play (unsigned, wrong hash, expired, revoked).2
audienceobjectPresent only once the audience service is on and an approved audience source has multipliers for the structures of the report; otherwise the key is absent and the document is byte for byte what it was without audience.
audience.vendorstringyesName of the audience source."Example Mobility Ltd"
audience.releasestringyesLabel of the release used."2027-A"
audience.basisstringyesHow plays were placed in quarter hours."plays of an hour are spread evenly over its four quarter hours"
audience.impactsarray of objectyesOne row per approval and tier; tiers are never added together.
audience.impacts[].approvalstringyesApproval number."TNB-2026-000123"
audience.impacts[].tierstringyesEvidence tier."mtls"
audience.impacts[].impactsstringyesSum of plays times multiplier, decimal text with three places."380.000"
audience.impacts[].plays_coveredintegeryesPlays in hours where all four quarter hours have a multiplier.175
audience.impacts[].plays_uncoveredintegeryesPlays that had no multiplier and add nothing.40

Example

{
  "schema": "tanba.delivery/1",
  "scope": {
    "kind": "campaign",
    "ref": "7a1f0c2e-5b6d-4e8f-9a0b-1c2d3e4f5a6b",
    "name": "Autumn campaign",
    "external_ref": "PO-2026-17"
  },
  "period": {
    "from": "2026-10-01",
    "to": "2026-10-14"
  },
  "grain": "day",
  "view": "all",
  "owner": "Example Agency LLP",
  "issued_at": "2026-10-14T17:00:00+05:00",
  "tiers": [
    "mtls"
  ],
  "approvals": [
    {
      "number": "TNB-2026-000123",
      "advertiser": "Example Advertising LLP",
      "media_sha256": "2419fe2d001c9185b3b903283894a5d955f45a57d1eaf1c6b787759650f00a17",
      "valid_from": "2026-10-01",
      "valid_until": "2026-10-31",
      "revoked_at": "2026-10-12T08:00:00+05:00",
      "regulation": {
        "code": "placement-rules",
        "version": "1"
      },
      "structures": [
        "ALM-0001"
      ],
      "totals": {}
    }
  ],
  "rows": [
    {
      "approval": "TNB-2026-000123",
      "structure": "ALM-0001",
      "slot": "2026-10-03",
      "declared": 100,
      "tiers": {}
    }
  ],
  "gaps": [
    {
      "structure": "ALM-0001",
      "offline_minutes": 180,
      "compliance_minutes": 45,
      "cutoff_minutes": 0,
      "refusals": 2
    }
  ],
  "audience": {
    "vendor": "Example Mobility Ltd",
    "release": "2027-A",
    "basis": "plays of an hour are spread evenly over its four quarter hours",
    "impacts": [
      {
        "approval": "TNB-2026-000123",
        "tier": "mtls",
        "impacts": "380.000",
        "plays_covered": 175,
        "plays_uncovered": 40
      }
    ]
  }
}

Errors

Errors are problem documents (application/problem+json) with a stable code.

StatusMeaning
401No valid session or API key (unauthenticated, session_expired, invalid_api_key).
403The role or the key's scope does not allow this (forbidden, key_scope_denied, key_route_denied).
404Nothing there, or not visible to the caller.
422Field errors (validation_failed).
defaultAn error as a problem document.

Code samples

curl

curl 'https://app.tanba-ooh.kz/api/v1/delivery/approvals/TNB-2026-000123' \
  -H 'Authorization: Bearer YOUR_API_KEY'
Python
import requests

response = requests.get(
    "https://app.tanba-ooh.kz/api/v1/delivery/approvals/TNB-2026-000123",
    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/delivery/approvals/TNB-2026-000123", 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))
}