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.
import { app } from '@bsky/sdk/lexicons'
await client.call(app.bsky.graph.getList, {
list: uri,
limit: 30,
})
The output will match this interface:
{
cursor?: string;
list: app.bsky.graph.defs.ListView;
items: app.bsky.graph.defs.ListItemView[];
}
Use the cursor to paginate through the full list.
import { app } from '@bsky/sdk/lexicons'
let cursor: string | undefined
let members: app.bsky.graph.defs.ListItemView[] = []
do {
const res = await client.call(app.bsky.graph.getList, {
list: uri,
limit: 30,
cursor
})
cursor = res.cursor
members = members.concat(res.items)
} while (cursor)
Get created lists
- TypeScript
Call app.bsky.graph.getLists to view lists created by an actor.
await client.call(app.bsky.graph.getLists, {
actor: didOrHandle,
limit: 30
})
The output will match this interface:
{
cursor?: string;
lists: app.bsky.graph.defs.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.
await client.call(app.bsky.graph.getListMutes, {
limit: 30
})
The output will match this interface:
{
cursor?: string;
lists: app.bsky.graph.defs.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.
await client.call(app.bsky.graph.getListBlocks, {
limit: 30
})
The output will match this interface:
{
cursor?: string;
lists: app.bsky.graph.defs.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 client.call(app.bsky.graph.getList, {
list: listUri
})
if (res.list.viewer?.muted) {
// is muting list
}
if (res.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.
import { muteActorList, unmuteActorList } from '@bsky/sdk'
await client.call(muteActorList, { list: listUri })
Call app.bsky.graph.unmuteActorList to unmute a list.
await client.call(unmuteActorList, { list: 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 blockActorList action:
import { blockActorList, unblockActorList } from '@bsky/sdk'
await client.call(blockActorList, { list: listUri })
You delete the listblock record to unblock the list. This is also simplified for you with unblockActorList
await client.call(unblockActorList, { list: listUri })
Create a list
- TypeScript
Create a list by creating a app.bsky.graph.list record.
import { currentDatetimeString } from '@atproto/lex'
import { app } from '@bsky/sdk/lexicons'
await client.create(app.bsky.graph.list, {
purpose: 'app.bsky.graph.defs#curatelist',
name: 'Pals',
description: 'My good pals',
createdAt: currentDatetimeString()
})
Update a list's metadata
- TypeScript
Update a list by updating its app.bsky.graph.list record.
import { AtUri } from '@atproto/syntax'
const { rkey } = new AtUri(listUri)
// get the current record
const { value: record } = await client.get(app.bsky.graph.list, { rkey })
// modify the fields and write it back
await client.put(app.bsky.graph.list, {
...record,
name: newName,
description: newDescription,
}, { rkey })
Delete a list
- TypeScript
Delete a list by deleting its app.bsky.graph.list record.
const { rkey } = new AtUri(listUri)
await client.delete(app.bsky.graph.list, { rkey })
Add a user to a list
- TypeScript
Add a user to a list by creating a app.bsky.graph.listitem record.
await client.create(app.bsky.graph.listitem, {
subject: userDid,
list: listUri,
createdAt: currentDatetimeString()
})
Remove a user from a list
- TypeScript
Remove a user from a list by deleting their app.bsky.graph.listitem record.
const { rkey } = new AtUri(listItemUri)
await client.delete(app.bsky.graph.listitem, { rkey })