API

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.

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. null means 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.


GET/v1/teams

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

GET
/v1/teams
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"
        }
    ]
}

POST/v1/teams

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 memberRole override. Must reference a role in the same organisation.

  • Name
    service_account_role_id
    Type
    string
    Description

    Role ID to apply as the team's serviceAccountRole override. Must reference a role in the same organisation.

Request

POST
/v1/teams
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/v1/teams/:id

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

GET
/v1/teams/:id
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" }
            ]
        }
    ]
}

PUT/v1/teams/:id

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 ("") for member_role_id or service_account_role_id to 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

PUT
/v1/teams/:id
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/v1/teams/:id

Delete Team

Delete a team. This soft-deletes the team and cascades:

  • All team-granted EnvironmentKey rows 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

DELETE
/v1/teams/:id
curl -X DELETE https://api.phase.dev/v1/teams/cf3c159d-3edb-4da6-8dbf-0af4959dabf4/ \
  -H "Authorization: Bearer {token}"

Response

204 No Content

POST/v1/teams/:id/members

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 user additions — 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 — returns 409 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 user or service_account. Defaults to user.

  • Name
    member_ids
    Type
    array
    Description

    Array of OrganisationMember IDs (for user) or ServiceAccount IDs (for service_account). Must be a non-empty list.

Request

POST
/v1/teams/:id/members
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"
        }
    ]
}

DELETE/v1/teams/:id/members/:member_id

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 user removals — 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 user or service_account. Defaults to user. Required to disambiguate when the same ID exists in both tables.

Request

DELETE
/v1/teams/:id/members/:member_id
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

PUT/v1/teams/:id/access

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 EnvironmentKey records (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 apps array.
  • 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 Forbidden otherwise.

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

PUT
/v1/teams/:id/access
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" }
            ]
        }
    ]
}