> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.simplified.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.simplified.com/_mcp/server.

# API · BrandKit · Populate a brand kit (canonical schema)

POST https://api.simplified.com/api/v2/brandkits/{brand_id}/build
Content-Type: application/json

Submit a canonical BrandKitDocument body to populate a brand kit.
The body has four top-level sections — all optional, allowing incremental calls:

* `brand` — name, description, website URL
* `social_links` — array of \{type, url} objects
* `content_pillars` — 1–5 grounded themes, merged by normalized name
* `style` — full visual-identity JSON (colors, typography, logos, imagery,
  logo\_lockup, on\_image\_copy, ai\_guardrails, prose, inferred\_fields)

The body shape is identical to the GET response (without `id`). Empty body `{}`
is a valid no-op. Server-controlled fields (`id`, `version`) in the body are ignored.

Runs synchronously and returns 200 with the result. Calling this endpoint multiple
times is safe — sections sent overwrite their own fields; omitted sections are left
unchanged. Content pillars omitted from a supplied list are preserved. **Do NOT call
`getTaskResult` after this** — there is no async task; the
operation is complete by the time the response returns.

Reference: https://docs.simplified.com/api-reference/platform/brand-kits/build-brand-kit

## Authentication

- `Authorization` header (required) (prefixed with ` Api-Key   `) — Header authentication of the form `Api-Key  <token>`
- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Request

### Path parameters

- `brand_id` (string, required) — Brand kit UUID

### Body (application/json)

This endpoint expects a BrandKitDocument.

- `id` (string, optional) — Brand kit UUID (GET only).
- `version` (integer, optional) — Envelope schema version. `1` = legacy kit, `2` = canonical V2. Server-stamped. Client values in POST are ignored.
- `extract_ref` (string, optional) — Handle returned by `web_brand_extract` (as the `_extract_ref` field). When set, the agent runtime fetches the cached extraction and fills missing `brand` (description, website — never `name`, which is the kit title set at create), `social_links`, and the mechanical parts of `style`: `colors`, `typography`, `logos`, and every `assets.reference_images` entry the crawler kept. Explicit fields on the request override the inflated values. The agent authors only the judgement fields of `style` (imagery, ai_guardrails, prose). An expired or unknown handle (extracts live 15 minutes) is a tool error — re-run `web_brand_extract` for a fresh one. This field is consumed by the apikit pre-hook and is never forwarded to the API itself.
- `brand` (BrandKitDocumentBrand, optional, nullable) — Core brand identity.
- `social_links` (list of BrandKitDocumentSocialLinksItems, optional) — Social media and web presence links.
- `icps` (list of BrandKitDocumentIcpsItems, optional, nullable) — Canonical ideal-customer profiles grounded during onboarding. Supplying this section creates or updates ICPs by case-insensitive title and preserves existing ICPs omitted from the request. Titles must be unique and at most one item may set `is_primary` to true. Omit the section to leave all ICPs unchanged; deletion remains an explicit action in the Brand Kit UI or ICP CRUD API.
- `content_pillars` (list of BrandKitDocumentContentPillarsItems, optional, nullable) — Canonical content themes grounded during onboarding. Supplying this section creates or updates pillars by case-insensitive name and preserves existing pillars omitted from the request. Omit the section to leave all pillars unchanged; deletion remains an explicit action in the Brand Kit UI or pillar CRUD API.
- `style` (BrandKitDocumentStyle, optional, nullable) — Visual identity sub-document. Versioned independently via `schema_version`. Sub-fields permit unknown keys for forward-compat (motion tokens, dark-mode palette, etc.)

## Response

### 200

Build complete. Operation finished synchronously.

- `brand_kit_id` (string, optional)
- `status` (string, optional) — ok
- `version` (integer, optional) — Stamped envelope version (always 2 after a V2 build)
- `warnings` (list of string, optional) — Non-fatal warnings from sub-steps (e.g. style_guide render)

## Errors

### 400 Bad Request Error

Invalid body — Pydantic validation failed (unknown V2 envelope keys, malformed sub-models)

- `any`

### 401 Unauthorized Error

Unauthorized

- `any`

### 403 Forbidden Error

Forbidden — user does not have access to this brand kit

- `any`

### 404 Not Found Error

Brand kit not found

- `any`

## Types

### BrandKitDocumentBrand

Core brand identity.

- `name` (string, optional) — Brand display name. Mirrors BrandKit.title.
- `description` (string, optional) — Short brand description.
- `website` (string, optional) — Primary website URL. Prepended to social_links as type "website".

### BrandKitDocumentSocialLinksItems

- `type` (string, optional) — Platform type (linkedin, twitter, x, youtube, facebook, instagram, github, website, etc.)
- `url` (string, optional) — Full URL to the profile or page.

### BrandKitDocumentIcpsItems

- `title` (string, required) — Stable, user-facing ICP title.
- `description` (string, required) — Grounded audience definition and needs.
- `is_primary` (boolean, optional) — Whether this is the single primary ICP.
- `segment_name` (string, optional)
- `industry` (string, optional)
- `job_role` (string, optional)
- `company_size` (string, optional)

### BrandKitDocumentContentPillarsItems

- `name` (string, required) — Stable, user-facing theme name.
- `description` (string, required) — Grounded scope, audience value, and thematic boundaries.
- `tags` (list of string, optional) — Short discovery labels grounded in the source material.
- `priority` (enum, optional, default: medium)
  - Allowed values: `high`, `medium`, `low`
- `preferred_channels` (list of string, optional) — Channels supported by observed brand activity or user direction.

### BrandKitDocumentStyle

Visual identity sub-document. Versioned independently via `schema_version`. Sub-fields permit unknown keys for forward-compat (motion tokens, dark-mode palette, etc.)

- `schema_version` (integer, optional, default: 1) — Style sub-schema version. Bump when shape changes.
- `name` (string, optional) — Snapshot of brand.name when style was authored.
- `phase` (integer, optional)
- `generated_at` (string, optional) — ISO date string.
- `colors` (BrandKitDocumentStyleColors, optional) — Brand colors grouped by role.
- `typography` (BrandKitDocumentStyleTypography, optional) — Brand fonts keyed by slot.
- `logos` (BrandKitDocumentStyleLogos, optional) — Logo variants keyed by role + global rules.
- `imagery` (map from string to any, optional) — Visual style guidance for AI image generation.
- `logo_lockup` (map from string to any, optional) — Where logos appear in compositions.
- `on_image_copy` (map from string to any, optional) — Rules for text rendered on top of an image.
- `ai_guardrails` (list of string, optional)
- `assets` (BrandKitDocumentStyleAssets, optional) — Reference imagery the brand uses on its website.
- `prose` (map from string to any, optional) — Human-readable paragraph descriptions.
- `inferred_fields` (list of string, optional) — Dot-paths to fields the agent inferred (vs extracted).

### BrandKitDocumentStyleColors

Brand colors grouped by role.

- `primary` (list of ColorToken, optional)
- `secondary` (list of ColorToken, optional)
- `accent` (list of ColorToken, optional)
- `neutral` (list of ColorToken, optional)

### BrandKitDocumentStyleTypography

Brand fonts keyed by slot.

- `headline` (FontSpec, optional)
- `body` (FontSpec, optional)
- `accent` (FontSpec, optional)

### BrandKitDocumentStyleLogos

Logo variants keyed by role + global rules.

- `primary` (LogoVariant, optional)
- `primary_dark` (LogoVariant, optional)
- `mark_only` (LogoVariant, optional)
- `wordmark_only` (LogoVariant, optional)
- `clearspace_ratio` (double, optional)
- `do_not_recolor` (boolean, optional)
- `do_not_distort` (boolean, optional)

### BrandKitDocumentStyleAssets

Reference imagery the brand uses on its website.

- `reference_images` (list of BrandKitDocumentStyleAssetsReferenceImagesItems, optional)

### ColorToken

One colour. Send `hex` whenever the brand gave a code. When they named a colour without one ("mostly white, green accents"), send `name` alone — do not substitute a shade you picked. A token needs a `hex` or a `name`; one carrying neither is rejected.

- `hex` (string, optional) — Hex code with leading #. Omit when the brand named the colour but gave no code; generators skip a colour with no hex, and the exact shade is asked for in the Brand Kit UI.
- `name` (string, optional) — Token name, or the colour as the brand said it (e.g. brand.primary, "verde")
- `role` (string, optional) — Free-form description of where this color is used

### FontSpec

- `family` (string, optional)
- `weights` (list of integer, optional)

### LogoVariant

- `url` (string, optional)
- `asset_id` (string, optional) — GET-only enrichment when linked to an Asset record.
- `on_bg` (string, optional) — light | dark
- `min_width_px` (integer, optional)

### BrandKitDocumentStyleAssetsReferenceImagesItems

- `url` (string, required)
- `note` (string, optional)
- `asset_id` (string, optional) — GET-only enrichment when linked to an Asset record.

## Examples

**Request**

```json
{}
```

**Response**

```json
{
  "brand_kit_id": "string",
  "status": "string",
  "version": 1,
  "warnings": [
    "string"
  ]
}
```

**SDK Code**

```python
import requests

url = "https://api.simplified.com/api/v2/brandkits/brand_id/build"

payload = {}
headers = {
    "Authorization": "Api-Key  <apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.simplified.com/api/v2/brandkits/brand_id/build';
const options = {
  method: 'POST',
  headers: {Authorization: 'Api-Key  <apiKey>', 'Content-Type': 'application/json'},
  body: '{}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.simplified.com/api/v2/brandkits/brand_id/build"

	payload := strings.NewReader("{}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Api-Key  <apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.simplified.com/api/v2/brandkits/brand_id/build")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Api-Key  <apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.simplified.com/api/v2/brandkits/brand_id/build")
  .header("Authorization", "Api-Key  <apiKey>")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.simplified.com/api/v2/brandkits/brand_id/build', [
  'body' => '{}',
  'headers' => [
    'Authorization' => 'Api-Key  <apiKey>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.simplified.com/api/v2/brandkits/brand_id/build");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Api-Key  <apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Api-Key  <apiKey>",
  "Content-Type": "application/json"
]
let parameters = [] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.simplified.com/api/v2/brandkits/brand_id/build")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```