API reference

Brand kits

Use with your agent

Give this prompt to your AI agent. The agent does the task for you.

Read https://thirds.ai/docs/api-reference/brand-kits and help me choose the right thirds.ai endpoint and write a request. Check the fields and credentials in this reference.

Manage brand colours, logos, and fonts, then apply the same brand kit when you create a template or image.

See all API resources or read API keys and requests.

Endpoints

createBrandKit

POST /v1/brand-kits

Create a brand kit

Create one mutable account-owned brand kit. Logos and fonts are uploaded through the kit's asset route after creation. The account plan sets how many kits the account can keep: 1 on Free, a pack-only account, and Starter, 5 on Growth, and 20 on Scale. Every kit of the account counts, archived kits too. A kit over that limit answers 409 brand_kit_limit with error.plan_limit. An account above its limit after a downgrade keeps every kit and can still change and archive them.

Authentication: bearer API key. See authentication.

Request body: application/json, BrandKitWrite.

StatusMeaningBody
201The brand kit was created.application/json: BrandKitDetail
400The one error envelope every backend response uses.application/json: ErrorEnvelope
401The one error envelope every backend response uses.application/json: ErrorEnvelope
403The authenticated account is suspended. The code is account_suspended.application/json: ErrorEnvelope
405The method is not allowed on this route.application/json: ErrorEnvelope
409The one error envelope every backend response uses.application/json: ErrorEnvelope
413The one error envelope every backend response uses.application/json: ErrorEnvelope
415The one error envelope every backend response uses.application/json: ErrorEnvelope
422The one error envelope every backend response uses.application/json: ErrorEnvelope
431The request has more than 64 headers or more than 32 KiB of header names and values.application/json: ErrorEnvelope

listBrandKits

GET /v1/brand-kits

List brand kits

List the account's active and archived brand kits newest first. Asset metadata is omitted from the page; read one kit for its current assets.

Authentication: bearer API key. See authentication.

ParameterLocationRequiredRule
statusqueryNo{"type":"string","enum":["active","archived","all"],"default":"all"}
limitqueryNo{"type":"integer","default":20}
cursorqueryNo{"type":"string","maxLength":128}
StatusMeaningBody
200One page of brand-kit summaries.application/json: BrandKitPage
400The one error envelope every backend response uses.application/json: ErrorEnvelope
401The one error envelope every backend response uses.application/json: ErrorEnvelope
403The authenticated account is suspended. The code is account_suspended.application/json: ErrorEnvelope
405The method is not allowed on this route.application/json: ErrorEnvelope
431The request has more than 64 headers or more than 32 KiB of header names and values.application/json: ErrorEnvelope

getBrandKit

GET /v1/brand-kits/{brand_kit_id}

Get a brand kit

Return one owned kit and its current logo and font metadata. Replaced assets remain private durable content but are omitted.

Authentication: bearer API key. See authentication.

ParameterLocationRequiredRule
brand_kit_idpathYesBrandKitId
StatusMeaningBody
200The brand kit and its current assets.application/json: BrandKitDetail
401The one error envelope every backend response uses.application/json: ErrorEnvelope
403The authenticated account is suspended. The code is account_suspended.application/json: ErrorEnvelope
404The one error envelope every backend response uses.application/json: ErrorEnvelope
405The method is not allowed on this route.application/json: ErrorEnvelope
431The request has more than 64 headers or more than 32 KiB of header names and values.application/json: ErrorEnvelope

updateBrandKit

PATCH /v1/brand-kits/{brand_kit_id}

Update a brand kit

Replace any supplied mutable brand values. Omitted fields stay unchanged; a null tone_guidance clears it. Archived kits cannot change.

Authentication: bearer API key. See authentication.

ParameterLocationRequiredRule
brand_kit_idpathYesBrandKitId

Request body: application/json, BrandKitPatch.

StatusMeaningBody
200The updated kit and its current assets.application/json: BrandKitDetail
400The one error envelope every backend response uses.application/json: ErrorEnvelope
401The one error envelope every backend response uses.application/json: ErrorEnvelope
403The authenticated account is suspended. The code is account_suspended.application/json: ErrorEnvelope
404The one error envelope every backend response uses.application/json: ErrorEnvelope
405The method is not allowed on this route.application/json: ErrorEnvelope
413The one error envelope every backend response uses.application/json: ErrorEnvelope
415The one error envelope every backend response uses.application/json: ErrorEnvelope
422The one error envelope every backend response uses.application/json: ErrorEnvelope
431The request has more than 64 headers or more than 32 KiB of header names and values.application/json: ErrorEnvelope

archiveBrandKit

DELETE /v1/brand-kits/{brand_kit_id}

Archive a brand kit

Archive one owned kit. The operation is idempotent. The kit and every current or replaced asset stay durable for already captured references.

Authentication: bearer API key. See authentication.

ParameterLocationRequiredRule
brand_kit_idpathYesBrandKitId
StatusMeaningBody
204The brand kit is archived.No body
401The one error envelope every backend response uses.application/json: ErrorEnvelope
403The authenticated account is suspended. The code is account_suspended.application/json: ErrorEnvelope
404The one error envelope every backend response uses.application/json: ErrorEnvelope
405The method is not allowed on this route.application/json: ErrorEnvelope
431The request has more than 64 headers or more than 32 KiB of header names and values.application/json: ErrorEnvelope

createBrandAsset

POST /v1/brand-kits/{brand_kit_id}/assets

Add a brand asset

Add one logo or WOFF2 font to an active owned kit. The declared Content-Type and the complete bytes must agree. No customer bytes or storage reference appears in the response.

Authentication: bearer API key. See authentication.

ParameterLocationRequiredRule
brand_kit_idpathYesBrandKitId

Request body: image/png, {"type":"string","format":"binary"}.

Request body: image/jpeg, {"type":"string","format":"binary"}.

Request body: image/webp, {"type":"string","format":"binary"}.

Request body: font/woff2, {"type":"string","format":"binary"}.

StatusMeaningBody
201The immutable asset was accepted and selected by the kit.application/json: BrandAsset
400The one error envelope every backend response uses.application/json: ErrorEnvelope
401The one error envelope every backend response uses.application/json: ErrorEnvelope
403The authenticated account is suspended. The code is account_suspended.application/json: ErrorEnvelope
404The one error envelope every backend response uses.application/json: ErrorEnvelope
405The method is not allowed on this route.application/json: ErrorEnvelope
413The one error envelope every backend response uses.application/json: ErrorEnvelope
415The one error envelope every backend response uses.application/json: ErrorEnvelope
422The one error envelope every backend response uses.application/json: ErrorEnvelope
429The one error envelope every backend response uses.application/json: ErrorEnvelope
431The request has more than 64 headers or more than 32 KiB of header names and values.application/json: ErrorEnvelope
503The one error envelope every backend response uses.application/json: ErrorEnvelope

readBrandAsset

GET /v1/brand-kits/{brand_kit_id}/assets/{asset_id}

Read a brand asset

Read the validated logo or font bytes from an owned kit. Captured assets remain readable after replacement or archive. Responses are private and must not be cached.

Authentication: bearer API key. See authentication.

ParameterLocationRequiredRule
brand_kit_idpathYesBrandKitId
asset_idpathYesBrandAssetId
StatusMeaningBody
200The validated image or WOFF2 font bytes.image/png: {"type":"string","format":"binary"}; image/jpeg: {"type":"string","format":"binary"}; image/webp: {"type":"string","format":"binary"}; font/woff2: {"type":"string","format":"binary"}
401The one error envelope every backend response uses.application/json: ErrorEnvelope
403The authenticated account is suspended. The code is account_suspended.application/json: ErrorEnvelope
404The one error envelope every backend response uses.application/json: ErrorEnvelope
405The method is not allowed on this route.application/json: ErrorEnvelope
431The request has more than 64 headers or more than 32 KiB of header names and values.application/json: ErrorEnvelope

replaceBrandAsset

PUT /v1/brand-kits/{brand_kit_id}/assets/{asset_id}

Replace a brand asset

Create a new immutable asset of the same kind and make it current. The old asset and bytes stay unchanged for any template or queued operation that already captured its ID.

Authentication: bearer API key. See authentication.

ParameterLocationRequiredRule
brand_kit_idpathYesBrandKitId
asset_idpathYesBrandAssetId

Request body: image/png, {"type":"string","format":"binary"}.

Request body: image/jpeg, {"type":"string","format":"binary"}.

Request body: image/webp, {"type":"string","format":"binary"}.

Request body: font/woff2, {"type":"string","format":"binary"}.

StatusMeaningBody
201The new immutable current asset.application/json: BrandAsset
400The one error envelope every backend response uses.application/json: ErrorEnvelope
401The one error envelope every backend response uses.application/json: ErrorEnvelope
403The authenticated account is suspended. The code is account_suspended.application/json: ErrorEnvelope
404The one error envelope every backend response uses.application/json: ErrorEnvelope
405The method is not allowed on this route.application/json: ErrorEnvelope
413The one error envelope every backend response uses.application/json: ErrorEnvelope
415The one error envelope every backend response uses.application/json: ErrorEnvelope
422The one error envelope every backend response uses.application/json: ErrorEnvelope
429The one error envelope every backend response uses.application/json: ErrorEnvelope
431The request has more than 64 headers or more than 32 KiB of header names and values.application/json: ErrorEnvelope
503The one error envelope every backend response uses.application/json: ErrorEnvelope

Schemas

BrandAssetId

Schema rules: {"type":"string","pattern":"^asset_[0-9a-f]{32}$"}.

BrandKitWrite

FieldRequiredDescription and type
nameYes{"type":"string","minLength":1,"maxLength":100}
coloursNo{"type":"array","maxItems":16,"uniqueItems":true,"items":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"},"default":[]}
tone_guidanceNo{"type":["string","null"],"minLength":1,"maxLength":500}

Schema rules: {"type":"object","additionalProperties":false}.

BrandKitPatch

FieldRequiredDescription and type
archived_atNoRestore the item. Omit this field to keep its archive state. {"type":"null"}
nameNo{"type":"string","minLength":1,"maxLength":100}
coloursNo{"type":"array","maxItems":16,"uniqueItems":true,"items":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$"}}
tone_guidanceNo{"type":["string","null"],"minLength":1,"maxLength":500}

Schema rules: {"type":"object","minProperties":1,"additionalProperties":false}.

BrandKitSummary

FieldRequiredDescription and type
idYesBrandKitId
nameYes{"type":"string","minLength":1,"maxLength":100}
coloursYes{"type":"array","maxItems":16,"uniqueItems":true,"items":{"type":"string","pattern":"^#[0-9a-f]{6}$"}}
tone_guidanceYes{"type":["string","null"],"minLength":1,"maxLength":500}
created_atYes{"type":"string","format":"date-time"}
updated_atYes{"type":"string","format":"date-time"}
archived_atYes{"type":["string","null"],"format":"date-time"}
assetsYes{"type":"array","maxItems":16,"items":{"$ref":"#/components/schemas/BrandAsset"}}BrandAsset

Schema rules: {"type":"object","additionalProperties":false}.

BrandAsset

FieldRequiredDescription and type
idYesBrandAssetId
kindYes{"type":"string","enum":["logo","font"]}
media_typeYes{"type":"string","enum":["image/png","image/jpeg","image/webp","font/woff2"]}
byte_sizeYes{"type":"integer","minimum":1,"maximum":10485760}
created_atYes{"type":"string","format":"date-time"}

Schema rules: {"type":"object","additionalProperties":false}.

BrandKitDetail

FieldRequiredDescription and type
archive_historyYes{"type":"array","items":{"$ref":"#/components/schemas/ArchivePeriod"}}ArchivePeriod
idYesBrandKitId
nameYes{"type":"string","minLength":1,"maxLength":100}
coloursYes{"type":"array","maxItems":16,"uniqueItems":true,"items":{"type":"string","pattern":"^#[0-9a-f]{6}$"}}
tone_guidanceYes{"type":["string","null"],"minLength":1,"maxLength":500}
created_atYes{"type":"string","format":"date-time"}
updated_atYes{"type":"string","format":"date-time"}
archived_atYes{"type":["string","null"],"format":"date-time"}
assetsYes{"type":"array","maxItems":16,"items":{"$ref":"#/components/schemas/BrandAsset"}}BrandAsset

Schema rules: {"type":"object","additionalProperties":false}.

BrandKitPage

FieldRequiredDescription and type
itemsYes{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/BrandKitSummary"}}BrandKitSummary
next_cursorYes{"type":["string","null"],"maxLength":128}

Schema rules: {"type":"object","additionalProperties":false}.

Shared errors, headers, and authentication schemes are in shared types and security.

Ready to make your first file?

Start in the playground with a gallery template, or get an API key and send your first request from your own terminal.