Skip to main content

Overview

The app.bsky.graph namespace provides lexicons for managing social relationships including follows, blocks, lists, and starter packs.

Key Concepts

  • Follow: Social connection between users
  • Block: Preventing interaction with another user
  • List: Curated collection of users
  • Starter Pack: Onboarding bundle with suggested follows and feeds
  • Mute: Hiding content from a user without blocking

Record Types

follow

Follow relationship record.
subject
string
required
DID of the account being followed
createdAt
string
required
Timestamp
via
ref
Optional reference to how the follow was discovered
Example:
await agent.follow('did:plc:z72i7hdynmk6r22z27h6tvur')

// Or manually:
await agent.com.atproto.repo.createRecord({
  repo: agent.session.did,
  collection: 'app.bsky.graph.follow',
  record: {
    $type: 'app.bsky.graph.follow',
    subject: 'did:plc:z72i7hdynmk6r22z27h6tvur',
    createdAt: new Date().toISOString()
  }
})

block

Block relationship record.
subject
string
required
DID of the account being blocked
createdAt
string
required
Timestamp
Example:
await agent.com.atproto.repo.createRecord({
  repo: agent.session.did,
  collection: 'app.bsky.graph.block',
  record: {
    $type: 'app.bsky.graph.block',
    subject: 'did:plc:spammer123',
    createdAt: new Date().toISOString()
  }
})

list

List of users.
name
string
required
List name (1-64 characters)
purpose
string
required
List purpose: app.bsky.graph.defs#modlist, app.bsky.graph.defs#curatelist, or app.bsky.graph.defs#referencelist
description
string
List description (max 300 graphemes)
descriptionFacets
array
Rich text facets for description
avatar
blob
List avatar image
labels
union
Self-applied labels
createdAt
string
required
Timestamp
List Purposes:
  • modlist: Moderation list (for muting/blocking)
  • curatelist: Curation list (for feeds, interaction gating)
  • referencelist: Reference list (for starter packs)
Example:
await agent.com.atproto.repo.createRecord({
  repo: agent.session.did,
  collection: 'app.bsky.graph.list',
  record: {
    $type: 'app.bsky.graph.list',
    name: 'My Favorite Devs',
    purpose: 'app.bsky.graph.defs#curatelist',
    description: 'Developers working on cool projects',
    createdAt: new Date().toISOString()
  }
})

listitem

Membership in a list.
subject
string
required
DID of the account
list
string
required
AT-URI of the list
createdAt
string
required
Timestamp
Example:
// Add user to list
await agent.com.atproto.repo.createRecord({
  repo: agent.session.did,
  collection: 'app.bsky.graph.listitem',
  record: {
    $type: 'app.bsky.graph.listitem',
    subject: 'did:plc:z72i7hdynmk6r22z27h6tvur',
    list: listUri,
    createdAt: new Date().toISOString()
  }
})

listblock

Block a list (applies modlist to your account).
subject
string
required
AT-URI of the list
createdAt
string
required
Timestamp

starterpack

Starter pack for onboarding.
name
string
required
Starter pack name (max 50 graphemes)
description
string
Description (max 300 graphemes)
descriptionFacets
array
Rich text facets
list
string
required
AT-URI of reference list with suggested follows
feeds
array
Array of feed generator AT-URIs (max 3)
createdAt
string
required
Timestamp

Queries

getFollows

Get accounts followed by an actor. Endpoint: app.bsky.graph.getFollows
actor
string
required
Handle or DID
limit
integer
Max follows (1-100, default 50)
cursor
string
Pagination cursor
Response:
subject
object
required
Profile of the actor
cursor
string
Next page cursor
follows
array
required
Array of followed profiles
Example:
const response = await agent.getFollows({
  actor: 'alice.bsky.social'
})

for (const follow of response.data.follows) {
  console.log('Follows:', follow.handle)
}

getFollowers

Get accounts following an actor. Endpoint: app.bsky.graph.getFollowers
actor
string
required
Handle or DID
limit
integer
Max followers (1-100, default 50)
cursor
string
Pagination cursor
Response:
subject
object
required
Profile of the actor
cursor
string
Next page cursor
followers
array
required
Array of follower profiles

getKnownFollowers

Get followers whom you also follow. Endpoint: app.bsky.graph.getKnownFollowers Authentication: Required
actor
string
required
Handle or DID
limit
integer
Max followers (1-100, default 50)
cursor
string
Pagination cursor

getRelationships

Get relationships between actors. Endpoint: app.bsky.graph.getRelationships Authentication: Required
actor
string
required
Your handle or DID
others
array
Array of other actors to check relationships with
Response: Array of relationship objects showing follow/block status Example:
const response = await agent.app.bsky.graph.getRelationships({
  actor: agent.session.did,
  others: ['alice.bsky.social', 'bob.bsky.social']
})

for (const rel of response.data.relationships) {
  console.log('Following:', rel.following)
  console.log('Followed by:', rel.followedBy)
}

getSuggestedFollowsByActor

Get suggested accounts to follow based on an actor. Endpoint: app.bsky.graph.getSuggestedFollowsByActor
actor
string
required
Handle or DID

List Queries

getList

Get detailed information about a list. Endpoint: app.bsky.graph.getList
list
string
required
AT-URI of the list
limit
integer
Max list items (1-100, default 50)
cursor
string
Pagination cursor
Response: List details with items

getLists

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

getListsWithMembership

Get lists that include a specific actor. Endpoint: app.bsky.graph.getListsWithMembership
actor
string
required
Handle or DID of the list member
limit
integer
Max lists (1-100, default 50)
cursor
string
Pagination cursor

getListBlocks

Get lists you have blocked (subscribed to as modlists). Endpoint: app.bsky.graph.getListBlocks Authentication: Required
limit
integer
Max lists (1-100, default 50)
cursor
string
Pagination cursor

getListMutes

Get lists you have muted. Endpoint: app.bsky.graph.getListMutes Authentication: Required
limit
integer
Max lists (1-100, default 50)
cursor
string
Pagination cursor

Starter Pack Queries

getStarterPack

Get a starter pack. Endpoint: app.bsky.graph.getStarterPack
starterPack
string
required
AT-URI of the starter pack

getStarterPacks

Get multiple starter packs. Endpoint: app.bsky.graph.getStarterPacks
uris
array
required
Array of starter pack AT-URIs

getActorStarterPacks

Get starter packs created by an actor. Endpoint: app.bsky.graph.getActorStarterPacks
actor
string
required
Handle or DID
limit
integer
Max starter packs (1-100, default 50)
cursor
string
Pagination cursor

searchStarterPacks

Search for starter packs. Endpoint: app.bsky.graph.searchStarterPacks
q
string
required
Search query
limit
integer
Max results (1-100, default 25)
cursor
string
Pagination cursor

Mute Procedures

muteActor

Mute an actor. Endpoint: app.bsky.graph.muteActor Authentication: Required
actor
string
required
Handle or DID to mute
Example:
await agent.mute('spammer.bsky.social')

unmuteActor

Unmute an actor. Endpoint: app.bsky.graph.unmuteActor Authentication: Required
actor
string
required
Handle or DID to unmute

getMutes

Get muted actors. Endpoint: app.bsky.graph.getMutes Authentication: Required
limit
integer
Max mutes (1-100, default 50)
cursor
string
Pagination cursor

muteActorList

Mute all members of a list. Endpoint: app.bsky.graph.muteActorList Authentication: Required
list
string
required
AT-URI of the list

unmuteActorList

Unmute a list. Endpoint: app.bsky.graph.unmuteActorList Authentication: Required
list
string
required
AT-URI of the list

getBlocks

Get blocked actors. Endpoint: app.bsky.graph.getBlocks Authentication: Required
limit
integer
Max blocks (1-100, default 50)
cursor
string
Pagination cursor

muteThread

Mute a thread. Endpoint: app.bsky.graph.muteThread Authentication: Required
root
string
required
AT-URI of the root post

unmuteThread

Unmute a thread. Endpoint: app.bsky.graph.unmuteThread Authentication: Required
root
string
required
AT-URI of the root post

Type Definitions

listPurpose

Purpose types for lists:
  • app.bsky.graph.defs#modlist: Moderation list for muting/blocking
  • app.bsky.graph.defs#curatelist: Curation list for feeds/gating
  • app.bsky.graph.defs#referencelist: Reference list for starter packs

relationship

Bi-directional relationship between actors.
did
string
required
Target actor DID
following
string
AT-URI of follow record (if following)
followedBy
string
AT-URI of their follow record (if they follow you)
blocking
string
AT-URI of block record (if blocking)
blockedBy
string
AT-URI of their block record (if they block you)

Common Use Cases

Follow and Check Relationship

// Follow a user
await agent.follow('alice.bsky.social')

// Check if they follow back
const { data } = await agent.app.bsky.graph.getRelationships({
  actor: agent.session.did,
  others: ['alice.bsky.social']
})

if (data.relationships[0].followedBy) {
  console.log('They follow you back!')
}

Create and Populate a List

// Create list
const list = await agent.com.atproto.repo.createRecord({
  repo: agent.session.did,
  collection: 'app.bsky.graph.list',
  record: {
    $type: 'app.bsky.graph.list',
    name: 'Cool Developers',
    purpose: 'app.bsky.graph.defs#curatelist',
    createdAt: new Date().toISOString()
  }
})

// Add users to list
const usersToAdd = ['alice.bsky.social', 'bob.bsky.social']

for (const user of usersToAdd) {
  const profile = await agent.getProfile({ actor: user })
  
  await agent.com.atproto.repo.createRecord({
    repo: agent.session.did,
    collection: 'app.bsky.graph.listitem',
    record: {
      $type: 'app.bsky.graph.listitem',
      subject: profile.data.did,
      list: list.uri,
      createdAt: new Date().toISOString()
    }
  })
}

Create a Starter Pack

// Create reference list first
const list = await agent.com.atproto.repo.createRecord({
  repo: agent.session.did,
  collection: 'app.bsky.graph.list',
  record: {
    $type: 'app.bsky.graph.list',
    name: 'Recommended Follows',
    purpose: 'app.bsky.graph.defs#referencelist',
    createdAt: new Date().toISOString()
  }
})

// Add suggested follows to list
// ... (add listitem records)

// Create starter pack
const starterPack = await agent.com.atproto.repo.createRecord({
  repo: agent.session.did,
  collection: 'app.bsky.graph.starterpack',
  record: {
    $type: 'app.bsky.graph.starterpack',
    name: 'AT Protocol Developers',
    description: 'Join the AT Protocol community!',
    list: list.uri,
    feeds: [
      'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot'
    ],
    createdAt: new Date().toISOString()
  }
})

console.log('Starter pack:', starterPack.uri)

Resources

Build docs developers (and LLMs) love