Pulsebook / docs

brand.json

Every published brand serves one machine-readable document, pulsebook.brand version 1. It holds the same tokens the guideline page shows, so a build script, a design tool or an AI agent reads the rules the team reads. The version changes only on a breaking change; new optional fields can appear within a version, so ignore keys you do not know. To edit brands from an AI assistant instead, see the MCP server docs.

Fetch it

The document lives next to the page at /brand/<slug>/brand.json. Send the ETag you stored last time in If-None-Match and the server answers 304 with no body while nothing changed.

# first request: keep the ETag header from the response
curl -sS -D headers.txt https://example.com/brand/meridian/brand.json -o brand.json

# later: revalidate
curl -sS -i https://example.com/brand/meridian/brand.json \
  -H 'If-None-Match: "<etag from headers.txt>"'
# HTTP/2 304  (nothing changed, use your copy)

Response headers

ETag
Strong validator over the body. The generatedAt timestamp is left out of the hash, so an unchanged brand keeps the same tag.
Cache-Control
public, max-age=0, must-revalidate. Caches may store it but must revalidate every time; the 304 makes that cheap.
Access-Control-Allow-Origin
* on GET, HEAD and the OPTIONS preflight, so a browser app on any origin can read it. Allowed request headers: Authorization and If-None-Match.
304 Not Modified
Returned when If-None-Match contains the current ETag. Headers are sent, the body is empty.
404 Not Found
Unknown slug, an unpublished brand, and a password protected brand without its unlock cookie all answer 404, so the endpoint never reveals that a protected brand exists.
X-Robots-Tag
noindex, nofollow when the brand is not marked indexable.

JSON Schema

Generated at build time from the Zod schema the server validates every response with, so it cannot drift from the code. Fetch it as /docs/brand-json/schema.json (application/schema+json, CORS open). It targets JSON Schema 2020-12 and describes the output shape, so keys with defaults are listed as required. Every part of the schema is representable, so nothing was widened to any. Rules that compare several fields, such as every motion token naming an easing that exists or a duration band whose minimum does not exceed its maximum, are checked by the server but have no JSON Schema form and are described in the field notes instead.

Document

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": [
    "contract",
    "brand",
    "links",
    "theme",
    "palette",
    "gradients",
    "fonts",
    "sections",
    "meta"
  ],
  "additionalProperties": false
}

contract required

Always { name: "pulsebook.brand", version: 1 }. Check both before you read anything else.

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "const": "pulsebook.brand"
    },
    "version": {
      "type": "number",
      "const": 1
    }
  },
  "required": [
    "name",
    "version"
  ],
  "additionalProperties": false
}

brand required

Name, slug and optional tagline.

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 80
    },
    "slug": {
      "type": "string",
      "minLength": 2,
      "maxLength": 63,
      "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
    },
    "tagline": {
      "type": "string",
      "maxLength": 200
    }
  },
  "required": [
    "name",
    "slug"
  ],
  "additionalProperties": false
}

theme required

The three colours and the light or dark mode the public page is themed with.

{
  "type": "object",
  "properties": {
    "background": {
      "type": "string",
      "pattern": "^#[0-9A-Fa-f]{6}$"
    },
    "ink": {
      "type": "string",
      "pattern": "^#[0-9A-Fa-f]{6}$"
    },
    "accent": {
      "type": "string",
      "pattern": "^#[0-9A-Fa-f]{6}$"
    },
    "mode": {
      "default": "light",
      "type": "string",
      "enum": [
        "light",
        "dark"
      ]
    }
  },
  "required": [
    "background",
    "ink",
    "accent",
    "mode"
  ],
  "additionalProperties": false
}

palette required

Every colour with hex plus derived rgb, hsl and oklch strings, role, group and optional usage share.

{
  "minItems": 1,
  "maxItems": 24,
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64,
        "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
      },
      "name": {
        "type": "string",
        "minLength": 1,
        "maxLength": 60
      },
      "hex": {
        "type": "string",
        "pattern": "^#[0-9A-Fa-f]{6}$"
      },
      "role": {
        "type": "string",
        "enum": [
          "background",
          "surface",
          "ink",
          "secondary",
          "accent",
          "neutral",
          "signal"
        ]
      },
      "group": {
        "default": "Core",
        "type": "string",
        "minLength": 1,
        "maxLength": 60
      },
      "description": {
        "type": "string",
        "maxLength": 200
      },
      "usagePct": {
        "type": "number",
        "minimum": 0,
        "maximum": 100
      },
      "cmyk": {
        "type": "array",
        "prefixItems": [
          {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          }
        ],
        "items": false,
        "minItems": 4,
        "maxItems": 4
      },
      "pantone": {
        "type": "string",
        "maxLength": 40
      },
      "rgb": {
        "type": "string"
      },
      "hsl": {
        "type": "string"
      },
      "oklch": {
        "type": "string"
      }
    },
    "required": [
      "id",
      "name",
      "hex",
      "role",
      "group",
      "rgb",
      "hsl",
      "oklch"
    ],
    "additionalProperties": false
  }
}

gradients required

Named gradients with their stops and ready-made CSS.

{
  "maxItems": 8,
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64,
        "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
      },
      "name": {
        "type": "string",
        "minLength": 1,
        "maxLength": 60
      },
      "angleDeg": {
        "default": 180,
        "type": "number",
        "minimum": 0,
        "maximum": 360
      },
      "stops": {
        "minItems": 2,
        "maxItems": 8,
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "hex": {
              "type": "string",
              "pattern": "^#[0-9A-Fa-f]{6}$"
            },
            "pos": {
              "type": "number",
              "minimum": 0,
              "maximum": 100
            }
          },
          "required": [
            "hex",
            "pos"
          ],
          "additionalProperties": false
        }
      }
    },
    "required": [
      "id",
      "name",
      "angleDeg",
      "stops"
    ],
    "additionalProperties": false
  }
}

fonts required

Up to three font families by role, with files resolved to URLs.

{
  "minItems": 1,
  "maxItems": 3,
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "role": {
        "type": "string",
        "enum": [
          "display",
          "text",
          "mono"
        ]
      },
      "family": {
        "type": "string",
        "minLength": 1,
        "maxLength": 80
      },
      "source": {
        "type": "string",
        "enum": [
          "google",
          "fontshare",
          "upload"
        ]
      },
      "fallback": {
        "default": "ui-sans-serif, system-ui, sans-serif",
        "type": "string",
        "minLength": 1,
        "maxLength": 200
      },
      "cssUrl": {
        "type": "string",
        "format": "uri"
      },
      "weights": {
        "minItems": 1,
        "maxItems": 18,
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "weight": {
              "type": "integer",
              "minimum": 100,
              "maximum": 900
            },
            "style": {
              "default": "normal",
              "type": "string",
              "enum": [
                "normal",
                "italic"
              ]
            },
            "name": {
              "type": "string",
              "maxLength": 40
            }
          },
          "required": [
            "weight",
            "style"
          ],
          "additionalProperties": false
        }
      },
      "description": {
        "type": "string",
        "maxLength": 200
      },
      "files": {
        "default": [],
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "weight": {
              "type": "integer",
              "minimum": 100,
              "maximum": 900
            },
            "style": {
              "default": "normal",
              "type": "string",
              "enum": [
                "normal",
                "italic"
              ]
            },
            "format": {
              "type": "string",
              "enum": [
                "woff2",
                "woff",
                "ttf",
                "otf"
              ]
            },
            "url": {
              "type": "string",
              "format": "uri"
            }
          },
          "required": [
            "weight",
            "style",
            "format",
            "url"
          ],
          "additionalProperties": false
        }
      }
    },
    "required": [
      "role",
      "family",
      "source",
      "fallback",
      "weights",
      "files"
    ],
    "additionalProperties": false
  }
}

sections required

The sections that are switched on, in display order. A section that is off is absent from the document.

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "type": {
        "type": "string",
        "enum": [
          "intro",
          "logo",
          "color",
          "typography",
          "motion",
          "voice",
          "moodboard",
          "applications",
          "assets"
        ]
      },
      "position": {
        "type": "integer",
        "minimum": 0,
        "maximum": 8
      },
      "enabled": {
        "type": "boolean",
        "const": true
      }
    },
    "required": [
      "type",
      "position",
      "enabled"
    ],
    "additionalProperties": false
  }
}

intro optional, present when the section is enabled

Headline, statement paragraphs, facts and an optional cover image.

{
  "type": "object",
  "properties": {
    "headline": {
      "type": "string",
      "minLength": 1,
      "maxLength": 160
    },
    "statement": {
      "default": [],
      "maxItems": 20,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 4000
      }
    },
    "facts": {
      "default": [],
      "maxItems": 8,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 200
          },
          "value": {
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "label",
          "value"
        ],
        "additionalProperties": false
      }
    },
    "cover": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "format": "uuid",
          "pattern": "^([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)$"
        },
        "url": {
          "type": "string",
          "format": "uri"
        },
        "fileName": {
          "type": "string",
          "minLength": 1,
          "maxLength": 255
        },
        "mime": {
          "type": "string",
          "minLength": 1,
          "maxLength": 127
        },
        "bytes": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        },
        "width": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 9007199254740991
        },
        "height": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 9007199254740991
        },
        "alt": {
          "type": "string",
          "maxLength": 500
        }
      },
      "required": [
        "id",
        "url",
        "fileName",
        "mime",
        "bytes"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "headline",
    "statement",
    "facts"
  ],
  "additionalProperties": false
}

color optional, present when the section is enabled

How the palette is used: pairings and proportions.

{
  "type": "object",
  "properties": {
    "layout": {
      "default": "mosaic",
      "type": "string",
      "enum": [
        "mosaic",
        "proportions",
        "sheet"
      ]
    },
    "lead": {
      "type": "string",
      "maxLength": 2000
    },
    "notes": {
      "default": [],
      "maxItems": 20,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 4000
      }
    }
  },
  "required": [
    "layout",
    "notes"
  ],
  "additionalProperties": false
}

typography optional, present when the section is enabled

The type scale and pairing rules.

{
  "type": "object",
  "properties": {
    "layout": {
      "default": "sheets",
      "type": "string",
      "enum": [
        "sheets",
        "columns",
        "poster"
      ]
    },
    "sampleText": {
      "type": "string",
      "maxLength": 300
    },
    "scale": {
      "minItems": 1,
      "maxItems": 16,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "fontRole": {
            "type": "string",
            "enum": [
              "display",
              "text",
              "mono"
            ]
          },
          "sizePx": {
            "type": "number",
            "minimum": 8,
            "maximum": 400
          },
          "lineHeight": {
            "type": "number",
            "minimum": 0.7,
            "maximum": 3
          },
          "letterSpacingEm": {
            "type": "number",
            "minimum": -0.2,
            "maximum": 0.5
          },
          "weight": {
            "type": "integer",
            "minimum": 100,
            "maximum": 900
          }
        },
        "required": [
          "label",
          "fontRole",
          "sizePx",
          "lineHeight",
          "weight"
        ],
        "additionalProperties": false
      }
    },
    "notes": {
      "default": [],
      "maxItems": 20,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 4000
      }
    }
  },
  "required": [
    "layout",
    "scale",
    "notes"
  ],
  "additionalProperties": false
}

motion optional, present when the section is enabled

Personality, easing curves, duration bands, stagger and named motion tokens.

{
  "type": "object",
  "properties": {
    "personality": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "minLength": 1,
          "maxLength": 64,
          "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
        },
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 40
        },
        "description": {
          "type": "string",
          "maxLength": 200
        }
      },
      "required": [
        "id",
        "name"
      ],
      "additionalProperties": false
    },
    "easings": {
      "minItems": 1,
      "maxItems": 8,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "bezier": {
            "type": "array",
            "prefixItems": [
              {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              {
                "type": "number",
                "minimum": -2,
                "maximum": 3
              },
              {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              {
                "type": "number",
                "minimum": -2,
                "maximum": 3
              }
            ],
            "items": false,
            "minItems": 4,
            "maxItems": 4
          },
          "description": {
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "id",
          "name",
          "bezier"
        ],
        "additionalProperties": false
      }
    },
    "durations": {
      "type": "object",
      "properties": {
        "micro": {
          "type": "object",
          "properties": {
            "minMs": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000
            },
            "maxMs": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000
            }
          },
          "required": [
            "minMs",
            "maxMs"
          ],
          "additionalProperties": false
        },
        "ui": {
          "type": "object",
          "properties": {
            "minMs": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000
            },
            "maxMs": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000
            }
          },
          "required": [
            "minMs",
            "maxMs"
          ],
          "additionalProperties": false
        },
        "reveal": {
          "type": "object",
          "properties": {
            "minMs": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000
            },
            "maxMs": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000
            }
          },
          "required": [
            "minMs",
            "maxMs"
          ],
          "additionalProperties": false
        }
      },
      "required": [
        "micro",
        "ui",
        "reveal"
      ],
      "additionalProperties": false
    },
    "stagger": {
      "type": "object",
      "properties": {
        "eachMs": {
          "default": 50,
          "type": "integer",
          "minimum": 0,
          "maximum": 1000
        },
        "from": {
          "default": "start",
          "type": "string",
          "enum": [
            "start",
            "center",
            "end"
          ]
        }
      },
      "required": [
        "eachMs",
        "from"
      ],
      "additionalProperties": false
    },
    "tokens": {
      "minItems": 1,
      "maxItems": 12,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 40
          },
          "description": {
            "type": "string",
            "maxLength": 200
          },
          "durationMs": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000
          },
          "easingId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
          },
          "demo": {
            "type": "string",
            "enum": [
              "reveal",
              "hover",
              "press",
              "transition",
              "stagger"
            ]
          },
          "properties": {
            "default": [
              "opacity",
              "transform"
            ],
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "opacity",
                "transform",
                "clip-path",
                "color",
                "background-color"
              ]
            }
          },
          "distancePx": {
            "default": 16,
            "type": "number",
            "minimum": 0,
            "maximum": 400
          },
          "staggerMs": {
            "type": "integer",
            "minimum": 0,
            "maximum": 1000
          }
        },
        "required": [
          "id",
          "name",
          "durationMs",
          "easingId",
          "demo",
          "properties",
          "distancePx"
        ],
        "additionalProperties": false
      }
    },
    "principles": {
      "default": [],
      "maxItems": 8,
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 200
      }
    },
    "reducedMotion": {
      "default": "freeze",
      "type": "string",
      "enum": [
        "freeze",
        "crossfade"
      ]
    }
  },
  "required": [
    "personality",
    "easings",
    "durations",
    "stagger",
    "tokens",
    "principles",
    "reducedMotion"
  ],
  "additionalProperties": false
}

voice optional, present when the section is enabled

Tone pillars and do and don't pairs.

{
  "type": "object",
  "properties": {
    "lead": {
      "type": "string",
      "maxLength": 2000
    },
    "pillars": {
      "default": [],
      "maxItems": 8,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 200
          },
          "description": {
            "type": "string",
            "maxLength": 2000
          },
          "example": {
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "title",
          "description"
        ],
        "additionalProperties": false
      }
    },
    "doDont": {
      "default": [],
      "maxItems": 12,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "do": {
            "type": "string",
            "maxLength": 200
          },
          "dont": {
            "type": "string",
            "maxLength": 200
          },
          "context": {
            "type": "string",
            "maxLength": 200
          }
        },
        "required": [
          "do",
          "dont"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "pillars",
    "doDont"
  ],
  "additionalProperties": false
}

moodboard optional, present when the section is enabled

Images with captions.

{
  "type": "object",
  "properties": {
    "layout": {
      "default": "cloud",
      "type": "string",
      "enum": [
        "cloud",
        "columns"
      ]
    },
    "caption": {
      "type": "string",
      "maxLength": 200
    },
    "items": {
      "default": [],
      "maxItems": 40,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
          },
          "alt": {
            "type": "string",
            "maxLength": 300
          },
          "caption": {
            "type": "string",
            "maxLength": 200
          },
          "asset": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([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)$"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "fileName": {
                "type": "string",
                "minLength": 1,
                "maxLength": 255
              },
              "mime": {
                "type": "string",
                "minLength": 1,
                "maxLength": 127
              },
              "bytes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "width": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "height": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "alt": {
                "type": "string",
                "maxLength": 500
              }
            },
            "required": [
              "id",
              "url",
              "fileName",
              "mime",
              "bytes"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "alt",
          "asset"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "layout",
    "items"
  ],
  "additionalProperties": false
}

applications optional, present when the section is enabled

The brand in use: example applications with images.

{
  "type": "object",
  "properties": {
    "lead": {
      "type": "string",
      "maxLength": 2000
    },
    "items": {
      "default": [],
      "maxItems": 40,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "pattern": "^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
          },
          "kind": {
            "type": "string",
            "enum": [
              "social",
              "digital",
              "device",
              "print",
              "environment"
            ]
          },
          "title": {
            "type": "string",
            "maxLength": 200
          },
          "surface": {
            "default": "auto",
            "type": "string",
            "enum": [
              "auto",
              "light",
              "dark"
            ]
          },
          "copy": {
            "type": "object",
            "properties": {
              "headline": {
                "type": "string",
                "maxLength": 200
              },
              "subline": {
                "type": "string",
                "maxLength": 200
              },
              "cta": {
                "type": "string",
                "maxLength": 200
              },
              "handle": {
                "type": "string",
                "maxLength": 200
              }
            },
            "additionalProperties": false
          },
          "asset": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([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)$"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "fileName": {
                "type": "string",
                "minLength": 1,
                "maxLength": 255
              },
              "mime": {
                "type": "string",
                "minLength": 1,
                "maxLength": 127
              },
              "bytes": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "width": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "height": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "alt": {
                "type": "string",
                "maxLength": 500
              }
            },
            "required": [
              "id",
              "url",
              "fileName",
              "mime",
              "bytes"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "kind",
          "title",
          "surface",
          "asset"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "items"
  ],
  "additionalProperties": false
}

assets optional, present when the section is enabled

Downloadable files with sizes and types.

{
  "type": "object",
  "properties": {
    "lead": {
      "type": "string",
      "maxLength": 2000
    },
    "groups": {
      "default": [],
      "maxItems": 12,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 200
          },
          "note": {
            "type": "string",
            "maxLength": 200
          },
          "items": {
            "maxItems": 60,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string",
                  "maxLength": 200
                },
                "asset": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([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)$"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "fileName": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 255
                    },
                    "mime": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 127
                    },
                    "bytes": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 9007199254740991
                    },
                    "width": {
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    },
                    "height": {
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    },
                    "alt": {
                      "type": "string",
                      "maxLength": 500
                    }
                  },
                  "required": [
                    "id",
                    "url",
                    "fileName",
                    "mime",
                    "bytes"
                  ],
                  "additionalProperties": false
                }
              },
              "required": [
                "label",
                "asset"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "title",
          "items"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "groups"
  ],
  "additionalProperties": false
}

meta required

Status, timestamps, whether the page is indexable and whether it is password protected.

{
  "type": "object",
  "properties": {
    "status": {
      "type": "string",
      "enum": [
        "draft",
        "published"
      ]
    },
    "publishedAt": {
      "anyOf": [
        {
          "type": "string",
          "format": "date-time",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
        },
        {
          "type": "null"
        }
      ]
    },
    "updatedAt": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
    },
    "generatedAt": {
      "type": "string",
      "format": "date-time",
      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
    },
    "indexable": {
      "type": "boolean"
    },
    "protected": {
      "type": "boolean"
    }
  },
  "required": [
    "status",
    "publishedAt",
    "updatedAt",
    "generatedAt",
    "indexable",
    "protected"
  ],
  "additionalProperties": false
}