Users

Manage organization users and team members

Overview

Users represent team members in your organization. Each user has a role that determines their access level and permissions. Users can be assigned to appointments, services, and other organizational tasks. Some fields are auth-gated and only visible to users with the appropriate scopes.

User Roles

RoleDescription
ADMINFull access to all features including organization settings, billing, and user management
USERStandard access for technicians and team members

User Scopes

Scopes provide fine-grained access control for users. Each user can have multiple scopes assigned that determine what actions they can perform within the application.

Appointment Scopes

ScopeDescription
read:own:appointmentView appointments assigned to the user
read:all:appointmentView all appointments in the organization
write:appointmentCreate and update appointments
delete:appointmentDelete appointments
communication:appointmentSend communications related to appointments

Customer Scopes

ScopeDescription
read:customerView customer information
read:customer-detailsView detailed customer information
read:customer:telephone-numberView customer phone numbers
write:customerCreate and update customers
delete:customerDelete customers

Service Scopes

ScopeDescription
read:serviceView service records
read:pricing:serviceView service pricing information
write:serviceCreate and update services
delete:serviceDelete services
communication:serviceSend communications related to services
upload-from-gallery:serviceUpload photos from device gallery for services

Invoice Scopes

ScopeDescription
read:invoiceView invoices
read:pricing:invoiceView invoice pricing details
write:invoiceCreate and update invoices
delete:invoiceDelete invoices

Inventory Scopes

ScopeDescription
read:inventoryView inventory items and stock levels
write:inventoryCreate and update inventory items
delete:inventoryDelete inventory items

Organization Scopes

ScopeDescription
update:organizationUpdate organization settings
write:reportsGenerate and export reports

List Users (Cursor-based)

Retrieve a cursor-based paginated list of users in the organization using the infiniteUsers query. Accepts a selector with filters and search, along with sorting and pagination parameters.

query InfiniteUsers(
  $selector: UsersSelector,
  $sort: UserSort,
  $first: Int!,
  $after: String
) {
  infiniteUsers(
    selector: $selector,
    sort: $sort,
    first: $first,
    after: $after
  ) {
    edges {
      node {
        id
        firstName
        lastName
        isActive
        isDisplayedOnSchedule
        color
        createdAt
      }
      cursor
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

# Variables
{
  "first": 20,
  "selector": {
    "filters": {
      "isActive": { "equals": true }
    },
    "search": "Mike"
  }
}

Response:

{
  "data": {
    "infiniteUsers": {
      "edges": [
        {
          "node": {
            "id": "clxyz1234567890abcdef",
            "firstName": "Mike",
            "lastName": "Johnson",
            "isActive": true,
            "isDisplayedOnSchedule": true,
            "color": "#4A90D9",
            "createdAt": "2024-01-15T10:00:00Z"
          },
          "cursor": "eyJpZCI6ImNseHl6MTIzNDU2Nzg5MGFiY2RlZiJ9"
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "endCursor": "eyJpZCI6ImNseHl6MTIzNDU2Nzg5MGFiY2RlZiJ9"
      }
    }
  }
}

List Users (Offset-based)

Retrieve an offset-based paginated list of users using the paginatedUsers query. Accepts the same selector as infiniteUsers but uses limit and offset for pagination.

query PaginatedUsers(
  $selector: UsersSelector,
  $sort: UserSort,
  $limit: Int!,
  $offset: Int!
) {
  paginatedUsers(
    selector: $selector,
    sort: $sort,
    limit: $limit,
    offset: $offset
  ) {
    nodes {
      id
      firstName
      lastName
      isActive
      isDisplayedOnSchedule
      color
    }
    totalCount
  }
}

# Variables
{
  "limit": 20,
  "offset": 0,
  "selector": {
    "filters": {
      "isActive": { "equals": true },
      "isDisplayedOnSchedule": { "equals": true }
    }
  }
}

Response:

{
  "data": {
    "paginatedUsers": {
      "nodes": [
        {
          "id": "clxyz1234567890abcdef",
          "firstName": "Mike",
          "lastName": "Johnson",
          "isActive": true,
          "isDisplayedOnSchedule": true,
          "color": "#4A90D9"
        }
      ],
      "totalCount": 12
    }
  }
}

Get User by ID

Retrieve a specific user by their ID. Results are filtered by the authenticated user's organization.

query User($id: ID!) {
  user(id: $id) {
    id
    firstName
    lastName
    isActive
    isDisplayedOnSchedule
    color
    mobileAppVersion
    createdAt
    updatedAt
  }
}

# Variables
{
  "id": "clxyz1234567890abcdef"
}

Response:

{
  "data": {
    "user": {
      "id": "clxyz1234567890abcdef",
      "firstName": "Mike",
      "lastName": "Johnson",
      "isActive": true,
      "isDisplayedOnSchedule": true,
      "color": "#4A90D9",
      "mobileAppVersion": "2.5.1",
      "createdAt": "2024-01-15T10:00:00Z",
      "updatedAt": "2024-01-20T08:00:00Z"
    }
  }
}

Get Authenticated User

Retrieve the currently authenticated user. This query returns the full user object for the caller, including auth-gated fields like email, role, and scopes.

query AuthenticatedUser {
  authenticatedUser {
    id
    firstName
    lastName
    username
    email
    role
    isActive
    isDisplayedOnSchedule
    color
    scopes
    hourlyRate
    serviceRate
    payrollType
    createdAt
    updatedAt
  }
}

Response:

{
  "data": {
    "authenticatedUser": {
      "id": "clxyz0000000000admin",
      "firstName": "Admin",
      "lastName": "User",
      "username": "admin@example.com",
      "email": "admin@example.com",
      "role": "ADMIN",
      "isActive": true,
      "isDisplayedOnSchedule": true,
      "color": "#E74C3C",
      "scopes": [
        "read:all:appointment",
        "write:appointment",
        "read:customer",
        "write:customer",
        "update:organization"
      ],
      "hourlyRate": 2500,
      "serviceRate": 5000,
      "payrollType": "HOURLY",
      "createdAt": "2023-01-15T10:00:00Z",
      "updatedAt": "2024-01-20T09:00:00Z"
    }
  }
}

Lookup User

Check if a user exists by their username or email address.

query LookupUser($usernameOrEmail: String!) {
  lookupUser(usernameOrEmail: $usernameOrEmail) {
    id
    firstName
    lastName
  }
}

# Variables
{
  "usernameOrEmail": "mike@example.com"
}

Response:

{
  "data": {
    "lookupUser": {
      "id": "clxyz1234567890abcdef",
      "firstName": "Mike",
      "lastName": "Johnson"
    }
  }
}

Filtering

Both infiniteUsers and paginatedUsers accept a selector parameter with filters and search. The UserFilters type supports the following fields:

Filter FieldTypeNotes
idIDFilterFilter by user ID
firstNameStringFilterFilter by first name
lastNameStringFilterFilter by last name
isActiveBooleanFilterFilter by active status
isDisplayedOnScheduleBooleanFilterFilter by schedule visibility
usernameStringFilterAuth-gated
emailStringFilterAuth-gated
mobileAppVersionStringFilterFilter by mobile app version
createdAtDateTimeFilterFilter by creation date
updatedAtDateTimeFilterFilter by last update date
roleUserRoleEnumFilterAuth-gated

The search field on the selector performs a text search across user fields (max 600 characters).

Field Reference

FieldTypeDescription
idID!Unique identifier (cuid)
firstNameString!First name
lastNameString!Last name
usernameString(nullable)Username (auth-gated: requires update:organization scope or self)
emailString(nullable)Email address (auth-gated)
createdAtDate!Creation timestamp
updatedAtDate!Last update timestamp
isActiveBoolean!Whether the user is active
isDisplayedOnScheduleBoolean!Whether the user is displayed on the schedule
roleUserRoleEnum(nullable)User role (auth-gated)
mobileAppVersionString(nullable)Version of the mobile app the user is running
hourlyRateInt(nullable)Hourly pay rate in cents (auth-gated: update:organization)
serviceRateInt(nullable)Service rate in cents (auth-gated: update:organization)
payrollTypeUserPayrollTypeEnum(nullable)Payroll type (auth-gated)
colorString(nullable)Color used for calendar/schedule display
scopes[String](nullable)List of permission scopes (auth-gated)