# Organizations and members

Create an organization, invite people with a role, and control who keeps access.

An organization holds your projects and the people who work on them. Each member has one role in the organization, **Viewer**, **Developer** or **Admin**, and it applies to every project in it. See [Permissions](/security/permissions) for what each role can do.

## Sign in [#sign-in]

Sign in to the console with GitHub or Google. Invites match a verified email on the account: every verified email on a GitHub account, or the Google account's email. A GitHub account with no verified email is refused.

A GitHub account and a Google account are separate identities, each with its own memberships. Sign in with the account whose email the invite was sent to.

After sign-in you land on **Welcome to Parity** if you belong to no organization or have open invites. Otherwise the console opens in your organization.

| Section | What you do |
| --- | --- |
| Invitations | **Join** an organization you were invited to, with the role shown |
| Your organizations | **Open** one you already belong to |
| New organization | Enter an **Organization name** and select **Create organization** |

## Create an organization [#create-an-organization]

Whoever creates an organization is its first Admin. Names are up to 64 characters.

<Callout type="note" title="Early access">
Creating an organization is invite-only during early access. Request access at parity.ninja, or ask an Admin of your team's organization to invite you. One person can create up to 5 organizations.
</Callout>

## Invite people [#invite-people]

Admins invite from **Members** in the account menu.

1. Select **Invite people**.
2. Enter one or more emails, up to 50 at a time, and pick a role.
3. Copy the link the dialog shows and send it to them. Parity does not email invites.

An invite lasts 7 days. It can be accepted only by someone who signs in with that email verified on their GitHub or Google account, so a forwarded link is of no use to anyone else. Invitees see it under **Invitations** on the welcome page.

- Emails that already belong to a member are skipped.
- Inviting an email again renews its open invite with the new role and a fresh 7 days.
- Open invites appear in the members table with the days left. To revoke one, select it and choose **Remove**. To change its role, invite the email again.

With an [SSO connection](/security/sso), the dialog becomes **Add people** and also searches your IdP's people and groups.

## Change a role [#change-a-role]

On **Members**, select one or more people, choose **Change role**, and pick the new role. It applies within seconds.

Lowering a role revokes the project tokens the person created, since a token keeps the role it was created with. Raising a role leaves tokens as they are.

## Remove a member [#remove-a-member]

Select people on **Members** and choose **Remove**. They lose access at once:

- Their console session ends on its next request. Membership is checked on every request, cached for at most 5 seconds.
- The project tokens they created are revoked. Sandbox tokens stay valid until their sandbox expires.

You can invite them again later. A member provisioned by your IdP over SCIM is removed by unassigning them in the IdP; see [SSO and SCIM](/security/sso).

## Switch organizations [#switch-organizations]

If you belong to several organizations, open **Organizations** in the account menu. It returns you to the welcome page, where you **Open** another organization or accept an invite.

## Guards [#guards]

| Rule | Result |
| --- | --- |
| An organization always keeps at least one Admin who signs in with GitHub or Google | Demoting or removing the last one fails with `409 last_admin`. Make someone else Admin first. |
| Two Admins demote each other at the same time | One change succeeds and the other is refused. |
| Invite used by a different account | Refused: the invite is for another email address. |
| Invite expired, revoked or already used | Refused. Ask an Admin for a new one. |
| Accepting an invite to an organization you already belong to | You keep your current role. |
| Member managed by your IdP | Removing them in Parity fails with `409 managed_by_idp`. |
| Agents | Members are managed only from a console session. Project and sandbox tokens are refused, so an agent never changes who has access. |

Only Admins assigned directly who sign in with GitHub or Google count toward this guard. Admins through an IdP group or an SSO sign-in don't, so an IdP can never remove every Admin.

## API [#api]

The members API is for people signed in to the console. Project and sandbox tokens are refused with `403 forbidden`. Listing is open to every member; changes need `members.manage`, which only Admins have.

<Endpoint method="GET" path="/v0/members" permission="logs.read" />

Returns `members`, each with `person`, `email`, `role`, `effective_role`, `source`, `joined_at` and `last_active` (with SSO, also `managed`, `group_role` and `groups`), and the open `invites`.

<Endpoint method="POST" path="/v0/members/invites" permission="members.manage" />

```json title="Request"
{ "emails": ["ada@acme.com", "grace@acme.com"], "role": "Developer" }
```

Returns `201` with the `invites` created or renewed.

<Endpoint method="DELETE" path="/v0/members/invites/{invite}" permission="members.manage" />

<Endpoint method="PUT" path="/v0/members/{person}/role" permission="members.manage" />

```json title="Request"
{ "role": "Viewer" }
```

<Endpoint method="DELETE" path="/v0/members/{person}" permission="members.manage" />

`{person}` is the member's `person` id from the list, such as `github:1234567`, URL-encoded.

<Cards>
  <Card href="/security/permissions" title="Permissions">What each role can do, and how agents and tokens inherit it.</Card>
  <Card href="/security/sso" title="SSO and SCIM">Sign in through your IdP and map its groups to roles.</Card>
</Cards>
