TAŇBA-OOH Developers

Enrol a device with a one-time token and a certificate request

POST /d/v1/enroll

https://devices.tanba-ooh.kz/d/v1/enroll

The first call of a player. An administrator issues an enrolment token in the console (valid 24 hours, single use). The player makes an ECDSA P-256 key, sends a certificate request for it together with the token, and receives its device certificate, valid for one year, and the chain up to the device certificate authority. From then on every call except this one and the reading of the revocation lists presents that certificate. The token is the only credential of this call, and the calls from one address are rate limited.

The device protocol is in beta: the object identifiers of the signed attributes of the approval envelope sit in a provisional test arc, 1.3.6.1.4.1.59999.1. A registered arc replaces it before the protocol is called stable.

Authentication

Public call: the one-time enrolment token in the body is the credential.

Request body

application/json

NameTypeRequiredDescriptionExample
tokenstringyesThe one-time enrolment token from the console."tdt_4f9c2a71b86e3d05"
csrstringyesCertificate request for the device key, PEM or base64 of the DER form; ECDSA P-256."MIIBEjCBuAIBADAZMRcwFQYDVQQDEw5leGFtcGxlLXBsYXllcjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABA"
modelstringModel of the player."XP-100"
firmwarestringFirmware version of the player."4.2.1"
serial_nostringSerial number of the player."XP100-0042"
spec_versionstringVersion of the conformance specification the player claims."1.1"

Example

{
  "token": "tdt_4f9c2a71b86e3d05",
  "csr": "MIIBEjCBuAIBADAZMRcwFQYDVQQDEw5leGFtcGxlLXBsYXllcjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABA",
  "model": "XP-100",
  "firmware": "4.2.1",
  "serial_no": "XP100-0042",
  "spec_version": "1.1"
}

Responses

200 The device is enrolled.

application/json

NameTypeRequiredDescriptionExample
device_idstring (uuid)yesIdentifier of the device; it is in the certificate."5c0e8f3a-71d2-4b6e-9a14-d8e2f7b30c59"
certificate_pemstringyesThe device certificate in PEM form."-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----\n"
chain_pemstringyesThe chain up to the device certificate authority in PEM form."-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----\n"
noncestringyesThe nonce for the first heartbeat."3b9f0c6e2a7d41f85e0b9a3c7d2e1f60"
not_afterstring (date-time)yesWhen the certificate expires."2027-10-14T09:00:00Z"
revocation_listobject | nullThe newest revocation list: its version and address.
revocation_list.versionintegerVersion of the list.42
revocation_list.urlstringAddress of the list."https://devices.tanba-ooh.kz/d/v1/revocations/42"

Example

{
  "device_id": "5c0e8f3a-71d2-4b6e-9a14-d8e2f7b30c59",
  "certificate_pem": "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----\n",
  "chain_pem": "-----BEGIN CERTIFICATE-----\nMIIB...\n-----END CERTIFICATE-----\n",
  "nonce": "3b9f0c6e2a7d41f85e0b9a3c7d2e1f60",
  "not_after": "2027-10-14T09:00:00Z",
  "revocation_list": {
    "version": 42,
    "url": "https://devices.tanba-ooh.kz/d/v1/revocations/42"
  }
}

Errors

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

StatusMeaning
403The token is unknown, used or expired (invalid_token).
422Field errors (validation_failed).
429Rate limit; see Retry-After.
503The device channel is switched off (device_channel_disabled).
defaultAn error as a problem document.

Code samples

curl

curl -X POST 'https://devices.tanba-ooh.kz/d/v1/enroll' \
  -H 'Content-Type: application/json' \
  -d '{
  "token": "tdt_4f9c2a71b86e3d05",
  "csr": "MIIBEjCBuAIBADAZMRcwFQYDVQQDEw5leGFtcGxlLXBsYXllcjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABA",
  "model": "XP-100",
  "firmware": "4.2.1",
  "serial_no": "XP100-0042",
  "spec_version": "1.1"
}'
Python
import requests

response = requests.post(
    "https://devices.tanba-ooh.kz/d/v1/enroll",
    headers={
        "Content-Type": "application/json",
    },
    json={
        "token": "tdt_4f9c2a71b86e3d05",
        "csr": "MIIBEjCBuAIBADAZMRcwFQYDVQQDEw5leGFtcGxlLXBsYXllcjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABA",
        "model": "XP-100",
        "firmware": "4.2.1",
        "serial_no": "XP100-0042",
        "spec_version": "1.1",
    },
)
print(response.status_code, response.text)
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{
  "token": "tdt_4f9c2a71b86e3d05",
  "csr": "MIIBEjCBuAIBADAZMRcwFQYDVQQDEw5leGFtcGxlLXBsYXllcjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABA",
  "model": "XP-100",
  "firmware": "4.2.1",
  "serial_no": "XP100-0042",
  "spec_version": "1.1"
}`)
	req, err := http.NewRequest("POST", "https://devices.tanba-ooh.kz/d/v1/enroll", body)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Content-Type", "application/json")
	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))
}