An offer or request for a free item, discoverable by approximate location.
tid
Timestamp-based ID
Properties
category
string
Optional
Optional single-level category for opt-out feed filtering. Append-only enum; unknown or missing values index as 'other'. Never used for proximity or safety logic.
furniture, kitchen, clothing, baby, books, instruments, electronics, tools, garden, health, pets, hobbies, food, animals, service, othercreatedAt
string
datetime
Required
An RFC 3339 formatted timestamp.
description
string
Required
Required free text describing the item being offered or requested.
maxLength: 3000 bytesminLength: 1 bytesmaxGraphemes: 1500 graphemesminGraphemes: 1 graphemesfacets
array
of
ref
app.bsky.richtext.facet
Optional
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 direct-message-only.
geohash
string
Required
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.
maxLength: 6 bytesminLength: 1 bytesimageAlts
array
of
string
Optional
Alt text for images, parallel to the images array by index.
maxLength: 4 itemsimages
array
of
blob
Optional
Up to 4 images of the item, stored as blobs in the poster's repo.
maxLength: 4 itemsintent
string
Required
Whether the poster is giving away an item or looking for one.
offer, requestlabels
union
Optional
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.
langs
array
of
string
language
Optional
Language(s) the content is written in, as BCP-47 language tags. Author-asserted; clients default from the composer's locale.
maxLength: 3 itemslocationName
string
Optional
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.
maxLength: 300 bytesmaxGraphemes: 100 graphemesstatus
string
Optional
Current availability. Clients should treat a missing value as 'available'.
available, pending, gonetitle
string
Required
Required short title for the item being offered or requested.
maxLength: 200 bytesminLength: 1 bytesmaxGraphemes: 100 graphemesminGraphemes: 1 graphemesView raw schema
{
"key": "tid",
"type": "record",
"record": {
"type": "object",
"required": [
"title",
"intent",
"description",
"geohash",
"createdAt"
],
"properties": {
"langs": {
"type": "array",
"items": {
"type": "string",
"format": "language"
},
"maxLength": 3,
"description": "Language(s) the content is written in, as BCP-47 language tags. Author-asserted; clients default from the composer's locale."
},
"title": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Required short title for the item being offered or requested.",
"maxGraphemes": 100,
"minGraphemes": 1
},
"facets": {
"type": "array",
"items": {
"ref": "app.bsky.richtext.facet",
"type": "ref"
},
"description": "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 direct-message-only."
},
"images": {
"type": "array",
"items": {
"type": "blob",
"accept": [
"image/jpeg",
"image/png",
"image/webp"
],
"maxSize": 1000000
},
"maxLength": 4,
"description": "Up to 4 images of the item, stored as blobs in the poster's repo."
},
"intent": {
"enum": [
"offer",
"request"
],
"type": "string",
"description": "Whether the poster is giving away an item or looking for one."
},
"labels": {
"refs": [
"com.atproto.label.defs#selfLabels"
],
"type": "union",
"description": "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."
},
"status": {
"enum": [
"available",
"pending",
"gone"
],
"type": "string",
"description": "Current availability. Clients should treat a missing value as 'available'."
},
"geohash": {
"type": "string",
"maxLength": 6,
"minLength": 1,
"description": "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."
},
"category": {
"enum": [
"furniture",
"kitchen",
"clothing",
"baby",
"books",
"instruments",
"electronics",
"tools",
"garden",
"health",
"pets",
"hobbies",
"food",
"animals",
"service",
"other"
],
"type": "string",
"description": "Optional single-level category for opt-out feed filtering. Append-only enum; unknown or missing values index as 'other'. Never used for proximity or safety logic."
},
"createdAt": {
"type": "string",
"format": "datetime"
},
"imageAlts": {
"type": "array",
"items": {
"type": "string",
"maxGraphemes": 1000
},
"maxLength": 4,
"description": "Alt text for images, parallel to the images array by index."
},
"description": {
"type": "string",
"maxLength": 3000,
"minLength": 1,
"description": "Required free text describing the item being offered or requested.",
"maxGraphemes": 1500,
"minGraphemes": 1
},
"locationName": {
"type": "string",
"maxLength": 300,
"description": "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.",
"maxGraphemes": 100
}
}
},
"description": "An offer or request for a free item, discoverable by approximate location."
}