Teams
Teams group users and service accounts together and grant shared, scoped access to specific app environments. Each team can carry optional role overrides that apply only to apps accessed via that team's grants, so the same member can hold different effective permissions in different teams. On this page, we'll look at the Teams API endpoints for managing teams, their membership, and their app-environment scope.
Teams require a Pro or Enterprise plan. POST /v1/teams/ returns 403 on the Free plan.
The Team model
Properties
- Name
id- Type
- string
- Description
Unique identifier for the team.
- Name
name- Type
- string
- Description
The team name. Maximum 64 characters.
- Name
description- Type
- string
- Description
An optional team description.
- Name
isScimManaged- Type
- boolean
- Description
Whether this team is provisioned and synced by your SCIM identity provider. SCIM-managed teams cannot be renamed, deleted, or have user members added or removed via this API — those operations must be performed through the SCIM provider. Service account membership is unaffected and remains manageable via the API.
- Name
memberRole- Type
- object
- Description
The optional role override for human members of the team. When set, the role unions with each member's organisation role for app-level permissions on apps the team has access to.
nullmeans no override — members keep their organisation role on team-accessed apps.
- Name
serviceAccountRole- Type
- object
- Description
The optional role override for service-account members of the team. Same semantics as
memberRole, applied to service accounts.
- Name
owner- Type
- object
- Description
The OrganisationMember that owns the team (the team creator by default). Team owners can transfer access scope and add other members. Team owners retain their organisation role on team-accessed apps regardless of
memberRole.
- Name
createdAt- Type
- timestamp
- Description
Timestamp of when the team was created.
- Name
updatedAt- Type
- timestamp
- Description
Timestamp of when the team was last updated.
Permission model
Team access is additive: granting team membership never reduces a member's effective permissions. For each app the team has access to, the request is permitted if either the member's individual organisation role grants the action or the team's effective role (override → org role) grants it. The same member can be in multiple teams; permissions union across all of them.
Server-side Encryption (SSE) is required for an app to be granted to a team — the server provisions per-member EnvironmentKey records when teams are attached to apps or members are added to teams. Apps without SSE return 400 Bad Request when added to a team's scope.
List Teams
Retrieve all teams in the organisation. Requires the Teams.read org permission. Teams are returned without members or apps detail — fetch the Team Detail endpoint for those.
Request
curl https://api.phase.dev/v1/teams/ \
-H "Authorization: Bearer {token}"
Response
{
"data": [
{
"id": "cf3c159d-3edb-4da6-8dbf-0af4959dabf4",
"name": "backend-eng",
"description": "Backend engineering team",
"isScimManaged": false,
"memberRole": null,
"serviceAccountRole": null,
"owner": {
"id": "99e37555-108d-4331-a385-6db971bbd617",
"email": "[email protected]"
},
"createdAt": "2024-06-01T12:00:00Z",
"updatedAt": "2024-06-01T12:00:00Z"
}
]
}
Create Team
Create a new team. The calling user becomes the team's owner and is automatically added as a member. Service-account callers create the team without an owner and no auto-membership.
Requires the Teams.create org permission and a Pro or Enterprise plan.
JSON Body
Required fields
- Name
name- Type
- string
- Description
The team name. Maximum 64 characters. HTML tags and ASCII control characters are stripped; whitespace is trimmed.
Optional fields
- Name
description- Type
- string
- Description
A description for the team. Maximum 10,000 characters.
- Name
member_role_id- Type
- string
- Description
Role ID to apply as the team's
memberRoleoverride. Must reference a role in the same organisation.
- Name
service_account_role_id- Type
- string
- Description
Role ID to apply as the team's
serviceAccountRoleoverride. Must reference a role in the same organisation.
The is_scim_managed flag is set automatically by the SCIM provisioning flow. Passing it in the request body returns 400 Bad Request.
Request
curl -X POST https://api.phase.dev/v1/teams/ \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "backend-eng",
"description": "Backend engineering team"
}'
Response
{
"id": "cf3c159d-3edb-4da6-8dbf-0af4959dabf4",
"name": "backend-eng",
"description": "Backend engineering team",
"isScimManaged": false,
"memberRole": null,
"serviceAccountRole": null,
"owner": {
"id": "99e37555-108d-4331-a385-6db971bbd617",
"email": "[email protected]"
},
"createdAt": "2024-06-01T12:00:00Z",
"updatedAt": "2024-06-01T12:00:00Z",
"members": [
{
"type": "user",
"id": "99e37555-108d-4331-a385-6db971bbd617",
"email": "[email protected]",
"fullName": "Alice Smith"
}
],
"apps": []
}
Get Team
Retrieve a single team with its members and app-environment scope. Non-team-members can list teams via List Teams but cannot fetch detail unless they hold a global-access role (Owner or Admin).
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the team.
Request
curl https://api.phase.dev/v1/teams/cf3c159d-3edb-4da6-8dbf-0af4959dabf4/ \
-H "Authorization: Bearer {token}"
Response
{
"id": "cf3c159d-3edb-4da6-8dbf-0af4959dabf4",
"name": "backend-eng",
"description": "Backend engineering team",
"isScimManaged": false,
"memberRole": {
"id": "5d880011-2fc9-4e78-9be2-80f4183c0eea",
"name": "Developer"
},
"serviceAccountRole": null,
"owner": {
"id": "99e37555-108d-4331-a385-6db971bbd617",
"email": "[email protected]"
},
"createdAt": "2024-06-01T12:00:00Z",
"updatedAt": "2024-06-02T09:00:00Z",
"members": [
{
"type": "user",
"id": "99e37555-108d-4331-a385-6db971bbd617",
"email": "[email protected]",
"fullName": "Alice Smith"
},
{
"type": "service_account",
"id": "0df24d46-e057-4695-a519-eee3d34e291c",
"name": "deploy-bot"
}
],
"apps": [
{
"id": "72b9ddd5-8fce-49ab-89d9-c431d53a9552",
"name": "web-frontend",
"environments": [
{ "id": "af6b7a8e-c268-48c2-967c-032e86e26110", "name": "Development" },
{ "id": "b12c3d4e-5678-90ab-cdef-1234567890ab", "name": "Staging" }
]
}
]
}
Update Team
Update a team's name, description, or role overrides. At least one field must be provided.
- SCIM-managed teams reject all field updates — name and description are synced from the SCIM provider, and role overrides are managed via the console.
- Pass an empty string (
"") formember_role_idorservice_account_role_idto clear an existing override and fall back to the org role on team-accessed apps.
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the team.
JSON Body
- Name
name- Type
- string
- Description
The new team name. Maximum 64 characters.
- Name
description- Type
- string
- Description
The new description. Maximum 10,000 characters.
- Name
member_role_id- Type
- string
- Description
New role override for human members. Pass
""to clear the existing override.
- Name
service_account_role_id- Type
- string
- Description
New role override for service-account members. Pass
""to clear the existing override.
Request
curl -X PUT https://api.phase.dev/v1/teams/cf3c159d-3edb-4da6-8dbf-0af4959dabf4/ \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"name": "backend-engineering",
"member_role_id": "5d880011-2fc9-4e78-9be2-80f4183c0eea"
}'
Response
{
"id": "cf3c159d-3edb-4da6-8dbf-0af4959dabf4",
"name": "backend-engineering",
"description": "Backend engineering team",
"isScimManaged": false,
"memberRole": {
"id": "5d880011-2fc9-4e78-9be2-80f4183c0eea",
"name": "Developer"
},
"serviceAccountRole": null,
"owner": {
"id": "99e37555-108d-4331-a385-6db971bbd617",
"email": "[email protected]"
},
"createdAt": "2024-06-01T12:00:00Z",
"updatedAt": "2024-06-03T14:00:00Z",
"members": [],
"apps": []
}
Delete Team
Delete a team. This soft-deletes the team and cascades:
- All team-granted
EnvironmentKeyrows are revoked. Keys carrying an additional individual grant survive (their team grant is removed but the key itself is preserved). - All team-owned service accounts are soft-deleted, including their tokens.
SCIM-managed teams cannot be deleted via this endpoint — delete the corresponding group in your SCIM provider instead.
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the team.
Request
curl -X DELETE https://api.phase.dev/v1/teams/cf3c159d-3edb-4da6-8dbf-0af4959dabf4/ \
-H "Authorization: Bearer {token}"
Response
204 No Content
Add Team Members
Add one or more members (users or service accounts) to a team. The server provisions per-member EnvironmentKey records for every SSE-enabled app the team already has access to.
- SCIM-managed teams reject
useradditions — user membership is controlled by the SCIM provider. Service-account additions are permitted on SCIM-managed teams since service accounts are outside the SCIM scope. - Team-owned service accounts (SAs created with a
team_id) cannot be added to a different team — returns409 Conflict. The SA must first be transferred to org-level ownership.
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the team.
JSON Body
- Name
member_type- Type
- string
- Description
Either
userorservice_account. Defaults touser.
- Name
member_ids- Type
- array
- Description
Array of OrganisationMember IDs (for
user) or ServiceAccount IDs (forservice_account). Must be a non-empty list.
Request
curl -X POST https://api.phase.dev/v1/teams/cf3c159d-3edb-4da6-8dbf-0af4959dabf4/members/ \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"member_type": "user",
"member_ids": [
"3f2e1d0c-9b8a-7654-3210-fedcba987654"
]
}'
Response
{
"id": "cf3c159d-3edb-4da6-8dbf-0af4959dabf4",
"name": "backend-engineering",
"members": [
{
"type": "user",
"id": "99e37555-108d-4331-a385-6db971bbd617",
"email": "[email protected]",
"fullName": "Alice Smith"
},
{
"type": "user",
"id": "3f2e1d0c-9b8a-7654-3210-fedcba987654",
"email": "[email protected]",
"fullName": "Bob Jones"
}
]
}
Remove Team Member
Remove a single member from a team. The server revokes the member's team-granted EnvironmentKey records; keys carrying an additional individual grant are preserved.
- SCIM-managed teams reject
userremovals — user membership is controlled by the SCIM provider. - Team-owned service accounts cannot be removed from their owning team — returns
409 Conflict. Delete the service account or transfer ownership to org-level first.
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the team.
- Name
member_id- Type
- string
- Description
The OrganisationMember ID or ServiceAccount ID to remove.
Query parameters
- Name
member_type- Type
- string
- Description
Either
userorservice_account. Defaults touser. Required to disambiguate when the same ID exists in both tables.
Request
curl -X DELETE "https://api.phase.dev/v1/teams/cf3c159d-3edb-4da6-8dbf-0af4959dabf4/members/3f2e1d0c-9b8a-7654-3210-fedcba987654/?member_type=user" \
-H "Authorization: Bearer {token}"
Response
204 No Content
Manage Access
Set the apps and environments the team has access to. This is a declarative endpoint — the request body represents the entire desired access state.
- Apps not in the list have their team grants revoked; orphan
EnvironmentKeyrecords (no remaining grants) are soft-deleted. - Each app entry must include at least one environment. To revoke a team's access to an app entirely, omit it from the body.
- To revoke all team access, send an empty
appsarray. - Only apps with Server-side Encryption (SSE) enabled can be granted to a team. Non-SSE apps return
400 Bad Request. - The caller must individually have access to each app being granted to the team — returns
403 Forbiddenotherwise.
For new (app, environment) pairs added by this call, the server provisions per-member EnvironmentKey records for every existing team member.
URL parameters
- Name
id- Type
- string
- Description
The unique identifier of the team.
JSON Body
- Name
apps- Type
- array
- Description
An array of app access objects. Each object must have:
id(string): The app ID.environments(array): A list of environment IDs to grant access to. Must not be empty.
To revoke all team access, pass an empty array.
Request
curl -X PUT https://api.phase.dev/v1/teams/cf3c159d-3edb-4da6-8dbf-0af4959dabf4/access/ \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"apps": [
{
"id": "72b9ddd5-8fce-49ab-89d9-c431d53a9552",
"environments": [
"af6b7a8e-c268-48c2-967c-032e86e26110",
"b12c3d4e-5678-90ab-cdef-1234567890ab"
]
}
]
}'
Response
{
"id": "cf3c159d-3edb-4da6-8dbf-0af4959dabf4",
"name": "backend-engineering",
"apps": [
{
"id": "72b9ddd5-8fce-49ab-89d9-c431d53a9552",
"name": "web-frontend",
"environments": [
{ "id": "af6b7a8e-c268-48c2-967c-032e86e26110", "name": "Development" },
{ "id": "b12c3d4e-5678-90ab-cdef-1234567890ab", "name": "Staging" }
]
}
]
}