The Brand Object

A brand context JSON Schema

A JSON Schema for brand context from any vendor: name, voice, positioning, colors with roles, type, logos, rules, files, and where and when it was read.

This schema gives one shape for brand context from any endpoint. It keeps two things that most responses lose when you flatten them. The first is where each part came from. The second is whether a part is the brand's own, such as a rule or an official color, or read from its website. Every field except name and source is optional, because no endpoint returns all of them.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "BrandContext",
  "type": "object",
  "required": ["name", "source"],
  "properties": {
    "name": { "type": "string" },
    "description": { "type": "string" },
    "voice": {
      "type": "object",
      "properties": {
        "summary": { "type": "string" },
        "attributes": { "type": "array", "items": { "type": "string" } },
        "avoid": { "type": "array", "items": { "type": "string" } },
        "guide": { "type": "string", "description": "Written voice rules, in Markdown" }
      }
    },
    "positioning": {
      "type": "object",
      "properties": {
        "valueProposition": { "type": "string" },
        "audiences": { "type": "array", "items": { "type": "string" } },
        "products": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["name"],
            "properties": {
              "name": { "type": "string" },
              "description": { "type": "string" },
              "pricingUrl": { "type": "string", "format": "uri" }
            }
          }
        },
        "competitors": { "type": "array", "items": { "type": "string" } }
      }
    },
    "colors": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["hex"],
        "properties": {
          "hex": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
          "role": { "enum": ["primary", "accent", "background", "text", "other"] },
          "name": { "type": "string" },
          "official": { "type": ["boolean", "null"], "description": "true only when the brand says so" },
          "usage": { "type": "string" }
        }
      }
    },
    "typography": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["role", "family"],
        "properties": {
          "role": { "type": "string", "description": "heading, body, code" },
          "family": { "type": "string" },
          "weight": { "type": "number" },
          "size": { "type": "string" }
        }
      }
    },
    "logos": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["url"],
        "properties": {
          "url": { "type": "string" },
          "format": { "type": "string" },
          "form": { "enum": ["logo", "symbol", "icon", "wordmark", "lockup"] },
          "background": { "enum": ["light", "dark", "any"] },
          "expiresAt": { "type": ["string", "null"], "format": "date-time" }
        }
      }
    },
    "rules": { "type": "array", "items": { "type": "string" }, "description": "Instructions a model must follow" },
    "files": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["url"],
        "properties": {
          "url": { "type": "string" },
          "mediaType": { "type": "string" },
          "purpose": { "type": "string", "description": "What the file is for, such as style reference" },
          "expiresAt": { "type": ["string", "null"], "format": "date-time" }
        }
      }
    },
    "source": {
      "type": "object",
      "required": ["endpoint", "kind", "requestedAt"],
      "properties": {
        "endpoint": { "type": "string" },
        "kind": { "enum": ["observed", "maintained"] },
        "requestedAt": { "type": "string", "format": "date-time" },
        "readAt": { "type": ["string", "null"], "format": "date-time", "description": "When the data itself was read, if the response says" },
        "version": { "type": ["string", "null"], "description": "A version ID, if the endpoint has one" }
      }
    }
  }
}

Why these fields

  • source.readAt and source.requestedAt are separate. The Brandfetch Brand Context API answered on 11 November with data that it read on 16 October. Keep both dates. See Dates and versions.
  • colors[].official is null unless the brand says so. Observed context is context read from a company's public website. Four observed endpoints gave Linear four main colors. Only a maintained palette, prepared from sources added for the brand, marks which colors are official. See Colors.
  • rules is a list of instructions, not a description, because a model uses rules as instructions. See Rules and claims.
  • Files have expiresAt, because the signed links from Logo.dev and Rainbrand stop working.

The adapters fill this shape from each endpoint. The system prompt reads it.

Last updated 11 November 2026