# Teams

> Manage your organization's teams and assign a whole team to leads, deals, tasks, documents and phone numbers with teamIds.

A team is a named group of members, such as Sales or Rentals. Anywhere you can assign several people, you can send `teamIds` instead of picking them one by one.

These endpoints take a signed-in member's session token (`Authorization: Bearer <session-token>`); API keys do not open them. See [Authentication](https://www.fondaro.com/docs/api/authentication.md).

Every member can list teams. Creating, changing, archiving and backfilling are for organization admins; anyone else gets `403`.

Assigning a team is a snapshot: Fondaro assigns the team's members at the moment of the request. Someone who joins later does not gain earlier records (use [backfill](#give-a-new-member-the-teams-records)), and someone who leaves keeps what they have. Tag visibility is the one exception: it follows the team as it changes.

## The team object

| Field | Type | Description |
|---|---|---|
| `id` | string | UUID |
| `organizationId` | string | UUID |
| `name` | string | Up to 80 characters, unique in the organization ignoring case |
| `color` | string or null | `slate`, `blue`, `green`, `amber`, `red`, `purple`, `pink` or `teal` |
| `archivedAt` | string or null | Set while the team is archived |
| `memberIds` | string[] | User ids, up to 50, oldest member first |
| `memberCount` | number | |
| `createdAt`, `updatedAt` | string | ISO 8601 |

## List teams

`GET /teams`

Lists active teams, ordered by name.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `includeArchived` | Query, string | No | `1` or `true` to include archived teams |

```bash
curl https://api.fondaro.com/teams \
  -H "Authorization: Bearer $SESSION_TOKEN"
```

```json
{
  "teams": [
    {
      "id": "0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10",
      "organizationId": "5b1e2c3d-4f50-4a61-8b72-9c8d7e6f5a40",
      "name": "Rentals",
      "color": "teal",
      "archivedAt": null,
      "memberIds": ["user_2a", "user_2b"],
      "memberCount": 2,
      "createdAt": "2026-09-17T09:00:00.000Z",
      "updatedAt": "2026-09-17T09:00:00.000Z"
    }
  ]
}
```

## Create a team

`POST /teams`

Admins only. Returns the team.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `name` | Body, string | Yes | Up to 80 characters |
| `color` | Body, string or null | No | One of the colours above |
| `memberIds` | Body, string[] | No | Up to 50 user ids, each a current member of your organization |

```bash
curl -X POST https://api.fondaro.com/teams \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Rentals", "color": "teal", "memberIds": ["user_2a", "user_2b"]}'
```

```json
{ "id": "0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10", "name": "Rentals", "color": "teal", "memberIds": ["user_2a", "user_2b"], "memberCount": 2, "archivedAt": null }
```

An id that is not a member answers `400` naming it. A name already in use, archived teams included, answers `409`.

## Change, archive or restore a team

`PATCH /teams/:id`

Admins only. Returns the team.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `name` | Body, string | No | Up to 80 characters |
| `color` | Body, string or null | No | One of the colours above, or `null` |
| `archived` | Body, boolean | No | `true` archives, `false` restores with its members |

```bash
curl -X PATCH https://api.fondaro.com/teams/0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10 \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"archived": false}'
```

```json
{ "id": "0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10", "name": "Rentals", "archivedAt": null }
```

`DELETE /teams/:id` also archives the team and returns it. Teams are never deleted for good: past assignments keep pointing at the team. An archived team cannot be assigned and is left out of `GET /teams`.

## Replace a team's members

`PUT /teams/:id/members`

Admins only. Sends the complete list; an empty list empties the team. Only people you add are checked against your organization. Removing someone from a team never unassigns them from anything, and people removed from your organization leave every team automatically.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `userIds` | Body, string[] | Yes | Up to 50 unique user ids |

```bash
curl -X PUT https://api.fondaro.com/teams/0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10/members \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"userIds": ["user_2a", "user_2b", "user_2c"]}'
```

```json
{ "id": "0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10", "memberIds": ["user_2a", "user_2b", "user_2c"], "memberCount": 3 }
```

## Assign a team

Every write that takes a list of people also accepts `teamIds`, up to 20 team UUIDs. Fondaro adds each team's current members to the people you name, removes duplicates and stores plain user ids.

| Endpoint | Field the teams expand into |
|---|---|
| `POST /crm/leads` (admins) | `assigneeIds` |
| `POST`, `PATCH /crm/leads/:id/assignees` | `userIds` |
| `PATCH /crm/leads/bulk/assignees` | `userIds` |
| `POST /crm/leads/:id/tasks`, `PATCH /crm/tasks/:taskId` | `assigneeIds` |
| `POST`, `PATCH /crm/tasks/:taskId/assignees` | `userIds` |
| `POST /deals`, `PATCH /deals/:id` | `assigneeIds` |
| `POST`, `PATCH /deals/:id/assignees` | `userIds` |
| `PATCH /documents/:id` | `assigneeIds` |
| `PATCH /twilio/phone-numbers/:id` | `assignedUserIds` |

On a replace (`PATCH .../assignees`, or `assigneeIds` on an update), sending only `teamIds` replaces the list with the teams' members.

```bash
curl -X POST https://api.fondaro.com/crm/leads/10132/assignees \
  -H "Authorization: Bearer $SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"userIds": [], "teamIds": ["0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10"]}'
```

Assignment history (`GET /crm/leads/:id/assignee-history` and the timeline's `assignee-change` entries) records which people came through which team: each team gets its own entry carrying its `teamId`.

## Filter lists by team

`GET /crm/leads`, `GET /crm/leads/counts`, `GET /crm/tasks`, `GET /deals`, `GET /deals/export` and `GET /calendar` accept `teamIds` next to `assigneeIds` (repeat the parameter: `?teamIds=a&teamIds=b`). For admins, the teams' current members are added to the assignee filter. Members keep seeing only their own records, and a team with no members matches nothing.

## Scope a tag to teams

`POST /tags` and `PATCH /tags/:id` accept `teamIds` (and `POST /tags` also `assigneeIds`); `GET /tags` returns `teamIds` on every tag. A team-scoped tag shows in pickers for the team's current members, the named people and admins. It tidies pickers and is not a permission: every member still sees the tag on a lead.

## Give a new member the team's records

`POST /teams/:id/members/:userId/backfill-assignments`

Admins only. Adds a member who is already in the team to the leads, deals and tasks assigned through this team that another current member still holds. Deals and tasks also give the member their lead.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `id` | Path, string | Yes | Team id |
| `userId` | Path, string | Yes | A member of the team |

```bash
curl -X POST https://api.fondaro.com/teams/0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10/members/user_2c/backfill-assignments \
  -H "Authorization: Bearer $SESSION_TOKEN"
```

```json
{ "leads": 42, "deals": 5, "tasks": 11, "hasMore": false }
```

Counts are the records that changed. Each call handles up to 1,000 records of each type; call again while `hasMore` is `true`. A backfill is recorded in assignment history but sends no notifications or `lead.assigned` webhooks.

## Teams in other APIs

- [Integration API](https://www.fondaro.com/docs/api/integrations.md): lead, deal and task create and `POST /integrations/v1/leads/:id/assignees` accept `teamIds`.
- [MCP server](https://www.fondaro.com/docs/api/mcp.md): `list_org_teams` lists teams, and the assignee inputs of the lead, task and deal tools accept `teamIds`.

## Errors and limits

| Status | When |
|---|---|
| `400` | A team that is not yours or is archived, a user who is not a member, or the assignee limit below |
| `403` | A member calls an admin endpoint |
| `404` | Unknown team |
| `409` | Team name already in use |

One request can assign at most 50 people, picked or through teams. When teams push it over, nothing is written:

```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "code": "ASSIGNEE_LIMIT_EXCEEDED",
  "message": "Assigning the team \"Sales\" would give 53 assignees; the limit is 50.",
  "limit": 50,
  "requested": 53,
  "teams": [{ "id": "0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10", "name": "Sales" }]
}
```

Source: https://www.fondaro.com/docs/api/teams
