{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://agentsnacks.ai/api/schema.json",
  "title": "Agent Snacks feed (v1.0)",
  "description": "Shape of /api/snacks.json, /api/latest.json and /api/tools/<tool>.json. Field names are stable within major version 1.",
  "type": "object",
  "required": [
    "schema_version",
    "items"
  ],
  "properties": {
    "schema_version": {
      "type": "string"
    },
    "items": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/item"
      }
    }
  },
  "$defs": {
    "item": {
      "type": "object",
      "required": [
        "id",
        "type",
        "date",
        "shipped",
        "tool",
        "title",
        "summary",
        "spice",
        "source_url",
        "source_urls",
        "verified",
        "url",
        "also_in"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "type": {
          "enum": [
            "daily",
            "weekly",
            "shelf",
            "main_course",
            "video",
            "changelog"
          ]
        },
        "backfill": {
          "type": "boolean",
          "description": "true = added after the fact from primary sources to fill a tool timeline; date = when we added it, shipped = real vendor date"
        },
        "added": {
          "type": "string",
          "format": "date",
          "description": "backfill only: date the entry was added"
        },
        "category": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "Creative",
            null
          ],
          "description": "Creative = making images, video or audio with agents (shelf, video, daily, weekly Creator corner)"
        },
        "audience": {
          "type": "array",
          "items": {
            "enum": [
              "builders",
              "creators",
              "beginners"
            ]
          },
          "description": "shelf only: who it is for; drives the /shelf/ filter (#builders, #creators, #beginners; #creative is an alias for #creators)"
        },
        "media": {
          "type": [
            "object",
            "null"
          ],
          "description": "optional official sample media, embedded lazily; never rehosted beyond a tiny thumbnail",
          "required": [
            "type",
            "src",
            "credit",
            "source_url"
          ],
          "properties": {
            "type": {
              "enum": [
                "image",
                "video",
                "audio"
              ]
            },
            "src": {
              "type": "string",
              "format": "uri"
            },
            "poster": {
              "type": "string"
            },
            "credit": {
              "type": "string"
            },
            "source_url": {
              "type": "string",
              "format": "uri"
            },
            "alt": {
              "type": "string"
            },
            "width": {
              "type": "integer"
            },
            "height": {
              "type": "integer"
            }
          }
        },
        "spice_basis": {
          "type": "string",
          "description": "how spice was set when not hand-rated, e.g. auto (release size)"
        },
        "level": {
          "enum": [
            "beginner",
            "intermediate",
            "advanced"
          ],
          "description": "video only"
        },
        "length": {
          "type": "string",
          "description": "video only, m:ss"
        },
        "channel": {
          "type": "string",
          "description": "video only: YouTube channel display name"
        },
        "channel_url": {
          "type": "string",
          "format": "uri",
          "description": "video only: verified YouTube channel URL from yt-dlp"
        },
        "after_watching": {
          "type": "string",
          "description": "video only"
        },
        "summary_source": {
          "type": "string",
          "description": "video only: chapters / transcript / description it was derived from"
        },
        "watch_parts": {
          "type": "array",
          "description": "video only: timestamps {t,label,title,url[,end,source]} from chapters, transcript or visual analysis"
        },
        "on_screen": {
          "type": [
            "string",
            "null"
          ],
          "description": "video only: short description of what is visible on screen (from visual analysis); null if not analysed"
        },
        "words": {
          "type": "integer",
          "description": "main_course only"
        },
        "read_minutes": {
          "type": "integer",
          "description": "main_course only"
        },
        "kind": {
          "enum": [
            "MCP server",
            "Skill",
            "Template",
            "SDK"
          ],
          "description": "shelf items only; app plugins use 'App plugin (<App>)', e.g. 'App plugin (Claude)'"
        },
        "works_with": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "shelf items only; verified compatible hosts"
        },
        "date": {
          "type": "string",
          "format": "date",
          "description": "PUBLISHED date on Agent Snacks (daily post date or Snack Pack issue date). Sort/filter by this for 'what's new on the site'."
        },
        "shipped": {
          "type": [
            "string",
            "null"
          ],
          "format": "date",
          "description": "date the vendor shipped it (first date in the snack title); null if unknown. Filter by this for 'what changed since X'."
        },
        "source_urls": {
          "type": "array",
          "items": {
            "type": "string",
            "format": "uri"
          },
          "description": "all primary/linked sources; source_url is the first"
        },
        "also_in": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "ids of other items with the same primary source_url (daily<->weekly duplicates)"
        },
        "tool": {
          "type": "string",
          "description": "slug: chatgpt, claude, claude-code, cline, codex, copilot, copilot-cli, cursor, devin-desktop, gemini, gemini-cli, mcp, microsoft-copilot, opencode, other, skills"
        },
        "title": {
          "type": "string"
        },
        "summary": {
          "type": "string"
        },
        "spice": {
          "type": [
            "integer",
            "null"
          ],
          "minimum": 1,
          "maximum": 3,
          "description": "workflow impact: 1 nice to know, 2 worth a look, 3 act this week; null if unrated"
        },
        "source_url": {
          "type": [
            "string",
            "null"
          ],
          "format": "uri",
          "description": "primary source"
        },
        "verified": {
          "type": "boolean",
          "description": "false = not yet re-checked against the primary source; re-check the source before relying on it"
        },
        "url": {
          "type": "string",
          "format": "uri"
        },
        "issue": {
          "type": [
            "integer",
            "null"
          ]
        }
      }
    }
  }
}
