curl --request PATCH \
--url https://api.moda.app/v1/brand-kits/{brand_kit_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "<string>",
"colors": [
{}
],
"fonts": [
{}
],
"company_name": "<string>",
"company_description": "<string>",
"tagline": "<string>",
"brand_values": [
"<string>"
],
"brand_aesthetic": [
"<string>"
],
"brand_tone_of_voice": [
"<string>"
],
"default_theme_canvas_id": "cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
"is_default": true
}
'import requests
url = "https://api.moda.app/v1/brand-kits/{brand_kit_id}"
payload = {
"title": "<string>",
"colors": [{}],
"fonts": [{}],
"company_name": "<string>",
"company_description": "<string>",
"tagline": "<string>",
"brand_values": ["<string>"],
"brand_aesthetic": ["<string>"],
"brand_tone_of_voice": ["<string>"],
"default_theme_canvas_id": "cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
"is_default": True
}
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({
title: '<string>',
colors: [{}],
fonts: [{}],
company_name: '<string>',
company_description: '<string>',
tagline: '<string>',
brand_values: ['<string>'],
brand_aesthetic: ['<string>'],
brand_tone_of_voice: ['<string>'],
default_theme_canvas_id: 'cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV',
is_default: true
})
};
fetch('https://api.moda.app/v1/brand-kits/{brand_kit_id}', 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.moda.app/v1/brand-kits/{brand_kit_id}",
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([
'title' => '<string>',
'colors' => [
[
]
],
'fonts' => [
[
]
],
'company_name' => '<string>',
'company_description' => '<string>',
'tagline' => '<string>',
'brand_values' => [
'<string>'
],
'brand_aesthetic' => [
'<string>'
],
'brand_tone_of_voice' => [
'<string>'
],
'default_theme_canvas_id' => 'cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV',
'is_default' => true
]),
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.moda.app/v1/brand-kits/{brand_kit_id}"
payload := strings.NewReader("{\n \"title\": \"<string>\",\n \"colors\": [\n {}\n ],\n \"fonts\": [\n {}\n ],\n \"company_name\": \"<string>\",\n \"company_description\": \"<string>\",\n \"tagline\": \"<string>\",\n \"brand_values\": [\n \"<string>\"\n ],\n \"brand_aesthetic\": [\n \"<string>\"\n ],\n \"brand_tone_of_voice\": [\n \"<string>\"\n ],\n \"default_theme_canvas_id\": \"cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV\",\n \"is_default\": true\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.moda.app/v1/brand-kits/{brand_kit_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"<string>\",\n \"colors\": [\n {}\n ],\n \"fonts\": [\n {}\n ],\n \"company_name\": \"<string>\",\n \"company_description\": \"<string>\",\n \"tagline\": \"<string>\",\n \"brand_values\": [\n \"<string>\"\n ],\n \"brand_aesthetic\": [\n \"<string>\"\n ],\n \"brand_tone_of_voice\": [\n \"<string>\"\n ],\n \"default_theme_canvas_id\": \"cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV\",\n \"is_default\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moda.app/v1/brand-kits/{brand_kit_id}")
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 \"title\": \"<string>\",\n \"colors\": [\n {}\n ],\n \"fonts\": [\n {}\n ],\n \"company_name\": \"<string>\",\n \"company_description\": \"<string>\",\n \"tagline\": \"<string>\",\n \"brand_values\": [\n \"<string>\"\n ],\n \"brand_aesthetic\": [\n \"<string>\"\n ],\n \"brand_tone_of_voice\": [\n \"<string>\"\n ],\n \"default_theme_canvas_id\": \"cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV\",\n \"is_default\": true\n}"
response = http.request(request)
puts response.read_body{}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}Update Brand Kit
Update a brand kit: palette, fonts, voice fields, title, default theme, team default.
colors / fonts are replace-all writes (send the full desired list).
is_default: true promotes this kit to the team default (clearing
whichever kit held it) in the same transaction as the field writes, so a
correct-and-promote never lands half-applied; is_default: false is a
400 — promote the replacement kit instead of leaving the team with no
default. Returns 404 not_found if the brand kit does not exist, has been
deleted, or the caller lacks team access — collapsed like the sibling
endpoints so the update path does not leak existence of brand kits in
other teams. Invalid field values (a color entry without color, a
font without family) are a 400.
curl --request PATCH \
--url https://api.moda.app/v1/brand-kits/{brand_kit_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"title": "<string>",
"colors": [
{}
],
"fonts": [
{}
],
"company_name": "<string>",
"company_description": "<string>",
"tagline": "<string>",
"brand_values": [
"<string>"
],
"brand_aesthetic": [
"<string>"
],
"brand_tone_of_voice": [
"<string>"
],
"default_theme_canvas_id": "cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
"is_default": true
}
'import requests
url = "https://api.moda.app/v1/brand-kits/{brand_kit_id}"
payload = {
"title": "<string>",
"colors": [{}],
"fonts": [{}],
"company_name": "<string>",
"company_description": "<string>",
"tagline": "<string>",
"brand_values": ["<string>"],
"brand_aesthetic": ["<string>"],
"brand_tone_of_voice": ["<string>"],
"default_theme_canvas_id": "cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV",
"is_default": True
}
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({
title: '<string>',
colors: [{}],
fonts: [{}],
company_name: '<string>',
company_description: '<string>',
tagline: '<string>',
brand_values: ['<string>'],
brand_aesthetic: ['<string>'],
brand_tone_of_voice: ['<string>'],
default_theme_canvas_id: 'cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV',
is_default: true
})
};
fetch('https://api.moda.app/v1/brand-kits/{brand_kit_id}', 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.moda.app/v1/brand-kits/{brand_kit_id}",
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([
'title' => '<string>',
'colors' => [
[
]
],
'fonts' => [
[
]
],
'company_name' => '<string>',
'company_description' => '<string>',
'tagline' => '<string>',
'brand_values' => [
'<string>'
],
'brand_aesthetic' => [
'<string>'
],
'brand_tone_of_voice' => [
'<string>'
],
'default_theme_canvas_id' => 'cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV',
'is_default' => true
]),
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.moda.app/v1/brand-kits/{brand_kit_id}"
payload := strings.NewReader("{\n \"title\": \"<string>\",\n \"colors\": [\n {}\n ],\n \"fonts\": [\n {}\n ],\n \"company_name\": \"<string>\",\n \"company_description\": \"<string>\",\n \"tagline\": \"<string>\",\n \"brand_values\": [\n \"<string>\"\n ],\n \"brand_aesthetic\": [\n \"<string>\"\n ],\n \"brand_tone_of_voice\": [\n \"<string>\"\n ],\n \"default_theme_canvas_id\": \"cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV\",\n \"is_default\": true\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.moda.app/v1/brand-kits/{brand_kit_id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"title\": \"<string>\",\n \"colors\": [\n {}\n ],\n \"fonts\": [\n {}\n ],\n \"company_name\": \"<string>\",\n \"company_description\": \"<string>\",\n \"tagline\": \"<string>\",\n \"brand_values\": [\n \"<string>\"\n ],\n \"brand_aesthetic\": [\n \"<string>\"\n ],\n \"brand_tone_of_voice\": [\n \"<string>\"\n ],\n \"default_theme_canvas_id\": \"cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV\",\n \"is_default\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.moda.app/v1/brand-kits/{brand_kit_id}")
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 \"title\": \"<string>\",\n \"colors\": [\n {}\n ],\n \"fonts\": [\n {}\n ],\n \"company_name\": \"<string>\",\n \"company_description\": \"<string>\",\n \"tagline\": \"<string>\",\n \"brand_values\": [\n \"<string>\"\n ],\n \"brand_aesthetic\": [\n \"<string>\"\n ],\n \"brand_tone_of_voice\": [\n \"<string>\"\n ],\n \"default_theme_canvas_id\": \"cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV\",\n \"is_default\": true\n}"
response = http.request(request)
puts response.read_body{}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}{
"type": "invalid_request",
"code": "<string>",
"message": "<string>",
"doc_url": "<string>",
"request_id": "<string>",
"causes": [
"<unknown>"
],
"details": {},
"retry_after_ms": 123,
"retryable": true
}Authorizations
API key from Settings > Developer > REST API
Headers
Calendar-dated API version pin. New integrations should pin 2026-05-01 to opt into the newest response shapes. For back-compat the server also accepts requests with no header and resolves them to the current default (today: 2026-04-12); that default advances on each sunset date. Any unsupported value returns 400 unsupported_version.
2026-04-12, 2026-05-01 "2026-05-01"
Path Parameters
Prefixed bk_ wire ID (Crockford base32 body) — the canonical, recommended form. For back-compat, a bare UUID string is also accepted in both path parameters and JSON request bodies (older integrations that stored raw UUIDs keep working), as is the prefix over a UUID body (bk_00000000-0000-4000-8000-000000000000). All three are permanent, supported inputs; only the canonical form is ever emitted.
^bk_[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$"bk_01HT9WK8N3M2J4A5Z6P7Q8R9TV"
Body
New display name for the brand kit.
255Array of {color, label?, mode?, gradient?} objects. Replaces all existing colors — send the full desired palette (read it first), including any mode/gradient values to keep.
Array of {family, label?, weight?} objects. Replaces all existing fonts. Each font's supported flag is derived server-side from the platform + team font catalogs; a caller-supplied value is ignored.
Company name.
Brief company description.
Company tagline or slogan.
List of brand values (e.g. 'innovative', 'trustworthy').
Deprecated list of aesthetic descriptors (e.g. 'minimal', 'bold'). The free-text aesthetic is derived during brand-kit population and is not settable via this API.
List of tone-of-voice descriptors (e.g. 'professional', 'friendly').
Prefixed cvs_ wire ID (Crockford base32 body) — the canonical, recommended form. For back-compat, a bare UUID string is also accepted in both path parameters and JSON request bodies (older integrations that stored raw UUIDs keep working), as is the prefix over a UUID body (cvs_00000000-0000-4000-8000-000000000000). All three are permanent, supported inputs; only the canonical form is ever emitted.
^cvs_[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$"cvs_01HT9WK8N3M2J4A5Z6P7Q8R9TV"
Send true to make this the team's default brand kit, clearing whichever kit held it. Applied in the same transaction as the field writes above. Omit to leave the flag unchanged. false is rejected (400): demoting without naming a replacement leaves the team with no default — promote the replacement kit instead.
Response
Successful Response
The response is of type Response Updatebrandkit · object.