---
id: members-roles-scopes
title: 'Members, Roles, and Scopes'
description: 'How access is granted and read through the API - default-role membership, the AssignWithRole operations, and the Project Roles read API'
sidebar_label: 'Members, Roles & Scopes'
sidebar_position: 9
tags: ['guides', 'members', 'roles', 'scopes', 'security']
---

Access in Agility is a triangle: a **Member** (who) holds a **Role** (what
they may do) on a **Scope** (where). A role assigned on a scope applies to
that scope's whole subtree; the effective role at any scope is the nearest
assignment at or above it. Each member also carries a **`DefaultRole`** —
the role used when membership is granted without naming one.

The asset model tells only part of this story. `Member.Scopes` (and its
reverse, `Scope.Members`) records *membership*, and `Member.DefaultRole`
the default — but the **member-scope-role assignment itself is not an
asset**. No asset type carries it, so no `rest-1.v1` or `query.v1` query
can return "what role does this member hold on this scope." Writing and
reading assignments each have their own path.

## Granting Membership at the Default Role

Adding a scope to `Member.Scopes` grants that member their default role on
the scope (and, by inheritance, its subtree):

```json
{
  "from": "Member:3907",
  "update": { "Scopes": { "add": ["Scope:1071"] } }
}
```

Updating from the other side — `Scope.Members` — is equivalent.

## Granting a Specific Role

Naming the role takes one of two parameterized operations — the same
assignment reached from either corner of the triangle:

- **`Member.AssignToScopeWithRole`** with `{ Scope, Role, IsOwner }`
- **`Scope.AssignMemberWithRole`** with `{ Member, Role, IsOwner }`

```json
{
  "from": "Member:1040",
  "execute": {
    "op": "AssignToScopeWithRole",
    "args": { "Scope": "Scope:1503", "Role": "Role:3", "IsOwner": true }
  }
}
```

The [Bulk API's operations page](/apis/asset-bulk/operations) covers
parameterized execution in detail, including running the assignment
against many members or scopes at once. Repeating the operation with a
different role replaces the assignment; `IsOwner` additionally marks the
member as an owner of the project.

Roles themselves are queryable assets (`/rest-1.v1/Data/Role`) — note
their `Name` values return as localization tags (`Role.Name'Project
Lead`), which resolve through the
[localization API](/apis/loc-2-v1) like any
[display name](/guides/display-names).

## Reading Assignments: the Project Roles API

Because assignments aren't assets, reading them has a
[dedicated endpoint](/apis/project-roles): **`api/ProjectRoles`**, grouped
from either direction:

```text
GET ~/api/ProjectRoles/ByMember?where=ID='Member:20'
GET ~/api/ProjectRoles/ByProject?where=ID='Scope:0'
```

Each row reports the **effective** role — inherited assignments included —
plus `isOwner` and the member's `defaultRole`:

```json
{
  "member": { "oidToken": "Member:20", "name": "Administrator", "defaultRole": { "oidToken": "Role:1", "name": "System Admin" } },
  "projectRoles": [
    { "isOwner": true, "project": { "oidToken": "Scope:0", "name": "System (All Projects)" }, "role": { "oidToken": "Role:1", "name": "System Admin" } }
  ]
}
```

Details worth knowing:

- Filter tokens are **relative to the grouping asset**: `where=ID='Member:20'`,
  not `where=Member.ID='Member:20'`. Each direction takes a second filter
  for the other side — `projectswhere` on `ByMember`, `memberswhere` on
  `ByProject` — plus `page` and `sort`.
- A bare `GET ~/api/ProjectRoles/ByMember` (no parameters) returns the
  endpoint's own usage documentation as a RAML document.

## Provision a Member

Finding, creating and deactivating members is a common administrative
automation, separate from the role and scope questions above.

**Find an existing member** — `Username` is unique, so a lookup
returns at most one member:

```json
{
  "from": "Member",
  "where": { "Username": "andre.agile" },
  "select": ["Name", "Username", "Email"]
}
```

`Email` is not unique, so a `where` match on it can return more than one
`Member` — bound the result with `page` if you use it as the lookup key
instead.

**Create a member**, providing the required fields plus the fields most
useful for administration:

```json
{
  "AssetType": "Member",
  "Name": "Andre Agile",
  "Username": "andre.agile",
  "Nickname": "Andre",
  "Password": "<initial-password>",
  "Email": "andre.agile@example.com",
  "IsCollaborator": false,
  "DefaultRole": "Role:4"
}
```

See [Creating assets](/apis/asset-bulk/creating-assets) for the full
create-command shape, including resolving `DefaultRole` by name instead of
OID token.

**Update a member** the same way as any other asset:

```json
{
  "from": "Member:30633",
  "update": { "Phone": "555-555-1212" }
}
```

**Deactivate a member** with the `Inactivate` operation. The member loses
system access (a sign-in that worked returns 401 afterwards) but stays
queryable with `AssetState` `Closed`:

```json
{ "from": "Member:30633", "execute": "Inactivate" }
```

See [Invoking operations](/apis/asset-bulk/operations) for the operation
syntax in full.

Prefer `Inactivate` when someone leaves: the member keeps its place in
history, so ownership and time-by-person reports stay accurate. `Delete`
removes the member from every query that doesn't request deleted assets,
historical ones included, and from Agility's by-member reports, so their
past ownership and logged time stop being attributed to them. Delete only a
member created by mistake, or one whose username you need to reuse. An
inactive member can't be deleted; reactivate it first.

## Related Topics

- Product feature: [Assigning a project role](https://docs.digital.ai/agility/docs/agility/assigning-project-role)
  and [Which project role should I choose?](https://docs.digital.ai/agility/docs/agility/which-project-role-should-i-choose)
  — the UI and semantics behind the assignments this guide automates.

- [Project Roles API](/apis/project-roles) — the endpoint in full,
  including its self-published RAML specification
- [Roles and permissions](/reference/roles-and-permissions)
- [Scope context and filtering](/guides/scope-context)
- [Bulk API operations](/apis/asset-bulk/operations) — parameterized
  execution
- [System names and display names](/guides/display-names) — resolving
  role-name tags
