Skip to content

Members

client.members and client.invitations do what the dashboard’s Members pages do: list who has access and at which role, give or take a role, and invite people by email. Without project= a call is about the organization; with a workspace ID, about that workspace.

An API key needs the opt-in members:read scope to read and members:write to change; no default key and no * key holds either (see Admin scopes). Reading a space also takes projects:read. A key acts as the person who made it: only an admin or owner manages people, and nobody grants a role above their own. A workspace key acts only on its own workspace, so it always passes project=. Each change shows in Activity with the key’s name.

people = client.members.list() # the organization
people = client.members.list(project="<PROJECT_ID>") # one workspace
for m in people.people:
print(m.email, m.role, [p.source for p in m.paths])
print(people.my_role, people.can_manage_members)

Response

MemberList
{
"space": {"space_id": "…", "kind": "organization", "name": "Qualia", "slug": "qualia"},
"people": [
{
"user_id": "…",
"email": "bob@example.com",
"display_name": "Bob",
"role": "admin",
"paths": [
{"role": "admin", "source": "direct", "grant_id": "…",
"granted_on": {"space_id": "…", "kind": "organization", "name": "Qualia"}}
]
}
],
"can_manage_members": true,
"can_create_children": true,
"my_role": "owner"
}

can_manage_members says whether this caller may change people there: for a key, its creator’s role allows it and the key holds members:write.

One person’s role on every space of the organization you can read. Needs an organization key.

person = client.members.get("<USER_ID>")
for space in person.spaces:
print(space.name, space.kind, space.role, space.direct)

Returns a PersonAccess: member is false for a guest of a workspace.

Give a person a role on the organization, or on one workspace, or move them to another. An organization role is for the organization’s members: invite anyone else. A workspace role raises a member above their organization role there, or makes someone a guest of it.

change = client.members.set_role("<USER_ID>", "contributor")
change = client.members.set_role("<USER_ID>", "admin", project="<PROJECT_ID>")
print(change.from_role, change.role, change.effective_role, change.changed)

Returns a RoleChange. changed is false when they already held that role.

Take a person’s role on one workspace away (they keep what the organization gives them), or remove them from the organization. keep= names the workspaces they stay a guest of, at the role they hold there. A key cannot remove its own creator from the organization: leaving one takes a signed-in session.

client.members.remove("<USER_ID>", project="<PROJECT_ID>")
change = client.members.remove("<USER_ID>", keep=["<PROJECT_ID>"])
print(change.kept)
for inv in client.invitations.list(): # every one in the organization
print(inv.email, inv.space_role, inv.space_name, inv.expires_at)
inv = client.invitations.send("new@example.com", "viewer", project="<PROJECT_ID>")
client.invitations.withdraw(inv.invitation_id)

send invites to the organization, or with project= to one workspace as a guest, never above your own role. Someone already in the organization gets a role with set_role instead (400). withdraw finds the invitation anywhere in the organization; a workspace key passes its own workspace as project=.

StatusMeaning
403The key lacks members:read or members:write, or the role does not allow it
404No such person, invitation or space, or not one you can read
400Invite them first: they are not in the organization
409The organization’s last owner stays