Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
424 linesCodeBlameRaw
1---
2title: Teams
3description: Group a workspace's people into teams, give a team a lead and a channel, give a team a role on repositories, mention it with @workspace/team, and ask it to review pull requests, with review assignment picking who.
4---
5
6A **team** is a group of a workspace's people. Instead of giving each
7person a role on each repository, you give the team a role, and everyone
8in it has it. A team can have a lead and a channel. A team is also a name you can use in conversation: mention
9`@acme/backend` in a comment and everyone in it hears of it, or ask it to
10review a pull request and it decides who looks.
11
12Only members of a workspace can be in its teams.
13Someone who leaves the workspace leaves all of its teams with it.
14
15For the workspace's directory and profiles, see
16[people and teams](/guides/people-and-teams/).
17
18## Create a team
19
20Any member of the workspace with a confirmed email address can create a
21team, and becomes its first maintainer, unless an owner has set
22[who can create teams](#who-can-create-teams) to owners only.
23
241. Open **Teams** in the sidebar: `g1t.sh/<workspace>/-/teams`.
252. Choose **New team**, or go to `g1t.sh/<workspace>/-/teams/new`. The
26 **+** menu in the top bar has **New team** too, for the workspace the
27 sidebar is on.
283. Give it a **name**, such as `Backend`. Its **slug**, the name used in
29 addresses and mentions, is made from the name (`backend`); you can
30 change it.
314. Optionally, add a **description**, choose its **visibility**, pick a
32 **parent** team, and add **members**.
335. Choose **Create team**.
34
35The team's page is `g1t.sh/<workspace>/-/teams/<team>`, and it is
36mentioned as `@<workspace>/<team>`.
37
38| Field | Limits |
39| --- | --- |
40| Name | Up to 80 characters. |
41| Slug | 1 to 60 lowercase letters, digits and single hyphens, not starting or ending with a hyphen. Unique in the workspace. `Web & Mobile` becomes `web-mobile`. |
42| Description | Up to 280 characters. |
43| Teams in one workspace | Up to 500. |
44
45The **Teams** page lists the teams you can see, yours first, then by
46name, with a search box that matches names and slugs. Each team shows
47counts such as *2 members · 1 repository*. A person's teams also show on
48their card in the [People directory](/guides/people-and-teams/#the-directory)
49and on their profile.
50
51### Who can create teams
52
53An owner chooses who can create the workspace's teams, under **Workspace →
54Access → [Permissions](/guides/permissions/#people-and-teams)**, in the
55**People and teams** card:
56
57| Who can create teams | |
58| --- | --- |
59| **Any member** | Every member with a confirmed email address. The default. |
60| **Owners only** | Only the workspace's owners. Members see **Only owners can create teams in this workspace.** on the Teams page instead of **New team**, and **New team** in the **+** menu is greyed out. |
61
62Teams that already exist stay as they are, and their maintainers still
63manage them. The change is recorded in the [audit log](/guides/audit-log/)
64as `workspace.team_creation_changed`.
65
66Through the API, set `team_creation` to `members` or `owners` with
67[`PATCH /workspaces/{workspace}`](/reference/api/workspaces/update-workspace/)
68(the `workspace` tool's `update` action over MCP); the workspace you get
69back, and [`GET /workspaces/{workspace}`](/reference/api/workspaces/get-workspace/),
70include it. Creating a team when you may not is refused with `403`.
71
72## Visibility
73
74| Visibility | Who can see it, mention it and ask it to review |
75| --- | --- |
76| **Visible** | Every member of the workspace. The default. |
77| **Secret** | Its own people and the workspace's owners. To anyone else it does not exist. |
78
79Secret teams cannot be nested: a secret team has no parent and no child
80teams. To make a nested team secret, first take it out from under its
81parent and move its child teams elsewhere.
82
83## Maintainers and members
84
85Each person in a team is a **maintainer** or a **member**. Maintainers
86look after the team; owners of the workspace can do everything a
87maintainer can on every team, whether or not they are in it.
88
89| | Who |
90| --- | --- |
91| See a visible team | Every member of the workspace |
92| See a secret team | Its own people and the workspace's owners |
93| Create a team | Any member. Under a parent: an owner, or a maintainer of the parent |
94| Add and remove people, make someone a maintainer | Owners, and the team's maintainers |
95| Set its lead and channel | Owners, and the team's maintainers |
96| Change its name, slug, description, visibility, notifications and review assignment | Owners, and the team's maintainers |
97| Move it under another team | Owners, or someone who maintains both teams |
98| Delete it | Owners, and the team's maintainers |
99| Give it a role on a repository | Anyone with the Admin [role](/guides/access-and-roles/) on that repository |
100| Take its role on a repository away | Admin on that repository, owners, and the team's maintainers |
101| Leave it | Anyone in it |
102
103Changing a team is for people, signed in or with a personal access token,
104with a confirmed email address. A workspace's token cannot change one.
105
106To manage the people in a team:
107
1081. Open the team, `g1t.sh/<workspace>/-/teams/<team>`. **People** is its
109 first tab.
1102. Add someone by username. They must already be a member of the
111 workspace.
1123. Beside a person, choose **Make maintainer** (or **Make member**), or
113 **Remove**. Beside yourself, **Leave**.
114
115Turn on **Include the people of child teams** to also list the people of its
116[child teams](#nesting), each with the child team they are in.
117
118## Lead and channel
119
120A team's header shows **Led by**, its **#channel**, **Code: N
121repositories** (its roles on repositories) and **Storage** (coming).
122
123A maintainer or an owner sets them under the team's **Settings**, **Lead
124and channel**:
125
126| Setting | What it is |
127| --- | --- |
128| **Lead** | A person on the team. |
129| **Channel** | The team's channel in [Chat](/guides/chat/), by name. Leave it empty for none. |
130| **Storage level** | Coming. |
131
132Taking the lead off the team, or out of the workspace, leaves the team
133with no lead.
134
135## Nesting
136
137A team can have a **parent**. Choose one when you create it, or under the
138team's **Settings**. A child team:
139
140- **inherits its parent's roles on repositories**, and its parent's
141 parent's, all the way up. Its own role on a repository counts too; the
142 highest wins.
143- **is reached by its parent's mentions and review requests.** Mentioning
144 `@acme/engineering` tells the people of `@acme/backend` under it too, and
145 asking `@acme/engineering` to review asks them too.
146
147It never works the other way: a team's own people get nothing from its
148child teams.
149
150| Rule | |
151| --- | --- |
152| How deep | At most 8 levels: a team, its child, that child's child, and so on. |
153| Secret teams | Cannot have a parent or child teams. |
154| Cycles | A team cannot go under itself or one of its own child teams. |
155| Deleting a parent | Its child teams move up to its own parent, or to the top if it had none. |
156
157The **Child teams** tab, `g1t.sh/<workspace>/-/teams/<team>/teams`, lists
158a team's children. To take a team out from under its parent, clear
159**Parent** in its settings.
160
161## Repository access
162
163A team is given a role on a repository the way a person is, with the
164same five [roles](/guides/access-and-roles/#the-roles). Everyone in the
165team, and in its child teams, has that role there. A team has roles only on
166its own workspace's repositories.
167
168From the team:
169
1701. Open the team's **Repositories** tab,
171 `g1t.sh/<workspace>/-/teams/<team>/repositories`.
1722. Choose a repository and a role, and **Add**.
173
174Or from the repository: someone with Admin opens **Settings → Access**,
175`g1t.sh/<workspace>/<repo>/settings/access`, and adds the team, with a role,
176under **Teams with access**.
177
178The **Repositories** tab lists the team's own roles and the ones it
179inherits, each repository once at the highest role, naming the parent team
180an inherited one comes from. Change a role by picking another, or
181**Remove** it. A role a team inherits can only be changed on the parent
182that gives it.
183
184### How roles combine
185
186Your role on a repository is the highest of everything that gives you one:
187ownership, the base permission, roles given to you directly, and the roles
188of every team you are in and of their parents. See
189[how your role is worked out](/guides/access-and-roles/#how-your-role-is-worked-out).
190
191For example, in a workspace whose base permission is **Read**:
192
193| Where it comes from | Role on `acme/api` |
194| --- | --- |
195| Base permission | Read |
196| `@acme/engineering`, a parent of `@acme/backend` | Write |
197| `@acme/backend`, which Ana is in | Maintain |
198| Given to Ana directly | Triage |
199| **Ana's role** | **Maintain**, from `@acme/backend` |
200
201The repository's **Settings → Access** lists **Teams with access**, each
202with its role and how many people are in it, and shows for each person
203where their role comes from, such as **Through team backend**. When two give
204the same role, a role given directly is shown first, then a team's, so the
205one shown is the one you would change.
206
207Taking someone's direct role away leaves what their teams give them. To
208take away what a team gives, remove the team's role, or remove the person
209from the team.
210
211## Mentions
212
213Write `@<workspace>/<team>`, such as `@acme/backend`, in a comment, or in
214the description of an issue or pull request when you open it, and the
215people of that team and its child teams are told in their
216[notifications](/guides/notifications/), with the reason `team_mention`:
217
218```text
219ana mentioned @acme/backend on acme/api#42
220```
221
222Comment boxes suggest teams as you type `@acme/`.
223
224| | |
225| --- | --- |
226| Who is told | Everyone in the team and its child teams, but not whoever wrote it. |
227| When | The team's **Notify the team when it is mentioned** setting is on (the default), and the writer can see the team: a member of its workspace, and for a secret team, in it or an owner. Otherwise nobody is told. |
228| Not a mention | `@acme/backend` in code, in a quoted line (`>`), inside an address or a path such as `ops@acme/backend` or `@acme/backend/src`, or in a package name such as `@acme/backend@1`. |
229| Subscribes them | Yes. Each person told is subscribed to the issue or pull request, as with a mention by name. |
230
231Someone mentioned by name and through a team is told once, as `mention`.
232People only see what is about repositories they can read.
233
234To stop a team's mentions telling its people, a maintainer turns off
235**Notify the team when it is mentioned** in the team's **Settings**. The team can still be
236mentioned; the text links to it, and nobody is told.
237
238## Review requests
239
240A pull request can ask a team to review it. Add the team in the
241**Reviewers** box on the pull request, as `@acme/backend`, or have a
242[CODEOWNERS file](/guides/codeowners/) ask it. Asking needs what asking a
243person needs: the Triage role or higher, or being the pull request's
244author.
245
246- Only teams of the repository's own workspace can be asked.
247- A secret team can be asked only by its own people and owners.
248- A pull request can ask up to 10 teams.
249
250The team stays listed under **Reviewers** as requested. What happens next
251depends on its **review assignment**:
252
253| Review assignment | Who is asked |
254| --- | --- |
255| **Off** (the default) | Everyone in the team and its child teams is told, with the reason `review_requested`, never the pull request's author. Anyone in it can review. |
256| **On** | g1t picks people from the team. Each one picked becomes a reviewer in their own right, listed under **Reviewers** beside the team, and is told. |
257
258Removing a team from **Reviewers** takes the request away; people it
259picked stay reviewers until you remove them too.
260
261### Review assignment
262
263A maintainer sets it in the team's **Settings**, under **Code review
264assignment**:
265
266| Setting | Default | What it does |
267| --- | --- | --- |
268| **Assign reviewers from the team** | Off | On: pick people instead of asking the whole team. |
269| **How many people** | 1 | People to pick, 1 to 10. People from the team who are already reviewers count towards it. |
270| **Who goes first** | Round robin | **Round robin** or **Load balance**. See below. |
271| **Skip people who are busy** | Off | Leave out anyone with too many pull requests waiting on their review. Beside it, how many waiting pull requests makes someone busy, 1 to 100 (5 by default). |
272| **Pick from child teams too** | Off | Also pick from the people of its child teams. |
273| **Also tell the rest of the team** | Off | Also tell everyone else in the team when people are picked. |
274| **Never pick** | None | Usernames never picked, up to 100. |
275
276A pull request is **waiting on** someone when it is open or a draft, they
277are one of its reviewers, and they have not yet approved it or asked for
278changes.
279
280g1t never picks the pull request's author, anyone under **Never pick**,
281or anyone already asked. The same facts always pick the same people: ties go
282by username.
283
284| Algorithm | Who goes first |
285| --- | --- |
286| **Round robin** | Whoever this team has had asked least recently. People it has never asked come first of all. Everyone is asked once before anyone is asked twice. |
287| **Load balance** | Whoever has the fewest pull requests waiting on their review. Among equals, whoever this team asked least recently. |
288
289For example, `@acme/backend` has five people:
290
291| Person | Last asked by the team | Waiting on them |
292| --- | --- | --- |
293| ana | 5 October | 1 |
294| bo | never | 4 |
295| cy | 1 October | 0 |
296| dee | 6 October | 0 |
297| eve | never | 2 |
298
299zed opens a pull request and asks `@acme/backend` to review it:
300
301| Settings | Picked |
302| --- | --- |
303| Round robin, how many 1 | bo (never asked; first by name) |
304| Round robin, how many 3 | bo, eve, cy |
305| Load balance, how many 2 | cy, dee (nothing waiting; cy asked longer ago) |
306| Round robin, how many 3, skip busy at 2 | cy, ana, dee (bo and eve are busy) |
307| Round robin, how many 2, bo already a reviewer | eve (bo counts towards the 2) |
308| Round robin, how many 3, opened by bo | eve, cy, ana (never the author) |
309
310### On the pull request
311
312The timeline records who asked whom: **ana requested a review from
313@acme/backend**, and, when people are picked, **requested a review from
314cy**. Notifications say **ana asked @acme/backend to review acme/api#42** to
315the team's people, and **ana asked you to review acme/api#42** to each
316person picked. A request made by a CODEOWNERS file reads **acme/api#42
317changes files @acme/backend owns**.
318
319## Settings
320
321A team's **Settings**, `g1t.sh/<workspace>/-/teams/<team>/settings`, holds
322its name, slug, description, visibility, parent, **Lead and channel**,
323**Notify the team when it is mentioned**, **Code review
324assignment**, and **Delete team**.
325
326Changing the slug changes how the team is mentioned and its address. A
327CODEOWNERS file that names the old slug no longer resolves it, and shows an
328error until you change the file.
329
330Deleting a team takes away every role it gave on repositories, and its
331child teams move up to its parent. Its people stay in the workspace.
332
333## Through the API
334
335Every route is in the [API reference](/reference/api/), and each is an
336action of the `team` [MCP tool](/reference/mcp/). Reading teams needs the
337`workspace:read` scope; changing them `workspace:admin`; giving or taking
338a team's role on a repository `access:admin`.
339
340| Route | MCP action | What it does |
341| --- | --- | --- |
342| `GET /workspaces/{workspace}/teams` | `list` | The teams you can see, yours first. `q` narrows by name or slug. |
343| `POST /workspaces/{workspace}/teams` | `create` | Create a team. Body: `name`, and optionally `slug`, `description`, `visibility` (`visible` or `secret`), `parent` (a slug), `notify` and `members` (usernames). |
344| `GET /workspaces/{workspace}/teams/{team}` | `get` | One team. |
345| `PATCH /workspaces/{workspace}/teams/{team}` | `update` | Change what you give: `name`, `slug`, `description`, `visibility`, `parent` (`""` takes it out from under its parent), `notify`, `review_assignment`. |
346| `DELETE /workspaces/{workspace}/teams/{team}` | `delete` | Delete a team. |
347| `GET /workspaces/{workspace}/teams/{team}/members` | `list_members` | Its people. `include_child_teams=true` adds its child teams' people, each with `via`. |
348| `PUT /workspaces/{workspace}/teams/{team}/members/{username}` | `set_member` | Add someone, or change their place. Body: `role`, `member` or `maintainer`. |
349| `DELETE /workspaces/{workspace}/teams/{team}/members/{username}` | `remove_member` | Take someone out, or leave. |
350| `GET /workspaces/{workspace}/teams/{team}/teams` | `list_child_teams` | Its child teams. |
351| `GET /workspaces/{workspace}/teams/{team}/repos` | `list_repos` | The repositories it has a role on, its own and inherited (`inherited_from`). |
352| `PUT /workspaces/{workspace}/teams/{team}/repos/{repo}` | `set_repo` | Give it a role on a repository, or change it. Body: `role`. |
353| `DELETE /workspaces/{workspace}/teams/{team}/repos/{repo}` | `remove_repo` | Take its role away. |
354| `PUT /workspaces/{workspace}/teams/{team}/review_assignment` | `set_review_assignment` | Set review assignment: `enabled`, `algorithm` (`round_robin` or `load_balance`), `count`, `skip_busy`, `busy_at`, `include_child_teams`, `excluded`, `notify_team`. |
355| `GET /workspaces/{workspace}/members/{username}/teams` | `list_user_teams` | The teams someone is in, as you can see them. |
356
357Asking a team to review is on the pull request: `POST
358/repos/{owner}/{name}/pulls/{number}/requested_reviewers` with
359`team_reviewers` (each as `workspace/team`, or the team's slug), and
360`DELETE` on the same route to take a request away
361(the `pull_request` tool's `request_reviewers` and
362`remove_requested_reviewers` actions, with the `pull_requests:write`
363scope). A pull request's `team_reviewers` lists the teams asked, as
364`workspace/team`.
365
366```sh
367curl -X POST https://api.g1t.sh/workspaces/acme/teams \
368 -H "Authorization: Bearer $G1T_TOKEN" -H "Content-Type: application/json" \
369 -d '{"name": "Backend", "parent": "engineering", "members": ["ana", "cy"]}'
370```
371
372```json
373{
374 "id": "team_01m4a3k0q6e8pd9h2x7c5vbn1r",
375 "workspace": "acme",
376 "slug": "backend",
377 "name": "Backend",
378 "description": null,
379 "visibility": "visible",
380 "parent": { "slug": "engineering", "name": "Engineering" },
381 "notify": true,
382 "review_assignment": {
383 "enabled": false,
384 "algorithm": "round_robin",
385 "count": 1,
386 "skip_busy": false,
387 "busy_at": 5,
388 "include_child_teams": false,
389 "excluded": [],
390 "notify_team": false
391 },
392 "members_count": 3,
393 "repos_count": 0,
394 "child_teams_count": 0,
395 "viewer_role": "maintainer",
396 "can_manage": true,
397 "created_at": "2026-10-07T15:04:11.208Z",
398 "updated_at": "2026-10-07T15:04:11.208Z"
399}
400```
401
402```sh
403curl -X PUT https://api.g1t.sh/workspaces/acme/teams/backend/repos/api \
404 -H "Authorization: Bearer $G1T_TOKEN" -H "Content-Type: application/json" \
405 -d '{"role": "maintain"}'
406```
407
408## Webhooks and the audit log
409
410Changes to a team are sent to the workspace's [webhooks](/guides/webhooks/).
411The `team.repo_*` events are about a repository, so that repository's
412webhooks get them too.
413
414| Event | When |
415| --- | --- |
416| `team.created`, `team.edited`, `team.deleted` | A team was created, changed or deleted. On `team.edited`, `data.changes` names what changed, such as `name` or `parent`. |
417| `team.member_added`, `team.member_role_changed`, `team.member_removed` | Someone joined or left a team, or became a maintainer or a member. `data.username`, `data.role`, `data.previous_role`. |
418| `team.repo_added`, `team.repo_role_changed`, `team.repo_removed` | A team was given a role on a repository, had it changed, or lost it. `data.repo`, `data.repo_id`, `data.repo_role`, `data.previous_repo_role`. |
419
420Each has `data.workspace`, `data.team_id`, `data.team` (its slug),
421`data.name`, `data.visibility` and, for a child team, `data.parent`.
422
423The workspace's [audit log](/guides/audit-log/) records the same changes
424under the same names.