# team

Reference for surrealctl team — listing organisation members, inspecting one, inviting someone, changing a role, and ending a membership.

`surrealctl team` manages organisation members: the people who already belong. Invitations that have been sent but not accepted live in [`invite`](/docs/reference/cli/surrealctl/commands/invite.md), and `team list` deliberately does not fold them in — a pending invitation is not a member.

<Synopsis>
surrealctl team <COMMAND> [OPTIONS]
surrealctl teams <COMMAND> [OPTIONS]
</Synopsis>

| Verb | Purpose | Alias |
| --- | --- | --- |
| [`list`](#team-list) | List the members of an organisation | `ls` |
| [`get`](#team-get) | Show one member | |
| [`invite`](#team-invite) | Invite someone to an organisation | |
| [`update`](#team-update) | Change a member's role | |
| [`remove`](#team-remove) | End someone's membership of an organisation | `rm` |

Two verbs here break the house grammar on purpose. `remove` is not `delete`, because `delete` invites the reading that the *person* is deleted rather than their membership. `invite` exists because sending one is how a team gains a member and no house verb covers it — and it shares [`invite create`](/docs/reference/cli/surrealctl/commands/invite.md#invite-create)'s implementation rather than copying it.

The API has no route for a single member, so `get`, `update` and `remove` fetch the member list and match locally, by id or username, with did-you-mean suggestions when nothing matches.

## surrealctl team list {#team-list}

List the members of an organisation.

<Synopsis>
surrealctl team list [OPTIONS]
</Synopsis>

This command takes no positional argument. The organisation comes from `--org` and the [precedence chain](/docs/reference/cli/surrealctl/global-flags.md#the-precedence-chain).

Accepts the [list presentation flags](/docs/reference/cli/surrealctl/output-and-exit-codes.md#list-presentation-flags) and nothing else. Column ids are `username`, `name` and `role`, with `user_id` and `profile_picture` under `--wide`.

```bash
surrealctl team list
```

```text title="Output"
USERNAME             NAME            ROLE
ana@acme.example     Ana Silva       owner
bo@acme.example      Bo Nakamura     admin
cai@acme.example     Cai Oduya       member
```

```bash title="Owners and admins only"
surrealctl team list --json | jq -r '.[] | select(.role != "member") | .username'
```

## surrealctl team get {#team-get}

Show one member.

<Synopsis>
surrealctl team get [OPTIONS] <MEMBER>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<MEMBER>",
            "required": true,
            "description": "The member, by username or user id."
        }
    ]}
/>

This command has no options of its own.

```bash
surrealctl team get bo@acme.example
```

A username that does not match any member exits `5`, and lists the near matches it found.

## surrealctl team invite {#team-invite}

Invite someone to an organisation.

<Synopsis>
surrealctl team invite [OPTIONS] --role <ROLE> <EMAIL>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<EMAIL>",
            "required": true,
            "description": "The email address to invite."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--role",
            "value": "<ROLE>",
            "required": true,
            "description": "The role to grant. Run `surrealctl org roles` for the ones this organisation defines."
        }
    ]}
/>

```bash
surrealctl team invite dee@acme.example --role member
```

The answer is the invitation, not a member — the person appears in [`team list`](#team-list) only once they accept. Track it in the meantime with [`invite list`](/docs/reference/cli/surrealctl/commands/invite.md#invite-list).

**Refusals**, exit `2`, before any request. The address validator is deliberately shallow — an `@` with something either side and no internal whitespace — because the API is the authority on deliverability:

```text
`dee.acme.example` is not an email address: it has no `@`.
```

The role vocabulary is per organisation, so only an empty value is refused locally:

```text
A role cannot be empty. Run `surrealctl org roles` to see the ones this organization defines.
```

A role the API rejects as invalid is annotated with a pointer to [`org roles`](/docs/reference/cli/surrealctl/commands/org.md#org-roles) — but only for that class of error, never for a 403 or a rate limit, where the role is not the problem.

## surrealctl team update {#team-update}

Change a member's role.

<Synopsis>
surrealctl team update [OPTIONS] --role <ROLE> <MEMBER>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<MEMBER>",
            "required": true,
            "description": "The member, by username or user id."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--role",
            "value": "<ROLE>",
            "required": true,
            "description": "The new role. Run `surrealctl org roles` for the ones this organisation defines."
        }
    ]}
/>

```bash
surrealctl team update cai@acme.example --role admin
```

## surrealctl team remove {#team-remove}

End someone's membership of an organisation.

<Synopsis>
surrealctl team remove [OPTIONS] <MEMBER>
</Synopsis>

<OptionsTable
    title="Arguments"
    options={[
        {
            "name": "<MEMBER>",
            "required": true,
            "description": "The member, by username or user id."
        }
    ]}
/>

<OptionsTable
    title="Options"
    options={[
        {
            "name": "--force",
            "description": "Remove without confirming."
        }
    ]}
/>

```bash title="With a confirmation"
surrealctl team remove cai@acme.example
```

```bash title="From an offboarding script"
surrealctl team remove cai@acme.example --force --json
```

This ends a membership. It does not delete the person's SurrealDB account, and it does not touch anything they created.

**Refusals.** The confirmation names the person. Declining exits `0`. In a non-interactive session without `--force` or `--yes`, it exits `2` having sent nothing.

## Related pages

- [`invite` commands](/docs/reference/cli/surrealctl/commands/invite.md) — pending invitations
- [`org roles`](/docs/reference/cli/surrealctl/commands/org.md#org-roles) — the roles this organisation defines
- [`org permissions`](/docs/reference/cli/surrealctl/commands/org.md#org-permissions) — what a role lets you do
- [Overview](/docs/reference/cli/surrealctl/overview.md) — the rest of the reference
- [SurrealDB CLI](/docs/reference/cli/surrealdb-cli/overview.md) — database users, which are a separate concept from organisation members
