Skip to content

feat: add team role management - #44

Merged
bjarn merged 1 commit into
feat/team-invitesfrom
feat/team-roles
Oct 21, 2026
Merged

bjarn merged 1 commit into
feat/team-invitesfrom
feat/team-roles

Conversation

@bjarn

@bjarn bjarn commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

What changed

Adds custom team role management as methods on team, next to the existing team.roles() list method (team token). team.roles is already that list method, so the new calls are named …Role on team:

Method Request Returns
retrieveRole(roleId, options?) GET /team/roles/{roleId} TeamRoleData
createRole(body, options?) POST /team/roles with CreateTeamRoleData (name, description?, permissions) TeamRoleData (201)
updateRole(roleId, body, options?) PUT /team/roles/{roleId} with UpdateTeamRoleData TeamRoleData
deleteRole(roleId, query?, options?) DELETE /team/roles/{roleId}, optional { replacement_role_id } MessageResponse
duplicateRole(roleId, body, options?) POST /team/roles/{roleId}/duplicate with DuplicateTeamRoleData (name, description?) TeamRoleData (201)
  • Creating a role needs a plan with custom roles. The permissions that the chosen permissions depend on must be included, and role names are unique.
  • Built-in roles can't be changed or deleted, and the Owner role can't be duplicated.
  • deleteRole takes the optional query the same way the other methods with query parameters do. replacement_role_id is the role that receives the deleted role's assignments. It is needed only while the role is still assigned to members, invitations or SCIM groups. Without it (or with null), no query parameter is sent.
  • duplicateRole without a description keeps the source role's description.
  • TeamRoleData.description (string | null, optional) is typed on every role result, including team.roles().
  • A 409 throws the existing ConflictError and a 422 the existing ValidationError. Empty, . and .. role IDs are rejected before any request. No Idempotency-Key.
  • The coverage test no longer lists the role operations as pending.
  • README: the methods are in the Team API table and the Team API example.

Non-breaking.

Usage

const role = await lettermint.team.createRole({
  name: 'Support',
  description: 'Answers customer questions.',
  permissions: ['members:read'],
});

await lettermint.team.updateRole(role.id, {
  name: 'Support',
  description: null,
  permissions: ['members:read', 'members:manage'],
});

const copy = await lettermint.team.duplicateRole(role.id, { name: 'Support EU' });

// Move the role's members, invitations and SCIM groups to another role, then delete it.
await lettermint.team.deleteRole(copy.id, { replacement_role_id: role.id });

Checks

On this branch:

  • npm run lint: passed
  • npm run type-check: passed
  • npm run generate:check: generated files up to date with the pinned spec; the header-only mode that CI runs also passes
  • npm run test:coverage: 8 suites, 345 tests passed
  • npm run test:coverage on Node 20.18.0, 22.21.0 and 24.18.0: 345 passed each
  • npm run build: passed
  • npm run test:smoke: ESM import, CJS require and type declarations OK

Not run locally

Nothing; every CI step was run locally.

🤖 Generated with Claude Code

Add `team.retrieveRole`, `team.createRole`, `team.updateRole`,
`team.deleteRole` and `team.duplicateRole` (team token). `deleteRole`
takes an optional `replacement_role_id` query, which moves the role's
existing assignments to another role.

Co-Authored-By: Claude <noreply@anthropic.com>
@bjarn
bjarn requested a review from a team as a code owner October 20, 2026 20:46
@bjarn
bjarn added this pull request to stack #46 October 20, 2026 20:46
@bjarn
bjarn merged commit 9995f16 into main Oct 21, 2026
4 checks passed
@bjarn
bjarn deleted the feat/team-roles branch October 21, 2026 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants