{
  "openapi": "3.1.0",
  "info": {
    "title": "Cockatoo Agent API",
    "version": "1.0.0",
    "description": "Structured one-page websites with owner-approved agent access. Availability is controlled by rollout flags."
  },
  "servers": [
    {
      "url": "https://app.cockatoo.com.au/api/v1"
    }
  ],
  "paths": {
    "/token": {
      "get": {
        "operationId": "tokenInfo",
        "summary": "Inspect the current API grant without requiring site-read permission",
        "security": [
          {
            "agentToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    },
    "/catalog": {
      "get": {
        "operationId": "catalog",
        "summary": "List templates, industries, style presets and an example document",
        "security": [],
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    },
    "/onboarding": {
      "post": {
        "operationId": "startOnboarding",
        "summary": "Prepare a private owner-approved account and website handoff",
        "security": [],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9_-]+$"
            },
            "description": "Use a fresh random UUID per write; reuse the same key and identical body when retrying within 24 hours."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email",
                  "agentName",
                  "document"
                ],
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "agentName": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "document": {
                    "$ref": "#/components/schemas/SiteDocument"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    },
    "/onboarding/{id}": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "operationId": "onboardingStatus",
        "summary": "Check pending_owner_approval, approved, denied, processing or exchanged",
        "security": [
          {
            "continuation": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    },
    "/onboarding/{id}/exchange": {
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "operationId": "exchangeOnboarding",
        "summary": "Exchange approved onboarding for an API token",
        "security": [
          {
            "continuation": []
          }
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9_-]+$"
            },
            "description": "Use a fresh random UUID per write; reuse the same key and identical body when retrying within 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    },
    "/site": {
      "get": {
        "operationId": "getSite",
        "summary": "Read the owner’s site",
        "security": [
          {
            "agentToken": []
          }
        ],
        "x-required-scopes": [
          "sites:read"
        ],
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      },
      "post": {
        "operationId": "createSite",
        "summary": "Create a structured draft",
        "security": [
          {
            "agentToken": []
          }
        ],
        "x-required-scopes": [
          "sites:write"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9_-]+$"
            },
            "description": "Use a fresh random UUID per write; reuse the same key and identical body when retrying within 24 hours."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "document"
                ],
                "properties": {
                  "document": {
                    "$ref": "#/components/schemas/SiteDocument"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      },
      "put": {
        "operationId": "saveSite",
        "summary": "Replace the draft with revision checking",
        "security": [
          {
            "agentToken": []
          }
        ],
        "x-required-scopes": [
          "sites:write"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9_-]+$"
            },
            "description": "Use a fresh random UUID per write; reuse the same key and identical body when retrying within 24 hours."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "revision",
                  "document"
                ],
                "properties": {
                  "revision": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "document": {
                    "$ref": "#/components/schemas/SiteDocument"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    },
    "/site/assets": {
      "get": {
        "operationId": "listImages",
        "summary": "List the site’s retained uploaded images",
        "security": [
          {
            "agentToken": []
          }
        ],
        "x-required-scopes": [
          "sites:read"
        ],
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      },
      "post": {
        "operationId": "uploadImage",
        "summary": "Upload up to 5 MiB of JPEG, PNG or WebP",
        "security": [
          {
            "agentToken": []
          }
        ],
        "x-required-scopes": [
          "sites:write"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9_-]+$"
            },
            "description": "Use a fresh random UUID per write; reuse the same key and identical body when retrying within 24 hours."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "image/jpeg": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/png": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            },
            "image/webp": {
              "schema": {
                "type": "string",
                "format": "binary"
              }
            }
          }
        }
      }
    },
    "/site/preview": {
      "get": {
        "operationId": "previewSite",
        "summary": "Return private draft preview HTML; forms disabled",
        "security": [
          {
            "agentToken": []
          }
        ],
        "x-required-scopes": [
          "sites:read"
        ],
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    },
    "/site/publication": {
      "get": {
        "operationId": "publicationStatus",
        "summary": "Read live state and published revision",
        "security": [
          {
            "agentToken": []
          }
        ],
        "x-required-scopes": [
          "sites:read"
        ],
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    },
    "/site/publish": {
      "post": {
        "operationId": "publishSite",
        "summary": "Publish a saved revision",
        "security": [
          {
            "agentToken": []
          }
        ],
        "x-required-scopes": [
          "sites:publish"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9_-]+$"
            },
            "description": "Use a fresh random UUID per write; reuse the same key and identical body when retrying within 24 hours."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "revision"
                ],
                "properties": {
                  "revision": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "slug": {
                    "type": "string",
                    "pattern": "^[a-z0-9][a-z0-9-]{2,62}$"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    },
    "/site/unpublish": {
      "post": {
        "operationId": "unpublishSite",
        "summary": "Remove the public publication while retaining the draft",
        "security": [
          {
            "agentToken": []
          }
        ],
        "x-required-scopes": [
          "sites:publish"
        ],
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128,
              "pattern": "^[A-Za-z0-9_-]+$"
            },
            "description": "Use a fresh random UUID per write; reuse the same key and identical body when retrying within 24 hours."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "revision"
                ],
                "properties": {
                  "revision": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response"
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Missing, expired, revoked or wrong-audience credential"
          },
          "403": {
            "description": "Insufficient scope or access denied"
          },
          "409": {
            "description": "Revision/slug conflict, different input for an existing key, or uncertain operation outcome"
          },
          "413": {
            "description": "Body or storage quota exceeded"
          },
          "429": {
            "description": "Rate limit; honor Retry-After"
          },
          "503": {
            "description": "Feature disabled or hosting unavailable"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "agentToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Cockatoo API token",
        "description": "API tokens are issued for /api/v1 through onboarding or Agent access. MCP OAuth tokens cannot be reused here."
      },
      "continuation": {
        "type": "http",
        "scheme": "bearer",
        "description": "Private continuationCredential from onboarding, not an owner API token."
      }
    },
    "schemas": {
      "SiteDocument": {
        "type": "object",
        "required": [
          "version",
          "template",
          "industry",
          "businessName",
          "headline",
          "introduction",
          "about",
          "phone",
          "email",
          "bookingUrl",
          "hours",
          "serviceArea",
          "title",
          "description",
          "services",
          "colour",
          "font",
          "logo",
          "gallery",
          "sections"
        ],
        "properties": {
          "version": {
            "const": 1,
            "type": "integer"
          },
          "template": {
            "type": "string",
            "enum": [
              "local",
              "studio",
              "professional",
              "workshop",
              "hospitality",
              "care"
            ]
          },
          "industry": {
            "type": "string",
            "enum": [
              "4x4-accessories",
              "accountant",
              "air-conditioning",
              "air-conditioning-cleaning",
              "aluminium-fabricators-and-repairers",
              "aluminium-windows",
              "appliance-repairs-and-parts",
              "arborist",
              "asbestos-removals",
              "asphalt-and-bitumen",
              "auto-electricians",
              "auto-parts",
              "auto-wreckers",
              "awnings",
              "balustrading",
              "barber",
              "bathroom-renovations",
              "batteries",
              "beauty-salons",
              "bike-shops",
              "blinds",
              "blocked-drains",
              "boat-sales-and-service",
              "bobcat-and-dingo-hire",
              "bookkeeper",
              "bore-drilling",
              "brake-and-clutch-repairs",
              "bricklayers-and-blocklayers",
              "builder",
              "building-and-home-renovations",
              "pest-inspector",
              "building-designers",
              "butchers",
              "cabinet-makers",
              "cafes",
              "car-air-conditioning",
              "car-transmissions",
              "car-wash-and-detailing",
              "caravan-repairs",
              "caravans-sales-and-parts",
              "carpenter",
              "carpet-cleaning",
              "carpet-stores",
              "caterers",
              "cctv-and-security-cameras",
              "chemists-and-pharmacies",
              "child-care-centres",
              "chiropractor",
              "civil-contractors",
              "cleaner",
              "coach-charters-and-bus-tours",
              "commercial-air-conditioning",
              "commercial-cleaners",
              "computer-repairs",
              "computer-sales-and-equipment",
              "concrete-cutting",
              "concrete-pre-mixed",
              "concrete-pumping-services",
              "concreter",
              "conveyancing",
              "cosmetic-services",
              "couriers",
              "crane-hire",
              "cremation",
              "curtains",
              "data-cabling-and-communications",
              "demolition-contractors",
              "dentist",
              "denture-clinics",
              "diesel-mechanics",
              "disability-care-services-and-support",
              "doctors-and-medical-centres",
              "dog-boarding-kennels",
              "dog-grooming",
              "driving-schools",
              "electrician",
              "equipment-hire",
              "excavating-and-earthmoving-equipment",
              "excavator-and-earthmoving-hire",
              "family-lawyers",
              "farm-machinery",
              "fencer",
              "fencing-supplies",
              "finance-brokers-loans-and-mortgages",
              "financial-planning",
              "fire-protection-services",
              "fitness-centres-and-gyms",
              "floor-sanding-and-polishing",
              "flooring-stores",
              "florists",
              "funeral-directors",
              "garage-doors",
              "gardeners",
              "gas-fitter",
              "gate-installation-and-repairs",
              "general-engineering",
              "gift-shops",
              "glass-repairs-and-replacements",
              "guttering-and-downpipes",
              "hairdresser",
              "handyman-services",
              "heavy-transport",
              "high-pressure-cleaners",
              "hoses-and-fittings-sales-and-repairs",
              "hot-water-systems",
              "hydraulics",
              "insurance-brokers",
              "irrigation-and-sprinkler-systems",
              "kitchen-renovations-and-installations",
              "land-surveyors",
              "landscape-supplies",
              "landscaper",
              "lawn-and-turf-supplies",
              "lawn-mowers",
              "lawn-mowing-services",
              "lawyer",
              "locksmith",
              "massage-therapists",
              "mechanic",
              "mobile-mechanic",
              "mortgage-brokers",
              "motorcycle-dealers",
              "mufflers-and-exhausts",
              "nurseries-and-garden-centres",
              "optometrist",
              "paint-supplies-and-accessories",
              "painter",
              "panel-beaters-and-smash-repairs",
              "party-hire",
              "patio-builders",
              "pest-control",
              "physiotherapist",
              "picture-framing",
              "plasterer",
              "plumber",
              "podiatrist",
              "pool-cleaning-and-maintenance",
              "pool-fencing",
              "pool-shops-and-supplies",
              "powder-coating",
              "printing-services",
              "property-management",
              "pumps-sales-and-repairs",
              "quarries",
              "real-estate-agents",
              "refrigeration",
              "removalists",
              "restaurants",
              "retaining-and-rock-walls",
              "roadworthy-and-safety-certificates",
              "roof-painting",
              "roof-restorations-and-repairs",
              "roofer",
              "rubbish-removal",
              "sand-soil-and-gravel-supplies",
              "scaffolding-sales-and-hire",
              "scrap-metal-merchants",
              "security-doors-and-screens",
              "security-guards-and-patrolling-services",
              "security-systems",
              "self-storage",
              "septic-tank-cleaning-and-servicing",
              "septic-tank-sales-and-installation",
              "shade-sails-and-structures",
              "sheds",
              "sheet-metal-fabricators",
              "shock-absorbers-and-suspension",
              "shower-screens",
              "shutters",
              "sign-shops",
              "skip-bin-hire",
              "slashing-contractors",
              "solar-power-systems",
              "steel-fabrication",
              "steel-suppliers",
              "swimming-pool-builders",
              "takeaway-food",
              "tax-accountants",
              "termite-treatment",
              "tile-shops",
              "tiler",
              "timber-supplies",
              "towing-services",
              "trade-supplies",
              "transport-services",
              "tree-and-stump-removal",
              "truck-and-bus-repairs",
              "tv-antenna-installations",
              "tyres",
              "upholsterers",
              "used-car-dealers",
              "vacuum-excavation",
              "vet",
              "wardrobes",
              "water-cartage",
              "welders",
              "wheel-alignment-and-balancing",
              "window-tinting",
              "windscreen-repairs-and-replacements",
              "workwear",
              "jewellers",
              "prestige-car-dealers",
              "luxury-watch-dealers",
              "yacht-and-marine-dealers",
              "art-galleries",
              "luxury-fashion-boutiques",
              "cosmetic-surgery",
              "luxury-furniture-and-interiors",
              "beef-cattle-farming",
              "agricultural-support-services",
              "motels",
              "caravan-parks",
              "it-support-companies",
              "web-development-agencies",
              "video-production-companies",
              "service-stations",
              "online-retailers",
              "industrial-supplies-wholesalers",
              "craft-breweries",
              "commercial-bakeries",
              "joinery-cabinet-manufacturers",
              "early-learning-centres",
              "aged-care-providers",
              "freight-forwarding-services",
              "aquaculture-farms",
              "logging-contractors",
              "commercial-fishing-operators",
              "clothing-manufacturers",
              "boat-builders",
              "liquor-wholesalers",
              "fruit-vegetable-wholesalers",
              "wholesale-agents-brokers",
              "scenic-tour-operators",
              "software-companies",
              "online-media-publishers",
              "web-hosting-cloud-services",
              "recruitment-agencies",
              "travel-agencies",
              "creative-performing-arts",
              "pubs-and-bars",
              "landscapers",
              "earthmoving-excavation-contractors",
              "advertising-marketing-agencies",
              "photographers",
              "graphic-designers",
              "management-consultants",
              "consulting-engineers",
              "car-rental-companies",
              "dry-cleaners-laundromats",
              "appliance-stores",
              "swim-schools",
              "music-dance-schools",
              "greengrocers",
              "event-management-companies",
              "coal-mining-companies",
              "oil-gas-companies",
              "metal-ore-miners",
              "mining-services-contractors",
              "paper-pulp-manufacturers",
              "petroleum-product-manufacturers",
              "cleaning-product-manufacturers",
              "plastics-manufacturers",
              "metal-manufacturers",
              "energy-retailers",
              "gas-suppliers",
              "water-treatment-supply",
              "rail-operators",
              "shipping-companies",
              "air-charter-operators",
              "radio-tv-broadcasters",
              "telecommunications-providers",
              "libraries-archives",
              "non-bank-lenders",
              "insurance-companies",
              "local-government-councils",
              "defence-suppliers",
              "training-colleges-rtos",
              "private-hospitals-day-surgeries",
              "museums-galleries",
              "gaming-venues"
            ]
          },
          "businessName": {
            "type": "string",
            "maxLength": 120
          },
          "headline": {
            "type": "string",
            "maxLength": 180
          },
          "introduction": {
            "type": "string",
            "maxLength": 1600
          },
          "about": {
            "type": "string",
            "maxLength": 4000
          },
          "phone": {
            "type": "string",
            "maxLength": 40
          },
          "email": {
            "type": "string",
            "maxLength": 254
          },
          "bookingUrl": {
            "type": "string",
            "maxLength": 1000
          },
          "hours": {
            "type": "string",
            "maxLength": 1000
          },
          "serviceArea": {
            "type": "string",
            "maxLength": 500
          },
          "title": {
            "type": "string",
            "maxLength": 160
          },
          "description": {
            "type": "string",
            "maxLength": 320
          },
          "services": {
            "type": "array",
            "maxItems": 12,
            "items": {
              "type": "string",
              "maxLength": 180
            }
          },
          "colour": {
            "type": "string",
            "enum": [
              "forest",
              "ocean",
              "charcoal",
              "terracotta"
            ]
          },
          "font": {
            "type": "string",
            "enum": [
              "sans",
              "serif"
            ]
          },
          "logo": {
            "anyOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "assetId",
                  "alt"
                ],
                "properties": {
                  "assetId": {
                    "type": "string",
                    "pattern": "^[a-f0-9-]{36}$"
                  },
                  "alt": {
                    "type": "string",
                    "maxLength": 240
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "gallery": {
            "type": "array",
            "maxItems": 19,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "assetId",
                "alt"
              ],
              "properties": {
                "assetId": {
                  "type": "string",
                  "pattern": "^[a-f0-9-]{36}$"
                },
                "alt": {
                  "type": "string",
                  "maxLength": 240
                }
              }
            }
          },
          "sections": {
            "type": "array",
            "minItems": 7,
            "maxItems": 7,
            "items": {
              "type": "object",
              "required": [
                "id",
                "visible"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "enum": [
                    "hero",
                    "services",
                    "about",
                    "gallery",
                    "hours",
                    "area",
                    "contact"
                  ]
                },
                "visible": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      }
    }
  },
  "x-cockatoo-mcp": "https://app.cockatoo.com.au/mcp"
}
