Skip to main content

User lists

User lists are collections of users.

The app.bsky.graph.list record type declares the existence of a list.

at://did:plc:bob123/app.bsky.graph.list/pals
{
$type: "app.bsky.graph.list",
purpose: "app.bsky.graph.defs#curatelist",
name: "Pals",
description: "My good pals",
createdAt: "2024-01-20T21:09:25.326Z"
}

The app.bsky.graph.listitem record type declares the inclusion of a user in a list.

at://did:plc:bob123/app.bsky.graph.listitem/1
{
$type: "app.bsky.graph.listitem",
subject: "did:plc:alice123", // the user included
list: "at://did:plc:bob123/app.bsky.graph.list/pals", // the list declaration above
createdAt: "2024-01-20T21:09:25.326Z"
}
note

Only the creator of a list can declare its members.

List purpose

Every list has a "purpose" which expresses how it is expected to be used.

{
$type: "app.bsky.graph.list",
purpose: "app.bsky.graph.defs#curatelist", // the purpose
name: "Pals",
//...
}

There are two purposes:

  • app.bsky.graph.defs#curatelist: A list of users to drive feeds or set threadgates.
  • app.bsky.graph.defs#modlist: A list of users for muting or blocking.

Viewing a list

Call app.bsky.graph.getList to view a list and its members.

agent.app.bsky.graph.getList({
list: uri,
limit: 30,
})

The output will match this interface:

getList() output
{
cursor?: string;
list: AppBskyGraphDefs.ListView;
items: AppBskyGraphDefs.ListItemView[];
}

Use the cursor to paginate through the full list.

import {AppBskyGraphDefs} from '@atproto/api'

let cursor: string | undefined
let members: AppBskyGraphDefs.ListItemView[] = []
do {
let res = await agent.app.bsky.graph.getList({
list: uri,
limit: 30,
cursor
})
cursor = res.data.cursor
members = members.concat(res.data.items)
} while (cursor)

Get created lists

Call app.bsky.graph.getLists to view lists created by an actor.

agent.app.bsky.graph.getLists({
actor: didOrHandle,
limit: 30
})

The output will match this interface:

getLists() output
{
cursor?: string;
lists: AppBskyGraphDefs.ListView[];
}

Use the cursor to paginate through the full list, as detailed in Viewing a list.

Get muted lists

Call app.bsky.graph.getListMutes to view lists muted by the current actor.

agent.app.bsky.graph.getListMutes({
limit: 30
})

The output will match this interface:

getListMutes() output
{
cursor?: string;
lists: AppBskyGraphDefs.ListView[];
}

Use the cursor to paginate through the full list, as in Viewing a list.

Get blocked lists

Call app.bsky.graph.getListBlocks to view lists blocked by the current actor.

agent.app.bsky.graph.getListBlocks({
limit: 30
})

The output will match this interface:

getListBlocks() output
{
cursor?: string;
lists: AppBskyGraphDefs.ListView[];
}

Use the cursor to paginate through the full list, as in Viewing a list.

Has a user muted or blocked a list?

When you call app.bsky.graph.getList or use any API that returns a app.bsky.graph.defs#listView object, you can examine the viewer field to determine if the user has muted or blocked the list.

viewer object
{
muted?: boolean; // true if muted
blocked?: string; // the URI of the block record if blocking
}

For example:

const res = await agent.app.bsky.graph.getList({
list: listUri
})
if (res.data.list.viewer?.muted) {
// is muting list
}
if (res.data.list.viewer?.blocked) {
// is blocking list
}

Mute/unmute a list

Call app.bsky.graph.muteActorList to mute a list. The mute state is private.

await agent.muteModList(listUri)

Call app.bsky.graph.unmuteActorList to unmute a list.

await agent.unmuteModList(listUri)

Block/unblock a list

Blocks are public records. You block a list by creating the app.bsky.graph.listblock record.

This is simplified for you with the blockModList method:

await agent.blockModList(listUri)

You delete the listblock record to unblock the list. This is also simplified for you with unblockModList

await agent.unblockModList(listUri)

Create a list

Create a list by creating a app.bsky.graph.list record.

await agent.com.atproto.repo.createRecord({
repo: agent.session.did,
collection: 'app.bsky.graph.list',
record: {
$type: 'app.bsky.graph.list',
purpose: 'app.bsky.graph.defs#curatelist',
name: 'Pals',
description: 'My good pals',
createdAt: new Date().toISOString()
}
})

Update a list's metadata

Update a list by updating its app.bsky.graph.list record.

const {repo, collection, rkey} = new AtUri(listUri)

// get the current record
const {value: record} = await agent.com.atproto.repo.getRecord({repo, collection, rkey})

// modify the fields
record.name = newName
record.description = newDescription
// etc

await agent.com.atproto.repo.putRecord({
repo: currentAccount.did,
collection,
rkey,
record,
})

Delete a list

Delete a list by deleting its app.bsky.graph.list record.

const {repo, collection, rkey} = new AtUri(listUri)
await agent.com.atproto.repo.deleteRecord({repo, collection, rkey})

Add a user to a list

Add a user to a list by creating a app.bsky.graph.listitem record.

await agent.com.atproto.repo.createRecord({
repo: agent.session.did,
collection: 'app.bsky.graph.listitem',
record: {
$type: 'app.bsky.graph.listitem',
subject: userDid,
list: listUri,
createdAt: new Date().toISOString()
}
})

Remove a user from a list

Remove a user from a list by deleting their app.bsky.graph.listitem record.

const {repo, collection, rkey} = new AtUri(listItemUri)
await agent.com.atproto.repo.deleteRecord({repo, collection, rkey})