Skip to content

Change a brand's theme

PATCH
/api/v1/brands/{slug}/theme
curl --request PATCH \
--url http://localhost:3000/api/v1/brands/example/theme \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "accent": "example", "accentUse": "fill", "surface": "example", "panel": "example", "dark": "example", "ink": "example", "muted": "example", "head": "example", "body": "example", "label": "example", "logo": "example", "device": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "radius": 1, "width": "narrow", "density": "compact", "scale": 1, "nav": "sidebar", "band": true, "header": "plain", "separation": "space", "numbering": true, "motion": "none", "toc": "side", "titles": "medium", "grounds": "plain", "languages": [ { "code": "example", "label": "example", "dir": "ltr" } ], "links": [ { "label": "example", "url": "https://example.com" } ], "look": "documentation" }'

Merges: a key left out keeps its value, null clears it. A color setting names a color rule, a font setting a font rule, logo a rule with a picture and device an image asset: a 422 names each that doesn’t, with its path. Answers with the look and its checks, as GET does. A draft in the brand’s history until it is published.

Scope: write.

slug
required
string

Brand slug

Media typeapplication/json
object
accent
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
accentUse
Any of:

Hairline: the accent draws rules and marks, never fills

string
Allowed values: fill hairline
surface
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
panel
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
dark
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
ink
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
muted
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
head
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
body
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
label
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
logo
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
device
Any of:
string format: uuid
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/
radius
Any of:

Corner radius in px

integer
<= 40
width
Any of:
string
Allowed values: narrow normal wide
density
Any of:
string
Allowed values: compact normal airy
scale
Any of:

Heading size ratio; 1.25 when left out

number
>= 1.067 <= 1.618
nav
Any of:
string
Allowed values: sidebar top overlay
band
Any of:

Every page opens on a band of the brand color; header band says the same

boolean
header
Any of:

A page’s opening: on the page, on a band of the brand color, or beside its cover

string
Allowed values: plain band split
separation
Any of:

Between two sections on the page’s own ground: space alone, or a hairline too

string
Allowed values: space hairline
numbering
Any of:

Number chapters and pages: 01, 01.2

boolean
motion
Any of:

Subtle: sections reveal as they scroll in; never with reduced motion

string
Allowed values: none subtle
toc
Any of:

On this page: a side column, a list under the page header, or hidden

string
Allowed values: side inline none
titles
Any of:

Section titles: headings (medium), or headlines (large, huge); a section’s own size wins

string
Allowed values: medium large huge
grounds
Any of:

Alternate: every other section on the page’s own ground sits on the panel, so a long page has rhythm; canvas: under its header the page sits on the panel, dotted like a whiteboard, its section titles centered

string
Allowed values: plain alternate canvas
languages
Any of:

The languages readers pick from; the first is the one the pages are written in

Array<object>
<= 12 items
object
code
required
string
<= 20 characters /^[a-z]{2,3}(-[a-z0-9]{2,8})?$/
label
required
string
>= 1 characters <= 40 characters
dir

From the language when left out

string
Allowed values: ltr rtl
links
Any of:

Links beside search and print on the brand’s pages: its repository, its Figma library, its site

Array<object>
<= 8 items
object
label
required
string
>= 1 characters <= 40 characters
url
required

Http or https; a link to GitHub, Figma, npm and the like shows its icon

string format: uri
<= 2000 characters
look

A look sets the layout at once (documentation: dense, quiet, easy to scan; editorial: a book: airy, numbered, big titles; swiss: grid, hairlines, no corners, headlines; bold: every chapter opens on the brand color; cinematic: pictures first, dark, wide, airy; playful: round, warm, alternating grounds; board: a band of the brand color, then a dotted canvas); keys named beside it win

string
Allowed values: documentation editorial swiss bold cinematic playful board

The theme

Media typeapplication/json
object
data
required
object
brand
required
string
settings
required

Which rule plays which part, and the page’s measure, rhythm and chrome; left out: read from the rules

object
accent
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
accentUse

Hairline: the accent draws rules and marks, never fills

string
Allowed values: fill hairline
surface
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
panel
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
dark
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
ink
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
muted
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
head
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
body
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
label
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
logo
Any of:
string
<= 120 characters /^[a-z][a-zA-Z0-9]*(\.[a-z][a-zA-Z0-9]*)*$/
device
Any of:
string format: uuid
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/
radius

Corner radius in px

integer
<= 40
width
string
Allowed values: narrow normal wide
density
string
Allowed values: compact normal airy
scale

Heading size ratio; 1.25 when left out

number
>= 1.067 <= 1.618
nav
string
Allowed values: sidebar top overlay
band

Every page opens on a band of the brand color; header band says the same

boolean
header

A page’s opening: on the page, on a band of the brand color, or beside its cover

string
Allowed values: plain band split
separation

Between two sections on the page’s own ground: space alone, or a hairline too

string
Allowed values: space hairline
numbering

Number chapters and pages: 01, 01.2

boolean
motion

Subtle: sections reveal as they scroll in; never with reduced motion

string
Allowed values: none subtle
toc

On this page: a side column, a list under the page header, or hidden

string
Allowed values: side inline none
titles

Section titles: headings (medium), or headlines (large, huge); a section’s own size wins

string
Allowed values: medium large huge
grounds

Alternate: every other section on the page’s own ground sits on the panel, so a long page has rhythm; canvas: under its header the page sits on the panel, dotted like a whiteboard, its section titles centered

string
Allowed values: plain alternate canvas
languages

The languages readers pick from; the first is the one the pages are written in

Array<object>
<= 12 items
object
code
required
string
<= 20 characters /^[a-z]{2,3}(-[a-z0-9]{2,8})?$/
label
required
string
>= 1 characters <= 40 characters
dir

From the language when left out

string
Allowed values: ltr rtl
links

Links beside search and print on the brand’s pages: its repository, its Figma library, its site

Array<object>
<= 8 items
object
label
required
string
>= 1 characters <= 40 characters
url
required

Http or https; a link to GitHub, Figma, npm and the like shows its icon

string format: uri
<= 2000 characters
theme
required

The look the settings and rules give: grounds, inks, accent, faces and chrome

object
v1
required

The accent, lifted for light and dark pages, and the faces, as before W3

object
key
additional properties
surface
required
Any of:

A hex color

string
panel
required

A hex color

string
dark
required

A hex color

string
ink
required

A hex color

string
muted
required

A hex color

string
onDark
required

A hex color

string
mutedOnDark
required

A hex color

string
accent
required

The fill, as the brand has it: bands and buttons

string
accentText
required

The accent where it is text (links), at 4.5:1 on the surface

string
onAccent
required

A hex color

string
accentUse
required
string
Allowed values: fill hairline
line
required

A hex color

string
faces
required
object
head
object
family
required
string
weight
number
file

The font file for its weight

string format: uuid
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/
files

Every font file of the rule, one @font-face each

Array<object>
object
id
required
string format: uuid
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/
filename
required
string
mime
required
string
fallback
string
google

From Google Fonts, with no files here yet: set in its fallback until they are imported

boolean
body
object
family
required
string
weight
number
file

The font file for its weight

string format: uuid
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/
files

Every font file of the rule, one @font-face each

Array<object>
object
id
required
string format: uuid
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/
filename
required
string
mime
required
string
fallback
string
google

From Google Fonts, with no files here yet: set in its fallback until they are imported

boolean
label
object
family
required
string
weight
number
file

The font file for its weight

string format: uuid
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/
files

Every font file of the rule, one @font-face each

Array<object>
object
id
required
string format: uuid
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/
filename
required
string
mime
required
string
fallback
string
google

From Google Fonts, with no files here yet: set in its fallback until they are imported

boolean
case
required
string
tracking
required

In em

number
radius
required
number
width
required
string
Allowed values: narrow normal wide
density
required
string
Allowed values: compact normal airy
scale
required
number
device
required
Any of:
string format: uuid
/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/
logo
required
Any of:
object
key
required
string
nav
required
string
Allowed values: sidebar top overlay
band
required

Header is band

boolean
header
required
string
Allowed values: plain band split
separation
required
string
Allowed values: space hairline
numbering
required
boolean
motion
required
string
Allowed values: none subtle
toc
required

On this page: a side column, a list under the page header, or none

string
Allowed values: side inline none
checks
required

Contrast of each pair in the look: one that fails falls back to a color that reads, and says which

Array<object>
object
pair
required

Which color on which, e.g. ink on surface

string
fg
required
string
bg
required
string
ratio
required
number
need
required

The contrast it must reach: 4.5 for text, 3 for marks

number
ok
required
boolean
used
required

The color used: fg when it passes, else its fallback

string
checks
required

Contrast of each pair in the look: one that fails falls back to a color that reads, and says which

Array<object>
object
pair
required

Which color on which, e.g. ink on surface

string
fg
required
string
bg
required
string
ratio
required
number
need
required

The contrast it must reach: 4.5 for text, 3 for marks

number
ok
required
boolean
used
required

The color used: fg when it passes, else its fallback

string
warnings
required

Settings naming a rule that has gone since (the default is used), and each pair that fell back

Array<string>
Example
{
"data": {
"settings": {
"accentUse": "fill",
"width": "narrow",
"density": "compact",
"nav": "sidebar",
"header": "plain",
"separation": "space",
"motion": "none",
"toc": "side",
"titles": "medium",
"grounds": "plain",
"languages": [
{
"dir": "ltr"
}
]
},
"theme": {
"accentUse": "fill",
"faces": {
"head": {
"google": true
},
"body": {
"google": true
},
"label": {
"google": true
}
},
"width": "narrow",
"density": "compact",
"nav": "sidebar",
"header": "plain",
"separation": "space",
"motion": "none",
"toc": "side"
}
}
}

An error

Media typeapplication/json
object
error
required
object
code
required
string
message
required
string
detail
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"detail": "example"
}
}