page.mooring.site

mooring.page

{
  "id": "page.mooring.site",
  "defs": {
    "rgb": {
      "type": "object",
      "required": [
        "r",
        "g",
        "b"
      ],
      "properties": {
        "b": {
          "type": "integer",
          "maximum": 255,
          "minimum": 0
        },
        "g": {
          "type": "integer",
          "maximum": 255,
          "minimum": 0
        },
        "r": {
          "type": "integer",
          "maximum": 255,
          "minimum": 0
        }
      }
    },
    "main": {
      "key": "any",
      "type": "record",
      "record": {
        "type": "object",
        "required": [
          "createdAt"
        ],
        "properties": {
          "icon": {
            "type": "blob",
            "accept": [
              "image/*"
            ],
            "maxSize": 1000000,
            "description": "Square image used as the site icon/favicon. Should be at least 256x256."
          },
          "name": {
            "type": "string",
            "maxLength": 5000,
            "description": "Site title. When absent, renderers should fall back to the owner's profile displayName or handle.",
            "maxGraphemes": 500
          },
          "theme": {
            "ref": "#theme",
            "type": "ref"
          },
          "labels": {
            "refs": [
              "com.atproto.label.defs#selfLabels"
            ],
            "type": "union"
          },
          "signOff": {
            "type": "string",
            "maxLength": 640,
            "description": "Valediction rendered before the owner's name in the site's closing sign-off, like 'Warmly,'. When absent, the sign-off shows the name alone.",
            "maxGraphemes": 64
          },
          "sections": {
            "type": "array",
            "items": {
              "refs": [
                "#heroSection",
                "#postsSection",
                "#writingSection",
                "#careerSection",
                "#pagesSection"
              ],
              "type": "union",
              "closed": false
            },
            "maxLength": 50,
            "description": "Ordered sections of the site, rendered top to bottom; order is array position. When absent, renderers should use a sensible default order based on which sources have data."
          },
          "createdAt": {
            "type": "string",
            "format": "datetime",
            "description": "Client-declared timestamp when this record was created."
          },
          "description": {
            "type": "string",
            "maxLength": 30000,
            "description": "Short description of the site, used for meta tags and previews.",
            "maxGraphemes": 3000
          },
          "contactEmail": {
            "type": "string",
            "maxLength": 2540,
            "description": "Public contact email, rendered as a contact affordance on the site. Publishing an address here makes it world-readable.",
            "maxGraphemes": 254
          },
          "discoverable": {
            "type": "boolean",
            "description": "Default true when absent. When false, the renderer emits noindex directives for the site. Does not affect the public visibility of the underlying atproto records."
          }
        }
      },
      "description": "A Mooring site. Every field except createdAt is optional: an empty record is a valid site, and the renderer falls back to the owner's profile records and a default section order."
    },
    "theme": {
      "type": "object",
      "properties": {
        "colors": {
          "ref": "#colors",
          "type": "ref"
        },
        "preset": {
          "type": "string",
          "description": "Named theme preset. Unknown values should fall back to the renderer's default preset.",
          "knownValues": [
            "classic"
          ]
        }
      },
      "description": "Theme selection and overrides. All fields optional; renderer defaults apply."
    },
    "colors": {
      "type": "object",
      "properties": {
        "accent": {
          "refs": [
            "#rgb"
          ],
          "type": "union",
          "closed": false,
          "description": "Color used for links and button backgrounds."
        },
        "background": {
          "refs": [
            "#rgb"
          ],
          "type": "union",
          "closed": false,
          "description": "Color used for content background."
        },
        "foreground": {
          "refs": [
            "#rgb"
          ],
          "type": "union",
          "closed": false,
          "description": "Color used for content text."
        },
        "accentForeground": {
          "refs": [
            "#rgb"
          ],
          "type": "union",
          "closed": false,
          "description": "Color used for button text."
        }
      },
      "description": "Semantic color overrides, mirroring the role vocabulary of site.standard.theme.basic. Any subset may be set."
    },
    "heroSection": {
      "type": "object",
      "properties": {
        "style": {
          "type": "string",
          "description": "Banner treatment when the profile carries a banner: 'band' renders it full-width above the heading, 'postcard' renders it as a framed photograph beside the heading. Default 'band'. Without a banner both fall back to the avatar-led hero.",
          "knownValues": [
            "band",
            "postcard"
          ]
        },
        "title": {
          "type": "string",
          "maxLength": 1280,
          "description": "Heading override. When absent, renderers should fall back to profile data.",
          "maxGraphemes": 128
        },
        "tagline": {
          "type": "string",
          "maxLength": 3000,
          "description": "Short line under the heading. When absent, renderers should fall back to the profile description or sifa headline.",
          "maxGraphemes": 300
        },
        "showAvatar": {
          "type": "boolean",
          "description": "Default true when absent."
        }
      },
      "description": "Introductory section rendered from the owner's profile records (app.bsky.actor.profile, with id.sifa.profile.self as professional-context overlay when present)."
    },
    "pagesSection": {
      "type": "object",
      "properties": {
        "pages": {
          "type": "array",
          "items": {
            "type": "string",
            "format": "at-uri"
          },
          "maxLength": 100,
          "description": "Explicit ordered list of page records (AT-URIs) to show. Renderers should skip dangling references. When absent, all public pages are listed in a renderer-defined order."
        },
        "title": {
          "type": "string",
          "maxLength": 1280,
          "maxGraphemes": 128
        }
      },
      "description": "Listing of the site's authored page.mooring.page records."
    },
    "postsSection": {
      "type": "object",
      "properties": {
        "limit": {
          "type": "integer",
          "maximum": 50,
          "minimum": 1,
          "description": "Maximum number of posts to display. Renderer default applies when absent."
        },
        "title": {
          "type": "string",
          "maxLength": 1280,
          "maxGraphemes": 128
        }
      },
      "description": "Recent microblog posts from the owner's app.bsky.feed.post collection."
    },
    "careerSection": {
      "type": "object",
      "properties": {
        "parts": {
          "type": "array",
          "items": {
            "type": "string",
            "knownValues": [
              "positions",
              "education",
              "skills",
              "projects",
              "certifications",
              "publications"
            ]
          },
          "maxLength": 10,
          "description": "Which parts of the sifa profile to render, in order. When absent, renderers should show the parts that have data, in a default order."
        },
        "title": {
          "type": "string",
          "maxLength": 1280,
          "maxGraphemes": 128
        }
      },
      "description": "Professional profile rendered from the owner's id.sifa.* records."
    },
    "writingSection": {
      "type": "object",
      "properties": {
        "limit": {
          "type": "integer",
          "maximum": 50,
          "minimum": 1,
          "description": "Maximum number of documents to display. Renderer default applies when absent."
        },
        "title": {
          "type": "string",
          "maxLength": 1280,
          "maxGraphemes": 128
        },
        "publication": {
          "type": "string",
          "format": "at-uri",
          "description": "AT-URI of a site.standard.publication record to scope the listing to. When absent, renderers should list the owner's documents across publications."
        }
      },
      "description": "Long-form writing from the owner's site.standard.document collection (with pub.leaflet.* legacy records as fallback)."
    }
  },
  "$type": "com.atproto.lexicon.schema",
  "lexicon": 1,
  "description": "Configuration for a Mooring site. The record at rkey 'self' is the owner's default site; other rkeys are reserved for possible future multi-site support."
}

Validate Record

Validate a record against page.mooring.site

Validation Options
Automatically resolve and include external schemas for full validation
Treat any remaining unresolved references as valid

Metadata

DID
did:plc:o3zuar7kk2mrz7d4sqxdisy2
CID
bafyreidauwqicqmynoj677qlwhjkb5pjvnwhgvfg5si4yyqkldcm2htoni
Indexed At
2026-08-26 01:08 UTC
AT-URI
at://did:plc:o3zuar7kk2mrz7d4sqxdisy2/com.atproto.lexicon.schema/page.mooring.site

Version History (3 versions)

Referenced Schemas (1)

Lexicon Garden

@