gifthood.org Open the app

Reference

The Gifthood lexicon

On the open network, a Lexicon is the shared grammar that lets independent apps understand each other's data. This is ours — the handful of record types Gifthood writes to your repo, defined plainly, with the exact shapes underneath.

How to read this

listing

· record

community.gifthood.listing · keyed by tid

An offer or a request, set down where the neighbors closest to it will notice. A listing is the smallest unit of giving here — one thing you’re passing on, or one thing you’re hoping someone nearby can spare. Some gifts make a round trip: a listing can be to lend — or looking to borrow — and the offer stands while the ladder’s out and after it comes home. A standing offer is the one that renews: rides, lessons, the weekly eggs — it stays open through gift after gift, until you say it’s gone.

“Maria’s done with the crib. She posts a listing, and the blocks around her are the first to see it.”

Fields * required
title*
string · 1–100 graphemes

Required short title for the item being offered or requested.

description*
string · 1–1500 graphemes

Required free text describing the item being offered or requested.

intent*
string
offerrequest

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

status
string
availablependinggone

Current availability. Clients should treat a missing value as 'available'.

standing
boolean

Standing (renewing) offer: the owner can run exchange chains with multiple neighbors over time. Absent or false means the listing is exhausted by a single exchange. AppViews keep a standing listing available while chains run; only the owner's manual 'gone' ends it.

mode
string
one of 2: gift, lend

How the item changes hands. 'gift' (the default when absent) transfers ownership; 'lend' expects the item back — the listing behaves as a standing offer and each exchange gains a return leg (see exchange.returnedAt). Readers MUST treat unknown or missing values as 'gift'.

paused
boolean

Owner-set temporary unavailability (using the item themselves, away for a while). AppViews hide paused listings from feeds but keep the detail view reachable with interest disabled. Absent means active. Orthogonal to status; 'gone' still wins.

geohash*
string · ≤6 chars

Approximate location as a geohash, precision 6 (~1.2km cell). This is a privacy floor: indexers MUST truncate any finer-precision value to 6 characters before indexing or display.

locationName
string · ≤100 graphemes

Optional human-readable area name. App-populated via reverse geocoding of the geohash cell. Display only; MUST NOT be used for proximity matching or filtering.

images
blob[] · ≤4 · jpeg/png/webp · ≤1 MB

Up to 4 images of the item, stored as blobs in the poster's repo.

imageAlts
string[] · ≤4 · ≤1000 graphemes

Alt text for images, parallel to the images array by index.

category
string
one of 17: furniture, kitchen, clothing, baby, books, instruments, electronics, tools, garden, health, pets, hobbies, food, animals, service, office, other

Optional single-level category for opt-out feed filtering. Additive-only enum (values may be inserted, never removed or renamed); unknown or missing values index as 'other'. Never used for proximity or safety logic.

langs
string[] · ≤3 · language

Language(s) the content is written in, as BCP-47 language tags. Author-asserted; clients default from the composer's locale.

facets
facet[]

Annotations over `description` (mentions, links) keyed by UTF-8 byte range. Reuses app.bsky.richtext.facet for atmosphere-wide interop. Author-asserted at compose time; clients MUST treat them as display hints, re-validate ranges, and never trust a facet URI over the visible text. Addresses and phone numbers are deliberately NOT faceted here — those affordances are private-message-only.

labels
union · label.defs

Self-labels set by the author. Used to flag mature/adult content (e.g. the global 'sexual' value), which the AppView gates behind an opt-in.

createdAt*
datetime

↪ borrows facet · label.defs

profile

· record

community.gifthood.actor.profile · keyed by literal:self

How a neighbor shows up in Gifthood. It’s yours to set, and it sits lightly over your wider network identity: fill in a field and it speaks for you here; leave it blank and your Bluesky profile shows through.

“The same face you bring to the rest of the open network — with the parts particular to giving laid over the top.”

Fields * required
displayName
string · ≤64 graphemes

Gifthood display name. Overrides the Bluesky display name when set.

description
string · ≤256 graphemes

Gifthood bio. Overrides the Bluesky description when set.

pronouns
string · ≤20 graphemes

Free-form pronouns. Overrides the Bluesky pronouns when set.

website
uri

A personal link. Overrides the Bluesky website when set.

avatar
blob · png/jpeg · ≤1 MB

Avatar image blob in the member's repo. Overrides the Bluesky avatar when set.

banner
blob · png/jpeg · ≤1 MB

Banner image blob in the member's repo.

labels
union · label.defs

Self-label values on this profile. The only value gifthood enforces is !no-unauthenticated (hide from logged-out viewers).

createdAt*
datetime

The gifthood join date. Write-once: edits MUST preserve it.

↪ borrows label.defs

follow

· record

community.gifthood.follow · keyed by tid

A quiet way of saying you’d like to keep up with a neighbor. Following is public and entirely yours to give or take back, and it keeps a generous neighbor’s comings and goings within reach.

“You liked how someone gives — generous, no fuss. A follow keeps their offers in view.”

Fields * required
subject*
did

The DID of the member being followed.

createdAt*
datetime

interest

· record

community.gifthood.interest · keyed by tid

Raising your hand for a listing. Interest says, in the open, that you’d like the thing — a first hello. The where and when of a hand-off happen off to the side, in a private message on the listing, not here in the open.

“‘Still available?’ — a raised hand for the bookshelf; the rest gets sorted in a message.”

Fields * required
subject*
ref → strongRef

Strong reference (URI + CID) to the listing this interest refers to.

message
string · ≤300 graphemes

Optional short public note (e.g. 'still available?'). Pickup details belong in private messages, not here.

langs
string[] · ≤3 · language

Language(s) the message is written in, as BCP-47 language tags. Author-asserted; clients default from the composer's locale.

facets
facet[]

Annotations over `message` (mentions, links) keyed by UTF-8 byte range. Reuses app.bsky.richtext.facet for atmosphere-wide interop. Author-asserted at compose time; clients MUST treat them as display hints, re-validate ranges, and never trust a facet URI over the visible text. Addresses and phone numbers are deliberately NOT faceted here — those affordances are private-message-only.

createdAt*
datetime

↪ borrows strongRef · facet

exchange

· record

community.gifthood.exchange · keyed by tid

The listing owner’s half of a completed gift: who was chosen to give and who to receive, and — once the hand-off happens — when. When the gift is a loan, the record holds a second leg too: the owner marks it returned once the item comes home. It’s public, like interest, and it waits for its other half; paired with the neighbor’s confirming exchange response, it becomes quiet evidence of follow-through.

“Maria picks a neighbor for the crib. The exchange says who gives, who receives — and, once it’s handed over, that it happened.”

Fields * required
subject*
ref → strongRef

Strong reference (URI + CID) to the listing this exchange is for. Must be a listing authored by this record's author.

interest
ref → strongRef

Optional strong reference to the counterparty's interest record, when they raised a hand. Absent when the counterparty was chosen from a listing-scoped conversation.

giver*
did

DID of the member giving the item. Exactly one of giver/receiver is the record author (the listing owner): on an offer listing the author is the giver; on a request listing the author is the receiver.

receiver*
did

DID of the member receiving the item.

createdAt*
datetime
completedAt
datetime

Set (via record update) when the owner marks the gift complete — the item handed over or the service rendered. Absence means the exchange is still pending.

returnedAt
datetime

Set (via record update) by the owner when a lent item comes home. Only meaningful when the subject listing has mode 'lend'; indexers ignore it on gift exchanges and ignore a returnedAt without completedAt (an item cannot come back before it was handed over). Owner-attested only — the mutual response pair already attests the handover; disputes go through reporting.

↪ borrows strongRef

exchange response

· record

community.gifthood.exchangeResponse · keyed by tid

The other half of the attestation. The neighbor an exchange names answers it in the open: confirm that the hand-off happened, or decline the selection. Only that neighbor’s answer counts, the first one stands, and a confirmed pair is the network’s plainest proof that giving happened.

“‘Picked it up Saturday — thank you.’ The counterparty’s word that the gift really happened.”

Fields * required
subject*
ref → strongRef

Strong reference (URI + CID) to the community.gifthood.exchange record being answered.

response*
string
confirmdecline
createdAt*
datetime

↪ borrows strongRef

reply

· record

community.gifthood.reply · keyed by tid

The front porch of a listing: a public note anyone can leave — appreciation, a question, a joke. Notes thread the way the wider network’s posts do, and every one of them belongs to the listing it sits on. The where-and-when of a hand-off still goes in a private message; the porch is for saying hi.

“‘We had this same crib — happy travels, little bed.’ A note left on the listing, for everyone to see.”

Fields * required
root*
ref → strongRef

Strong reference (URI + CID) to the listing this note belongs to. Always the listing — one query on root fetches a whole thread family.

parent*
ref → strongRef

What this note replies to: the listing itself for top-level notes, or another reply. parent's root MUST equal this record's root; indexers enforce that at read time.

text*
string · 1–300 graphemes

The note. Keep pickup logistics in private messages.

facets
facet[]

Annotations over `text` (mentions, links) keyed by UTF-8 byte range. Reuses app.bsky.richtext.facet. Author-asserted display hints; clients re-validate ranges. Addresses and phone numbers are deliberately NOT faceted here.

langs
string[] · ≤3 · language
labels
union · label.defs

Self-labels set by the author (e.g. the global 'sexual' value), gated by the AppView like listing self-labels.

createdAt*
datetime

↪ borrows strongRef · facet · label.defs

reply gate

· record

community.gifthood.replygate · keyed by tid

How a listing’s owner keeps their own porch. Hiding a note tucks it out of the default view — nothing is deleted, and the note still lives in its author’s repo; it just stops shaping the conversation on this listing. Real trouble goes through reporting, same as anywhere else.

“The porch is yours to keep: a hidden note steps out of view without being torn up.”

Fields * required
listing*
ref → strongRef

Strong reference to the owner's own listing. Belt for the matching-rkey suspenders; indexers verify both.

hiddenReplies
string[] · ≤300 · at-uri

AT-URIs of community.gifthood.reply records hidden from default views on this listing.

createdAt*
datetime

↪ borrows strongRef

Loanwords

Words Gifthood borrows from the open network rather than coining its own — so the records interoperate with the wider atmosphere instead of standing apart.

com.atproto.repo.strongRef AT Protocol core
Lets an interest point at exactly one listing — by address and content hash — so it can't be quietly swapped underneath.
app.bsky.richtext.facet Bluesky
Marks up the mentions and links inside a description or message the same way the rest of the network does, so other apps understand them too.
com.atproto.label.defs AT Protocol moderation
The shared vocabulary of content labels, so a poster can flag their own listing as mature and every client can honor it.