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

# List roles

> GET /multi-users/access-levels/

Every shared user is assigned a role — Scanova's dashboard calls these "access levels" internally, and the same term appears throughout this endpoint. Use this endpoint to look up available roles before inviting a teammate via [`POST /multi-users/`](/api-reference/management-api/shared-users/invite), or to create a custom role from your own systems.

<Note>
  This endpoint was not previously documented. It requires a Management API key with `MANAGEMENT_API` (or `MANAGEMENT_API_SANDBOX`) quota — see the [Management API overview](/api-reference/management-api/overview). For what each role actually grants a teammate, see the human-facing [Roles & permissions](/team/roles-and-permissions) guide — this page only documents the wire format.
</Note>

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url 'https://management.scanova.io/multi-users/access-levels/' \
    --header 'Authorization: YOUR_API_KEY'
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "count": 6,
    "next": null,
    "previous": null,
    "results": [
      {
        "id": 3,
        "name": "Viewer",
        "slug": "viewer",
        "permissions": [
          {
            "id": 23,
            "code": "QR_CODE_CAN_VIEW",
            "name": "Can view QR Code",
            "description": "Allows viewing QR code details.",
            "is_boolean": true
          }
        ],
        "is_custom": false
      },
      {
        "id": 4,
        "name": "Analyst",
        "slug": "analyst",
        "permissions": ["..."],
        "is_custom": false
      },
      {
        "id": 5,
        "name": "Billing Manager",
        "slug": "billing-manager",
        "permissions": ["..."],
        "is_custom": false
      },
      {
        "id": 6,
        "name": "Manager",
        "slug": "manager",
        "permissions": ["..."],
        "is_custom": false
      },
      {
        "id": 7,
        "name": "Admin",
        "slug": "admin",
        "permissions": ["..."],
        "is_custom": false
      },
      {
        "id": 8,
        "name": "Full Access",
        "slug": "full-access",
        "permissions": ["..."],
        "is_custom": false
      }
    ]
  }
  ```
</ResponseExample>

<Note>
  Verified live: a fresh account returns exactly these 6 system roles (Viewer, Analyst, Billing Manager, Manager, Admin, Full Access) — matching the [Roles & permissions](/team/roles-and-permissions#default-system-roles) picker in the dashboard's Invite Users drawer. IDs shown above are illustrative; permission arrays are truncated for brevity in this example — a real response includes every permission the role grants, in full.
</Note>

Results are paginated (page size 10 by default) and can include custom roles the account has created, alongside the 6 system defaults.

<ParamField query="type" type="string">
  Filter to `system` (the built-in roles, `user` is null on these) or `custom` (roles this account created).
</ParamField>

<ParamField query="search" type="string">
  Substring match against the role name.
</ParamField>

<ParamField query="ordering" type="string">
  `name` or `-name`.
</ParamField>

### Response fields (per role)

<ResponseField name="id" type="integer">
  Role ID — pass this as `access_level` when inviting or updating a shared user.
</ResponseField>

<ResponseField name="name" type="string">
  Role display name, e.g. `Manager`.
</ResponseField>

<ResponseField name="slug" type="string | null">
  Stable slug for system roles (e.g. `manager`); `null` for custom roles.
</ResponseField>

<ResponseField name="is_custom" type="boolean">
  `false` for the 6 built-in system roles, `true` for a role this account created itself.
</ResponseField>

<ResponseField name="permissions" type="array">
  Every permission this role grants.

  <Expandable title="permission properties">
    <ResponseField name="id" type="integer">Permission ID — pass this in `permissions` when creating a custom role below.</ResponseField>
    <ResponseField name="code" type="string">Stable permission code, e.g. `QR_CODE_CAN_VIEW`.</ResponseField>
    <ResponseField name="name" type="string">Human-readable permission name.</ResponseField>
    <ResponseField name="description" type="string">Longer description of what the permission allows.</ResponseField>
    <ResponseField name="is_boolean" type="boolean">Whether this permission is a simple on/off flag (`true`) rather than a numeric quota.</ResponseField>
  </Expandable>
</ResponseField>

## Related

* [Create a custom role](/api-reference/management-api/shared-users/roles-create) — the other operation on this same endpoint.
* [Invite a shared user](/api-reference/management-api/shared-users/invite) — assign a role ID from this list when inviting or updating a teammate.
* [Update a shared user](/api-reference/management-api/shared-users/update) — assign a role ID from this list when inviting or updating a teammate.
* [Roles & permissions](/team/roles-and-permissions) — the human-facing explanation of what each role grants, including the custom-roles plan gate.
* [Shared users](/team/shared-users) — the dashboard's Users table where these roles are assigned via the UI.


## OpenAPI

````yaml api-reference/openapi/management-api.json GET /multi-users/access-levels/
openapi: 3.1.0
info:
  title: Scanova Management API (v2)
  description: >-
    The complete Scanova Management API — every endpoint available at
    management.scanova.io (QR codes, folders, tags, leads, forms, analytics,
    plans, shared users & roles), plus the token-creation and usage-stats
    endpoints used to authenticate against it. Every path and request/response
    shape below was verified live against a real API key and the actual running
    backend (Phase 7, 2026-08-16) — not guessed from reading urls.py alone.
  version: 2.0.0
servers:
  - url: https://management.scanova.io
    description: Management API — QR/folder/tag/lead/form/analytics/plans endpoints
security:
  - apiKeyAuth: []
paths:
  /multi-users/access-levels/:
    get:
      summary: List roles (access levels)
      description: >-
        Returns every role assignable to a shared user, including the account's
        default system roles and any custom roles it has created.
      operationId: listManagedAccessLevels
      parameters:
        - name: type
          in: query
          schema:
            type: string
            enum:
              - system
              - custom
        - name: search
          in: query
          schema:
            type: string
        - name: ordering
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Paginated list of roles, each with its permission set.
          content:
            application/json:
              example:
                count: 6
                next: null
                previous: null
                results:
                  - id: 3
                    name: Viewer
                    slug: viewer
                    permissions:
                      - id: 23
                        code: QR_CODE_CAN_VIEW
                        name: Can view QR Code
                        description: Allows viewing QR code details.
                        is_boolean: true
                    is_custom: false
components:
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: Authorization
      description: >-
        Send your Management API key as the raw value of the Authorization
        header — no "Bearer " or "Token " prefix, and no other characters.
        Example: `Authorization: 401f7ac837da42b97f613d789819ff93537bee6a`. A
        header containing more than one space-separated part is rejected
        outright. Requests also require the request's Host header to be the
        management API host (e.g. management.scanova.io) — the same key sent to
        the regular API host will not authenticate.

````