TAŇBA-OOH Developers

Upload the media file of a draft

POST /api/v1/submissions/{id}/media

https://app.tanba-ooh.kz/api/v1/submissions/{id}/media

Scope write:submissions. Send the raw file as the body and its name in X-Tanba-Filename (URL-encoded).

Authentication

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

Scope: write:submissions

Parameters

NameInTypeRequiredDescriptionExample
idpathstring (uuid)yesIdentifier of the draft submission.6f1c0d3e-52a4-4b57-9a7e-0c3a1b9d2e44
X-Tanba-FilenameheaderstringyesURL-encoded name of the uploaded file.autumn-sale.mp4

Request body

application/octet-stream

Responses

201 The submission with the new media.

application/json

Submission

NameTypeRequiredDescriptionExample
idstring (uuid)yesIdentifier of the submission."6f1c0d3e-52a4-4b57-9a7e-0c3a1b9d2e44"
numberstringyesNumber of the submission."SUB-2026-000087"
statestringyesCurrent state of the submission."draft"
advertiser_namestringyesName of the advertiser."Example Advertising LLP"
period_fromstring | nullyesFirst day of the campaign; null if not set yet."2026-11-01"
period_tostring | nullyesLast day of the campaign; null if not set yet."2026-11-30"
declared_daily_playsobjectPlays per day declared for each structure, keyed by structure identifier.
category_idinteger | nullAdvertiser product category, an id from GET /api/v1/categories (IAB Ad Product Taxonomy 2.0, tiers 1 and 2). Required to send a new submission for review; null on submissions that were already in review when categories were introduced.1004
categoryoneOfThe category with its names in the three console languages, or null when none is set.
channelstringWhere the creative comes from. direct, programmatic
fast_trackbooleanWhether the submission asked for the priority queue.true
external_refsobjectIdentifiers of the exchange partner that submitted the creative. Unknown keys are refused. Only with channel programmatic.
external_refs.cridstringCreative id in the partner's system."cr-4711"
external_refs.adomainarray of stringDomains of the advertiser, as in OpenRTB adomain.["example.com"]
external_refs.dspstringIdentifier of the demand-side platform."dsp-one"
external_refs.sspstringIdentifier of the supply-side platform."ssp-one"
review_due_atstring | nullDeadline of a fast-track review in Almaty time, counted in working hours; null without fast-track or before the submission is sent."2026-10-19T11:00:00+05:00"

Example

{
  "id": "6f1c0d3e-52a4-4b57-9a7e-0c3a1b9d2e44",
  "number": "SUB-2026-000087",
  "state": "draft",
  "advertiser_name": "Example Advertising LLP",
  "period_from": "2026-11-01",
  "period_to": "2026-11-30",
  "declared_daily_plays": {},
  "category_id": 1004,
  "category": {
    "id": 1004,
    "parent_id": 1002,
    "tier": 2,
    "name": {
      "en": "Beer",
      "ru": "Пиво",
      "kk": "Сыра"
    }
  },
  "channel": "programmatic",
  "fast_track": true,
  "external_refs": {
    "crid": "cr-4711",
    "adomain": [
      "example.com"
    ],
    "dsp": "dsp-one",
    "ssp": "ssp-one"
  },
  "review_due_at": "2026-10-19T11:00:00+05:00"
}

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.
defaultAn error as a problem document.

Code samples

curl

curl -X POST 'https://app.tanba-ooh.kz/api/v1/submissions/6f1c0d3e-52a4-4b57-9a7e-0c3a1b9d2e44/media' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'X-Tanba-Filename: autumn-sale.mp4' \
  -H 'Content-Type: application/octet-stream' \
  --data-binary @file
Python
import requests

response = requests.post(
    "https://app.tanba-ooh.kz/api/v1/submissions/6f1c0d3e-52a4-4b57-9a7e-0c3a1b9d2e44/media",
    headers={
        "Authorization": "Bearer YOUR_API_KEY",
        "X-Tanba-Filename": "autumn-sale.mp4",
        "Content-Type": "application/octet-stream",
    },
    data=open("file", "rb"),
)
print(response.status_code, response.text)
Go
package main

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

func main() {
	file, err := os.Open("file")
	if err != nil {
		panic(err)
	}
	defer file.Close()
	req, err := http.NewRequest("POST", "https://app.tanba-ooh.kz/api/v1/submissions/6f1c0d3e-52a4-4b57-9a7e-0c3a1b9d2e44/media", file)
	if err != nil {
		panic(err)
	}
	req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
	req.Header.Set("X-Tanba-Filename", "autumn-sale.mp4")
	req.Header.Set("Content-Type", "application/octet-stream")
	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))
}