# Teams

Group users for billing, access control and reporting.

> Enterprise API · https://developer.telgea.com/docs/enterprise/api/teams

## The team object {#object}

Group users for billing, access control, and reporting.

| Field | Type | Description |
| --- | --- | --- |
| `id` | string (required) | UUID of the team. Example: `"2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70"` |
| `name` | string (required) | Team name. Example: `"Field Sales"` |
| `emoji` | string (required) | Emoji shown next to the team name, or null. Example: `"🚀"` |
| `costCode` | string (required) | Cost center code applied to all users in this team Example: `"CC-4100"` |
| `memberCount` | integer (required) | Number of users currently in the team. Example: `12` |
| `isDefault` | boolean (required) | Whether this is your organization's default team, Unassigned. Every user in no other team is in it, and it cannot be updated. Example: `false` |

## Operations

- `GET` [List all teams](#list-all-teams)
- `POST` [Create a new team](#create-a-new-team)
- `PATCH` [Update a team](#update-a-team)

### List all teams {#list-all-teams}

`GET /v1/teams` · Enterprise API

Retrieves a paginated list of all teams in your organization. Teams are organizational units used to group users for billing, access control, and reporting purposes.

Use the `page` and `pageSize` query parameters to navigate through large result sets.

Requires the permission `teams:read` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/teams/GET/v1/teams). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `page` | query | integer | Page to return, starting at 1. Example: `1` |
| `pageSize` | query | integer | Items per page, at most 50. Defaults to 50. Example: `50` |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` | Successfully retrieved teams. Returns a paginated list with total count. | `ListTeamsResponse` |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to list teams | `ForbiddenError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Response fields (200, ListTeamsResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `page` | integer (required) | The page these items came from. Example: `1` |
| `pageSize` | integer (required) | Items per page, as requested. Example: `50` |
| `itemsCount` | integer (required) | Total items across all pages. Divide by pageSize to get the number of pages. Example: `142` |
| `items` | array of TeamListItem (required) | Teams on this page. |
| `items.id` | string (required) | UUID of the team. Example: `"2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70"` |
| `items.name` | string (required) | Team name. Example: `"Field Sales"` |
| `items.emoji` | string (required) | Emoji shown next to the team name, or null. Example: `"🚀"` |
| `items.costCode` | string (required) | Cost center code applied to all users in this team Example: `"CC-4100"` |
| `items.memberCount` | integer (required) | Number of users currently in the team. Example: `12` |
| `items.isDefault` | boolean (required) | Whether this is your organization's default team, Unassigned. Every user in no other team is in it, and it cannot be updated. Example: `false` |

**Example request**

```bash
curl -X GET "https://api.telgea.com/v1/teams" \
  -H "x-api-key: $TELGEA_API_KEY"
```

**Response 200**

```json
{
  "page": 1,
  "pageSize": 50,
  "itemsCount": 3,
  "items": [
    {
      "id": "2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70",
      "name": "Field Sales",
      "emoji": "🚀",
      "costCode": "CC-4100",
      "memberCount": 12,
      "isDefault": false
    },
    {
      "id": "7c2e9f10-4b83-4d55-a0e6-1f8b3d6c2a94",
      "name": "Support",
      "emoji": null,
      "costCode": null,
      "memberCount": 4,
      "isDefault": false
    },
    {
      "id": "2b8d4e61-9c37-4f02-b5a8-6e1d0c7f3a59",
      "name": "Unassigned",
      "emoji": "▫️",
      "costCode": null,
      "memberCount": 7,
      "isDefault": true
    }
  ]
}
```

### Create a new team {#create-a-new-team}

`POST /v1/teams` · Enterprise API

Creates a new team in your organization. Teams help organize users into logical groups for billing, access control, and reporting.

After creating a team, you can assign users to it and associate it with billing entities for billing allocation.

Requires the permission `teams:create` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/teams/POST/v1/teams). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `idempotency-key` | header | string | A value unique to this request, of 1 to 255 printable ASCII characters — a UUID is the usual choice. Retry with the same key within 24 hours and you get the original response back, even if it was a failure, and nothing is done twice. Send a new key whenever you change the request. Keys are private to your API key and organisation. Example: `0b7e4f1c-6a2d-4c9e-8f35-d1a7b2c93e60` |

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `name` | string (required) | Team name Example: `"Field Sales"` |
| `emoji` | string | Emoji representing the team Example: `"🚀"` |
| `costCode` | string | Cost center code applied to all users in this team Example: `"IT 5000"` |
| `userIds` | array of string (uuid) | Existing user IDs to add to the team on creation |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `200` | Team created successfully. Returns the created team object including the auto-generated team ID. | `CreateTeamResponse` |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to create teams | `ForbiddenError` |
| `404` | A user id in `userIds` is not in your organization | `NotFoundError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Response fields (200, CreateTeamResponse)**

| Field | Type | Description |
| --- | --- | --- |
| `id` | string (required) | UUID of the created team. Example: `"2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70"` |

**Example request**

```bash
curl -X POST "https://api.telgea.com/v1/teams" \
  -H "x-api-key: $TELGEA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Field Sales",
  "emoji": "🚀",
  "costCode": "IT 5000",
  "userIds": [
    "9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01"
  ]
}'
```

**Response 200**

```json
{
  "id": "2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70"
}
```

### Update a team {#update-a-team}

`PATCH /v1/teams/{teamId}` · Enterprise API

Updates an existing team's information. All fields are optional - only provide the fields you want to update.

You can update basic information like name, emoji, and cost center code. Providing `userIds` replaces the team's full membership: users in the list are added, and users not in the list move to the default team, Unassigned.

The default team (`isDefault: true` in GET /v1/teams) cannot be updated.

Requires the permission `teams:update` on the key.

[Try it in the playground](https://developer.telgea.com/playground#tag/teams/PATCH/v1/teams/{teamId}). Calls run against your live organization; there is no sandbox.

**Parameters**

| Parameter | In | Type | Description |
| --- | --- | --- | --- |
| `teamId` | path | string (uuid) (required) | UUID of the team. Example: `2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70` |
| `idempotency-key` | header | string | A value unique to this request, of 1 to 255 printable ASCII characters — a UUID is the usual choice. Retry with the same key within 24 hours and you get the original response back, even if it was a failure, and nothing is done twice. Send a new key whenever you change the request. Keys are private to your API key and organisation. Example: `0b7e4f1c-6a2d-4c9e-8f35-d1a7b2c93e60` |

**Request body**

| Field | Type | Description |
| --- | --- | --- |
| `name` | string | Team name Example: `"Field Sales"` |
| `emoji` | string | Emoji representing the team Example: `"🚀"` |
| `costCode` | string | Cost center code applied to all users in this team Example: `"IT 5000"` |
| `userIds` | array of string (uuid) | Full desired member list. When provided, replaces the team's membership: users not in the list are removed, new user IDs are added. |

**Responses**

| Status | Meaning | Body |
| --- | --- | --- |
| `204` | Team updated successfully. No content returned. | none |
| `400` | Request failed schema validation, or was refused by a business rule | none |
| `401` | Missing or invalid API key in the X-API-Key header | `UnauthorizedError` |
| `403` | Insufficient permissions to update teams | `ForbiddenError` |
| `404` | Team not found, or a user id in `userIds` is not in your organization | `NotFoundError` |
| `409` | This is your organization's default team, Unassigned, so it cannot be changed. | `ConflictError` |
| `429` | The API key has used its request quota for the current window. `Retry-After` says how many seconds until it resets. | `TooManyRequestsError` |
| `500` | Internal server error. Contact support if this persists. | `InternalError` |

**Example request**

```bash
curl -X PATCH "https://api.telgea.com/v1/teams/2f6b0d3a-8c1e-4a7f-9b2d-1e3c4d5f6a70" \
  -H "x-api-key: $TELGEA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Field Sales EMEA",
  "emoji": "🌍",
  "costCode": "IT 5001",
  "userIds": [
    "9c1f2a6e-3b7d-4e0a-8f21-5d6c7b8a9e01"
  ]
}'
```
