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

# RBAC REST API

> Manage custom roles, role bindings, and resource restrictions programmatically using the Arize REST API.

The Arize REST API provides endpoints for managing access control programmatically. Use these endpoints to automate role assignment, manage project restrictions, and integrate RBAC into your workflows.

<Note>
  These endpoints are currently in Alpha. Breaking changes are possible. See [API Version Stages](/ax/rest-reference/overview#api-version-stages) for details.
</Note>

## Authentication

All RBAC endpoints require Bearer token authentication:

```
Authorization: Bearer <api-key>
```

Both [User Keys](/ax/security-and-settings/api-keys) and [Service Keys](/ax/security-and-settings/service-keys) are supported. See [Authentication](/ax/rest-reference/overview#authentication) for details.

## Key Concepts

### Permission hierarchy

Arize AX uses a hierarchical RBAC model: **Account → Organization → Space → Project**. Permissions granted at a higher level flow down to resources below it. When a project is [restricted](/ax/security-and-settings/sso-and-rbac/project-restrictions), that inheritance is cut off — only users with an explicit role binding on that project can access it.

### Permission strings

Each permission follows the `{RESOURCE}_{ACTION}` pattern, for example `DATASET_CREATE` or `PROJECT_READ`. When building a custom role, you specify which permissions to grant. To discover available permissions on predefined roles, call [`GET /v2/roles?is_predefined=true`](/api-reference/roles/list-roles) and inspect the `permissions` arrays.

### Predefined vs. custom roles

**Predefined roles** are built-in system roles (e.g., Admin, Member, Read-only). They cannot be modified or deleted. **Custom roles** are account-scoped, user-defined roles that can hold any combination of permissions. See [Custom Roles](/ax/security-and-settings/sso-and-rbac/custom-roles) for conceptual details.

### Role binding uniqueness

A user can have at most one role binding per resource. To change a user's role, update the existing binding — do not delete and recreate it.

### Privilege escalation prevention

When creating service keys or assigning roles, you can only assign roles at or below your own privilege level.

## User Management

Invite, list, update, and remove users across your account, organizations, and spaces.

<table>
  <thead>
    <tr>
      <th width="100">Method</th>
      <th width="340">Path</th>
      <th>Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>POST</code></td>
      <td><code>/v2/users</code></td>
      <td>[Create a user](/api-reference/users/create-a-user)</td>
    </tr>

    <tr>
      <td><code>GET</code></td>
      <td><code>/v2/users</code></td>
      <td>[List users](/api-reference/users/list-users)</td>
    </tr>

    <tr>
      <td><code>GET</code></td>
      <td><code>/v2/users/\{user\_id}</code></td>
      <td>[Get a user](/api-reference/users/get-a-user)</td>
    </tr>

    <tr>
      <td><code>PATCH</code></td>
      <td><code>/v2/users/\{user\_id}</code></td>
      <td>[Update a user](/api-reference/users/update-a-user)</td>
    </tr>

    <tr>
      <td><code>DELETE</code></td>
      <td><code>/v2/users/\{user\_id}</code></td>
      <td>[Delete a user](/api-reference/users/delete-a-user)</td>
    </tr>

    <tr>
      <td><code>POST</code></td>
      <td><code>/v2/users/\{user\_id}/resend-invitation</code></td>
      <td>[Resend a user invitation](/api-reference/users/resend-a-user-invitation)</td>
    </tr>

    <tr>
      <td><code>POST</code></td>
      <td><code>/v2/users/\{user\_id}/reset-password</code></td>
      <td>[Trigger a password-reset email for a user](/api-reference/users/trigger-a-password-reset-email-for-a-user)</td>
    </tr>

    <tr>
      <td><code>POST</code></td>
      <td><code>/v2/organizations/\{org\_id}/users</code></td>
      <td>[Add a user to an organization](/api-reference/organizations/add-a-user-to-an-organization)</td>
    </tr>

    <tr>
      <td><code>DELETE</code></td>
      <td><code>/v2/organizations/\{org\_id}/users/\{user\_id}</code></td>
      <td>[Remove a user from an organization](/api-reference/organizations/remove-a-user-from-an-organization)</td>
    </tr>

    <tr>
      <td><code>POST</code></td>
      <td><code>/v2/spaces/\{space\_id}/users</code></td>
      <td>[Add a user to a space](/api-reference/spaces/add-a-user-to-a-space)</td>
    </tr>

    <tr>
      <td><code>DELETE</code></td>
      <td><code>/v2/spaces/\{space\_id}/users/\{user\_id}</code></td>
      <td>[Remove a user from a space](/api-reference/spaces/remove-a-user-from-a-space)</td>
    </tr>
  </tbody>
</table>

For `invite_mode` options when creating a user, see [Invite a user via API](#invite-a-user-via-api) in the Common Workflows section below.

## Roles

Manage custom and predefined roles for your account.

<table>
  <thead>
    <tr>
      <th width="100">Method</th>
      <th width="250">Path</th>
      <th>Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>GET</code></td>
      <td><code>/v2/roles</code></td>
      <td>[List roles](/api-reference/roles/list-roles)</td>
    </tr>

    <tr>
      <td><code>POST</code></td>
      <td><code>/v2/roles</code></td>
      <td>[Create a role](/api-reference/roles/create-a-role)</td>
    </tr>

    <tr>
      <td><code>GET</code></td>
      <td><code>/v2/roles/\{role\_id}</code></td>
      <td>[Get a role](/api-reference/roles/get-a-role)</td>
    </tr>

    <tr>
      <td><code>PATCH</code></td>
      <td><code>/v2/roles/\{role\_id}</code></td>
      <td>[Update a role](/api-reference/roles/update-a-role)</td>
    </tr>

    <tr>
      <td><code>DELETE</code></td>
      <td><code>/v2/roles/\{role\_id}</code></td>
      <td>[Delete a role](/api-reference/roles/delete-a-role)</td>
    </tr>
  </tbody>
</table>

<Info>
  Predefined roles (e.g., Admin, Member, Read-only) cannot be updated or deleted.
</Info>

### List roles

```bash theme={null}
curl https://api.arize.com/v2/roles \
  -H "Authorization: Bearer <api-key>"
```

You can filter by `is_predefined=true` or `is_predefined=false` to see only built-in or custom roles. Responses are paginated — use `limit` and `cursor` parameters for large role lists.

```json theme={null}
{
  "roles": [
    {
      "id": "Rol001",
      "name": "Dataset Manager",
      "description": "Can manage datasets and run experiments",
      "permissions": [
        "DATASET_READ",
        "DATASET_CREATE",
        "DATASET_UPDATE",
        "DATASET_DELETE",
        "EXPERIMENT_READ",
        "EXPERIMENT_CREATE"
      ],
      "is_predefined": false,
      "created_at": "2024-06-01T10:00:00Z",
      "updated_at": "2024-06-01T10:00:00Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}
```

### Get a role

```bash theme={null}
curl https://api.arize.com/v2/roles/<role-id> \
  -H "Authorization: Bearer <api-key>"
```

### Create a custom role

```bash theme={null}
curl -X POST https://api.arize.com/v2/roles \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Dataset Manager",
    "description": "Can manage datasets and run experiments",
    "permissions": [
      "DATASET_READ",
      "DATASET_CREATE",
      "DATASET_UPDATE",
      "DATASET_DELETE",
      "DATASET_EXAMPLE_READ",
      "DATASET_EXAMPLE_CREATE",
      "EXPERIMENT_READ",
      "EXPERIMENT_CREATE"
    ]
  }'
```

<Tip>
  To discover available permission values on predefined roles, call [`GET /v2/roles?is_predefined=true`](/api-reference/roles/list-roles) and inspect the `permissions` arrays.
</Tip>

### Update a custom role

```bash theme={null}
curl -X PATCH https://api.arize.com/v2/roles/<role-id> \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "permissions": [
      "DATASET_READ",
      "DATASET_CREATE",
      "EXPERIMENT_READ"
    ]
  }'
```

<Warning>
  When updating `permissions`, the provided list **replaces** the entire set — it is not a merge. Include all permissions you want the role to have.
</Warning>

Predefined roles cannot be updated. Attempting to do so returns a `403 Forbidden`.

### Delete a custom role

```bash theme={null}
curl -X DELETE https://api.arize.com/v2/roles/<role-id> \
  -H "Authorization: Bearer <api-key>"
```

Roles are soft-deleted. Predefined roles cannot be deleted.

## Role Bindings

Assign roles to users on specific resources (spaces or projects).

<table>
  <thead>
    <tr>
      <th width="100">Method</th>
      <th width="300">Path</th>
      <th>Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>POST</code></td>
      <td><code>/v2/role-bindings</code></td>
      <td>[Create a role binding](/api-reference/role-bindings/create-a-role-binding)</td>
    </tr>

    <tr>
      <td><code>GET</code></td>
      <td><code>/v2/role-bindings/\{binding\_id}</code></td>
      <td>[Get a role binding](/api-reference/role-bindings/get-a-role-binding)</td>
    </tr>

    <tr>
      <td><code>PATCH</code></td>
      <td><code>/v2/role-bindings/\{binding\_id}</code></td>
      <td>[Update a role binding](/api-reference/role-bindings/update-a-role-binding)</td>
    </tr>

    <tr>
      <td><code>DELETE</code></td>
      <td><code>/v2/role-bindings/\{binding\_id}</code></td>
      <td>[Delete a role binding](/api-reference/role-bindings/delete-a-role-binding)</td>
    </tr>
  </tbody>
</table>

<Info>
  Each user can have one role binding per resource. Attempting to create a duplicate binding returns a `409 Conflict` error.
</Info>

### Assign a role

The `resource_type` field accepts `SPACE` or `PROJECT`.

```bash theme={null}
curl -X POST https://api.arize.com/v2/role-bindings \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "role_id": "<role-id>",
    "user_id": "<user-id>",
    "resource_type": "PROJECT",
    "resource_id": "<project-id>"
  }'
```

```json theme={null}
{
  "id": "Rbd001",
  "role_id": "<role-id>",
  "user_id": "<user-id>",
  "resource_type": "PROJECT",
  "resource_id": "<project-id>",
  "created_at": "2024-06-01T10:00:00Z",
  "updated_at": "2024-06-01T10:00:00Z"
}
```

### Get a role binding

```bash theme={null}
curl https://api.arize.com/v2/role-bindings/<binding-id> \
  -H "Authorization: Bearer <api-key>"
```

### Update a role binding

To change the role assigned to a user, update the binding with a new `role_id`:

```bash theme={null}
curl -X PATCH https://api.arize.com/v2/role-bindings/<binding-id> \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "role_id": "<new-role-id>"
  }'
```

Only the `role_id` can be updated. The user, resource type, and resource cannot be changed — delete and recreate the binding instead.

### Delete a role binding

```bash theme={null}
curl -X DELETE https://api.arize.com/v2/role-bindings/<binding-id> \
  -H "Authorization: Bearer <api-key>"
```

## Resource Restrictions

Mark projects as restricted so only users with explicit role bindings can access them.

<table>
  <thead>
    <tr>
      <th width="100">Method</th>
      <th width="380">Path</th>
      <th>Description</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td><code>POST</code></td>
      <td><code>/v2/resource-restrictions</code></td>
      <td>[Restrict a resource](/api-reference/resource-restrictions/restrict-a-resource)</td>
    </tr>

    <tr>
      <td><code>DELETE</code></td>
      <td><code>/v2/resource-restrictions/\{resource\_id}</code></td>
      <td>[Unrestrict a resource](/api-reference/resource-restrictions/unrestrict-a-resource)</td>
    </tr>
  </tbody>
</table>

<Info>
  Currently, only projects can be restricted. Support for additional resource types is planned.
</Info>

### Restrict a project

```bash theme={null}
curl -X POST https://api.arize.com/v2/resource-restrictions \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{"resource_id": "<project-id>"}'
```

This operation is idempotent — restricting an already-restricted project returns successfully.

### Remove a restriction

```bash theme={null}
curl -X DELETE https://api.arize.com/v2/resource-restrictions/<project-id> \
  -H "Authorization: Bearer <api-key>"
```

See [Project-Level Restrictions](/ax/security-and-settings/sso-and-rbac/project-restrictions) for details on how restrictions affect access.

## Schema Reference

### Role

| Field           | Type      | Constraints                                    |
| --------------- | --------- | ---------------------------------------------- |
| `id`            | string    | Read-only                                      |
| `name`          | string    | Required, max 255 chars, unique within account |
| `description`   | string    | Optional, max 1000 chars                       |
| `permissions`   | string\[] | Required on create, min 1 item                 |
| `is_predefined` | boolean   | `true` = system role (immutable)               |
| `created_at`    | datetime  | Read-only                                      |
| `updated_at`    | datetime  | Read-only                                      |

### RoleBinding

| Field           | Type     | Constraints                                    |
| --------------- | -------- | ---------------------------------------------- |
| `id`            | string   | Read-only                                      |
| `role_id`       | string   | Required; only mutable field on PATCH          |
| `user_id`       | string   | Required; immutable after creation             |
| `resource_type` | string   | `SPACE` or `PROJECT`; immutable after creation |
| `resource_id`   | string   | Required; immutable after creation             |
| `created_at`    | datetime | Read-only                                      |
| `updated_at`    | datetime | Read-only                                      |

### ResourceRestriction

| Field           | Type     | Constraints      |
| --------------- | -------- | ---------------- |
| `resource_type` | string   | Always `PROJECT` |
| `resource_id`   | string   | Required         |
| `created_at`    | datetime | Read-only        |

## Common Workflows

### Invite a user via API

Use `POST /v2/users` to invite a user programmatically. The `invite_mode` field controls how the invited user completes sign-up:

| `invite_mode`        | Behavior                                                                                                                               |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `email_link`         | Sends the user an email with a sign-up link. Default for most accounts.                                                                |
| `temporary_password` | Sends the user a temporary password. Useful when email delivery is restricted.                                                         |
| `none`               | No email is sent. Use only when **Allow Only SAML Logins** is enabled — users log in directly via SSO without a separate sign-up step. |

<Warning>
  Using `invite_mode: none` on an account where **Allow Only SAML Logins** is not enabled will leave the user with no way to complete sign-up.
</Warning>

### Onboard a team member with scoped project access

1. **Restrict the project** (if not already restricted):
   `POST /v2/resource-restrictions` with the project ID.
2. **Create a role binding** for the user:
   `POST /v2/role-bindings` with the user ID, a role ID (e.g., Member), and the project ID.

### Create a least-privilege custom role and assign it

1. **Identify the permissions** your use case requires — call [`GET /v2/roles?is_predefined=true`](/api-reference/roles/list-roles) to inspect what permissions predefined roles use.
2. **Create a custom role** with only those permissions:
   `POST /v2/roles`
3. **Restrict the target project** so access is opt-in:
   `POST /v2/resource-restrictions`
4. **Bind the role to the user** on that project:
   `POST /v2/role-bindings`

### Rotate a user's role on a project

1. **Find the existing binding ID** (use your own records or `GET /v2/role-bindings/<id>`).
2. **Update the binding** with the new role:
   `PATCH /v2/role-bindings/<binding-id>` with `{ "role_id": "<new-role-id>" }`

### Audit roles and access

1. **List all custom roles**: `GET /v2/roles?is_predefined=false`
2. **List predefined roles**: `GET /v2/roles?is_predefined=true`
3. **Inspect a specific binding**: `GET /v2/role-bindings/<binding-id>`

## Full API Reference

For complete request and response schemas, see the API reference:

* [Users](/api-reference/users/list-users)
* [Roles](/api-reference/roles/list-roles)
* [Role Bindings](/api-reference/role-bindings/list-role-bindings)
* [Resource Restrictions](/api-reference/resource-restrictions/restrict-a-resource)

You can also explore and try out all endpoints interactively at [api.arize.com/v2/docs](https://api.arize.com/v2/docs).

<Tip>
  For additional support, join the [Arize Community Slack](https://join.slack.com/t/arize-ai/shared_invite/zt-2w57bhem8-hq24MB6u7yE_ZF_ilOYSBw).
</Tip>
