app.zeens.profile
Zeens-specific profile extensions. Stored on the user's own PDS so the data is portable — Zeens reads it on top of app.bsky.actor.profile to render extras like social links. The Bluesky profile (name, avatar, banner, bio) remains the canonical identity.
Details · record, key literal:self
| Kind | record |
|---|---|
| Record key | literal:self |
| Authority | zeens.app |
| Indexed |
Checks
Validunlimited-stringdefs.main.record.properties.$typeNo maxLength, maxGraphemes or format limits this string.field-name-syntaxdefs.main.record.properties.$typeThe field name $type should be letters and digits, starting with a letter.unlimited-stringdefs.socialLink.properties.platformNo maxLength, maxGraphemes or format limits this string.
{
"$type": "com.atproto.lexicon.schema",
"defs": {
"main": {
"description": "Zeens-specific profile extensions. Stored on the user's own PDS so the data is portable — Zeens reads it on top of app.bsky.actor.profile to render extras like social links. The Bluesky profile (name, avatar, banner, bio) remains the canonical identity.",
"key": "literal:self",
"record": {
"properties": {
"$type": {
"const": "app.zeens.profile",
"type": "string"
},
"bio": {
"description": "Zeens-specific bio. Replaces the Bluesky description on Zeens profile pages. Independent from app.bsky.actor.profile.description.",
"maxGraphemes": 256,
"maxLength": 2560,
"type": "string"
},
"socials": {
"description": "The member's profile links, in the order shown. Any https link: services Zeens recognises are stored under their platform id and drawn with that service's icon, everything else as 'link' with the site's own favicon. Capped at 6 entries; order is preserved.",
"items": {
"ref": "#socialLink",
"type": "ref"
},
"maxLength": 6,
"type": "array"
},
"website": {
"description": "LEGACY. A single personal website URL, from before profile links became one list. Readers show it as the first link; Zeens moves it into `socials` (as a 'link') and drops this field the next time the member saves. New writers should not set it.",
"format": "uri",
"maxLength": 200,
"type": "string"
}
},
"required": [],
"type": "object"
},
"type": "record"
},
"socialLink": {
"description": "One profile link.",
"properties": {
"handle": {
"description": "The link's full https URL. Records written before links were URL-only may hold a bare username here (user@instance for Mastodon/Pixelfed).",
"maxLength": 100,
"type": "string"
},
"icon": {
"accept": [
"image/png"
],
"description": "A plain link's favicon, fetched when the link was added and re-encoded as a 64px PNG. Absent = draw a generic link mark.",
"maxSize": 65536,
"type": "blob"
},
"platform": {
"description": "The service the link belongs to, detected from the URL rather than chosen. 'link' is any site Zeens does not recognise. Readers should treat an unknown value as 'link'.",
"knownValues": [
"bluesky",
"mastodon",
"pixelfed",
"flickr",
"glass",
"vsco",
"500px",
"behance",
"youtube",
"kofi",
"patreon",
"grain",
"flashes",
"link"
],
"type": "string"
},
"title": {
"description": "A plain link's site name, read from the site (og:site_name, else its page title) when the link was added. Not member-entered. Absent = show the host. Ignored for recognised services, which show the service's name.",
"maxGraphemes": 80,
"maxLength": 800,
"type": "string"
}
},
"required": [
"platform",
"handle"
],
"type": "object"
}
},
"id": "app.zeens.profile",
"lexicon": 1
}