curl --request GET \
--url https://api.example.com/api/v1/admin/brand-library/brands \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.example.com/api/v1/admin/brand-library/brands"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.example.com/api/v1/admin/brand-library/brands', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/admin/brand-library/brands",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/admin/brand-library/brands"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/admin/brand-library/brands")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/admin/brand-library/brands")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"brands": [
{
"advertiser_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"brand_name": "<string>",
"library_visibility": "<string>",
"is_uob": true,
"is_dob": true,
"is_gtb": true,
"is_utb": true,
"is_zob": true,
"created_at": "2023-11-07T05:31:56Z",
"brand_market_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"market_country": "<string>",
"domain": "<string>",
"homepage_url": "<string>",
"parent_company": "<string>",
"reviews_fetch_enabled": true,
"reviews_untrack_block_reason": "<string>",
"uob_owners": [],
"dob_origins": [],
"utb_trackers": [],
"unplaced_owner_count": 0,
"unplaced_origin_count": 0,
"target_country": "<string>",
"ad_count": 0,
"social_post_count": 0,
"content_piece_count": 0,
"review_count": 0,
"has_seo_data": false,
"market_count": 0,
"seed_count": 0
}
],
"total": 123,
"limit": 123,
"offset": 123,
"has_more": true
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}List Brands
Full Brand Library census, paginated and optionally filtered.
Admin bypasses the Task 8 tenancy predicate
(advertiser_identity.visible_to_caller_predicate) by definition —
this is the surface that answers “why is this row here?” for every
advertiser, including tenant_private rows no ordinary caller can
browse. Read-only: never mints, enqueues, or triggers acquisition.
Rows, total, limit and offset are all library-brand × market
(one row per brand_markets record; a brand with no record is one
row), so a class chip such as UOB selects the MARKET rows a user’s
copy sits on, not every row of the brand.
q, classes and visibility are census-WIDE: they filter in SQL ahead of
LIMIT/OFFSET, so total counts matches across the whole library and
the operator no longer has to page the library in before searching it.
Omitting all three returns the unfiltered census, unchanged.
classes is typed as a Literal, so an unknown class is a 422 here
rather than a silently ignored parameter that would return more rows than
the caller asked for.
curl --request GET \
--url https://api.example.com/api/v1/admin/brand-library/brands \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.example.com/api/v1/admin/brand-library/brands"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.example.com/api/v1/admin/brand-library/brands', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/admin/brand-library/brands",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/admin/brand-library/brands"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.example.com/api/v1/admin/brand-library/brands")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/admin/brand-library/brands")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"brands": [
{
"advertiser_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"brand_name": "<string>",
"library_visibility": "<string>",
"is_uob": true,
"is_dob": true,
"is_gtb": true,
"is_utb": true,
"is_zob": true,
"created_at": "2023-11-07T05:31:56Z",
"brand_market_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"market_country": "<string>",
"domain": "<string>",
"homepage_url": "<string>",
"parent_company": "<string>",
"reviews_fetch_enabled": true,
"reviews_untrack_block_reason": "<string>",
"uob_owners": [],
"dob_origins": [],
"utb_trackers": [],
"unplaced_owner_count": 0,
"unplaced_origin_count": 0,
"target_country": "<string>",
"ad_count": 0,
"social_post_count": 0,
"content_piece_count": 0,
"review_count": 0,
"has_seo_data": false,
"market_count": 0,
"seed_count": 0
}
],
"total": 123,
"limit": 123,
"offset": 123,
"has_more": true
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Query Parameters
1 <= x <= 500x >= 0Case-insensitive substring match on canonical_name or primary_domain, over the WHOLE library rather than the current page. LIKE metacharacters are escaped server-side.
255Origin classes to intersect (repeatable). Chips compose with AND: ?classes=UOB&classes=GTB is rows that are both.
UOB, DOB, GTB, UTB, ZOB Filter public or tenant_private brands; omitted returns both.
public, tenant_private Response
Successful Response
One page of the census, with enough metadata to page further.
has_more is computed from offset + len(brands) < total where
both sides come from the SAME unfiltered SQL query family (no Python-side
row dropping happens between the count and the page) — see the service
docstring for why that structurally avoids the has_more/offset drift bug
class this repo has hit before. total, limit and offset all
count library-brand × market rows, never library brands: the fan-out
happens in SQL (an outer join in the base select), so a multi-market
brand costs several rows of the page and the pager's arithmetic is
unchanged.
Was this page helpful?