Bookmarks

Overview

The API includes built-in support for bookmarking activities. Here's a quick example of how to use the bookmark API.

Adding Bookmarks

// Adding a bookmark to a new folder
_, err = client.Feeds().AddBookmark(context.Background(), activityID, &getstream.AddBookmarkRequest{
  UserID: getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error adding bookmark:", err)
}

// Adding to an existing folder
_, err = client.Feeds().AddBookmark(context.Background(), activityID, &getstream.AddBookmarkRequest{
  FolderID: getstream.PtrTo("folder_456"),
  UserID:   getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error adding bookmark to folder:", err)
}

// Update a bookmark (without a folder initially) - add custom data and move it to a new folder
_, err = client.Feeds().UpdateBookmark(context.Background(), activityID, &getstream.UpdateBookmarkRequest{
  FolderID: getstream.PtrTo("old folder id"),
  NewFolder: &getstream.AddFolderRequest{
    Name: "New folder name",
    Custom: map[string]any{
      "icon": "📂",
    },
  },
  Custom: getstream.PtrTo(map[string]any{
    "color": "blue",
  }),
  UserID: getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error updating bookmark:", err)
}

// Update a bookmark - move it from one existing folder to another existing folder
_, err = client.Feeds().UpdateBookmark(context.Background(), activityID, &getstream.UpdateBookmarkRequest{
  FolderID:    getstream.PtrTo("old folder id"),
  NewFolderID: getstream.PtrTo("new folder id"),
  UserID:      getstream.PtrTo("john"),
})
if err != nil {
  log.Fatal("Error moving bookmark:", err)
}

Removing Bookmarks

_, err = client.Feeds().DeleteBookmark(context.Background(), activityID, &getstream.DeleteBookmarkRequest{
  FolderID: getstream.PtrTo(folderID),
  UserID: getstream.PtrTo("john"),
})

Querying Bookmarks

// Query bookmarks
firstPage, err := client.Feeds().QueryBookmarks(context.Background(), &getstream.QueryBookmarksRequest{
  Filter: getstream.PtrTo(map[string]any{
    "user_id": "john",
  }),
  Limit: getstream.PtrTo(2),
})
if err != nil {
  log.Fatal("Error querying bookmarks:", err)
}

// Get next page
_, err = client.Feeds().QueryBookmarks(context.Background(), &getstream.QueryBookmarksRequest{
  Filter: getstream.PtrTo(map[string]any{
    "user_id": "john",
  }),
  Limit: getstream.PtrTo(2),
  Next:  firstPage.Data.Next,
})
if err != nil {
  log.Fatal("Error querying next page bookmarks:", err)
}

// Query by activity ID
_, err = client.Feeds().QueryBookmarks(context.Background(), &getstream.QueryBookmarksRequest{
  Filter: getstream.PtrTo(map[string]any{
    "user_id":     "john",
    "activity_id": activityID,
  }),
})
if err != nil {
  log.Fatal("Error querying bookmarks by activity ID:", err)
}

// Query by folder ID
_, err = client.Feeds().QueryBookmarks(context.Background(), &getstream.QueryBookmarksRequest{
  Filter: getstream.PtrTo(map[string]any{
    "user_id":   "john",
    "folder_id": folderID,
  }),
})
if err != nil {
  log.Fatal("Error querying bookmarks by folder ID:", err)
}

Bookmarks Queryable Built-In Fields

name type description supported operations example
user_id string or list of strings The ID of the user who owns the bookmark $in, $eq { user_id: { $eq: 'user_123' } }
activity_id string or list of strings The ID of the activity that was bookmarked $in, $eq { activity_id: { $eq: 'activity_123' } }
folder_id string or list of strings The ID of the folder containing the bookmark $eq, $in, $exists { folder_id: { $exists: true } }
created_at string, must be formatted as an RFC3339 timestamp The time the bookmark was created $eq, $gt, $gte, $lt, $lte { created_at: { $gte: '2023-12-04T09:30:20.45Z' } }
updated_at string, must be formatted as an RFC3339 timestamp The time the bookmark was last updated $eq, $gt, $gte, $lt, $lte { updated_at: { $gte: '2023-12-04T09:30:20.45Z' } }

Querying Bookmark Folders

// Query bookmark folders
firstPage, err := client.Feeds().QueryBookmarkFolders(context.Background(), &getstream.QueryBookmarkFoldersRequest{
  Filter: getstream.PtrTo(map[string]any{
    "user_id": "<user id>",
  }),
  Limit: getstream.PtrTo(2),
})
if err != nil {
  log.Fatal("Error querying bookmark folders:", err)
}
// Get next page
_, err = client.Feeds().QueryBookmarkFolders(context.Background(), &getstream.QueryBookmarkFoldersRequest{
  Filter: getstream.PtrTo(map[string]any{
    "user_id": "<user id>",
  }),
  Limit: getstream.PtrTo(2),
  Next:  firstPage.Data.Next,
})
if err != nil {
  log.Fatal("Error querying bookmark folders second page:", err)
}

// Query with folder name filter
_, err = client.Feeds().QueryBookmarkFolders(context.Background(), &getstream.QueryBookmarkFoldersRequest{
  Filter: getstream.PtrTo(map[string]any{
    "user_id": "<user id>",
    "folder_name": map[string]any{
      "$contains": "project",
    },
  }),
  Limit: getstream.PtrTo(2),
  Next:  firstPage.Data.Next,
})
if err != nil {
  log.Fatal("Error querying bookmark folders with filter:", err)
}

Bookmark Folders Queryable Built-In Fields

name type description supported operations example
user_id string or list of strings The ID of the user who owns the folder $in, $eq { user_id: { $eq: 'user_123' } }
folder_name string or list of strings The name of the bookmark folder $eq, $in, $contains { folder_name: { $contains: 'work' } }
created_at string, must be formatted as an RFC3339 timestamp The time the folder was created $eq, $gt, $gte, $lt, $lte { created_at: { $gte: '2023-12-04T09:30:20.45Z' } }
updated_at string, must be formatted as an RFC3339 timestamp The time the folder was last updated $eq, $gt, $gte, $lt, $lte { updated_at: { $gte: '2023-12-04T09:30:20.45Z' } }

Managing Bookmark Folders

Update bookmark folder

The endpoint performs a partial update: only the fields you include in the request are changed, and each of those fields is completely overwritten.

Updating a bookmark folder sends feeds.bookmark_folder.updated event to the clients of the user who owns the folder. There are no default client-side SDK handlers for this event, but you can add a custom handler if your UI needs to be updated.

Delete bookmark folder

Use the delete bookmark folder endpoint to remove a folder by ID. All bookmarks in that folder are removed.

Deleting a bookmark folder sends feeds.bookmark_folder.deleted event to the clients of the user who owns the folder. There are no default client-side SDK handlers for this event, but you can add a custom handler if your UI needs to be updated.

// Add a bookmark with a new folder
addResp, err := client.Feeds().AddBookmark(context.Background(), activityID, &getstream.AddBookmarkRequest{
  UserID: getstream.PtrTo("john"),
  NewFolder: &getstream.AddFolderRequest{
    Name:   "Breakfast recipes",
    Custom: map[string]any{"icon": "🍳"},
  },
})
if err != nil {
  log.Fatal(err)
}
folderID := addResp.Data.Bookmark.Folder.ID

// Update the folder
updateResp, err := client.Feeds().UpdateBookmarkFolder(context.Background(), folderID, &getstream.UpdateBookmarkFolderRequest{
  Name:   getstream.PtrTo("Sweet Breakfast Recipes"),
  Custom: getstream.PtrTo(map[string]any{"icon": "🥞"}),
})
if err != nil {
  log.Fatal(err)
}

// Delete the folder (and all bookmarks in it)
_, err = client.Feeds().DeleteBookmarkFolder(context.Background(), updateResp.Data.BookmarkFolder.ID)
if err != nil {
  log.Fatal(err)
}
Add Chat to my app: getstream.io/SKILL.md

The fastest way to build with Stream. Start a new project or improve an existing one. Full CLI and documentation integration out of the box.


Ask your agent:

/stream Build me a Social App with Feeds and Moderation.
/stream Any livestream calls running?
/stream Feeds Go v3: <Your Question>