Teams

REST endpoints for organization teams, and how teamIds assign a whole team to leads, deals, tasks, documents and phone numbers.

Overview

A team is a named group of members in your organization, for example Sales or Rentals. Teams save you from picking the same people one by one: anywhere you can assign several people, you can send a team instead.

Assigning a team is a shortcut, not a live link. When a request names a team, Fondaro looks up the team's members at that moment and assigns those people. Someone who joins the team later does not gain the records the team was assigned before, and someone who leaves the team keeps what they already have. To give a new member the team's current records, call the backfill endpoint after adding them.

Tags are the one exception: a tag scoped to a team is visible to whoever is in the team today (see Tag visibility by team).

The endpoints on this page use the dashboard's Clerk bearer token and resolve the organization from the request. Reading teams is open to every member, because every assignee picker needs the list. Creating, changing, archiving and backfilling are limited to organization admins; a member receives 403.

Endpoints

Method & pathWhoPurpose
GET /teamsAny memberList active teams with their members
POST /teamsAdminCreate a team, optionally with members
PATCH /teams/:idAdminRename, recolor, archive or restore
DELETE /teams/:idAdminArchive the team
PUT /teams/:id/membersAdminReplace the member list
POST /teams/:id/members/:userId/backfill-assignmentsAdminGive a member the team's current records

The team object

FieldTypeNotes
idstringUUID
organizationIdstringUUID
namestringUp to 80 characters, unique in the organization ignoring case
colorstring or nullOne of the tag colors: slate, blue, green, amber, red, purple, pink, teal
archivedAtstring or nullSet while the team is archived
memberIdsstring[]Clerk user ids, up to 50
memberCountnumber
createdAt / updatedAtstringISO-8601

List teams

GET /teams returns { "teams": [...] }, ordered by name. Archived teams are left out; add ?includeArchived=1 to include them.

curl 'https://api.fondaro.com/teams' \
  -H 'Authorization: Bearer <clerk-session-token>'
{
  "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, change and archive

POST /teams takes name (required), color and memberIds. Every member id must belong to your organization, otherwise the request returns 400 naming the ids that do not. A name that already exists (ignoring case, archived teams included) returns 409.

curl -X POST 'https://api.fondaro.com/teams' \
  -H 'Authorization: Bearer <clerk-session-token>' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Rentals","color":"teal","memberIds":["user_2a","user_2b"]}'

PATCH /teams/:id accepts any subset of name, color (or null) and archived. archived: true archives the team and archived: false restores it with its members.

DELETE /teams/:id archives the team and returns it. Teams are never hard-deleted from the dashboard: past assignments keep pointing at the team, and restoring it brings everything back. An archived team cannot be assigned (400) and does not appear in GET /teams.

Replace the members

PUT /teams/:id/members takes the complete list as { "userIds": [...] }. Up to 50 unique ids; an empty list empties the team. Only the people you add are checked against your organization, so a list that still contains someone who has since left never blocks the edit. Removing someone from a team never unassigns them from anything.

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

When someone is removed from your organization, Fondaro removes them from every team automatically.

Assign a team

Every write that takes a list of assignees also accepts teamIds: up to 20 team UUIDs. Fondaro looks up each team's current members, adds them to the people you listed, removes duplicates, and writes plain user ids, exactly as if you had picked everyone by hand. Requests without teamIds behave exactly as before.

EndpointField it expands into
PATCH and POST /crm/leads/:id/assigneesuserIds
PATCH /crm/leads/bulk/assigneesuserIds
POST /crm/leads (admins)assigneeIds
POST /crm/leads/:id/tasks, PATCH /crm/tasks/:taskIdassigneeIds
PATCH and POST /crm/tasks/:taskId/assigneesuserIds
POST /deals, PATCH /deals/:idassigneeIds
PATCH and POST /deals/:id/assigneesuserIds
PATCH /documents/:idassigneeIds
PATCH /twilio/phone-numbers/:idassignedUserIds

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

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

Deals and tasks give their lead to the same people, as they always do.

Limits

A single request can assign at most 50 people, whether you pick them one by one or through teams. A team itself holds at most 50 members, so any one team always fits on its own. When teams push a request over the limit, the request is refused with 400 and nothing is written:

{
  "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" }]
}

A team id that is not a team of your organization, or an archived team, returns 400 as well.

Assignment history

Assignment history entries (GET /crm/leads/:id/assignee-history, the lead timeline's assignee-change entries) record which people came through which team. An entry that added a team's members carries that team's teamId; its source and changedBy still name who made the request, as for any other assignment. A request that mixes picked people and teams produces one entry for the picked people (with any removals, and no teamId) and one per team, all at the same time. Webhooks, Loops and notifications still fire once per request.

Filter lists by team

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

Tag visibility by team

POST /tags now accepts assigneeIds and teamIds, and PATCH /tags/:id accepts teamIds, replacing the stored list. GET /tags returns teamIds on every tag. A tag scoped to teams is shown in pickers to the members of those teams, to the people in assigneeIds, and to admins. Unlike assignments, this follows the team as it changes. Like assigneeIds, it tidies pickers and is not a permission: every member can still see the tag on a lead.

Give a new member the team's records

Because assigning a team is a snapshot, adding someone to a team does not give them anything by itself. POST /teams/:id/members/:userId/backfill-assignments adds that member to the team's current records: leads, deals and tasks that were assigned through this team and are still held by at least one other current member. Deals and tasks also give the member their lead.

curl -X POST 'https://api.fondaro.com/teams/0f6d8f7e-3c1a-4a52-9d61-2b7a1c9e4d10/members/user_2c/backfill-assignments' \
  -H 'Authorization: Bearer <clerk-session-token>'
{ "leads": 42, "deals": 5, "tasks": 11, "hasMore": false }

The counts are the records that changed. Each call handles up to 1,000 records of each type; when hasMore is true, call again. The member must already be in the team (400 otherwise). A backfill is recorded in each record's assignment history as made by you through the team (with its teamId), but it does not send a notification or a lead.assigned webhook per record, so automations built on new assignments are not replayed on old leads.

Other surfaces

  • Integrations API (/integrations/v1): lead create, deal create, task create and POST /leads/:id/assignees accept teamIds in the same way. On the assignees endpoint, userIds may be omitted when teamIds names at least one team. See n8n workflows.
  • MCP (/mcp/v1) and Ask Fondaro: list_org_teams lists the teams, and the assignee inputs of create_lead, set_lead_assignees, add_lead_assignees, create_task, update_task, create_deal and update_deal accept teamIds. See MCP Server.