app.zeens.collection

zeens.app

Documentation

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.

main record

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.

Record Key tid Timestamp-based ID

Properties

animation string Optional

Story-layout scroll animation. 'alternate' fades photos in from alternating sides as they enter the viewport. Respects prefers-reduced-motion. Default 'none'.

Known values: none, alternate
app.zeens.v integer Optional

Zeens marker so the firehose / lua filters can identify our records.

autoApprove boolean Optional

Community collections only: approve every submission at once, whatever the photographer's standing.

community boolean Optional

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.

coverImage blob Optional

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: 4.0 MB
coverPhoto ref #coverPhoto Optional

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.

coverPhotos array of object Optional

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.

maxLength: 4 items
createdAt string datetime Required

An RFC 3339 formatted timestamp.

description string Optional

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 bytes
gridColumns integer Optional

Number of columns when gridLayout='grid'. Allowed: 2 or 3. Default 2.

minimum: 2maximum: 3
gridGap integer Optional

Gap in pixels between photos when gridLayout='grid'. Allowed: 0, 4, 8, or 16. Default 8.

minimum: 0maximum: 16
gridLayout string Optional

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'.

Known values: single, grid
name string Required

Display name for the collection.

maxLength: 100 bytes
publication ref #publication Optional

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.

rules string Optional

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 bytes
showCredit boolean Optional

Show each photo's photographer credit. Defaults to TRUE when absent. Only ever written as false.

showExif boolean Optional

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.

showLicense boolean Optional

Show each photo's licence label. Defaults to TRUE when absent. Only ever written as false.

subtitle string Optional

Short tagline shown under the title in the story layout.

maxLength: 200 bytes
theme string Optional

Background palette for the story layout. Default 'light'.

Known values: light, dark
title string Optional

Long-form display title shown in the story layout. Falls back to `name` when unset.

maxLength: 200 bytes
visibility string Required

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.

Known values: public, private
View raw schema
{
  "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"
}
coverPhoto object

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 string Required

CID of the image blob itself, NOT of the post record.

did string did Required

DID of the photo's author, which owns the blob. May differ from the collection owner.

uri string at-uri Optional

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).

View raw schema
{
  "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"
}
publication object

Pointer to the site.standard.document this collection publishes as, and the Bluesky post announcing it.

Properties

bskyPostRef ref com.atproto.repo.strongRef Optional

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.

canonicalUrl string uri Optional

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.

document string at-uri Required

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.

documentCid string cid Optional

CID of the document, for the strongRef the Bluesky announcement carries.

publishedAt string datetime Optional

An RFC 3339 formatted timestamp.

site string Optional

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.

View raw schema
{
  "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"
}

Lexicon Garden

@