curl --request PATCH \
--url https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"force": false
}'import requests
url = "https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility"
payload = { "force": False }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({force: false})
};
fetch('https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility', 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/{advertiser_id}/visibility",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'force' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility"
payload := strings.NewReader("{\n \"force\": false\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"force\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"force\": false\n}"
response = http.request(request)
puts response.read_body{
"advertiser_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"library_visibility": "<string>",
"changed": true,
"forced": false
}{
"detail": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Set Brand Visibility
Flip one advertiser between public and tenant_private.
library_visibility used to be fixed at mint time. It is now
operator-adjustable because the census surfaced the case it was blocking:
a ZOB — an advertiser minted tenant_private by an own-brand claim
whose owning Brand has since been deleted — is reachable by NO tenant at
all. advertiser_identity.visible_to_caller_predicate admits a
tenant_private row only for a caller who owns it through a brand link,
and a ZOB has no such link left. Flipping it public is the one action that
returns it to the library instead of leaving it stranded.
Free for ZOB. Guarded toward public for UOB/DOB. A row some tenant
still owns or discovered is that tenant’s private record; making it public
publishes it to every other tenant’s browse surfaces. That refusal is a
409 the caller can override with force: true — the operator sometimes
genuinely means it — and a forced flip is recorded as such in the audit
row rather than being indistinguishable from an unguarded one.
The guard is deliberately one-directional. Flipping TO tenant_private
only narrows who can see the row, so it needs no override; the exposure
this endpoint has to be careful about has exactly one direction.
Re-derives UOB/DOB server-side under the row lock, exactly as
untrack_brand does: the census page’s button state is computed from a
payload that can be minutes stale, and a direct API call has no button at
all.
Idempotent: requesting the visibility the row already holds is a 200 with
changed=false — no UPDATE, no audit row, no commit. Nothing is being
exposed that was not already exposed, so the UOB/DOB guard has nothing to
refuse and is not consulted.
curl --request PATCH \
--url https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"force": false
}'import requests
url = "https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility"
payload = { "force": False }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({force: false})
};
fetch('https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility', 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/{advertiser_id}/visibility",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'force' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility"
payload := strings.NewReader("{\n \"force\": false\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"force\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/admin/brand-library/brands/{advertiser_id}/visibility")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"force\": false\n}"
response = http.request(request)
puts response.read_body{
"advertiser_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"library_visibility": "<string>",
"changed": true,
"forced": false
}{
"detail": "<string>"
}{
"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.
Path Parameters
Body
Body for PATCH /admin/brand-library/brands/{id}/visibility.
library_visibility is spelled as a Literal rather than validated
against LIBRARY_VISIBILITY_VALUES at runtime so FastAPI rejects an
unknown value with a 422 naming the allowed ones, before any handler code
or row lock. The two are pinned to each other by
LIBRARY_VISIBILITY_LITERAL_VALUES below, so a future third visibility
cannot be added to the model without this contract noticing.
force only ever matters when flipping a UOB/DOB row TO public —
the one direction that can expose a tenant's private own-brand record to
every other tenant's browse surfaces. It is deliberately not a query
parameter: an override that widens who can see a customer's data should
have to be written into a request body, not appended to a URL that ends up
in a log or a browser history entry.
Response
Successful Response
What the visibility flip actually left on the row.
Returns the stored value rather than echoing the request so the client applies what the server committed — including on the no-op path, where the row was already at the requested visibility and nothing was written.
Was this page helpful?