Skip to main content

Overview

The app.bsky.feed namespace provides lexicons for posts, feeds, likes, reposts, and other feed-related functionality in Bluesky.

Key Concepts

  • Post: A message or content shared by a user
  • Feed: A chronological stream of posts
  • Feed Generator: Custom algorithmic feed
  • Interactions: Likes, reposts, replies, quotes
  • Thread: Conversation chain of posts

Record Types

post

A Bluesky post record. Record Structure:
text
string
required
Post content (max 300 graphemes, 3000 bytes)
facets
array
Rich text annotations (mentions, links, hashtags)
reply
object
Reply reference with root and parent
embed
union
Embedded content (images, video, external link, record, record with media)
langs
array
Language codes (max 3)
labels
union
Self-applied content labels
tags
array
Additional hashtags (max 8)
createdAt
string
required
ISO 8601 timestamp
Example:
await agent.post({
  text: 'Hello Bluesky! 👋',
  createdAt: new Date().toISOString()
})
With Images:
const imageBlob = await agent.uploadBlob(imageFile, {
  encoding: 'image/jpeg'
})

await agent.post({
  text: 'Check out this sunset!',
  embed: {
    $type: 'app.bsky.embed.images',
    images: [
      {
        image: imageBlob.data.blob,
        alt: 'Beautiful orange and pink sunset over mountains'
      }
    ]
  }
})
Reply to Post:
await agent.post({
  text: 'Great point!',
  reply: {
    root: { uri: rootPostUri, cid: rootPostCid },
    parent: { uri: parentPostUri, cid: parentPostCid }
  }
})

like

Like record for a post.
subject
ref
required
Strong reference to the liked post
createdAt
string
required
Timestamp
Example:
await agent.like(postUri, postCid)

// Or manually:
await agent.com.atproto.repo.createRecord({
  repo: agent.session.did,
  collection: 'app.bsky.feed.like',
  record: {
    $type: 'app.bsky.feed.like',
    subject: { uri: postUri, cid: postCid },
    createdAt: new Date().toISOString()
  }
})

repost

Repost record.
subject
ref
required
Strong reference to the reposted post
createdAt
string
required
Timestamp
Example:
await agent.repost(postUri, postCid)

threadgate

Thread interaction rules (who can reply).
post
string
required
AT-URI of the post
allow
array
Rules defining who can reply (mentions, followers, following, lists)
createdAt
string
required
Timestamp

postgate

Post embedding rules.
post
string
required
AT-URI of the post
embeddingRules
array
Rules for embedding (can disable embedding)
createdAt
string
required
Timestamp

generator

Feed generator declaration.
did
string
required
DID of the feed generator service
displayName
string
required
Feed name
description
string
Feed description (max 300 graphemes)
avatar
blob
Feed avatar image
acceptsInteractions
boolean
Whether feed accepts interaction data
labels
union
Self-applied labels
createdAt
string
required
Timestamp

Queries

getTimeline

Get the authenticated user’s home timeline. Endpoint: app.bsky.feed.getTimeline Authentication: Required
algorithm
string
Timeline algorithm variant
limit
integer
Max posts (1-100, default 50)
cursor
string
Pagination cursor
Response:
cursor
string
Next page cursor
feed
array
required
Array of feed view posts
Example:
const response = await agent.getTimeline({
  limit: 30
})

for (const item of response.data.feed) {
  console.log(item.post.author.handle, item.post.record.text)
}

getAuthorFeed

Get posts by a specific author. Endpoint: app.bsky.feed.getAuthorFeed
actor
string
required
Handle or DID
limit
integer
Max posts (1-100, default 50)
cursor
string
Pagination cursor
filter
string
Filter: posts_with_replies, posts_no_replies, posts_with_media, posts_and_author_threads
Example:
const response = await agent.getAuthorFeed({
  actor: 'alice.bsky.social',
  filter: 'posts_no_replies'
})

getFeed

Get posts from a feed generator. Endpoint: app.bsky.feed.getFeed
feed
string
required
AT-URI of the feed generator
limit
integer
Max posts (1-100, default 50)
cursor
string
Pagination cursor
Example:
const response = await agent.app.bsky.feed.getFeed({
  feed: 'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot'
})

getPosts

Get hydrated post views for specific posts. Endpoint: app.bsky.feed.getPosts
uris
array
required
Array of post AT-URIs (max 25)
Response:
posts
array
required
Array of post views
Example:
const response = await agent.app.bsky.feed.getPosts({
  uris: [
    'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.post/3k2y...',
    'at://did:plc:abc123/app.bsky.feed.post/3k3z...'
  ]
})

for (const post of response.data.posts) {
  console.log(post.record.text)
}

getPostThread

Get a post and its thread context. Endpoint: app.bsky.feed.getPostThread
uri
string
required
AT-URI of the post
depth
integer
How many levels of reply depth to fetch (default 6, max 1000)
parentHeight
integer
How many levels of parent posts to fetch (default 80, max 1000)
Response: Thread view with post, parent, and replies Example:
const response = await agent.getPostThread(postUri)

const thread = response.data.thread
console.log('Post:', thread.post.record.text)
console.log('Replies:', thread.replies?.length)

getLikes

Get likes for a post. Endpoint: app.bsky.feed.getLikes
uri
string
required
AT-URI of the post
limit
integer
Max likes (1-100, default 50)
cursor
string
Pagination cursor
Response: Array of likes with actor profiles

getRepostedBy

Get reposts for a post. Endpoint: app.bsky.feed.getRepostedBy
uri
string
required
AT-URI of the post
limit
integer
Max reposts (1-100, default 50)
cursor
string
Pagination cursor
Response: Array of actors who reposted

getQuotes

Get quote posts of a post. Endpoint: app.bsky.feed.getQuotes
uri
string
required
AT-URI of the post
limit
integer
Max quotes (1-100, default 50)
cursor
string
Pagination cursor

searchPosts

Search for posts. Endpoint: app.bsky.feed.searchPosts
q
string
required
Search query
limit
integer
Max results (1-100, default 25)
cursor
string
Pagination cursor
author
string
Filter by author
since
string
Filter by date (ISO 8601)
until
string
Filter by date (ISO 8601)
mentions
string
Filter by mentioned user
lang
string
Filter by language
domain
string
Filter by domain in links
url
string
Filter by URL in links
tag
array
Filter by hashtags
Example:
const response = await agent.app.bsky.feed.searchPosts({
  q: 'atproto',
  limit: 20,
  lang: 'en'
})

Feed Generators

getFeedGenerator

Get information about a feed generator. Endpoint: app.bsky.feed.getFeedGenerator
feed
string
required
AT-URI of the feed generator

getFeedGenerators

Get information about multiple feed generators. Endpoint: app.bsky.feed.getFeedGenerators
feeds
array
required
Array of feed generator AT-URIs

getSuggestedFeeds

Get suggested feed generators. Endpoint: app.bsky.feed.getSuggestedFeeds
limit
integer
Max feeds (1-100, default 50)
cursor
string
Pagination cursor

getActorFeeds

Get feed generators created by an actor. Endpoint: app.bsky.feed.getActorFeeds
actor
string
required
Handle or DID
limit
integer
Max feeds (1-100, default 50)
cursor
string
Pagination cursor

getActorLikes

Get posts liked by an actor. Endpoint: app.bsky.feed.getActorLikes
actor
string
required
Handle or DID
limit
integer
Max posts (1-100, default 50)
cursor
string
Pagination cursor

getListFeed

Get posts from a list. Endpoint: app.bsky.feed.getListFeed
list
string
required
AT-URI of the list
limit
integer
Max posts (1-100, default 50)
cursor
string
Pagination cursor

Procedures

sendInteractions

Send interaction events to feed generators. Endpoint: app.bsky.feed.sendInteractions Authentication: Required
interactions
array
required
Array of interaction events

Type Definitions

postView

Complete post view with engagement metrics.
uri
string
required
Post AT-URI
cid
string
required
Post CID
author
object
required
Author profile
record
object
required
Post record data
embed
union
Embedded content view
replyCount
integer
Number of replies
repostCount
integer
Number of reposts
likeCount
integer
Number of likes
quoteCount
integer
Number of quote posts
indexedAt
string
required
Indexing timestamp
viewer
object
Viewer’s interaction state
labels
array
Content labels

Common Use Cases

Create a Post with Mentions

import { RichText } from '@atproto/api'

const rt = new RichText({ text: 'Hello @alice.bsky.social!' })
await rt.detectFacets(agent)

await agent.post({
  text: rt.text,
  facets: rt.facets
})

Create Thread

// First post
const post1 = await agent.post({
  text: '1/ Here’s a thread about AT Protocol...'
})

// Reply to create thread
const post2 = await agent.post({
  text: '2/ The AT Protocol is designed to be decentralized...',
  reply: {
    root: { uri: post1.uri, cid: post1.cid },
    parent: { uri: post1.uri, cid: post1.cid }
  }
})

const post3 = await agent.post({
  text: '3/ It uses content-addressed storage...',
  reply: {
    root: { uri: post1.uri, cid: post1.cid },
    parent: { uri: post2.uri, cid: post2.cid }
  }
})

Quote Post

await agent.post({
  text: 'Great insight!',
  embed: {
    $type: 'app.bsky.embed.record',
    record: {
      uri: quotedPostUri,
      cid: quotedPostCid
    }
  }
})

Resources

Build docs developers (and LLMs) love