Packbase

pb.packs

Fetch, create, join, and manage packs with the TypeScript SDK.

A pack is a Packbase community. Call pb.packs(id) with a pack UUID to get a lazy PackHandle. The SDK does not send a request until you await the handle or call one of its methods. Use list methods such as pb.packs.list() and .create() directly on pb.packs.

Fetch and list packs

const  = await .('00000000-0000-0000-0000-000000000000')
const  = await ..()

.(.?.)
for (const  of .) {
  .(.)
}
.(`${.} packs hidden because you already belong to them`)

Awaiting a handle returns one Pack. list() returns a PackList object rather than a plain array because the response also includes visibility information:

interface PackList {
  packs: Pack[]
  hidden: number
  total_count?: number
}

Pass { search: 'text' } to filter the complete list. This endpoint has no continuation parameter, so the SDK removes the server's unusable has_more field.

Create a pack

const  = await ..({
  : 'My Art Community',
  : 'A place for digital artists.',
})

The signed-in user becomes the owner. display_name is limited to 128 characters and description to 256 characters.

Members

const  = await .('pack-id').()

for (const  of ) {
  .(., ., .)
}

This returns all members in one PackMember[]; there is no cursor or page number for this endpoint.

Join and leave

const  = await .('pack-id').()
.(., .)

await .('pack-id').()

Both methods require authentication. Pack owners cannot leave through this endpoint. Users also cannot leave if the target is their default pack.

Edit pack details

const  = await .('pack-id').({
  : 'New Name',
  : { : 'Updated description', : 'ART' },
  : { : 'data:image/png;base64,...' },
})

This operation requires the ManagePack permission. The response is a database PackUpdateResult, not a standard Pack object. Fetch the pack again if the user interface requires the formatted current state.

Settings

const  = await .('pack-id').()

for (const  of ) {
  .(., ., .)
}

settings() sends GET /pack/:id/settings and returns a discriminated PackSetting[]. Definitions contain type, a typed default, user_modifiable, and display metadata. They also contain type-specific fields such as values or range.

This route is read-only. For a definition with user_modifiable: true, update the current user's value through pb.me.settings():

await ..({ : false })

Roles

Role management requires the ManageRoles permission. Permissions are numeric bit flags, and | combines several flags into one value.

const  = await .({
  : 'Moderator',
  : . | .,
})

const  = await .()
await .(., {..., : 'Senior moderator'})
await .('user-id', [.])
await .(.)

setMemberRoles() takes the user's UUID, not the numeric membership record ID. The server strips the Owner permission bit from custom roles.

Moderate members

await .('user-id')
await .('user-id')

Despite the route calling it memberId, the value passed to kick() and ban() is the user's UUID.

Pinned howls

const { :  } = await .()
await .('howl-id', {: '2026-12-31T23:59:00.000Z'})
await .('howl-id')

Pinning requires PinHowls. A pack may have at most five active pins.

Report a pack

const  = await .('pack-id').(
  .,
  'Additional context.',
)

report() returns the created moderation ticket's id and status.

On this page