Replace your whole branding layer at once
A whole-layer replace, not a merge: the layer you send becomes the complete set of overrides, and anything you leave out falls back to the platform default.
PUT
/
branding
curl --request PUT "$MITHUNAI_URL/arukz/api/v1/branding" \
--header "Authorization: Bearer $MITHUNAI_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"revision": 3,
"layer": {
"identity": { "productName": "Northwind Answers", "companyName": "Northwind Traders" },
"assets": { "logoLight": "https://cdn.northwind.example/brand/logo-light.svg" },
"theme": {
"colors": { "light": { "brand": "#1F6FEB", "brandHover": "#1A5FCC" } },
"modeDefault": "system"
},
"domains": { "supportUrl": "https://support.northwind.example" },
"surfaces": { "widget": { "showBranding": false } }
}
}'
import os, requests
layer = {
"identity": {"productName": "Northwind Answers", "companyName": "Northwind Traders"},
"assets": {"logoLight": "https://cdn.northwind.example/brand/logo-light.svg"},
"theme": {
"colors": {"light": {"brand": "#1F6FEB", "brandHover": "#1A5FCC"}},
"modeDefault": "system",
},
"domains": {"supportUrl": "https://support.northwind.example"},
"surfaces": {"widget": {"showBranding": False}},
}
response = requests.put(
f"{os.environ['MITHUNAI_URL']}/arukz/api/v1/branding",
headers={"Authorization": f"Bearer {os.environ['MITHUNAI_API_KEY']}"},
json={"revision": 3, "layer": layer},
timeout=60,
)
response.raise_for_status()
print(response.json())
const layer = {
identity: { productName: 'Northwind Answers', companyName: 'Northwind Traders' },
assets: { logoLight: 'https://cdn.northwind.example/brand/logo-light.svg' },
theme: {
colors: { light: { brand: '#1F6FEB', brandHover: '#1A5FCC' } },
modeDefault: 'system',
},
domains: { supportUrl: 'https://support.northwind.example' },
surfaces: { widget: { showBranding: false } },
}
const response = await fetch(`${process.env.MITHUNAI_URL}/arukz/api/v1/branding`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.MITHUNAI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ revision: 3, layer }),
})
console.log(await response.json())
{
"layer": {
"identity": {
"productName": "Northwind Answers",
"companyName": "Northwind Traders"
},
"assets": {
"logoLight": "https://cdn.northwind.example/brand/logo-light.svg"
},
"theme": {
"colors": {
"light": {
"brand": "#1F6FEB",
"brandHover": "#1A5FCC"
}
},
"modeDefault": "system"
},
"domains": {
"supportUrl": "https://support.northwind.example"
},
"surfaces": {
"widget": {
"showBranding": false
}
}
},
"revision": 4,
"configured": true,
"updatedAt": "2026-09-24T10:48:13.209577+00:00",
"updatedBy": "8d3f6a21-4c9e-4b07-a1d5-e62f0b9c7a48"
}
{
"code": "validation_error",
"message": "Colours must be a hex value such as #4636D9, or an rgb(), rgba(), hsl() or hsla() value."
}
{ "code": "authorization_error", "message": "You do not have permission to perform this action." }
{ "code": "conflict", "message": "The branding was changed by someone else. Reload and try again." }
This is a whole-layer replace, not a merge. The
layer you send becomes the complete set of overrides. Any field you leave out, or send as null, has no override and falls back to the platform default. To clear one override, send the layer you last read with that field removed or set to null. If you omit layer entirely, every override is cleared.
The layer is sparse and uses the same camelCase shape GET /branding returns, so you can read it, edit it and send it back. Unknown keys are refused with 400 and named in the message, so a typo never saves silently. The whole request body is limited to 256 KiB, so large inline images count against that limit.
Concurrency. revision is required. Send the revision from your last read (0 if branding has never been saved). If anyone has saved or reset branding since, the request fails with 409 and nothing is changed; read again and retry. A successful save returns the new state with revision increased by one.
What becomes public. identity, assets, theme and surfaces are shown to anyone who loads your website widget. domains and legal are not sent to the widget.
Attribution. The layer has no field for third-party attribution notices. They cannot be set, changed or removed through this API.
Replacing branding requires the owner or admin role. Other roles receive 403. See Branding.
Value rules
| Rule | Accepted values |
|---|---|
| Text | 1 to 120 characters after trimming. No control, invisible formatting (such as zero-width or bidirectional-override), private-use or line-separator characters. An empty string is refused; use null to clear. |
| Link | An https:// URL of at most 1,024 characters, with no whitespace, quotes, <, >, \ or backticks. http:// is refused. |
| Asset | Either a URL following the link rule, or inline base64 image data data:<type>;base64,<data> where <type> is image/svg+xml, image/png, image/jpeg, image/webp, image/gif or image/x-icon. At most 262,144 characters. |
| Colour | A hex value (#rgb, #rgba, #rrggbb or #rrggbbaa), or rgb(), rgba(), hsl() or hsla() whose arguments contain only digits, spaces and . , % / + -, at most 64 characters inside the parentheses. Named colours such as red are refused. |
| Font stack | 1 to 200 characters from letters, digits, spaces and , . _ ' " ( ) -. |
| Base size | A whole number from 10 to 24. |
| Radius | A CSS length such as 10px: at most 16 characters of letters, digits, ., _ and %. |
| Appearance mode | light, dark or system. |
| Boolean | A JSON true or false. Strings such as "false" are refused. |
integer
required
The
revision from your last read, a whole number of at least 0. A stale value returns 409.object
The complete set of overrides. Every section and every field is optional.
Show properties
Show properties
object
object
Logos and images.
object
Colours, typography, corner radii and default appearance.
Show properties
Show properties
object
Colour palettes, one per appearance. Follows the colour rule.
Show properties
Show properties
object
Colour overrides for the light appearance. Each key takes a colour. Keys:
background, surface, surfaceRaised, surfaceSunken, border, borderStrong,
textPrimary, textSecondary, textMuted, textInverted, brand, brandHover,
brandContrast, brandSubtle, accent, accentContrast, focus, success,
successSubtle, warning, warningSubtle, danger, dangerSubtle, info,
infoSubtle, overlay.object
Colour overrides for the dark appearance. Each key takes a colour. Keys:
background,
surface, surfaceRaised, surfaceSunken, border, borderStrong, textPrimary,
textSecondary, textMuted, textInverted, brand, brandHover, brandContrast,
brandSubtle, accent, accentContrast, focus, success, successSubtle,
warning, warningSubtle, danger, dangerSubtle, info, infoSubtle, overlay.object
object
string
Appearance the interface starts in. Follows the appearance mode rule.
object
object
Your own legal links and notice. Third-party attribution notices are not part of the layer and
cannot be set, changed or removed through this API.
object
Display toggles.
Response
Returns200 OK with the stored branding.
object
required
Your organization’s overrides. Sparse: only fields you have set appear, and an organization with
no overrides returns
{}. Anything absent falls back to the platform default.Show properties
Show properties
object
object
object
Colours, typography, corner radii and default appearance.
Show properties
Show properties
object
Colour palettes, one per appearance.
Show properties
Show properties
object
Colour overrides for the light appearance. Each key takes a colour. Keys:
background, surface, surfaceRaised, surfaceSunken, border, borderStrong,
textPrimary, textSecondary, textMuted, textInverted, brand, brandHover,
brandContrast, brandSubtle, accent, accentContrast, focus, success,
successSubtle, warning, warningSubtle, danger, dangerSubtle, info,
infoSubtle, overlay.object
Colour overrides for the dark appearance. Each key takes a colour. Keys:
background,
surface, surfaceRaised, surfaceSunken, border, borderStrong, textPrimary,
textSecondary, textMuted, textInverted, brand, brandHover, brandContrast,
brandSubtle, accent, accentContrast, focus, success, successSubtle,
warning, warningSubtle, danger, dangerSubtle, info, infoSubtle, overlay.object
object
string
Appearance the interface starts in.
object
integer
required
Concurrency revision.
0 until the first save; each save or reset adds one. Send it back on PUT /branding or DELETE /branding.boolean
required
true once branding has been saved or reset at least once. false means the organization has
always used the platform default.string | null
required
When branding was last saved or reset, ISO 8601 in UTC.
null if never.string | null
required
Identifier of the user or API key that last saved or reset branding.
null if never.curl --request PUT "$MITHUNAI_URL/arukz/api/v1/branding" \
--header "Authorization: Bearer $MITHUNAI_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"revision": 3,
"layer": {
"identity": { "productName": "Northwind Answers", "companyName": "Northwind Traders" },
"assets": { "logoLight": "https://cdn.northwind.example/brand/logo-light.svg" },
"theme": {
"colors": { "light": { "brand": "#1F6FEB", "brandHover": "#1A5FCC" } },
"modeDefault": "system"
},
"domains": { "supportUrl": "https://support.northwind.example" },
"surfaces": { "widget": { "showBranding": false } }
}
}'
import os, requests
layer = {
"identity": {"productName": "Northwind Answers", "companyName": "Northwind Traders"},
"assets": {"logoLight": "https://cdn.northwind.example/brand/logo-light.svg"},
"theme": {
"colors": {"light": {"brand": "#1F6FEB", "brandHover": "#1A5FCC"}},
"modeDefault": "system",
},
"domains": {"supportUrl": "https://support.northwind.example"},
"surfaces": {"widget": {"showBranding": False}},
}
response = requests.put(
f"{os.environ['MITHUNAI_URL']}/arukz/api/v1/branding",
headers={"Authorization": f"Bearer {os.environ['MITHUNAI_API_KEY']}"},
json={"revision": 3, "layer": layer},
timeout=60,
)
response.raise_for_status()
print(response.json())
const layer = {
identity: { productName: 'Northwind Answers', companyName: 'Northwind Traders' },
assets: { logoLight: 'https://cdn.northwind.example/brand/logo-light.svg' },
theme: {
colors: { light: { brand: '#1F6FEB', brandHover: '#1A5FCC' } },
modeDefault: 'system',
},
domains: { supportUrl: 'https://support.northwind.example' },
surfaces: { widget: { showBranding: false } },
}
const response = await fetch(`${process.env.MITHUNAI_URL}/arukz/api/v1/branding`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.MITHUNAI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ revision: 3, layer }),
})
console.log(await response.json())
{
"layer": {
"identity": {
"productName": "Northwind Answers",
"companyName": "Northwind Traders"
},
"assets": {
"logoLight": "https://cdn.northwind.example/brand/logo-light.svg"
},
"theme": {
"colors": {
"light": {
"brand": "#1F6FEB",
"brandHover": "#1A5FCC"
}
},
"modeDefault": "system"
},
"domains": {
"supportUrl": "https://support.northwind.example"
},
"surfaces": {
"widget": {
"showBranding": false
}
}
},
"revision": 4,
"configured": true,
"updatedAt": "2026-09-24T10:48:13.209577+00:00",
"updatedBy": "8d3f6a21-4c9e-4b07-a1d5-e62f0b9c7a48"
}
{
"code": "validation_error",
"message": "Colours must be a hex value such as #4636D9, or an rgb(), rgba(), hsl() or hsla() value."
}
{ "code": "authorization_error", "message": "You do not have permission to perform this action." }
{ "code": "conflict", "message": "The branding was changed by someone else. Reload and try again." }
Last modified on September 26, 2026
⌘I
curl --request PUT "$MITHUNAI_URL/arukz/api/v1/branding" \
--header "Authorization: Bearer $MITHUNAI_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"revision": 3,
"layer": {
"identity": { "productName": "Northwind Answers", "companyName": "Northwind Traders" },
"assets": { "logoLight": "https://cdn.northwind.example/brand/logo-light.svg" },
"theme": {
"colors": { "light": { "brand": "#1F6FEB", "brandHover": "#1A5FCC" } },
"modeDefault": "system"
},
"domains": { "supportUrl": "https://support.northwind.example" },
"surfaces": { "widget": { "showBranding": false } }
}
}'
import os, requests
layer = {
"identity": {"productName": "Northwind Answers", "companyName": "Northwind Traders"},
"assets": {"logoLight": "https://cdn.northwind.example/brand/logo-light.svg"},
"theme": {
"colors": {"light": {"brand": "#1F6FEB", "brandHover": "#1A5FCC"}},
"modeDefault": "system",
},
"domains": {"supportUrl": "https://support.northwind.example"},
"surfaces": {"widget": {"showBranding": False}},
}
response = requests.put(
f"{os.environ['MITHUNAI_URL']}/arukz/api/v1/branding",
headers={"Authorization": f"Bearer {os.environ['MITHUNAI_API_KEY']}"},
json={"revision": 3, "layer": layer},
timeout=60,
)
response.raise_for_status()
print(response.json())
const layer = {
identity: { productName: 'Northwind Answers', companyName: 'Northwind Traders' },
assets: { logoLight: 'https://cdn.northwind.example/brand/logo-light.svg' },
theme: {
colors: { light: { brand: '#1F6FEB', brandHover: '#1A5FCC' } },
modeDefault: 'system',
},
domains: { supportUrl: 'https://support.northwind.example' },
surfaces: { widget: { showBranding: false } },
}
const response = await fetch(`${process.env.MITHUNAI_URL}/arukz/api/v1/branding`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${process.env.MITHUNAI_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ revision: 3, layer }),
})
console.log(await response.json())
{
"layer": {
"identity": {
"productName": "Northwind Answers",
"companyName": "Northwind Traders"
},
"assets": {
"logoLight": "https://cdn.northwind.example/brand/logo-light.svg"
},
"theme": {
"colors": {
"light": {
"brand": "#1F6FEB",
"brandHover": "#1A5FCC"
}
},
"modeDefault": "system"
},
"domains": {
"supportUrl": "https://support.northwind.example"
},
"surfaces": {
"widget": {
"showBranding": false
}
}
},
"revision": 4,
"configured": true,
"updatedAt": "2026-09-24T10:48:13.209577+00:00",
"updatedBy": "8d3f6a21-4c9e-4b07-a1d5-e62f0b9c7a48"
}
{
"code": "validation_error",
"message": "Colours must be a hex value such as #4636D9, or an rgb(), rgba(), hsl() or hsla() value."
}
{ "code": "authorization_error", "message": "You do not have permission to perform this action." }
{ "code": "conflict", "message": "The branding was changed by someone else. Reload and try again." }