> ## Documentation Index
> Fetch the complete documentation index at: https://astronomer.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage teams via API

Teams in Astro Private Cloud let you group users and assign permissions collectively. You can manage teams locally or sync them from an Identity Provider (IdP). To configure IdP group sync, see [Import identity provider (IdP) groups](/docs/astro-private-cloud/v-2-x/import-idp-groups).

## Prerequisites

* Access to the APC API GraphQL API endpoint for your Astro Private Cloud installation.
* A valid authentication token. See [Authenticate to the APC API](/docs/astro-private-cloud/v-2-x/houston-api-authenticate).
* The UUIDs of any users, workspaces, or Deployments you want to reference.

## Team types

| Type        | Provider                                    | User Management      | Use Case                               |
| ----------- | ------------------------------------------- | -------------------- | -------------------------------------- |
| Local teams | `local`                                     | Manual add/remove    | Local authentication, custom groupings |
| IdP teams   | `okta`, `auth0`, `microsoft`, `ida`, `adfs` | Auto-synced from IdP | Enterprise SSO integration             |

## Create a team

### Create local team

```graphql wrap theme={null}
mutation {
  createTeam(
    name: "Data Engineering"
    description: "Data engineering team"
    provider: "local"
    userIds: ["<user-uuid-1>", "<user-uuid-2>"]
  ) {
    team {
      id
      name
      provider
      description
      users {
        id
        username
      }
    }
    message
  }
}
```

### Create IdP team

[IdP group sync](/docs/astro-private-cloud/v-2-x/import-idp-groups) automatically creates IdP teams, but you can also create them manually:

```graphql wrap theme={null}
mutation {
  createTeam(
    name: "engineering-group"
    description: "Synced from Okta"
    provider: "okta"
  ) {
    team {
      id
      name
      provider
    }
    message
  }
}
```

<Note>
  You can't assign users to IdP teams at creation time. The IdP syncs users to the team.
</Note>

### Parameters

| Parameter     | Type   | Required | Description                                                    |
| ------------- | ------ | -------- | -------------------------------------------------------------- |
| `name`        | String | Yes      | Team name (unique per provider)                                |
| `description` | String | No       | Team description                                               |
| `provider`    | String | No       | `local` (default), `okta`, `auth0`, `microsoft`, `ida`, `adfs` |
| `userIds`     | \[ID]  | No       | User UUIDs (local teams only)                                  |

## Update a team

### Update team details

```graphql wrap theme={null}
mutation {
  updateTeam(
    id: "<team-uuid>"
    newName: "Platform Engineering"
    description: "Updated description"
  ) {
    team {
      id
      name
      description
    }
    message
  }
}
```

### Add users to local team

```graphql wrap theme={null}
mutation {
  updateTeam(
    id: "<team-uuid>"
    addUserIds: ["<user-uuid-3>", "<user-uuid-4>"]
  ) {
    team {
      id
      users {
        id
        username
      }
    }
  }
}
```

### Remove users from local team

```graphql wrap theme={null}
mutation {
  updateTeam(
    id: "<team-uuid>"
    removeUserIds: ["<user-uuid-1>"]
  ) {
    team {
      id
      users {
        id
        username
      }
    }
  }
}
```

### Replace all users

```graphql wrap theme={null}
mutation {
  updateTeam(
    id: "<team-uuid>"
    teamUserIds: ["<user-uuid-5>", "<user-uuid-6>"]
  ) {
    team {
      users {
        id
        username
      }
    }
  }
}
```

### Update by name (alternative)

Team names are unique per provider, not globally. You must include `provider` alongside `name` to uniquely identify a team.

```graphql wrap theme={null}
mutation {
  updateTeam(
    name: "Data Engineering"
    provider: "local"
    newName: "Data Platform"
  ) {
    team {
      id
      name
    }
  }
}
```

## Remove a team

### Remove by UUID

```graphql wrap theme={null}
mutation {
  removeTeam(teamUuid: "<team-uuid>") {
    id
    name
  }
}
```

### Remove by name and provider

```graphql wrap theme={null}
mutation {
  removeTeam(
    name: "Data Engineering"
    provider: "local"
  ) {
    id
    name
  }
}
```

<Note>
  You can only remove IdP teams that have no attached users.
</Note>

## Query teams

### Get single team

```graphql wrap theme={null}
query {
  team(teamUuid: "<team-uuid>") {
    id
    name
    provider
    description
    createdAt
    updatedAt
    users {
      id
      username
      emails {
        address
      }
    }
    roleBindings {
      role
      workspace {
        id
        label
      }
      deployment {
        id
        label
      }
    }
  }
}
```

### List teams with search

<Note>
  `searchPhrase` requires a minimum of three characters.
</Note>

```graphql wrap theme={null}
query {
  paginatedTeams(
    take: 20
    pageNumber: 1
    searchPhrase: "engineering"
  ) {
    teams {
      id
      name
      provider
      users {
        id
      }
    }
    count
  }
}
```

### List workspace teams

```graphql wrap theme={null}
query {
  workspaceTeams(workspaceUuid: "<workspace-uuid>") {
    id
    name
    roleBindings {
      role
    }
  }
}
```

### List deployment teams

```graphql wrap theme={null}
query {
  deploymentTeams(deploymentUuid: "<deployment-uuid>") {
    id
    name
    roleBindings {
      role
    }
  }
}
```

## Assign team roles

### Assign a team role

### Assign a team to a workspace

<Note>
  If you omit `role`, the team defaults to `WORKSPACE_VIEWER`.
</Note>

```graphql wrap theme={null}
mutation {
  workspaceAddTeam(
    teamUuid: "<team-uuid>"
    workspaceUuid: "<workspace-uuid>"
    role: WORKSPACE_EDITOR
  ) {
    id
    label
  }
}
```

Assign workspace and deployment roles in a single mutation:

```graphql wrap theme={null}
mutation {
  workspaceAddTeam(
    teamUuid: "<team-uuid>"
    workspaceUuid: "<workspace-uuid>"
    role: WORKSPACE_VIEWER
    deploymentRoles: [
      { deploymentId: "<deployment-uuid-1>", role: DEPLOYMENT_ADMIN }
      { deploymentId: "<deployment-uuid-2>", role: DEPLOYMENT_EDITOR }
    ]
  ) {
    id
  }
}
```

### Assign a team to a Deployment

```graphql wrap theme={null}
mutation {
  deploymentAddTeamRole(
    teamUuid: "<team-uuid>"
    deploymentUuid: "<deployment-uuid>"
    role: DEPLOYMENT_EDITOR
  ) {
    id
    role
  }
}
```

### Update a team's role

### Update a team's workspace role

```graphql wrap theme={null}
mutation {
  workspaceUpdateTeamRole(
    teamUuid: "<team-uuid>"
    workspaceUuid: "<workspace-uuid>"
    role: WORKSPACE_ADMIN
  )
}
```

### Update a team's Deployment role

```graphql wrap theme={null}
mutation {
  deploymentUpdateTeamRole(
    teamUuid: "<team-uuid>"
    deploymentUuid: "<deployment-uuid>"
    role: DEPLOYMENT_ADMIN
  ) {
    id
    role
  }
}
```

### Remove a team's role

### Remove a team from a workspace

```graphql wrap theme={null}
mutation {
  workspaceRemoveTeam(
    teamUuid: "<team-uuid>"
    workspaceUuid: "<workspace-uuid>"
  ) {
    id
  }
}
```

### Remove a team from a Deployment

```graphql wrap theme={null}
mutation {
  deploymentRemoveTeamRole(
    teamUuid: "<team-uuid>"
    deploymentUuid: "<deployment-uuid>"
  ) {
    id
  }
}
```

## Available roles

### Workspace roles

| Role               | Permissions                                 |
| ------------------ | ------------------------------------------- |
| `WORKSPACE_ADMIN`  | Full Workspace control, manage users/teams  |
| `WORKSPACE_EDITOR` | Create/manage Deployments, service accounts |
| `WORKSPACE_VIEWER` | View Workspace and Deployment details       |

### Deployment roles

| Role                | Permissions                            |
| ------------------- | -------------------------------------- |
| `DEPLOYMENT_ADMIN`  | Full Deployment control, manage access |
| `DEPLOYMENT_EDITOR` | Deploy code, manage configuration      |
| `DEPLOYMENT_VIEWER` | View Deployment details                |

## Configuration

### Enable local teams

```yaml wrap theme={null}
auth:
  local:
    teams:
      enabled: true
```

### Enable IdP group sync

For full setup instructions, see [Import identity provider (IdP) groups](/docs/astro-private-cloud/v-2-x/import-idp-groups).

```yaml wrap theme={null}
auth:
  openidConnect:
    idpGroupsImportEnabled: true
```

## Error handling

| Error                              | Cause                         | Resolution                                                  |
| ---------------------------------- | ----------------------------- | ----------------------------------------------------------- |
| `LocalTeamManagementDisabledError` | Local teams not enabled       | Enable in Helm values                                       |
| `IDPTeamManagementDisabledError`   | IdP groups import disabled    | Enable IdP group sync                                       |
| `DuplicateTeamError`               | Team name exists for provider | Use unique name                                             |
| `DuplicateRoleBindingError`        | Team already has role         | Update existing role instead                                |
| `InvalidTeamProviderError`         | Unsupported provider value    | Use `local`, `okta`, `auth0`, `microsoft`, `ida`, or `adfs` |
| `ResourceNotFoundError`            | Team/user not found           | Verify UUIDs                                                |

## Best practices

* Use IdP teams for enterprise SSO environments.
* Use local teams for custom access groups.
* Assign Workspace roles before Deployment roles.
* Use Viewer roles as default and escalate as needed.
* Audit team membership regularly.

## Related documentation

* [Import IdP groups](/docs/astro-private-cloud/v-2-x/import-idp-groups)
* [Manage user permissions](/docs/astro-private-cloud/v-2-x/manage-permissions)
* [APC API](/docs/astro-private-cloud/v-2-x/houston-api)
