Raw schema
{
"type": "object",
"properties": {
"category": {
"type": "string",
"enum": [
"STRATEGY",
"IDEAS",
"COPY",
"VISUALS",
"MOTION"
],
"description": "One of STRATEGY, IDEAS, COPY, VISUALS, MOTION. BRIEFS is not accepted — briefs live in the creator_briefs table via the briefs API."
},
"format": {
"type": "string",
"description": "Per-category format. STRATEGY: positioning, brand-platform, campaign-strategy, strategic-doc. IDEAS: hook, concept, big-idea, territory. COPY: ad-script, hook, campaign-copy. VISUALS: static-ad, product, lifestyle, hero, moodboard, packaging, logo. MOTION: talking-head, b-roll, product-motion, brand-lifestyle."
},
"tags": {
"description": "Free-form tags for filtering and search.",
"type": "array",
"items": {
"type": "string"
}
},
"source": {
"type": "object",
"properties": {
"heist_slug": {
"description": "Source Heist slug — e.g. \"adscript\", \"hooks\", \"creative-director\".",
"type": "string"
},
"session_id": {
"description": "Optional source session id.",
"type": "string"
},
"message_id": {
"description": "Optional source message id (for highlight-from-chat saves).",
"type": "string"
},
"pattern": {
"type": "string",
"enum": [
"direct",
"highlight",
"tool",
"document"
],
"description": "How the save was created. `direct` for explicit save action."
}
},
"required": [
"pattern"
],
"description": "Save attribution."
},
"brand_id": {
"description": "Brand the asset is for. Resolved from brief_id when omitted.",
"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)$"
},
"brief_id": {
"description": "PowerSource (brief) the asset was generated against.",
"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)$"
},
"parent_id": {
"description": "Parent asset id for variations grouped under one save set.",
"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)$"
},
"title": {
"type": "string",
"description": "Card title — what shows in /assets."
},
"body_text": {
"description": "Primary text body for STRATEGY / IDEAS / COPY saves.",
"type": "string"
},
"body_html": {
"description": "Rich-text body where the asset carries structured markup.",
"type": "string"
},
"media_url": {
"description": "Direct media URL for VISUALS / MOTION (external host).",
"type": "string",
"format": "uri"
},
"media_storage_path": {
"description": "Storage path inside the private `saved-assets` bucket. Obtain via the /api/saved-assets/upload-url route (REST only; no MCP upload tool yet).",
"type": "string"
},
"thumb_url": {
"description": "Card thumbnail URL.",
"type": "string",
"format": "uri"
},
"metadata": {
"description": "Type-specific bag — duration, image dimensions, model used, beat count, etc.",
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
},
"required": [
"category",
"format",
"source",
"title"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}