Applications on the AT Protocol connect to the user's Personal Data Server (PDS) to access their account. Once a session is established, the app can use the lexicons implemented by the PDS to drive behaviors.
In this guide, we'll step through a couple of common patterns (with simple code examples) to help you develop an intuition about this. All APIs shown below are generated using Lexicon's code-generator CLI.
Sign-in and authentication is a simple session-oriented process. The com.atproto.session lexicon includes APIs for creating and managing these sessions.
// create an API instance with my PDS
const api = AtpApi.service('my-pds.com')
// sign in using my username and password
const res = await api.com.atproto.session.create({}, {
username: 'alice.host.com',
password: 'hunter2'
})
// configure future calls to include the token in the Authorization header
api.setHeader('Authorization', `Bearer ${res.data.accessJwt}`)
Every user has a public data repository. The application can do basic CRUD on records using the API.
await api.com.atproto.repo.listRecords({
repo: 'alice.com',
type: 'app.bsky.post'
})
await api.com.atproto.repo.getRecord({
repo: 'alice.com',
type: 'app.bsky.post',
tid: '1'
})
await api.com.atproto.repo.createRecord({
repo: 'alice.com',
type: 'app.bsky.post'
}, {
text: 'Second post!',
createdAt: (new Date()).toISOString()
})
await api.com.atproto.repo.putRecord({
repo: 'alice.com',
type: 'app.bsky.post',
tid: '1'
}, {
text: 'Hello universe!',
createdAt: originalPost.data.createdAt
})
await api.com.atproto.repo.deleteRecord({
repo: 'alice.com',
type: 'app.bsky.post',
tid: '1'
})
You may notice that the repo above is identified by a domain name alice.com
. Take a look at the Identity guide to learn more about that.
If you're noticing the "type" field and wondering how that works, see the Intro to Lexicon guide. Here is a short list of types that are currently used by the ATP software.
You'll notice "cids" in some of the schemas. A "cid" is a "Content ID," a sha256 hash of some referenced content. These are used to ensure integrity; for instance, a like includes the cid of the post being liked so that a future edit can be detected and noted in the UI.
A social follow. Example:
{
$type: 'app.bsky.graph.follow',
subject: {
did: 'did:plc:bv6ggog3tya2z3vxsub7hnal',
declarationCid: 'bafyreid27zk7lbis4zw5fz4podbvbs4fc5ivwji3dmrwa6zggnj4bnd57u'
},
createdAt: '2022-10-10T00:39:08.609Z'
}
A like on a piece of content. Example:
{
$type: 'app.bsky.feed.like',
subject: {
uri: 'at://did:plc:bv6ggog3tya2z3vxsub7hnal/app.bsky.post/1',
cid: 'bafyreif5lqnk3tgbhi5vgqd6wy5dtovfgndhwta6bwla4iqaohuf2yd764'
}
createdAt: '2022-10-10T00:39:08.609Z'
}
A microblog post. Example:
{
$type: 'app.bsky.feed.post',
text: 'Hello, world!',
createdAt: '2022-10-10T00:39:08.609Z'
}
A user profile. Example:
{
$type: 'app.bsky.actor.profile',
displayName: 'Alice',
description: 'A cool hacker'
}
A repost of an existing microblog post (similar to retweets). Example:
{
$type: 'app.bsky.feed.repost',
subject: {
uri: 'at://did:plc:bv6ggog3tya2z3vxsub7hnal/app.bsky.post/1',
cid: 'bafyreif5lqnk3tgbhi5vgqd6wy5dtovfgndhwta6bwla4iqaohuf2yd764'
}
createdAt: '2022-10-10T00:39:08.609Z'
}
While there's a lot that can be done by repo CRUD and other low-level com.atproto.* APIs, the app.bsky.* lexicon provides more powerful and easy-to-use APIs for social applications.
await api.app.bsky.feed.getTimeline()
await api.app.bsky.feed.getAuthorFeed({author: 'alice.com'})
await api.app.bsky.feed.getPostThread({uri: 'at://alice.com/app.bsky.post/1'})
await api.app.bsky.feed.getLikedBy({uri: 'at://alice.com/app.bsky.post/1'})
await api.app.bsky.feed.getRepostedBy({uri: 'at://alice.com/app.bsky.post/1'})
await api.app.bsky.actor.getProfile({user: 'alice.com'})
await api.app.bsky.graph.getFollowers({user: 'alice.com'})
await api.app.bsky.graph.getFollows({user: 'alice.com'})
await api.app.bsky.notification.list()
await api.app.bsky.notification.getCount()
await api.app.bsky.notification.updateSeen()
The AT Protocol will launch soon.
Join the waitlist to try the beta before it's publicly available.