User lists
User lists are collections of users.
The app.bsky.graph.list record type declares the existence of a list.
{
$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.
{
$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"
}
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
- Typescript
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:
{
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
- Typescript
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:
{
cursor?: string;
lists: AppBskyGraphDefs.ListView[];
}
Use the cursor to paginate through the full list, as detailed in Viewing a list.
Get muted lists
- Typescript
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:
{
cursor?: string;
lists: AppBskyGraphDefs.ListView[];
}
Use the cursor to paginate through the full list, as in Viewing a list.
Get blocked lists
- Typescript
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:
{
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?
- Typescript
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.
{
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
- Typescript
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
- Typescript
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
- Typescript
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
- Typescript
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
- Typescript
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
- Typescript
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
- Typescript
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})