Skip to main content

Overview

The app.bsky.actor namespace provides lexicons for managing user profiles, preferences, and actor-related operations in Bluesky.

Key Concepts

  • Actor: A user or account in the Bluesky network
  • Profile: User’s public profile information
  • Preferences: User’s application settings and preferences
  • Viewer State: Relationship between the viewing user and the subject

Record Types

profile

User profile record stored at app.bsky.actor.profile with rkey self. Record Structure:
displayName
string
Display name (max 64 graphemes)
description
string
Profile bio (max 256 graphemes)
avatar
blob
Profile picture blob reference
banner
blob
Banner image blob reference
labels
union
Self-applied labels (content warnings)
joinedViaStarterPack
ref
Starter pack used to join (if any)
createdAt
string
Profile creation timestamp
pinnedPost
ref
Strong reference to pinned post
Example:
await agent.com.atproto.repo.putRecord({
  repo: agent.session.did,
  collection: 'app.bsky.actor.profile',
  rkey: 'self',
  record: {
    $type: 'app.bsky.actor.profile',
    displayName: 'Alice Smith',
    description: 'Software engineer • Coffee enthusiast • 🌊',
    avatar: avatarBlob,
    banner: bannerBlob,
    createdAt: new Date().toISOString()
  }
})

Queries

getProfile

Get detailed profile view of an actor. Endpoint: app.bsky.actor.getProfile
actor
string
required
Handle or DID of account to fetch
Response: Returns profileViewDetailed with full profile information Example:
const response = await agent.app.bsky.actor.getProfile({
  actor: 'alice.bsky.social'
})

const profile = response.data
console.log(profile.displayName)
console.log(profile.followersCount)
console.log(profile.description)
curl "https://bsky.social/xrpc/app.bsky.actor.getProfile?actor=alice.bsky.social"

getProfiles

Get multiple profile views. Endpoint: app.bsky.actor.getProfiles
actors
array
required
Array of handles or DIDs (max 25)
Response: Array of profileViewDetailed objects Example:
const response = await agent.app.bsky.actor.getProfiles({
  actors: ['alice.bsky.social', 'bob.bsky.social', 'carol.bsky.social']
})

for (const profile of response.data.profiles) {
  console.log(profile.handle, profile.followersCount)
}

searchActors

Search for actors matching a query. Endpoint: app.bsky.actor.searchActors
q
string
required
Search query
limit
integer
Maximum results (1-100, default 25)
cursor
string
Pagination cursor
Response:
cursor
string
Next page cursor
actors
array
required
Array of matching profiles
Example:
const response = await agent.app.bsky.actor.searchActors({
  q: 'alice',
  limit: 10
})

for (const actor of response.data.actors) {
  console.log(actor.handle, actor.displayName)
}

searchActorsTypeahead

Search for actors with typeahead/autocomplete. Endpoint: app.bsky.actor.searchActorsTypeahead
q
string
required
Search query
limit
integer
Maximum results (1-100, default 10)
Response: Array of matching actors Example:
// As user types "ali..."
const response = await agent.app.bsky.actor.searchActorsTypeahead({
  q: 'ali',
  limit: 5
})

// Show suggestions
for (const actor of response.data.actors) {
  console.log(`@${actor.handle} - ${actor.displayName}`)
}

getSuggestions

Get suggested actors to follow. Endpoint: app.bsky.actor.getSuggestions
limit
integer
Maximum suggestions (1-100, default 50)
cursor
string
Pagination cursor
Response: Array of suggested actors to follow Example:
const response = await agent.app.bsky.actor.getSuggestions({
  limit: 10
})

for (const actor of response.data.actors) {
  console.log('Suggested:', actor.handle)
}

Preferences

getPreferences

Get user preferences. Endpoint: app.bsky.actor.getPreferences Authentication: Required Response: Array of preference objects Example:
const response = await agent.app.bsky.actor.getPreferences()

for (const pref of response.data.preferences) {
  if (pref.$type === 'app.bsky.actor.defs#savedFeedsPrefV2') {
    console.log('Saved feeds:', pref.items)
  }
}

putPreferences

Update user preferences. Endpoint: app.bsky.actor.putPreferences Authentication: Required
preferences
array
required
Array of preference objects
Example:
await agent.app.bsky.actor.putPreferences({
  preferences: [
    {
      $type: 'app.bsky.actor.defs#adultContentPref',
      enabled: false
    },
    {
      $type: 'app.bsky.actor.defs#contentLabelPref',
      label: 'graphic-media',
      visibility: 'warn'
    }
  ]
})

Type Definitions

profileViewBasic

Basic profile information.
did
string
required
Actor DID
handle
string
required
Actor handle
displayName
string
Display name
avatar
string
Avatar image URL
viewer
object
Viewer’s relationship to this actor
labels
array
Content labels

profileView

Standard profile view with additional details. Includes all fields from profileViewBasic plus:
description
string
Profile bio
indexedAt
string
When profile was indexed

profileViewDetailed

Complete profile information. Includes all fields from profileView plus:
banner
string
Banner image URL
followersCount
integer
Number of followers
followsCount
integer
Number of accounts followed
postsCount
integer
Number of posts
pinnedPost
ref
Pinned post reference

viewerState

Viewer’s relationship with the actor.
muted
boolean
Whether viewer has muted this actor
mutedByList
ref
List that mutes this actor (if any)
blockedBy
boolean
Whether viewer is blocked by this actor
blocking
string
AT-URI of block record (if blocking)
following
string
AT-URI of follow record (if following)
followedBy
string
AT-URI of their follow record (if they follow you)

Preference Types

adultContentPref

Adult content preference.
{
  $type: 'app.bsky.actor.defs#adultContentPref',
  enabled: boolean
}

contentLabelPref

Content label visibility preference.
{
  $type: 'app.bsky.actor.defs#contentLabelPref',
  labelerDid?: string,
  label: string,
  visibility: 'ignore' | 'show' | 'warn' | 'hide'
}

savedFeedsPrefV2

Saved and pinned feeds.
{
  $type: 'app.bsky.actor.defs#savedFeedsPrefV2',
  items: [
    {
      id: string,
      type: 'feed' | 'list' | 'timeline',
      value: string,
      pinned: boolean
    }
  ]
}

mutedWordsPref

Muted words/phrases.
{
  $type: 'app.bsky.actor.defs#mutedWordsPref',
  items: [
    {
      value: string,
      targets: ['content' | 'tag'],
      actorTarget?: 'all' | 'exclude-following',
      expiresAt?: string
    }
  ]
}

Common Use Cases

Update Profile

// Upload avatar
const avatarBlob = await agent.uploadBlob(avatarFile, {
  encoding: 'image/jpeg'
})

// Update profile
await agent.com.atproto.repo.putRecord({
  repo: agent.session.did,
  collection: 'app.bsky.actor.profile',
  rkey: 'self',
  record: {
    $type: 'app.bsky.actor.profile',
    displayName: 'Alice Smith',
    description: 'Software engineer 👩‍💻',
    avatar: avatarBlob.data.blob
  }
})

Search and Follow Users

// Search for users
const results = await agent.app.bsky.actor.searchActors({
  q: 'alice'
})

// Follow the first result
if (results.data.actors.length > 0) {
  const actor = results.data.actors[0]
  
  await agent.com.atproto.repo.createRecord({
    repo: agent.session.did,
    collection: 'app.bsky.graph.follow',
    record: {
      $type: 'app.bsky.graph.follow',
      subject: actor.did,
      createdAt: new Date().toISOString()
    }
  })
}

Manage Muted Words

// Get current preferences
const prefs = await agent.app.bsky.actor.getPreferences()

// Find or create muted words pref
let mutedWords = prefs.data.preferences.find(
  p => p.$type === 'app.bsky.actor.defs#mutedWordsPref'
)

if (!mutedWords) {
  mutedWords = {
    $type: 'app.bsky.actor.defs#mutedWordsPref',
    items: []
  }
}

// Add a muted word
mutedWords.items.push({
  value: 'spoiler',
  targets: ['content'],
  actorTarget: 'all'
})

// Save preferences
await agent.app.bsky.actor.putPreferences({
  preferences: prefs.data.preferences
})

Resources

Build docs developers (and LLMs) love