The Puter.js Teams feature lets your app see the team context around the user in front of it: whether they belong to one, and who their colleagues are.
A team is a Puter account that pays for other accounts. Members are ordinary Puter accounts — your app talks to them like any other user, and the team never gains access to a member's files. Team administration (creating teams, provisioning accounts, suspending them) happens in the account console rather than through apps, so what puter.teams offers is read-only.
Team context. list() tells you whether the signed-in user belongs to a team, and is also how you detect whether the deployment has Teams at all: it rejects with not_found where the feature is off, and resolves to an empty array where it is on and the user has no team. Called from an app, it only includes teams whose owner opened the directory to apps (see below); others are simply omitted.
Member and colleague lookup. listDirectory() returns the team's active members so your app can suggest people by name instead of asking users to type usernames. listMembers() returns the same roster; called with the user's own session or API token it also carries orgOwned and createdAt, but an app only ever gets username. Both are opt-in per team: until an owner opens the directory to apps, an app gets team_not_found, which is indistinguishable from having no team.
Sharing with a team. Anything shared with a team reaches every member with one grant, including anyone added later. Pass the team's uid as the recipient of puter.fs.share(); there is no string form, since a bare string is always read as an email or username.
Stable identifiers. A team has a uid and an optional handle. Only the uid is stable — a handle is a mutable label, and deleting the team releases it for anyone else to take. Display the name and handle; pass the uid.
puter.teams.list() - List the teams the signed-in user belongs to, and detect whether Teams is available at allputer.teams.listMembers() - List a team's accounts, with owner-only seat detailsputer.teams.listDirectory() - List a team's members, where the owner has opened the directory to appsAll three are keyset-paginated and take the same options; see each method page for the paging forms and the full error list.
Detect whether the user is on a team
<html>
<body>
<script src="https://js.puter.com/v2/"></script>
<script>
(async () => {
let teams = [];
try {
teams = await puter.teams.list();
} catch (e) {
// Teams are unavailable on this deployment.
}
puter.print(teams.length
? `On ${teams.length} team(s): ${teams.map(t => t.name).join(', ')}`
: 'Not on a team');
})();
</script>
</body>
</html>
Suggest a colleague to share with
<html>
<body>
<script src="https://js.puter.com/v2/"></script>
<script>
(async () => {
const [team] = await puter.teams.list();
if ( ! team ) return puter.print('Not on a team');
try {
const colleagues = await puter.teams.listDirectory(team.uid);
colleagues.forEach(c => puter.print(`${c.username}<br>`));
} catch (e) {
// The owner has not opened the directory to apps.
puter.print('No directory for this team');
}
})();
</script>
</body>
</html>
Share a file with the whole team
<html>
<body>
<script src="https://js.puter.com/v2/"></script>
<script>
(async () => {
const [team] = await puter.teams.list();
await puter.fs.write('report.txt', 'Quarterly numbers');
await puter.fs.share({
path: 'report.txt',
recipient: { team: team.uid },
mode: 'read',
});
puter.print(`Shared with everyone on ${team.name}`);
})();
</script>
</body>
</html>