---
title: "Team Members"
description: "Add, invite, re-role and remove the members of an Incident Management team."
---

Team membership decides who can be put on a team's rotations and overrides, and who is a **team admin** (`imRole: "admin"`) with write access to that one team. To read the current members, use [Get a team](/api/incident-management/teams#get-a-team).

Member roles (`imRole`): `admin`, `member` or `stakeholder`. Default is `member`.

Only accounts that could use Incident Management themselves can be members: active users with the organization role `admin`, `editor` or `responder`.

## Authentication

Base IM access (an IM-eligible role or an organization-wide API token, Incident Management activated) plus the team write bar: organization `admin` role, or team admin of this team. An API token runs with the role of the user who created it, so only a token created by an organization admin passes. Creating a **new** user account through the invite additionally needs the organization `admin` role.

## Add a member

`POST /api/im/teams/:id/members`

Adds an existing user of your organization to the team.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `userId` | string | Yes | The user to add. Must belong to the team's organization. |
| `imRole` | string | No | `admin`, `member` or `stakeholder`. Default `member`. |

### Example (cURL)

```bash
curl -X POST "$BASE_URL/api/im/teams/3/members" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "userId": "u_def456", "imRole": "member" }'
```

### Response

`200 OK`

```json
{
  "id": 18,
  "userId": "u_def456",
  "imRole": "member",
  "user": { "name": "Bob Fixit", "email": "bob@example.com" }
}
```

`id` is the membership id used by the endpoints below. `user.email` is `null` unless you are an organization admin.

## Invite a member by email

`POST /api/im/teams/:id/invite`

Adds a member by email address instead of user id:

- **Email belongs to a user of your organization:** that user is linked to the team. Their account and role stay untouched, no email is sent.
- **Email belongs to no account:** a new user with the organization role `responder` is created, linked to the team and sent an invitation email. Needs the organization `admin` role.
- **Email belongs to an account in another organization:** refused with `422`, nothing is created.

The email is matched case-insensitively and stored lowercase.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `email` | string | Yes | Email address of the person to add. |
| `imRole` | string | No | `admin`, `member` or `stakeholder`. Default `member`. |

### Example (cURL)

```bash
curl -X POST "$BASE_URL/api/im/teams/3/invite" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "email": "carla@example.com" }'
```

### Response

`200 OK`

```json
{
  "id": 19,
  "userId": "u_ghi789",
  "imRole": "member",
  "invitedNewUser": true,
  "user": { "name": "carla@example.com", "email": "carla@example.com" }
}
```

`invitedNewUser` is `true` when a new account was created and the invitation email went out. Until the person signs in, their `name` is their email address.

## Change a member's role

`PATCH /api/im/teams/:id/members/:memberId`

`:memberId` is the membership id (`members[].id` from [Get a team](/api/incident-management/teams#get-a-team)), not the user id.

### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `imRole` | string | Yes | `admin`, `member` or `stakeholder`. |

### Example (cURL)

```bash
curl -X PATCH "$BASE_URL/api/im/teams/3/members/18" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "imRole": "admin" }'
```

### Response

`200 OK`

```json
{ "id": 18, "userId": "u_def456", "imRole": "admin" }
```

Sending the role the member already has returns the same shape and changes nothing.

## Remove a member

`DELETE /api/im/teams/:id/members/:memberId`

Removes the membership. The user stays in any rotation group of the team's schedules and keeps their overrides; take them out of the rotations with [Update a schedule](/api/incident-management/update-schedule) if they should no longer be paged.

### Example (cURL)

```bash
curl -X DELETE "$BASE_URL/api/im/teams/3/members/18" \
  -H "Authorization: Bearer $TOKEN"
```

### Response

`200 OK`

```json
{ "success": true }
```

## Common errors

- `401 Unauthorized` (`unauthorized`) when not authenticated
- `403 Forbidden` (`imAccessDenied`) for a customer-scoped token, or a session without an IM-eligible role
- `403 Forbidden` (`imNotEnabled`) when Incident Management is not activated for the organization
- `403 Forbidden` (`imTeamWriteDenied`) when you are neither organization admin nor team admin of this team
- `403 Forbidden` (`forbidden`) on invite when the email has no account yet and you are not an organization admin
- `404 Not Found` (`imTeamNotFound`) when the team does not exist or belongs to another organization
- `404 Not Found` (`imTeamMemberNotFound`) when `:memberId` is not a membership of this team
- `404 Not Found` (`userNotFound`) when `userId` does not exist or belongs to another organization
- `400 Bad Request` (`invalidRequestBody`) when `:id` or `:memberId` is not a positive integer, `userId` is missing, `email` is missing or not an email address, or `imRole` is not `admin`, `member` or `stakeholder`
- `400 Bad Request` (`imUserNotEligible`) when the user is inactive or does not have the organization role `admin`, `editor` or `responder`
- `422 Unprocessable Entity` (`imInviteEmailNotEligible`) when the email belongs to an account in another organization
- `409 Conflict` (`imTeamMemberExists`) when the user is already a member of this team
