community.gifthood.feed.defs

gifthood.community

Documentation

activityView object

One row of the viewer's activity feed: an outgoing interest the viewer raised on someone's listing, an incoming raised hand on the viewer's own listing, or a neighbor who followed the viewer (carries 'followers' instead of 'listing').

Properties

createdAt string datetime Required

When this activity event was created — the newest-first merge/sort key across all activity kinds (interest, hand, follow).

followers array of refcommunity.gifthood.actor.defs#profileView Optional

The neighbor(s) who followed the viewer. Present only on 'follow' rows; followers[0] is the primary actor, length > 1 is a grouped card. Each row carries its own viewer state (the inline follow-back button reads viewer.following).

isFollowBack boolean Optional

Order-sensitive reciprocity: true when the viewer followed this actor first and they reciprocated. Server-computed; meaningful only on single (ungrouped) 'follow' rows.

kind string Required

Row kind — 'interest' = the viewer raised their hand on someone's listing (outgoing); 'hand' = a neighbor raised their hand on the viewer's listing (incoming). Open set (knownValues, not a closed enum): future kinds extend without a breaking change. 'follow' = a neighbor followed the viewer (incoming social signal; carries 'followers' instead of 'listing'). Exchange kinds (all carry 'listing' + 'neighbor' = the other party): 'exchangeChosen'/'exchangeCompleted' for the counterparty, 'exchangeConfirmed'/'exchangeDeclined' for the listing owner. 'exchangeReturned' = the owner marked the item the viewer borrowed as returned (incoming). 'reply' = a neighbor left a note on the viewer's listing (incoming; carries 'listing' + 'neighbor' + 'note'; hidden notes and the note author's own listing never produce a row).

Known values: interest, hand, follow, exchangeChosen, exchangeCompleted, exchangeConfirmed, exchangeDeclined, exchangeReturned, reply
listing ref #listingView Optional

The listing this activity is about (full listingView; carries the moderation signal the outgoing-row gate reads). Absent on 'follow' rows.

neighbor ref community.gifthood.actor.defs#profileViewBasic Optional

The other member this row is about. Present on 'hand' rows (the neighbor who raised their hand), 'reply' rows (the note's author), and on exchange rows (the other party of the exchange); absent on 'interest' rows.

note string Optional

The interest's note/message — the viewer's own on an 'interest' row, the neighbor's on a 'hand' row (the same underlying interests.message field), or the note's text on a 'reply' row (replies.text). Absent when none left.

View raw schema
{
  "type": "object",
  "required": [
    "kind",
    "createdAt"
  ],
  "properties": {
    "kind": {
      "type": "string",
      "description": "Row kind — 'interest' = the viewer raised their hand on someone's listing (outgoing); 'hand' = a neighbor raised their hand on the viewer's listing (incoming). Open set (knownValues, not a closed enum): future kinds extend without a breaking change. 'follow' = a neighbor followed the viewer (incoming social signal; carries 'followers' instead of 'listing'). Exchange kinds (all carry 'listing' + 'neighbor' = the other party): 'exchangeChosen'/'exchangeCompleted' for the counterparty, 'exchangeConfirmed'/'exchangeDeclined' for the listing owner. 'exchangeReturned' = the owner marked the item the viewer borrowed as returned (incoming). 'reply' = a neighbor left a note on the viewer's listing (incoming; carries 'listing' + 'neighbor' + 'note'; hidden notes and the note author's own listing never produce a row).",
      "knownValues": [
        "interest",
        "hand",
        "follow",
        "exchangeChosen",
        "exchangeCompleted",
        "exchangeConfirmed",
        "exchangeDeclined",
        "exchangeReturned",
        "reply"
      ]
    },
    "note": {
      "type": "string",
      "description": "The interest's note/message — the viewer's own on an 'interest' row, the neighbor's on a 'hand' row (the same underlying interests.message field), or the note's text on a 'reply' row (replies.text). Absent when none left."
    },
    "listing": {
      "ref": "#listingView",
      "type": "ref",
      "description": "The listing this activity is about (full listingView; carries the moderation signal the outgoing-row gate reads). Absent on 'follow' rows."
    },
    "neighbor": {
      "ref": "community.gifthood.actor.defs#profileViewBasic",
      "type": "ref",
      "description": "The other member this row is about. Present on 'hand' rows (the neighbor who raised their hand), 'reply' rows (the note's author), and on exchange rows (the other party of the exchange); absent on 'interest' rows."
    },
    "createdAt": {
      "type": "string",
      "format": "datetime",
      "description": "When this activity event was created — the newest-first merge/sort key across all activity kinds (interest, hand, follow)."
    },
    "followers": {
      "type": "array",
      "items": {
        "ref": "community.gifthood.actor.defs#profileView",
        "type": "ref"
      },
      "description": "The neighbor(s) who followed the viewer. Present only on 'follow' rows; followers[0] is the primary actor, length > 1 is a grouped card. Each row carries its own viewer state (the inline follow-back button reads viewer.following)."
    },
    "isFollowBack": {
      "type": "boolean",
      "description": "Order-sensitive reciprocity: true when the viewer followed this actor first and they reciprocated. Server-computed; meaningful only on single (ungrouped) 'follow' rows."
    }
  },
  "description": "One row of the viewer's activity feed: an outgoing interest the viewer raised on someone's listing, an incoming raised hand on the viewer's own listing, or a neighbor who followed the viewer (carries 'followers' instead of 'listing')."
}
exchangeCounterpartyView object

The non-listing-owner exchange party's resolved identity.

Properties

did string did Required

DID of the counterparty.

displayName string Optional

Real display name. Absent when none set.

maxLength: 640 bytesmaxGraphemes: 64 graphemes
handle string handle Optional

Live-resolved handle (without leading @). Absent when unresolvable.

View raw schema
{
  "type": "object",
  "required": [
    "did"
  ],
  "properties": {
    "did": {
      "type": "string",
      "format": "did",
      "description": "DID of the counterparty."
    },
    "handle": {
      "type": "string",
      "format": "handle",
      "description": "Live-resolved handle (without leading @). Absent when unresolvable."
    },
    "displayName": {
      "type": "string",
      "maxLength": 640,
      "description": "Real display name. Absent when none set.",
      "maxGraphemes": 64
    }
  },
  "description": "The non-listing-owner exchange party's resolved identity."
}
exchangeView object

The active exchange on a listing, flattened with the counterparty's resolved identity.

Properties

cid string cid Required

CID of the exchange record.

completedAt string datetime Optional

When the giver marked the gift complete — the item handed over or the service rendered. Absent until then.

createdAt string datetime Required

When the exchange record was created.

giverDid string did Required

DID of the party giving the item.

listingUri string at-uri Required

AT-URI of the listing this exchange is for.

receiverDid string did Required

DID of the party receiving the item.

respondedAt string datetime Optional

When the counterparty confirmed or declined. Absent until they respond.

returnedAt string datetime Optional

When the owner marked the lent item returned. Absent until then; only present on lend-listing exchanges.

state string Required

Derived exchange state. Open set (knownValues, not a closed enum).

Known values: pending, completed, confirmed, declined
uri string at-uri Required

AT-URI of the exchange record.

View raw schema
{
  "type": "object",
  "required": [
    "uri",
    "cid",
    "listingUri",
    "giverDid",
    "receiverDid",
    "counterparty",
    "state",
    "createdAt"
  ],
  "properties": {
    "cid": {
      "type": "string",
      "format": "cid",
      "description": "CID of the exchange record."
    },
    "uri": {
      "type": "string",
      "format": "at-uri",
      "description": "AT-URI of the exchange record."
    },
    "state": {
      "type": "string",
      "description": "Derived exchange state. Open set (knownValues, not a closed enum).",
      "knownValues": [
        "pending",
        "completed",
        "confirmed",
        "declined"
      ]
    },
    "giverDid": {
      "type": "string",
      "format": "did",
      "description": "DID of the party giving the item."
    },
    "createdAt": {
      "type": "string",
      "format": "datetime",
      "description": "When the exchange record was created."
    },
    "listingUri": {
      "type": "string",
      "format": "at-uri",
      "description": "AT-URI of the listing this exchange is for."
    },
    "returnedAt": {
      "type": "string",
      "format": "datetime",
      "description": "When the owner marked the lent item returned. Absent until then; only present on lend-listing exchanges."
    },
    "completedAt": {
      "type": "string",
      "format": "datetime",
      "description": "When the giver marked the gift complete — the item handed over or the service rendered. Absent until then."
    },
    "receiverDid": {
      "type": "string",
      "format": "did",
      "description": "DID of the party receiving the item."
    },
    "respondedAt": {
      "type": "string",
      "format": "datetime",
      "description": "When the counterparty confirmed or declined. Absent until they respond."
    },
    "counterparty": {
      "ref": "#exchangeCounterpartyView",
      "type": "ref",
      "description": "The non-listing-owner party's resolved identity."
    }
  },
  "description": "The active exchange on a listing, flattened with the counterparty's resolved identity."
}
imageView object

A single image blob associated with a listing.

Properties

alt string Optional

Alt text for the image. Absent when no alt text was provided.

cid string cid Required

CID of the image blob in the poster's repo.

View raw schema
{
  "type": "object",
  "required": [
    "cid"
  ],
  "properties": {
    "alt": {
      "type": "string",
      "description": "Alt text for the image. Absent when no alt text was provided."
    },
    "cid": {
      "type": "string",
      "format": "cid",
      "description": "CID of the image blob in the poster's repo."
    }
  },
  "description": "A single image blob associated with a listing."
}
interestView object

An interest ('raised hand') on a listing, flattened with the interested person's resolved identity (real displayName + handle + avatar). Mirrors the InterestedPerson row.

Properties

avatar string Optional

Avatar image URL (proxied). Absent when none.

cid string cid Required

CID of the interest record (used for messaging/report).

createdAt string datetime Required

When the interest was created (client-set; the row order key).

did string did Required

DID of the interested person.

displayName string Optional

Real display name (nullable — the row shows name + @handle separately). Absent when none set.

handle string Optional

Live-resolved handle (without leading @). Absent when unresolvable.

note string Optional

The interest's note/message. Absent when none left.

noteFacets array of refapp.bsky.richtext.facet Optional

Rich-text facets (links + mentions) over the note. Absent when none.

uri string at-uri Required

AT-URI of the interest record.

View raw schema
{
  "type": "object",
  "required": [
    "did",
    "uri",
    "cid",
    "createdAt"
  ],
  "properties": {
    "cid": {
      "type": "string",
      "format": "cid",
      "description": "CID of the interest record (used for messaging/report)."
    },
    "did": {
      "type": "string",
      "format": "did",
      "description": "DID of the interested person."
    },
    "uri": {
      "type": "string",
      "format": "at-uri",
      "description": "AT-URI of the interest record."
    },
    "note": {
      "type": "string",
      "description": "The interest's note/message. Absent when none left."
    },
    "avatar": {
      "type": "string",
      "description": "Avatar image URL (proxied). Absent when none."
    },
    "handle": {
      "type": "string",
      "description": "Live-resolved handle (without leading @). Absent when unresolvable."
    },
    "createdAt": {
      "type": "string",
      "format": "datetime",
      "description": "When the interest was created (client-set; the row order key)."
    },
    "noteFacets": {
      "type": "array",
      "items": {
        "ref": "app.bsky.richtext.facet",
        "type": "ref"
      },
      "description": "Rich-text facets (links + mentions) over the note. Absent when none."
    },
    "displayName": {
      "type": "string",
      "description": "Real display name (nullable — the row shows name + @handle separately). Absent when none set."
    }
  },
  "description": "An interest ('raised hand') on a listing, flattened with the interested person's resolved identity (real displayName + handle + avatar). Mirrors the InterestedPerson row."
}
listingDetailView object

Full detail view of a single listing, including all images, rich-text facets, and viewer state.

Properties

cid string cid Required

CID of the listing record in the poster's repo.

description string Optional

Full description of the item, in plain text. Absent when the poster provided no description.

facets array of refapp.bsky.richtext.facet Optional

Rich-text annotations (links, mentions, tags) over the description. Absent when no facets are present.

images array of ref#imageView Required

All images associated with the listing. May be empty.

langs array of stringlanguage Optional

BCP-47 language tags for the listing's text content. Absent when unspecified.

listing ref #listingView Required

The summary listing view.

viewer ref #viewerState Optional

The requesting account's viewer-specific state for this listing (e.g. their own interest). Absent for logged-out viewers.

View raw schema
{
  "type": "object",
  "required": [
    "listing",
    "cid",
    "images"
  ],
  "properties": {
    "cid": {
      "type": "string",
      "format": "cid",
      "description": "CID of the listing record in the poster's repo."
    },
    "langs": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "language"
      },
      "description": "BCP-47 language tags for the listing's text content. Absent when unspecified."
    },
    "facets": {
      "type": "array",
      "items": {
        "ref": "app.bsky.richtext.facet",
        "type": "ref"
      },
      "description": "Rich-text annotations (links, mentions, tags) over the description. Absent when no facets are present."
    },
    "images": {
      "type": "array",
      "items": {
        "ref": "#imageView",
        "type": "ref"
      },
      "description": "All images associated with the listing. May be empty."
    },
    "viewer": {
      "ref": "#viewerState",
      "type": "ref",
      "description": "The requesting account's viewer-specific state for this listing (e.g. their own interest). Absent for logged-out viewers."
    },
    "listing": {
      "ref": "#listingView",
      "type": "ref",
      "description": "The summary listing view."
    },
    "description": {
      "type": "string",
      "description": "Full description of the item, in plain text. Absent when the poster provided no description."
    }
  },
  "description": "Full detail view of a single listing, including all images, rich-text facets, and viewer state."
}
listingView object

A flattened, display-ready view of a single listing as returned by the AppView feed.

Properties

adult boolean Required

True if the listing is flagged as adult/mature content (self-label or moderator label).

category string Required

Single-level category for feed filtering. Unknown or missing values are indexed as 'other'. Not enum-restricted here to remain forward-compatible with new category values.

createdAt string datetime Required

ISO 8601 datetime when the listing was created. Clients derive relative-time display from this value.

did string did Required

DID of the account that created the listing.

distanceKm integer Optional

Coarse cell-center-to-cell-center distance in kilometres from the query geohash, rounded to the nearest km. Absent when no search centre is available.

geohash string Required

Approximate location as a geohash. Always at precision-6 (the ~1.2 km privacy floor). Used for map marker placement.

imageAlt string Optional

Alt text for the first image, parallel to imageCid. Absent when there is no first image or no alt text was provided.

imageCid string Optional

CID of the first image blob in the poster's repo. Used to construct the image proxy URL. Absent when the listing has no images.

intent string Required

Whether the poster is giving away an item or looking for one.

locationName string Optional

Human-readable area name derived from reverse geocoding the geohash. Display only; must not be used for proximity matching.

mode string Optional

How the item changes hands: 'gift' or 'lend'. Open set (knownValues); absent means gift.

Known values: gift, lend
moderation ref #moderationView Optional

Active soft moderation signal for the listing, if any. Absent when the listing has no active moderation.

out boolean Optional

Derived: a lend listing whose item is currently out on loan (an exchange completed but not yet returned). Absent means not out.

paused boolean Optional

Owner paused lending — hidden from feeds, interest disabled. Absent means active.

replyCount integer Optional

Visible notes on this listing. Derived by the AppView; absent on cards that don't compute it.

rkey string Required

Record key (TID) of the listing record in the poster's repo.

standing boolean Optional

Standing (renewing) offer — exchanges never drive status; clients may label availability as ongoing.

status string Optional

Current availability of the item. Absent means 'available'.

title string Required

Short title of the item being offered or requested.

View raw schema
{
  "type": "object",
  "required": [
    "did",
    "rkey",
    "title",
    "intent",
    "createdAt",
    "category",
    "adult",
    "geohash"
  ],
  "properties": {
    "did": {
      "type": "string",
      "format": "did",
      "description": "DID of the account that created the listing."
    },
    "out": {
      "type": "boolean",
      "description": "Derived: a lend listing whose item is currently out on loan (an exchange completed but not yet returned). Absent means not out."
    },
    "mode": {
      "type": "string",
      "description": "How the item changes hands: 'gift' or 'lend'. Open set (knownValues); absent means gift.",
      "knownValues": [
        "gift",
        "lend"
      ]
    },
    "rkey": {
      "type": "string",
      "description": "Record key (TID) of the listing record in the poster's repo."
    },
    "adult": {
      "type": "boolean",
      "description": "True if the listing is flagged as adult/mature content (self-label or moderator label)."
    },
    "title": {
      "type": "string",
      "description": "Short title of the item being offered or requested."
    },
    "intent": {
      "enum": [
        "offer",
        "request"
      ],
      "type": "string",
      "description": "Whether the poster is giving away an item or looking for one."
    },
    "paused": {
      "type": "boolean",
      "description": "Owner paused lending — hidden from feeds, interest disabled. Absent means active."
    },
    "status": {
      "enum": [
        "available",
        "pending",
        "gone"
      ],
      "type": "string",
      "description": "Current availability of the item. Absent means 'available'."
    },
    "geohash": {
      "type": "string",
      "description": "Approximate location as a geohash. Always at precision-6 (the ~1.2 km privacy floor). Used for map marker placement."
    },
    "category": {
      "type": "string",
      "description": "Single-level category for feed filtering. Unknown or missing values are indexed as 'other'. Not enum-restricted here to remain forward-compatible with new category values."
    },
    "imageAlt": {
      "type": "string",
      "description": "Alt text for the first image, parallel to imageCid. Absent when there is no first image or no alt text was provided."
    },
    "imageCid": {
      "type": "string",
      "description": "CID of the first image blob in the poster's repo. Used to construct the image proxy URL. Absent when the listing has no images."
    },
    "standing": {
      "type": "boolean",
      "description": "Standing (renewing) offer — exchanges never drive status; clients may label availability as ongoing."
    },
    "createdAt": {
      "type": "string",
      "format": "datetime",
      "description": "ISO 8601 datetime when the listing was created. Clients derive relative-time display from this value."
    },
    "distanceKm": {
      "type": "integer",
      "description": "Coarse cell-center-to-cell-center distance in kilometres from the query geohash, rounded to the nearest km. Absent when no search centre is available."
    },
    "moderation": {
      "ref": "#moderationView",
      "type": "ref",
      "description": "Active soft moderation signal for the listing, if any. Absent when the listing has no active moderation."
    },
    "replyCount": {
      "type": "integer",
      "description": "Visible notes on this listing. Derived by the AppView; absent on cards that don't compute it."
    },
    "locationName": {
      "type": "string",
      "description": "Human-readable area name derived from reverse geocoding the geohash. Display only; must not be used for proximity matching."
    }
  },
  "description": "A flattened, display-ready view of a single listing as returned by the AppView feed."
}
moderationView object

Active soft moderation signal applied to a listing (warn or hide tier).

Properties

reason string Required

Human-readable reason for the moderation action.

tier string Required

Severity tier. 'warn' shows a content warning over the card; 'hide' collapses the card to a quiet strip behind an expand affordance. Both tiers keep the listing in the feed response — only hard takedowns and blocked authors are omitted.

View raw schema
{
  "type": "object",
  "required": [
    "tier",
    "reason"
  ],
  "properties": {
    "tier": {
      "enum": [
        "warn",
        "hide"
      ],
      "type": "string",
      "description": "Severity tier. 'warn' shows a content warning over the card; 'hide' collapses the card to a quiet strip behind an expand affordance. Both tiers keep the listing in the feed response — only hard takedowns and blocked authors are omitted."
    },
    "reason": {
      "type": "string",
      "description": "Human-readable reason for the moderation action."
    }
  },
  "description": "Active soft moderation signal applied to a listing (warn or hide tier)."
}
replyAuthorView object

A reply author's resolved identity — sibling def to exchangeCounterpartyView (inline object property types are illegal in this lexicon toolchain).

Properties

avatar string Optional

Avatar image URL (proxied). Absent when none.

did string did Required

DID of the reply's author.

displayName string Optional

Real display name. Absent when none set.

maxLength: 640 bytesmaxGraphemes: 64 graphemes
handle string handle Optional

Live-resolved handle (without leading @). Absent when unresolvable.

View raw schema
{
  "type": "object",
  "required": [
    "did"
  ],
  "properties": {
    "did": {
      "type": "string",
      "format": "did",
      "description": "DID of the reply's author."
    },
    "avatar": {
      "type": "string",
      "description": "Avatar image URL (proxied). Absent when none."
    },
    "handle": {
      "type": "string",
      "format": "handle",
      "description": "Live-resolved handle (without leading @). Absent when unresolvable."
    },
    "displayName": {
      "type": "string",
      "maxLength": 640,
      "description": "Real display name. Absent when none set.",
      "maxGraphemes": 64
    }
  },
  "description": "A reply author's resolved identity — sibling def to exchangeCounterpartyView (inline object property types are illegal in this lexicon toolchain)."
}
replyView object

A public note on a listing, flattened with the author's resolved identity. Mirrors the ListingReplyRow db row (getRepliesForListing).

Properties

cid string cid Required

CID of the reply record.

createdAt string datetime Required

When the reply was created (client-set).

facets array of refapp.bsky.richtext.facet Optional

Rich-text annotations (links, mentions) over the text. Absent when none.

hidden boolean Optional

True when the listing owner's replygate hides this note from default views. Present only in owner (includeHidden) reads — otherwise hidden rows are omitted, not flagged.

text string Required

The note text.

uri string at-uri Required

AT-URI of the reply record.

View raw schema
{
  "type": "object",
  "required": [
    "uri",
    "cid",
    "author",
    "text",
    "createdAt"
  ],
  "properties": {
    "cid": {
      "type": "string",
      "format": "cid",
      "description": "CID of the reply record."
    },
    "uri": {
      "type": "string",
      "format": "at-uri",
      "description": "AT-URI of the reply record."
    },
    "text": {
      "type": "string",
      "description": "The note text."
    },
    "author": {
      "ref": "#replyAuthorView",
      "type": "ref",
      "description": "The reply author's resolved identity."
    },
    "facets": {
      "type": "array",
      "items": {
        "ref": "app.bsky.richtext.facet",
        "type": "ref"
      },
      "description": "Rich-text annotations (links, mentions) over the text. Absent when none."
    },
    "hidden": {
      "type": "boolean",
      "description": "True when the listing owner's replygate hides this note from default views. Present only in owner (includeHidden) reads — otherwise hidden rows are omitted, not flagged."
    },
    "createdAt": {
      "type": "string",
      "format": "datetime",
      "description": "When the reply was created (client-set)."
    }
  },
  "description": "A public note on a listing, flattened with the author's resolved identity. Mirrors the ListingReplyRow db row (getRepliesForListing)."
}
viewerState object

Metadata about the requesting account's relationship to this listing. Empty for logged-out viewers and viewers with no interaction.

Properties

interest string at-uri Optional

AT-URI of the viewer's own interest record on this listing, present when they have raised their hand. Absent otherwise. Follows the app.bsky viewerState.like as-string pattern.

View raw schema
{
  "type": "object",
  "properties": {
    "interest": {
      "type": "string",
      "format": "at-uri",
      "description": "AT-URI of the viewer's own interest record on this listing, present when they have raised their hand. Absent otherwise. Follows the app.bsky viewerState.like as-string pattern."
    }
  },
  "description": "Metadata about the requesting account's relationship to this listing. Empty for logged-out viewers and viewers with no interaction."
}

Lexicon Garden

@