Sharing
Sharing is how a second user gets access to nodes in ESP RainMaker Neo. Because access is scoped by group membership, you share a group rather than a node; the recipient gains access to whatever the group contains, and to whatever is added to it later.
Sharing is an invitation, not an immediate grant: the sender creates a request, and the recipient accepts or declines it.
Invite a user
await home.share({
username: "<email-or-phone>",
accessType: "secondary",
});
share(options) returns Promise<ESPAPIResponse>. username is the recipient's email address or E.164 phone number, and accessType is either:
"secondary": invite as a member who can see and control"primary": transfer ownership
It throws ESPAPICallValidationError when username is missing or blank.
Called on a subgroup, it shares just that subgroup, which is how you give somebody access to one room rather than the whole home.
The API deliberately does not reveal whether an account exists for an address, so a request for an unregistered user fails with a not-found error. Do not present that as "no such user"; the same response covers a mistyped address and an address that simply has not signed up.
Accept or decline an invitation
The recipient reads their pending invitations from the user object:
const requests = await user.listSharingRequests();
for (const request of requests) {
console.log(request.groupId, request.accessType, request.primaryEmail);
await request.accept();
}
listSharingRequests() returns Promise<ESPRMNeoSharingRequest[]>, requests received by this user. Each instance carries the request ID, the groupId and subgroupId it concerns, the accessType on offer, and the sender's primaryUserId, primaryEmail and primaryPhoneNumber so you can show who is asking.
accept() and decline() both return Promise<SuccessResponse>. Accepting grants the access; declining denies it. There is no method to list or cancel requests you sent.
accessType on a request may also be "subentity", which the group-level access type never is; that value appears when the invitation concerns a subgroup rather than a whole group.
See who has access
const info = await home.getSharingInfo();
for (const member of info.users) {
console.log(member.userId, member.email, member.accessType);
}
getSharingInfo() returns Promise<GroupSharingInfo>, whose users array carries userId, email, optional phoneNumber, accessType, and subgroups when access came through a subgroup.
What you see depends on your own access, and the cloud decides that:
| Your access | You see |
|---|---|
| primary | Every member |
| secondary | The group's primary owners |
| subgroup | The group's primary owners |
So an empty-looking member list on a secondary account is expected, not a failure.
Remove access
await home.removeMember("<user-id>");
await home.leave();
removeMember(userId) returns Promise<ESPAPIResponse> and removes another user. It throws ESPAPICallValidationError when userId is blank or refers to the caller.
leave() removes the calling user. The two are not interchangeable: use leave() for yourself, removeMember() for anyone else. Get your own ID from user.getUserInfo() if you need to filter yourself out of a member list.
A group must always keep at least one primary user, so the last owner can neither be removed nor leave.
Method summary
| Method | Returns |
|---|---|
group.share(options) | ESPAPIResponse |
group.getSharingInfo() | GroupSharingInfo |
group.removeMember(userId) | ESPAPIResponse |
group.leave() | ESPAPIResponse |
user.listSharingRequests() | ESPRMNeoSharingRequest[] |
request.accept() | SuccessResponse |
request.decline() | SuccessResponse |
Related
- Groups — access types and the group model
- Manage groups — lifecycle and membership
- User info — obtaining your own user ID
- User–node association — how ownership works
- Security model — how access is enforced