# Share your account with a team

> Invite people to work in your Coritan account with their own sign-in, give each one a role, and remove them when they leave.

Source: https://www.coritan.com/docs/account/team-members/

In the dashboard:

- /dashboard/settings/team: https://www.coritan.com/dashboard/settings/team
- /solutions/agencies: https://www.coritan.com/solutions/agencies

*Team members* work in your account with their own Coritan account and password, so nobody has to share yours. You invite each one on the **Team** tab of **Settings**, with a role that sets what they can do. You stay the owner of the account.

## Before you begin

- Sign in to the [dashboard](https://www.coritan.com/dashboard).
- Have the email address of each person you want to invite. They accept with the Coritan account that signs in with that address, or create one with it.
- While [account plans](/docs/billing/account-plans/) apply to your account, check how many seats your plan includes. See [Seats](#seats).

## Roles

| Role | What the member can do |
| --- | --- |
| **Admin** | Everything, including billing and the team. Only you can close the account. |
| **Technical** | Services, domains, email and the rest of the account. Sees the team without changing it, and cannot see billing. |
| **Billing** | Invoices, payments, the account plan and the [billing address](/docs/billing/billing-address/). Sees everything else without changing it. |
| **Read only** | Sees everything except the billing address, and changes nothing. |

A role covers the account's own resources. Each member keeps their own sign-in, sessions, password, API keys and email choices, and nobody can change those for them.

## Invite someone

1. In the sidebar, select **Settings**, then the **Team** tab.
2. On the **Team members** card, select **Invite member…**.
3. Enter their **Email** and choose a **Role**.
4. Select **Send invitation**.

A message confirms it, such as `Invitation sent to sam@example.com.` The invitation appears in the table as `Pending`, with the date its link expires. We email the link to that address, and it works for 7 days.

## Accept an invitation

If someone invited you:

1. Open the email and select its link. It opens the **Team** tab of **Settings**, with an **Invitation** card.
2. If the dashboard asks you to sign in, sign in with the address the invitation went to. If you do not have an account yet, create one with that address, then open the link again.
3. Select **Accept invitation**.

A message confirms it, such as `You joined the team of Example Ltd.` The account appears under **Teams you are on** and in the account menu.

## Work in an account you joined

1. Select your initials at the top right. Under **Work in another account**, select the account. On the **Team** tab, **Work in this account** in the account's row under **Teams you are on** does the same.
2. The dashboard opens the account's home page. A banner at the top of every page names the account and your role there, such as `You are working in Example Ltd` and `Your role here is Technical.`

What you do then happens in that account, within your role. When your role does not allow something, the dashboard tells you, such as `Your role on this account (Technical) does not allow this.` The account menu lists five accounts at most, and **All teams you are on** opens the **Team** tab with the rest.

To go back, select **Switch back** in the banner, or **Switch back to your account** in the account menu.

The choice belongs to the tab you made it in, and lasts until you close that tab or sign out. [Organizations](/docs/organizations/) open only in your own account, because each brand has its own team. If you leave the team, or the account stops letting you in, the dashboard goes back to your own account and says why.

To work in an account from a script, use the API, as [Act for an account](#act-for-an-account) shows. **Teams you are on** lists each account with the **Account ID** the API needs.

## Change a role

1. In the table, open the actions menu at the end of the member's row, and select **Change role…**.
2. Choose the new **Role**, then select **Save role**.

A member's new role applies from their next request. For an invitation that is still waiting, the new role is the one it offers.

## Remove a member or withdraw an invitation

1. Open the actions menu at the end of the row.
2. Select **Remove from team…** for a member, or **Withdraw invitation…** for an invitation that is waiting.
3. Confirm with **Remove member** or **Withdraw invitation**.

Within 10 seconds, a removed member can no longer work in your account, and the link in a withdrawn invitation stops working. You can invite them again later. For an invitation that expired, select **Remove invitation** to clear it from the table.

## Leave a team

1. On the **Team** tab, find the account under **Teams you are on**.
2. Select **Leave…**, then **Leave team**.

You can no longer work in that account. If you were working in it, the dashboard goes back to your own account. Its owner can invite you again.

## Seats

While account plans apply to your account, your plan sets how many people can share it, as [What each plan includes](/docs/billing/account-plans/#what-each-plan-includes) lists: 1 on Free, 3 on Pro, and no limit on Business and Enterprise. You count as the first seat, and so does every member and every invitation that is still waiting. An expired invitation frees its seat.

The caption under the table shows how many seats you use, such as `2 of 3 seats used, counting you.` When every seat is taken, **Invite member…** is greyed out until you remove a member or withdraw an invitation, and a card above the table offers the plan with room for one more person, with its price. Until account plans apply to your account, there is no limit and no caption.

## Result

The people you invite can work in your account within their role, each with their own sign-in. Coritan records every change a member makes in your account, and who made it.

## Troubleshooting

`That person is already on the team.`
: The address belongs to a member already. To change what they can do, [change their role](#change-a-role).

`An invitation to that address is waiting. Remove it first to send a new one.`
: Withdraw the waiting invitation, then invite the address again.

`That is the account owner's own address.`
: You entered your own address. You are the owner already.

**Every seat is taken**
: Every seat your plan includes is taken. Remove a member or withdraw an invitation, or select the upgrade the card offers ([Change your account plan](/docs/billing/change-account-plan/)).

`Your role on this account (Technical) does not allow this.`
: You are working in another account, and your role there does not cover that change. Ask the account's owner for another role, or [switch back](#work-in-an-account-you-joined) to your own account.

**You are back in your own account**
: You left the team of the account you were working in, its owner removed you, or the account is closed or suspended. Ask its owner to invite you again if you still need it.

`Organizations opens only in your own account`
: Each brand has its own team, so the [Organizations](/docs/organizations/) area cannot work in another account. Select **Switch back to your account**, or ask the brand's owner to add you to the brand's team. With account plans, the area is called **Reseller program**.

`You sent a lot of invitations in the last hour. Wait a while and try again.`
: You can send 20 invitations an hour. Wait an hour, then try again.

**Sent to another address**
: You are signed in with an address the invitation was not sent to. Select **Sign out and switch account**, then sign in with the address the invitation went to.

**This invitation has expired**
: The link is more than 7 days old. Ask the person who invited you to send a new one.

**This invitation no longer works**
: The invitation was accepted or withdrawn. Ask the person who invited you for a new one if you still need access.

**This invitation is for your own account**
: You opened a link you sent. The person you invited accepts it from their own account.

`That account is closed or suspended, so it cannot be joined.`
: The account that invited you cannot be used right now. Ask its owner.

## Related

- [Review your account's activity](/docs/account/activity-log/)
- [How account plans work](/docs/billing/account-plans/)
- [Sign out and end sessions](/docs/account/sessions/)
- [Authentication](/docs/api/authentication/)

## With the API

Routes about you always answer for you and ignore the `X-Coritan-Account` header: your sign-in routes (`/auth/...`), the routes under `/account/memberships` and `/account/invitations`, and webmail (`/client/webmail/...` and `/webmail/...`). The billing address at [`/auth/me/billing-profile`](/docs/billing/billing-address/#with-the-api) belongs to the account, so it follows the header. Only the **Admin** and **Billing** roles can read or change it.

### List your team

[`GET /account/members`](/docs/api/reference/client/account-team/#op-get-api-v1-account-members) answers the owner, the members and the invitations that are waiting or expired:

```bash
curl https://api.coritan.com/api/v1/account/members \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

```json
{
  "owner": {"user_id": 4821, "email": "alex@example.com", "name": "Alex Morgan"},
  "members": [
    {
      "id": 57,
      "email": "sam@example.com",
      "name": "Sam Taylor",
      "user_id": 5310,
      "role": "technical",
      "role_label": "Technical",
      "status": "active",
      "invited_at": "2026-09-20T10:02:11",
      "invite_expires_at": null,
      "accepted_at": "2026-09-20T12:40:05",
      "invited_by": 4821
    }
  ],
  "seats_used": 2,
  "seats_limit": 3
}
```

`status`
: `active` for a member, `pending` for an invitation that is waiting, and `expired` for one that was not accepted in time.

`name` and `user_id`
: The member's name and account number, or `null` until they accept.

`invite_expires_at`
: When a waiting invitation expires, or `null` once it is accepted.

`seats_used`
: You, every member and every waiting invitation.

`seats_limit`
: Your plan's limit, or `-1` for no limit. It is `null` until account plans apply to your account.

### Send an invitation

[`POST /account/members`](/docs/api/reference/client/account-team/#op-post-api-v1-account-members) takes the address and one of the roles `admin`, `technical`, `billing` or `readonly`:

```bash
curl -X POST https://api.coritan.com/api/v1/account/members \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email": "sam@example.com", "role": "technical"}'
```

It answers `201` with the invitation, in the shape of a member above. When every seat is taken, it answers `402` with `"code": "entitlement_exceeded"` and `"entitlement": "team_members"`, as [When you reach a limit](/docs/billing/account-plans/#when-you-reach-a-limit) describes. The other refusals are in [Troubleshooting](#troubleshooting): `422` for your own address, `409` for a member or a waiting invitation, and `429` after 20 invitations in an hour.

### Change a role or remove someone

[`PATCH /account/members/{member_id}`](/docs/api/reference/client/account-team/#op-patch-api-v1-account-members-member-id) with `{"role": "billing"}` changes the role of a member or a waiting invitation, and answers the row.

[`DELETE /account/members/{member_id}`](/docs/api/reference/client/account-team/#op-delete-api-v1-account-members-member-id) removes a member or withdraws an invitation, and answers `{"removed": true, "id": 57}`.

Both answer `404` with `Team member not found` for a row that is not on your team or was already removed. Only you and your **Admin** members can change the team.

### Read and accept an invitation

The link in the email is `https://www.coritan.com/dashboard/settings/team?invite=...`. Read what its `invite` value offers with [`GET /account/invitations/{token}`](/docs/api/reference/client/account-team/#op-get-api-v1-account-invitations-token). The answer holds `status`, `account_name`, `inviter_name`, `role`, `role_label`, `expires_at`, `email_matches` (whether you can accept it) and `own_account`.

Accept it with [`POST /account/invitations/{token}/accept`](/docs/api/reference/client/account-team/#op-post-api-v1-account-invitations-token-accept), signed in with the address it was sent to:

```bash
curl -X POST https://api.coritan.com/api/v1/account/invitations/TOKEN/accept \
  -H "Authorization: Bearer $CORITAN_TOKEN"
```

```json
{"membership_id": 57, "owner_user_id": 4821, "account_name": "Example Ltd", "role": "technical", "role_label": "Technical"}
```

| Status | Answer |
| --- | --- |
| `403` | `This invitation was sent to another address. Sign in with that address to accept it.` |
| `404` | `This invitation does not exist or was withdrawn.` |
| `409` | `This invitation is for your own account.`, `You are already on this team.` or `That account is closed or suspended, so it cannot be joined.` |
| `410` | `This invitation has expired. Ask for a new one.` |

### List and leave your teams

[`GET /account/memberships`](/docs/api/reference/client/account-team/#op-get-api-v1-account-memberships) lists the accounts you can work in:

```json
{
  "memberships": [
    {
      "id": 57,
      "owner_user_id": 4821,
      "account_name": "Example Ltd",
      "owner_email": "alex@example.com",
      "role": "technical",
      "role_label": "Technical",
      "accepted_at": "2026-09-20T12:40:05"
    }
  ]
}
```

[`DELETE /account/memberships/{membership_id}`](/docs/api/reference/client/account-team/#op-delete-api-v1-account-memberships-membership-id) leaves a team, and answers `{"left": true, "id": 57}`, or `404` with `Membership not found`.

### Act for an account

The dashboard names the account for you while you [work in it](#work-in-an-account-you-joined). To work in an account you joined from a script, send its `owner_user_id` in the `X-Coritan-Account` header with your own access token:

```bash
curl https://api.coritan.com/api/v1/client/servers \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "X-Coritan-Account: 4821"
```

The request then answers for that account, within your role. Coritan records each change you make there, and who made it, before the change runs. Pricing an order with [`POST /checkout/quote`](/docs/api/reference/client/checkout/#op-post-api-v1-checkout-quote) changes nothing, so every role can do it.

| Status | Answer | Why |
| --- | --- | --- |
| `400` | `X-Coritan-Account must be the user id of the account to act for` | The header is not an account number. |
| `403` | `"code": "not_a_member"` | You are not on that account's team, or it is closed or suspended. |
| `403` | `"code": "role_refused"` | Your role does not allow the request. `role` names your role. |
| `403` | `"code": "act_for_refused"` | Organization routes, under `/orgs`, never act for another account, because each [organization](/docs/organizations/) has its own team. Every one of them answers `Brands have their own team. Ask the brand's owner to add you to it.` when the header names another account. A header with your own account's ID is allowed. |
| `503` | `This action could not be recorded, so it was not taken. Try again.` | Coritan could not record the change, so it did not run. |

## API

- `GET /api/v1/account/members`: The account's owner, its members and the invitations not yet accepted (https://www.coritan.com/docs/api/reference/client/account-team/#op-get-api-v1-account-members)
- `POST /api/v1/account/members`: Invite an address to the team with a role (https://www.coritan.com/docs/api/reference/client/account-team/#op-post-api-v1-account-members)
- `PATCH /api/v1/account/members/{member_id}`: Give a member, or a waiting invitation, another role (https://www.coritan.com/docs/api/reference/client/account-team/#op-patch-api-v1-account-members-member-id)
- `DELETE /api/v1/account/members/{member_id}`: Remove a member, or withdraw an invitation (https://www.coritan.com/docs/api/reference/client/account-team/#op-delete-api-v1-account-members-member-id)
- `GET /api/v1/account/invitations/{token}`: What an invitation offers, for the page that accepts it (https://www.coritan.com/docs/api/reference/client/account-team/#op-get-api-v1-account-invitations-token)
- `POST /api/v1/account/invitations/{token}/accept`: Accept invitation (https://www.coritan.com/docs/api/reference/client/account-team/#op-post-api-v1-account-invitations-token-accept)
- `GET /api/v1/account/memberships`: The accounts the signed-in person can act for, and their role in each (https://www.coritan.com/docs/api/reference/client/account-team/#op-get-api-v1-account-memberships)
- `DELETE /api/v1/account/memberships/{membership_id}`: Leave a team the signed-in person belongs to (https://www.coritan.com/docs/api/reference/client/account-team/#op-delete-api-v1-account-memberships-membership-id)
