Lexicons
Published AT Proto record schemas for reader state in each user's PDS.
Overview
Standard Reader owns the app.standard-reader.* namespace. These lexicons describe repo records — bookmarks, read state, lists, and related shared definitions. AppView XRPC queries and procedures are documented on /docs/api.
Namespace
Authority for app.standard-reader resolves via DNS _lexicon.* TXT records to the publishing account.
9 shared schema definitions for AppView responses and unions.
Definitions
| Name | Type |
|---|---|
| publicationView | object |
| documentView | object |
| profileView | object |
| cursorPagePublications | object |
| cursorPageDocuments | object |
| resolveViewArticle | object |
| resolveViewPublication | object |
| resolveViewReaderLink | object |
| resolveViewUnknown | object |
{ "lexicon": 1, "id": "app.standard-reader.defs", "defs": { "publicationView": { "type": "object", "description": "A publication as shown in directory cards and profile headers.", "required": [ "uri", "did", "name", "url", "subscriberCount", "documentCount" ], "properties": { "uri": { "type": "string", "format": "at-uri" }, "did": { "type": "string", "format": "did" }, "name": { "type": "string", "maxLength": 128 }, "url": { "type": "string", "format": "uri" }, "description": { "type": "string", "nullable": true, "maxLength": 4096 }, "iconUrl": { "type": "string", "format": "uri", "nullable": true }, "ownerAvatarUrl": { "type": "string", "format": "uri", "nullable": true }, "ownerHandle": { "type": "string", "nullable": true, "maxLength": 128 }, "topic": { "type": "string", "nullable": true, "maxLength": 128 }, "verified": { "type": "boolean" }, "subscriberCount": { "type": "integer" }, "documentCount": { "type": "integer" }, "lastDocumentAt": { "type": "string", "format": "datetime", "nullable": true }, "searchNameHtml": { "type": "string", "nullable": true, "maxLength": 512 }, "searchSnippetHtml": { "type": "string", "nullable": true, "maxLength": 8192 } } }, "documentView": { "type": "object", "description": "An article as shown in feed rows and search results (metadata only).", "required": [ "uri", "did", "title", "publishedAt", "recommendCount", "commentCount", "hasRenderableBody", "isRead" ], "properties": { "uri": { "type": "string", "format": "at-uri" }, "did": { "type": "string", "format": "did" }, "title": { "type": "string", "maxLength": 512 }, "description": { "type": "string", "nullable": true, "maxLength": 4096 }, "path": { "type": "string", "nullable": true, "maxLength": 2048 }, "canonicalUrl": { "type": "string", "format": "uri", "nullable": true }, "coverImageUrl": { "type": "string", "format": "uri", "nullable": true }, "publishedAt": { "type": "string", "format": "datetime" }, "featured": { "type": "boolean" }, "publicationUri": { "type": "string", "format": "at-uri", "nullable": true }, "publicationName": { "type": "string", "nullable": true, "maxLength": 128 }, "publicationIconUrl": { "type": "string", "format": "uri", "nullable": true }, "publicationOwnerAvatarUrl": { "type": "string", "format": "uri", "nullable": true }, "publicationOwnerHandle": { "type": "string", "nullable": true, "maxLength": 128 }, "publicationBannerUrl": { "type": "string", "format": "uri", "nullable": true }, "publicationTopic": { "type": "string", "nullable": true, "maxLength": 128 }, "tags": { "type": "array", "items": { "type": "string", "maxLength": 128 }, "nullable": true }, "recommendCount": { "type": "integer" }, "commentCount": { "type": "integer" }, "hasRenderableBody": { "type": "boolean" }, "isRead": { "type": "boolean" }, "searchTitleHtml": { "type": "string", "nullable": true, "maxLength": 1024 }, "searchSnippetHtml": { "type": "string", "nullable": true, "maxLength": 8192 } } }, "profileView": { "type": "object", "required": [ "did" ], "properties": { "did": { "type": "string", "format": "did" }, "handle": { "type": "string", "nullable": true, "maxLength": 128 }, "displayName": { "type": "string", "nullable": true, "maxLength": 128 }, "description": { "type": "string", "nullable": true, "maxLength": 4096 }, "avatarUrl": { "type": "string", "format": "uri", "nullable": true }, "bannerUrl": { "type": "string", "format": "uri", "nullable": true } } }, "cursorPagePublications": { "type": "object", "required": [ "items" ], "properties": { "cursor": { "type": "string", "nullable": true, "maxLength": 8192 }, "items": { "type": "array", "items": { "type": "ref", "ref": "app.standard-reader.defs#publicationView" } } } }, "cursorPageDocuments": { "type": "object", "required": [ "items" ], "properties": { "cursor": { "type": "string", "nullable": true, "maxLength": 8192 }, "items": { "type": "array", "items": { "type": "ref", "ref": "app.standard-reader.defs#documentView" } } } }, "resolveViewArticle": { "type": "object", "required": [ "kind", "documentUri", "title", "readerUrl", "recommendCount", "commentCount" ], "properties": { "kind": { "type": "string", "const": "article", "maxLength": 64 }, "documentUri": { "type": "string", "format": "at-uri" }, "title": { "type": "string", "maxLength": 512 }, "publicationUri": { "type": "string", "format": "at-uri", "nullable": true }, "publicationName": { "type": "string", "nullable": true, "maxLength": 128 }, "publicationHandle": { "type": "string", "nullable": true, "maxLength": 128 }, "publicationIconUrl": { "type": "string", "format": "uri", "nullable": true }, "publicationOwnerAvatarUrl": { "type": "string", "format": "uri", "nullable": true }, "publicationSubscriberCount": { "type": "integer", "nullable": true }, "publicationReaderUrl": { "type": "string", "format": "uri", "nullable": true }, "publishedAt": { "type": "string", "format": "datetime", "nullable": true }, "readingMinutes": { "type": "integer", "nullable": true }, "authorName": { "type": "string", "nullable": true, "maxLength": 128 }, "authorHandle": { "type": "string", "nullable": true, "maxLength": 128 }, "authorAvatarUrl": { "type": "string", "format": "uri", "nullable": true }, "readerUrl": { "type": "string", "format": "uri" }, "canonicalUrl": { "type": "string", "format": "uri", "nullable": true }, "isBookmarked": { "type": "boolean" }, "isRead": { "type": "boolean" }, "isFollowing": { "type": "boolean" }, "recommendCount": { "type": "integer" }, "commentCount": { "type": "integer" } } }, "resolveViewPublication": { "type": "object", "required": [ "kind", "publicationUri", "name", "readerUrl" ], "properties": { "kind": { "type": "string", "const": "publication", "maxLength": 64 }, "publicationUri": { "type": "string", "format": "at-uri" }, "name": { "type": "string", "maxLength": 128 }, "description": { "type": "string", "nullable": true, "maxLength": 4096 }, "handle": { "type": "string", "nullable": true, "maxLength": 128 }, "iconUrl": { "type": "string", "format": "uri", "nullable": true }, "ownerAvatarUrl": { "type": "string", "format": "uri", "nullable": true }, "subscriberCount": { "type": "integer", "nullable": true }, "readerUrl": { "type": "string", "format": "uri" }, "siteUrl": { "type": "string", "format": "uri", "nullable": true }, "isFollowing": { "type": "boolean" } } }, "resolveViewReaderLink": { "type": "object", "required": [ "kind", "readerUrl" ], "properties": { "kind": { "type": "string", "const": "reader-link", "maxLength": 64 }, "readerUrl": { "type": "string", "format": "uri", "maxLength": 2048 } } }, "resolveViewUnknown": { "type": "object", "required": [ "kind" ], "properties": { "kind": { "type": "string", "const": "unknown", "maxLength": 64 } } } } }
2 shared schema definitions for AppView responses and unions.
Definitions
| Name | Type |
|---|---|
| labelerPolicies | object |
| labelerView | object |
{ "lexicon": 1, "id": "app.standard-reader.labeler.defs", "defs": { "labelerPolicies": { "type": "object", "required": [ "labelValues" ], "properties": { "labelValues": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#labelValue" }, "description": "The label values which this labeler publishes. May include global or custom (labeler-defined) values." }, "labelValueDefinitions": { "type": "array", "items": { "type": "ref", "ref": "com.atproto.label.defs#labelValueDefinition" }, "description": "Label values created by this labeler and scoped exclusively to it. Each value provides its own meaning and behaviors." } } }, "labelerView": { "type": "object", "required": [ "did" ], "properties": { "did": { "type": "string", "format": "did" }, "displayName": { "type": "string", "maxGraphemes": 64, "maxLength": 640 }, "description": { "type": "string", "maxGraphemes": 300, "maxLength": 3000 }, "avatar": { "type": "string", "format": "uri" }, "policies": { "type": "ref", "ref": "#labelerPolicies" }, "indexedAt": { "type": "string", "format": "datetime" } } } } }
Records
PDS records · 12 schemasMarks a site.standard.document as saved for later by the reader. Presence of the record means saved; deleting it removes the article from the save queue.
Fields
| Name | Type |
|---|---|
| subject*AT URI of the site.standard.document record to save. | string · at-uri |
| createdAt*When the reader saved the article. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.bookmark", "defs": { "main": { "type": "record", "description": "Marks a site.standard.document as saved for later by the reader. Presence of the record means saved; deleting it removes the article from the save queue.", "key": "any", "record": { "type": "object", "required": [ "subject", "createdAt" ], "properties": { "subject": { "type": "string", "format": "at-uri", "description": "AT URI of the site.standard.document record to save." }, "createdAt": { "type": "string", "format": "datetime", "description": "When the reader saved the article." } } } } } }
Curated magazine collection manifest for a site.standard.document. Uses the same record key as the document it extends so both records can be fetched with one predictable pair of GETs.
Fields
| Name | Type |
|---|---|
| document*AT URI of the site.standard.document record this collection renders. | string · at-uri |
| editorial | app.standard-reader.collection#editorial |
| colophon | app.standard-reader.collection#colophon |
| items*Ordered curated articles plus optional per-item notes. | app.standard-reader.collection#item[] |
| createdAt*When the collection manifest was first published. | string · datetime |
| updatedAtWhen the collection manifest was last edited. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.collection", "defs": { "main": { "type": "record", "description": "Curated magazine collection manifest for a site.standard.document. Uses the same record key as the document it extends so both records can be fetched with one predictable pair of GETs.", "key": "any", "record": { "type": "object", "required": [ "document", "items", "createdAt" ], "properties": { "document": { "type": "string", "format": "at-uri", "description": "AT URI of the site.standard.document record this collection renders." }, "editorial": { "type": "ref", "ref": "app.standard-reader.collection#editorial" }, "colophon": { "type": "ref", "ref": "app.standard-reader.collection#colophon" }, "items": { "type": "array", "maxLength": 42, "items": { "type": "ref", "ref": "app.standard-reader.collection#item" }, "description": "Ordered curated articles plus optional per-item notes." }, "createdAt": { "type": "string", "format": "datetime", "description": "When the collection manifest was first published." }, "updatedAt": { "type": "string", "format": "datetime", "description": "When the collection manifest was last edited." } } } }, "editorial": { "type": "object", "description": "Optional editorial intro shown ahead of the curated pieces.", "properties": { "title": { "type": "string", "maxLength": 160 }, "body": { "type": "union", "refs": [ "at.markpub.markdown" ], "description": "Editorial body as Markpub markdown (legacy plain string accepted on read during migration)." } } }, "colophon": { "type": "object", "description": "Optional closing credits on the magazine end spread.", "properties": { "body": { "type": "union", "refs": [ "at.markpub.markdown" ], "description": "Colophon body as Markpub markdown (legacy plain string accepted on read during migration)." } } }, "item": { "type": "object", "required": [ "document" ], "properties": { "document": { "type": "string", "format": "at-uri", "description": "AT URI of an included site.standard.document." }, "note": { "type": "union", "refs": [ "at.markpub.markdown" ], "description": "Optional Markpub markdown note shown ahead of the piece (legacy plain string accepted on read during migration)." } } }, "documentLink": { "type": "object", "required": [ "uri" ], "description": "Inverse link entry for site.standard.document#links pointing back at this collection sidecar.", "properties": { "uri": { "type": "string", "format": "at-uri", "description": "AT URI of the app.standard-reader.collection sidecar record." } } } } }
Marks a site.standard.publication as a Standard Reader collections series. Uses the same record key as the publication it marks.
Fields
| Name | Type |
|---|---|
| publication*AT URI of the site.standard.publication record used to publish collections. | string · at-uri |
| createdAt*When this publication was marked as a collections series. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.collectionsPublication", "defs": { "main": { "type": "record", "description": "Marks a site.standard.publication as a Standard Reader collections series. Uses the same record key as the publication it marks.", "key": "any", "record": { "type": "object", "required": [ "publication", "createdAt" ], "properties": { "publication": { "type": "string", "format": "at-uri", "description": "AT URI of the site.standard.publication record used to publish collections." }, "createdAt": { "type": "string", "format": "datetime", "description": "When this publication was marked as a collections series." } } } } } }
Follows another user (a DID, not a publication). Presence of the record means followed; deleting it unfollows. The rkey is derived from the subject DID so each followed user maps to a single record. A followed user's recommends and documents enrich the reader's home feed.
Fields
| Name | Type |
|---|---|
| subject*DID of the user being followed. | string · did |
| excludedPublicationsPublications owned by the followed user that the reader has explicitly opted out of (following a user subscribes to all their publications except these). AT URIs of site.standard.publication records. | at-uri[] |
| createdAt*When the reader followed the user. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.graph.follow", "defs": { "main": { "type": "record", "description": "Follows another user (a DID, not a publication). Presence of the record means followed; deleting it unfollows. The rkey is derived from the subject DID so each followed user maps to a single record. A followed user's recommends and documents enrich the reader's home feed.", "key": "any", "record": { "type": "object", "required": [ "subject", "createdAt" ], "properties": { "subject": { "type": "string", "format": "did", "description": "DID of the user being followed." }, "excludedPublications": { "type": "array", "maxLength": 1000, "items": { "type": "string", "format": "at-uri" }, "description": "Publications owned by the followed user that the reader has explicitly opted out of (following a user subscribes to all their publications except these). AT URIs of site.standard.publication records." }, "createdAt": { "type": "string", "format": "datetime", "description": "When the reader followed the user." } } } } } }
Registers a Standard Reader labeler. This record is the single source of truth for a labeler: its identity, where to reach its label server, how it presents, and its label-value definitions. Indexed off the network like any other record (the owner of the record is the labeler's author); the label server itself only answers com.atproto.label.queryLabels / subscribeLabels.
Fields
| Name | Type |
|---|---|
| did*DID of the labeler — the `src` on its labels (and whose key signs them). | string · did |
| serviceEndpoint*Origin serving this labeler's com.atproto.label.queryLabels / subscribeLabels. | string · uri |
| displayName | string |
| description | string |
| avatar | blob |
| policies | app.standard-reader.labeler.defs#labelerPolicies |
| createdAt* | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.labeler.service", "defs": { "main": { "type": "record", "description": "Registers a Standard Reader labeler. This record is the single source of truth for a labeler: its identity, where to reach its label server, how it presents, and its label-value definitions. Indexed off the network like any other record (the owner of the record is the labeler's author); the label server itself only answers com.atproto.label.queryLabels / subscribeLabels.", "key": "tid", "record": { "type": "object", "required": [ "did", "serviceEndpoint", "createdAt" ], "properties": { "did": { "type": "string", "format": "did", "description": "DID of the labeler — the `src` on its labels (and whose key signs them)." }, "serviceEndpoint": { "type": "string", "format": "uri", "description": "Origin serving this labeler's com.atproto.label.queryLabels / subscribeLabels." }, "displayName": { "type": "string", "maxGraphemes": 64, "maxLength": 640 }, "description": { "type": "string", "maxGraphemes": 300, "maxLength": 3000 }, "avatar": { "type": "blob", "accept": [ "image/png", "image/jpeg", "image/svg+xml" ], "maxSize": 1000000 }, "policies": { "type": "ref", "ref": "app.standard-reader.labeler.defs#labelerPolicies" }, "createdAt": { "type": "string", "format": "datetime" } } } } } }
Subscribes the reader to a labeler service (like adding a Bluesky moderation service). Presence of the record means subscribed; deleting it unsubscribes. The rkey is derived from the labeler DID so each labeler maps to a single record. Successor to app.standard-reader.labelerSubscription, nested under the labeler NSID group.
Fields
| Name | Type |
|---|---|
| labeler*DID of the labeler service being subscribed to. | string · did |
| labelsPer-label visibility overrides for this labeler's label values. | #labelPref[] |
| createdAt*When the reader subscribed to the labeler. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.labeler.subscription", "defs": { "main": { "type": "record", "description": "Subscribes the reader to a labeler service (like adding a Bluesky moderation service). Presence of the record means subscribed; deleting it unsubscribes. The rkey is derived from the labeler DID so each labeler maps to a single record. Successor to app.standard-reader.labelerSubscription, nested under the labeler NSID group.", "key": "any", "record": { "type": "object", "required": [ "labeler", "createdAt" ], "properties": { "labeler": { "type": "string", "format": "did", "description": "DID of the labeler service being subscribed to." }, "labels": { "type": "array", "description": "Per-label visibility overrides for this labeler's label values.", "items": { "type": "ref", "ref": "#labelPref" } }, "createdAt": { "type": "string", "format": "datetime", "description": "When the reader subscribed to the labeler." } } } }, "labelPref": { "type": "object", "description": "How the reader wants a single label value from this labeler treated.", "required": [ "val", "visibility" ], "properties": { "val": { "type": "string", "maxLength": 128, "description": "The label value this preference applies to." }, "visibility": { "type": "string", "maxLength": 16, "knownValues": [ "ignore", "warn", "hide" ], "description": "ignore = show normally; warn = content warning / blur; hide = filter out." } } } } }
Subscribes the reader to a labeler service (like adding a Bluesky moderation service). Presence of the record means subscribed; deleting it unsubscribes. The rkey is derived from the labeler DID so each labeler maps to a single record.
Fields
| Name | Type |
|---|---|
| labeler*DID of the labeler service being subscribed to. | string · did |
| labelsPer-label visibility overrides for this labeler's label values. | #labelPref[] |
| createdAt*When the reader subscribed to the labeler. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.labelerSubscription", "defs": { "main": { "type": "record", "description": "Subscribes the reader to a labeler service (like adding a Bluesky moderation service). Presence of the record means subscribed; deleting it unsubscribes. The rkey is derived from the labeler DID so each labeler maps to a single record.", "key": "any", "record": { "type": "object", "required": [ "labeler", "createdAt" ], "properties": { "labeler": { "type": "string", "format": "did", "description": "DID of the labeler service being subscribed to." }, "labels": { "type": "array", "description": "Per-label visibility overrides for this labeler's label values.", "items": { "type": "ref", "ref": "#labelPref" } }, "createdAt": { "type": "string", "format": "datetime", "description": "When the reader subscribed to the labeler." } } } }, "labelPref": { "type": "object", "description": "How the reader wants a single label value from this labeler treated.", "required": [ "val", "visibility" ], "properties": { "val": { "type": "string", "maxLength": 128, "description": "The label value this preference applies to." }, "visibility": { "type": "string", "maxLength": 16, "knownValues": [ "ignore", "warn", "hide" ], "description": "ignore = show normally; warn = content warning / blur; hide = filter out." } } } } }
A named, ordered, shareable list of publications (like a Bluesky user list, but for site.standard.publication subscriptions). Lists are one level deep; a publication may appear in multiple lists.
Fields
| Name | Type |
|---|---|
| name*Display name of the list. | string |
| descriptionOptional description shown on the list's public page. | string |
| publications*Ordered AT URIs of the site.standard.publication records in this list. | at-uri[] |
| usersOrdered DIDs of the users (authors) in this list. Optional; a list may hold publications, users, or both. | did[] |
| createdAt*When the list was created. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.list", "defs": { "main": { "type": "record", "description": "A named, ordered, shareable list of publications (like a Bluesky user list, but for site.standard.publication subscriptions). Lists are one level deep; a publication may appear in multiple lists.", "key": "tid", "record": { "type": "object", "required": [ "name", "publications", "createdAt" ], "properties": { "name": { "type": "string", "maxLength": 640, "maxGraphemes": 64, "description": "Display name of the list." }, "description": { "type": "string", "maxLength": 3000, "maxGraphemes": 300, "description": "Optional description shown on the list's public page." }, "publications": { "type": "array", "maxLength": 500, "items": { "type": "string", "format": "at-uri" }, "description": "Ordered AT URIs of the site.standard.publication records in this list." }, "users": { "type": "array", "maxLength": 500, "items": { "type": "string", "format": "did" }, "description": "Ordered DIDs of the users (authors) in this list. Optional; a list may hold publications, users, or both." }, "createdAt": { "type": "string", "format": "datetime", "description": "When the list was created." } } } } } }
Saves another reader's app.standard-reader.list into this reader's app (like adding a Bluesky list). Presence of the record means saved; deleting it removes the list again.
Fields
| Name | Type |
|---|---|
| list*AT URI of the app.standard-reader.list record being saved. | string · at-uri |
| createdAt*When the list was saved. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.listSave", "defs": { "main": { "type": "record", "description": "Saves another reader's app.standard-reader.list into this reader's app (like adding a Bluesky list). Presence of the record means saved; deleting it removes the list again.", "key": "any", "record": { "type": "object", "required": [ "list", "createdAt" ], "properties": { "list": { "type": "string", "format": "at-uri", "description": "AT URI of the app.standard-reader.list record being saved." }, "createdAt": { "type": "string", "format": "datetime", "description": "When the list was saved." } } } } } }
Standard Reader typography for a collections publication. Uses the same record key as the publication. Colors remain on the publication's site.standard.theme.basic record.
Fields
| Name | Type |
|---|---|
| publication*AT URI of the site.standard.publication this theme applies to. | string · at-uri |
| fonts | app.standard-reader.publicationTheme#fonts |
| createdAt*When the theme record was first published. | string · datetime |
| updatedAtWhen the theme record was last edited. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.publicationTheme", "defs": { "main": { "type": "record", "description": "Standard Reader typography for a collections publication. Uses the same record key as the publication. Colors remain on the publication's site.standard.theme.basic record.", "key": "any", "record": { "type": "object", "required": [ "publication", "createdAt" ], "properties": { "publication": { "type": "string", "format": "at-uri", "description": "AT URI of the site.standard.publication this theme applies to." }, "fonts": { "type": "ref", "ref": "app.standard-reader.publicationTheme#fonts" }, "createdAt": { "type": "string", "format": "datetime", "description": "When the theme record was first published." }, "updatedAt": { "type": "string", "format": "datetime", "description": "When the theme record was last edited." } } } }, "fonts": { "type": "object", "description": "Google Font family names for collection title and body typography.", "properties": { "title": { "type": "string", "maxLength": 60 }, "body": { "type": "string", "maxLength": 60 } } } } }
Marks a site.standard.document as read by the reader. Presence of the record means read; deleting it marks the article unread again.
Fields
| Name | Type |
|---|---|
| subject*AT URI of the site.standard.document record that was read. | string · at-uri |
| createdAt*When the reader opened / marked the article read. | string · datetime |
{ "lexicon": 1, "id": "app.standard-reader.read", "defs": { "main": { "type": "record", "description": "Marks a site.standard.document as read by the reader. Presence of the record means read; deleting it marks the article unread again.", "key": "any", "record": { "type": "object", "required": [ "subject", "createdAt" ], "properties": { "subject": { "type": "string", "format": "at-uri", "description": "AT URI of the site.standard.document record that was read." }, "createdAt": { "type": "string", "format": "datetime", "description": "When the reader opened / marked the article read." } } } } } }