Skip to main content
The collections router allows users to create custom collections and organize their books.

List collections

Get all collections for the authenticated user.
const collections = await client.collections.list();

Response

Array of collection objects:
id
string
Collection UUID
name
string
Collection name
description
string | null
Collection description
isPublic
boolean
Whether collection is visible to other users
userId
string
Owner user ID
bookCount
number
Number of books in this collection
createdAt
string
ISO timestamp

Get collection details

Retrieve a collection with all its books.
const collection = await client.collections.getDetails({
  collectionId: "collection-uuid",
});

Input

collectionId
string
required
Collection UUID

Response

collection
object
Collection metadata
books
array
Array of book objects in this collection (same structure as books.getBookWithMetadata)

List book memberships

Get all collections that contain a specific book.
const memberships = await client.collections.listBookMemberships({
  bookUuid: "book-uuid",
});

Input

bookUuid
string
required
Book UUID

Response

Array of collection objects with an additional inCollection boolean indicating membership.

Create collection

Create a new collection, optionally adding a book immediately.
const collection = await client.collections.create({
  name: "Currently Reading",
  description: "Books I'm reading right now",
  isPublic: false,
  addBookUuid: "book-uuid", // Optional
});

Input

name
string
required
Collection name (1-80 characters)
description
string
Collection description (max 280 characters)
isPublic
boolean
default:false
Whether collection is visible to other users
addBookUuid
string
Optionally add this book to the collection immediately

Response

Created collection object.

Set book membership

Add or remove a book from a collection.
// Add book to collection
await client.collections.setBookMembership({
  collectionId: "collection-uuid",
  bookUuid: "book-uuid",
  inCollection: true,
});

// Remove book from collection
await client.collections.setBookMembership({
  collectionId: "collection-uuid",
  bookUuid: "book-uuid",
  inCollection: false,
});

Input

collectionId
string
required
Collection UUID
bookUuid
string
required
Book UUID
inCollection
boolean
required
true to add book, false to remove

Update collection visibility

Change whether a collection is public or private.
await client.collections.updateVisibility({
  collectionId: "collection-uuid",
  isPublic: true,
});

Input

collectionId
string
required
Collection UUID
isPublic
boolean
required
New visibility setting

Delete collection

Delete a collection (does not delete the books).
await client.collections.delete({
  collectionId: "collection-uuid",
});

Input

collectionId
string
required
Collection UUID

Input schemas

The collection input schemas are defined in packages/api/src/routers/collections/collections.model.ts:
export const CreateCollectionInput = z.object({
  name: z.string().trim().min(1).max(80),
  description: z.string().trim().max(280).optional(),
  isPublic: z.boolean().default(false),
  addBookUuid: z.string().optional(),
});

export const SetBookMembershipInput = z.object({
  collectionId: z.string().uuid(),
  bookUuid: z.string(),
  inCollection: z.boolean(),
});

export const UpdateCollectionVisibilityInput = z.object({
  collectionId: z.string().uuid(),
  isPublic: z.boolean(),
});

Example: Collection management UI

import { useState } from "react";
import { orpc } from "@/utils/orpc";

function CollectionManager({ bookUuid }: { bookUuid: string }) {
  const { data: memberships } = orpc.collections.listBookMemberships.useQuery({
    bookUuid,
  });
  
  const setMembership = orpc.collections.setBookMembership.useMutation();
  
  const handleToggle = async (collectionId: string, inCollection: boolean) => {
    await setMembership.mutateAsync({
      collectionId,
      bookUuid,
      inCollection: !inCollection,
    });
  };
  
  return (
    <div>
      <h3>Add to collections</h3>
      {memberships?.map((collection) => (
        <label key={collection.id}>
          <input
            type="checkbox"
            checked={collection.inCollection}
            onChange={() => handleToggle(collection.id, collection.inCollection)}
          />
          {collection.name}
        </label>
      ))}
    </div>
  );
}

Build docs developers (and LLMs) love