// The following methods are available to add or edit the members of a feed
await feed.updateFeedMembers({
operation: "upsert",
members: [
{
user_id: "john",
custom: {
joined: "2024-01-01",
},
},
],
});
// Remove members
await feed.updateFeedMembers({
operation: "remove",
members: [
{
user_id: "john",
},
{
user_id: "jane",
},
],
});
// Set members (overwrites the list)
await feed.updateFeedMembers({
operation: "set",
members: [
{
user_id: "john",
},
],
});Members
Manage members
You can add and remove members to a feed. This is useful for building communities where a set of users can add content to the feed.
It's not possible to set/update member role on client-side. Use server-side SDKs for this. When adding members client-side all new members will have feed_member role:
Overview of the feed member model
FeedMemberResponse
| Name | Type | Description | Constraints |
|---|---|---|---|
created_at | number | When the membership was created | Required |
custom | object | Custom data for the membership | - |
invite_accepted_at | number | When the invite was accepted | - |
invite_rejected_at | number | When the invite was rejected | - |
membership_level | MembershipLevelResponse | Membership level assigned to the member | - |
role | string | Role of the member in the feed | Required |
status | string (member, pending, rejected) | Status of the membership. One of: member, pending, rejected | Required |
updated_at | number | When the membership was last updated | Required |
user | UserResponse | User who is a member | Required |
Feed members vs followers
Followers and members might seem like similar concepts, but they serve two different purposes with some key differences.
Followers can only be feeds (for example the timeline feed of Alice follows the user feed of Bob). Followers' aim is to access the content of a feed they're interested in and interact with it.
Members can only be users (for example Alice adds Bob as a member to her feed about "Travel Hacks"). The aim of feed members is usually to help out with admin tasks (helpful if you want to build apps similar to Facebook pages) or to decide what activities a user has access to using membership levels (for example Bob becomes a premium member in Alice's community).
Member invites
You can invite members with the invite flag, where invited users can accept or reject the membership.
await invitingFeed.updateFeedMembers({
operation: "upsert",
members: [
{
user_id: "john",
invite: true,
custom: {
reason: "community builder",
},
},
],
});
const feed = johnClient.feed(invitingFeed.group, invitingFeed.id);
// Then John can accept or reject
await feed.acceptFeedMemberInvite();
await feed.rejectFeedMemberInvite();Membership statuses
Every row in a feed's member list carries a status, and it decides what that user can do. There are exactly three:
| Status | Meaning | Can read a members feed | Real-time fan-out |
|---|---|---|---|
member | Accepted. A full member. | Yes | Yes |
pending | Invited, has not answered yet. | Yes | No |
rejected | Invited and declined. | No | No |
A member added without the invite flag is member immediately. A member added with invite: true starts as pending and becomes member or rejected when they answer.
A pending invitee can already read the feed, but does not receive its activities. This is deliberate: the invitee needs read access to see what they are being invited to, and needs to hold the membership in order to accept it — but until they accept they are not a member for delivery purposes.
Note that real-time fan-out is delivered to follows, and membership and following are separate relationships: accepting an invite does not create a follow. A user receives a members feed's activities in their own feed only when they are both an accepted member and following it. The status column above decides the membership half of that.
Rejecting is not a delete. The row stays with status: rejected, so you can tell "declined" apart from "never invited". A rejected user has no access to a members feed: they cannot read it, they receive nothing, and they can no longer follow it from a client-side request.
To remove the row entirely, remove the member explicitly:
await feed.updateFeedMembers({
operation: "remove",
members: [{ user_id: "john" }],
});Statuses and the rest of the API
member_countcounts accepted members only. Pending invitations and declined invitations do not contribute to it, so a feed whose only rows are invites reportsmember_count: 0. The same applies when filtering or sorting feeds onmember_count.queryFeedMembersreturns accepted members only unless you ask for more. Pass astatusfilter to see invitations —{ status: { $in: ['pending'] } }for outstanding invites, or{ status: { $in: ['member', 'pending', 'rejected'] } }for everything. See Feed Members Queryable Built-in Fields below.own_membershipon a feed response is populated for accepted and pending members, and is absent for a user who declined.- Membership levels are applied only to accepted members. Granting a level to a pending invitee has no effect on what they receive until they accept.
Query Feed Members
You can query the members of a feed. This is useful for showing the list of members in a community.
await feed.queryFeedMembers({
filter: {
role: "moderator",
},
});Feed Members Queryable Built-in Fields
| name | type | description | supported operations | example |
|---|---|---|---|---|
user_id | string or list of strings | The ID of the user who is a member of the feed | $in, $eq | { user_id: { $eq: 'user_123' } } |
role | string or list of strings | The role of the member | $in, $eq | { role: { $in: [ 'admin', 'moderator', 'member' ] } } |
status | string or list of strings | The membership status | $in, $eq | { status: { $in: [ 'member', 'pending', 'rejected' ] } } |
created_at | string, must be formatted as an RFC3339 timestamp | The time the membership 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 membership was last updated | $eq, $gt, $gte, $lt, $lte | { updated_at: { $gte: '2023-12-04T09:30:20.45Z' } } |