app.zeens.collection

zeens.app

{
  "$type": "com.atproto.lexicon.schema",
  "defs": {
    "coverPhoto": {
      "description": "Pointer to one photo in the collection, used as its cover. Stores the image blob CID together with the photo's AUTHOR DID (not the collection owner's) so a cover picked from another user's photo still resolves on the CDN. Readers must ignore the pointer unless both `cid` and `did` are present.",
      "properties": {
        "cid": {
          "description": "CID of the image blob itself, NOT of the post record.",
          "type": "string"
        },
        "did": {
          "description": "DID of the photo's author, which owns the blob. May differ from the collection owner.",
          "format": "did",
          "type": "string"
        },
        "uri": {
          "description": "AT-URI of the subject post the cover was picked from. Used to match the pointer against the collection's items (e.g. to clear it when that photo is removed).",
          "format": "at-uri",
          "type": "string"
        }
      },
      "required": [
        "cid",
        "did"
      ],
      "type": "object"
    },
    "main": {
      "description": "A user-curated collection (folder) of Zeens posts and articles. Visibility controls whether anyone other than the owner can see it via the AppView. The cover is the owner's chosen `coverPhoto` when set, otherwise the most recently added item, resolved at render time.",
      "key": "tid",
      "record": {
        "properties": {
          "animation": {
            "description": "Story-layout scroll animation. 'alternate' fades photos in from alternating sides as they enter the viewport. Respects prefers-reduced-motion. Default 'none'.",
            "knownValues": [
              "none",
              "alternate"
            ],
            "type": "string"
          },
          "app.zeens.v": {
            "description": "Zeens marker so the firehose / lua filters can identify our records.",
            "type": "integer"
          },
          "autoApprove": {
            "description": "Community collections only: approve every submission at once, whatever the photographer's standing.",
            "type": "boolean"
          },
          "community": {
            "description": "A community collection: owned by the Zeens account, open to submissions. Only honoured on collections in the configured community account's repo; anyone else setting it changes nothing.",
            "type": "boolean"
          },
          "coverImage": {
            "accept": [
              "image/jpeg",
              "image/png",
              "image/webp"
            ],
            "description": "Legacy user-uploaded cover image, resolved against the OWNER's DID. Superseded by `coverPhoto`; still honoured for records written before it existed. Readers should prefer `coverPhoto` when both are set.",
            "maxSize": 4000000,
            "type": "blob"
          },
          "coverPhoto": {
            "description": "Optional pointer to one photo already in this collection, chosen by the owner as its cover. When unset, readers fall back to the most recently added photo.",
            "ref": "#coverPhoto",
            "type": "ref"
          },
          "coverPhotos": {
            "description": "Community collections only: up to four photos from the collection shown together as its cover, in order. Each carries the photo's image blob cid and author DID so it resolves on the CDN, like coverPhoto.",
            "items": {
              "properties": {
                "cid": {
                  "description": "Image blob CID.",
                  "type": "string"
                },
                "did": {
                  "format": "did",
                  "type": "string"
                },
                "uri": {
                  "format": "at-uri",
                  "type": "string"
                }
              },
              "required": [
                "uri",
                "cid",
                "did"
              ],
              "type": "object"
            },
            "maxLength": 4,
            "type": "array"
          },
          "createdAt": {
            "format": "datetime",
            "type": "string"
          },
          "description": {
            "description": "Optional long-form description shown in the story layout's left rail and used as the collection's meta description for share previews.",
            "maxLength": 2000,
            "type": "string"
          },
          "gridColumns": {
            "description": "Number of columns when gridLayout='grid'. Allowed: 2 or 3. Default 2.",
            "maximum": 3,
            "minimum": 2,
            "type": "integer"
          },
          "gridGap": {
            "description": "Gap in pixels between photos when gridLayout='grid'. Allowed: 0, 4, 8, or 16. Default 8.",
            "maximum": 16,
            "minimum": 0,
            "type": "integer"
          },
          "gridLayout": {
            "description": "How photos stack in the portfolio view. Both options preserve natural aspect ratio (no cropping). 'single' = one column at full width. 'grid' = masonry grid; column count + gap are controlled by `gridColumns` and `gridGap`. Default 'single'.",
            "knownValues": [
              "single",
              "grid"
            ],
            "type": "string"
          },
          "name": {
            "description": "Display name for the collection.",
            "maxLength": 100,
            "type": "string"
          },
          "publication": {
            "description": "Set once this collection has been published to the ATmosphere as a site.standard.document. Absent means never published. Cleared (and the document deleted) if the collection is later made private.",
            "ref": "#publication",
            "type": "ref"
          },
          "rules": {
            "description": "Community collections only: the theme and rules a photo has to meet. Shown on the collection page; a declined submission means the photo did not meet them.",
            "maxLength": 3000,
            "type": "string"
          },
          "showCredit": {
            "description": "Show each photo's photographer credit. Defaults to TRUE when absent. Only ever written as false.",
            "type": "boolean"
          },
          "showExif": {
            "description": "Show each photo's camera settings (or its film stock) beneath it in the single-column story layout. Defaults to TRUE when absent: attribution is opt-out, so a record written before this field existed keeps its full caption. Only ever written as false.",
            "type": "boolean"
          },
          "showLicense": {
            "description": "Show each photo's licence label. Defaults to TRUE when absent. Only ever written as false.",
            "type": "boolean"
          },
          "subtitle": {
            "description": "Short tagline shown under the title in the story layout.",
            "maxLength": 200,
            "type": "string"
          },
          "theme": {
            "description": "Background palette for the story layout. Default 'light'.",
            "knownValues": [
              "light",
              "dark"
            ],
            "type": "string"
          },
          "title": {
            "description": "Long-form display title shown in the story layout. Falls back to `name` when unset.",
            "maxLength": 200,
            "type": "string"
          },
          "visibility": {
            "description": "public = visible to anyone via the AppView. private = only the owner can fetch it via getCollection. Records remain readable from the user's PDS by anyone who knows the URI; treat 'private' as obscurity-level, not cryptographic.",
            "knownValues": [
              "public",
              "private"
            ],
            "type": "string"
          }
        },
        "required": [
          "name",
          "visibility",
          "createdAt"
        ],
        "type": "object"
      },
      "type": "record"
    },
    "publication": {
      "description": "Pointer to the site.standard.document this collection publishes as, and the Bluesky post announcing it.",
      "properties": {
        "bskyPostRef": {
          "description": "The Bluesky post announcing this collection, when the owner chose to announce. Kept so the announcement can be found later; it does NOT suppress re-announcing, since ticking the box is an explicit request each time.",
          "ref": "com.atproto.repo.strongRef",
          "type": "ref"
        },
        "canonicalUrl": {
          "description": "The public address on the owner's portfolio, e.g. https://alice.zeens.app/<rkey>. The document's `site` + `path` resolve to this, and it is the host that serves the /.well-known/site.standard.publication proof. Stored so the collection page canonicalises to what the record actually says.",
          "format": "uri",
          "type": "string"
        },
        "document": {
          "description": "AT-URI of the site.standard.document on the owner's repo. Re-publishing reuses this record's rkey so the document is updated in place rather than duplicated.",
          "format": "at-uri",
          "type": "string"
        },
        "documentCid": {
          "description": "CID of the document, for the strongRef the Bluesky announcement carries.",
          "format": "cid",
          "type": "string"
        },
        "publishedAt": {
          "format": "datetime",
          "type": "string"
        },
        "site": {
          "description": "The document's `site`: a publication AT-URI. Collections publish INTO the owner's site.standard.publication (auto-created on first publish) because only an at:// ref renders the rich standard.site card on Bluesky. Older records may carry a plain https URL from when collections published as loose documents.",
          "type": "string"
        }
      },
      "required": [
        "document"
      ],
      "type": "object"
    }
  },
  "id": "app.zeens.collection",
  "lexicon": 1
}

Validate Record

Validate a record against app.zeens.collection

Validation Options
Treat any remaining unresolved references as valid

Metadata

DID
did:plc:pwpuqwge6g7xrjmfbw73uycw
CID
bafyreiduiodwfgbmgsjgttg35f63a2ipi4c6i5yn4btzjbmc7jo5ud2rvi
Indexed At
2026-10-22 16:31 UTC
AT-URI
at://did:plc:pwpuqwge6g7xrjmfbw73uycw/com.atproto.lexicon.schema/app.zeens.collection

Similar Lexicons

Lexicons whose schemas describe something close to this one. Check them before publishing a new one that overlaps.

  • A single item (post or article) inside a Zeens collection. The collection itself is referenced by its AT-URI. Removing an item is a record delete. Re-adding the same subject creates a new item record (clients should de-…

  • A zeen: a sequence of 1:1.414 pages (ISO A-series proportion) mixing photographs and writing, published as a readable object. Pages may draw photos from a collection, from individual posts, or from the author's own uplo…

  • Configuration for a user's public Portfolio site (e.g. alice.zeens.app). One per user, keyed 'self'. A portfolio is a curated list of the user's COLLECTIONS, displayed beautifully: it holds the subdomain, a theme + layo…

  • ATPix album container. Maps to schema:ImageGallery / schema:Collection conceptually.

  • art.cllctv.core.collection recordnot from the namespace authority

Lexicon Garden

@