Skip to main content

NestJS Class Validators

Generated from the API docs. Covers all request body DTOs (inputs) and response DTOs (outputs) across every domain.


Shared / Common

import {
IsUUID, IsString, IsInt, IsBoolean, IsDateString,
IsOptional, IsArray, IsNotEmpty, IsEnum, IsUrl,
IsHexColor, IsNumber, ValidateNested, Min, ArrayNotEmpty,
} from 'class-validator';
import { Type } from 'class-transformer';

Catalog

CatalogVendor

export class CatalogVendor {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
name: string;

@IsOptional()
@IsUrl()
url: string | null;
}

CatalogCategory

export class CatalogCategory {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
name: string;
}

CatalogApp

export class CatalogApp {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
canonical_name: string;

@IsOptional()
@IsString()
description: string | null;

@IsOptional()
@IsHexColor()
display_colour: string | null;

@IsOptional()
@IsUrl()
logo: string | null;

@IsOptional()
@IsString()
type: string | null;

@IsOptional()
@ValidateNested()
@Type(() => CatalogVendor)
vendor: CatalogVendor | null;

@IsArray()
@ValidateNested({ each: true })
@Type(() => CatalogCategory)
categories: CatalogCategory[];

@IsDateString()
created_at: string;

@IsDateString()
updated_at: string;
}

UrlPattern

export class UrlPattern {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
pattern: string;
}

DesktopAlias

export class DesktopAlias {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
alias: string;
}

Clients

Partner

export class Partner {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
name: string;
}

EnrollmentToken

export class EnrollmentToken {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
value: string;

@IsString()
@IsNotEmpty()
description: string;

@IsOptional()
@IsString()
site_id: string | null;

@IsEnum(['active', 'inactive'])
status: 'active' | 'inactive';

@IsOptional()
@IsInt()
@Min(1)
max_uses: number | null;

@IsOptional()
@IsInt()
@Min(0)
remaining_uses: number | null;

@IsOptional()
@IsDateString()
expires_at: string | null;

@IsDateString()
created_at: string;
}

Client

export class Client {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
name: string;

@IsEnum(['active'])
status: 'active';

@ValidateNested()
@Type(() => Partner)
partner: Partner;

@IsOptional()
@ValidateNested()
@Type(() => EnrollmentToken)
enrollment_token: EnrollmentToken | null;

@IsDateString()
created_at: string;

@IsDateString()
updated_at: string;
}

Users

LastActivity

export class LastActivity {
@IsOptional()
@IsDateString()
at: string | null;

@IsOptional()
@IsDateString()
desktop_at: string | null;

@IsOptional()
@IsDateString()
web_at: string | null;
}

UserRef

export class UserRef {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
username: string;

@IsString()
@IsNotEmpty()
user_key: string;

@ValidateNested()
@Type(() => LastActivity)
last_activity: LastActivity;
}

DepartmentRef

export class DepartmentRef {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
name: string;

@IsOptional()
@IsString()
description: string | null;
}

User

export class User extends UserRef {
@IsArray()
@ValidateNested({ each: true })
@Type(() => DepartmentRef)
departments: DepartmentRef[];

@IsDateString()
created_at: string;

@IsDateString()
updated_at: string;
}

UpdateUserDtoPATCH /users/{id}

export class UpdateUserDto {
@IsArray()
@IsUUID('4', { each: true })
departments: string[];
}

Departments

Department

export class Department extends DepartmentRef {
@IsInt()
@Min(0)
member_count: number;

@IsDateString()
created_at: string;

@IsDateString()
updated_at: string;
}

BulkMemberFailure

export class BulkMemberFailure {
@IsUUID()
id: string;

@IsString()
error: string;
}

BulkMemberResult

export class BulkMemberResult {
@IsArray()
@IsUUID('4', { each: true })
succeeded: string[];

@IsArray()
@ValidateNested({ each: true })
@Type(() => BulkMemberFailure)
failed: BulkMemberFailure[];
}

CreateDepartmentDtoPOST /departments

export class CreateDepartmentDto {
@IsString()
@IsNotEmpty()
name: string;

@IsOptional()
@IsString()
description?: string | null;
}

UpdateDepartmentDtoPATCH /departments/{id}

export class UpdateDepartmentDto {
@IsOptional()
@IsString()
@IsNotEmpty()
name?: string;

@IsOptional()
@IsString()
description?: string | null;
}

BulkMembersDtoPOST /departments/{id}/members and .../members/remove

export class BulkMembersDto {
@IsArray()
@ArrayNotEmpty()
@IsUUID('4', { each: true })
user_ids: string[];
}

Devices

DeviceRef

export class DeviceRef {
@IsUUID()
id: string;

@IsOptional()
@IsString()
name: string | null;

@IsOptional()
@IsEnum(['active', 'inactive', 'pending'])
status: 'active' | 'inactive' | 'pending' | null;

@IsOptional()
@IsString()
os_name: string | null;

@IsOptional()
@IsString()
os_version: string | null;

@IsOptional()
@IsDateString()
last_seen_at: string | null;
}

DeviceHardware

export class DeviceHardware {
@IsOptional()
@IsString()
manufacturer: string | null;

@IsOptional()
@IsString()
model: string | null;

@IsOptional()
@IsString()
cpu_model: string | null;

@IsOptional()
@IsInt()
@Min(1)
cpu_cores: number | null;

@IsOptional()
@IsNumber()
@Min(0)
ram: number | null;
}

BrowserExtension

export class BrowserExtension {
@IsOptional()
@IsString()
version: string | null;

@IsBoolean()
installed: boolean;

@IsBoolean()
auto_update: boolean;

@IsOptional()
@IsDateString()
last_activity_at: string | null;
}

DeviceExtensions

export class DeviceExtensions {
@ValidateNested()
@Type(() => BrowserExtension)
chrome: BrowserExtension;

@ValidateNested()
@Type(() => BrowserExtension)
edge: BrowserExtension;

@ValidateNested()
@Type(() => BrowserExtension)
firefox: BrowserExtension;
}

Device

export class Device extends DeviceRef {
@IsOptional()
@IsString()
serial_number: string | null;

@IsOptional()
@IsString()
unique_key: string | null;

@IsOptional()
@IsDateString()
installed_at: string | null;

@IsOptional()
@IsString()
agent_version: string | null;

@ValidateNested()
@Type(() => DeviceHardware)
hardware: DeviceHardware;

@ValidateNested()
@Type(() => DeviceExtensions)
extensions: DeviceExtensions;

@IsDateString()
created_at: string;

@IsDateString()
updated_at: string;
}

DeviceUserRef

export class DeviceUserRef extends UserRef {
@IsDateString()
enrolled_at: string;

@IsOptional()
@IsDateString()
last_seen_at: string | null;
}

DeviceDeploymentRef

export class DeviceDeploymentRef {
@IsUUID()
id: string;

@IsOptional()
@IsEnum(['success', 'error', 'pending'])
status: 'success' | 'error' | 'pending' | null;

@IsOptional()
@IsDateString()
enrollment_date: string | null;
}

DeviceDeployment

export class DeviceDeployment extends DeviceDeploymentRef {
@IsUUID()
enrollment_token_id: string;

@IsOptional()
@IsUUID()
user_id: string | null;

@IsOptional()
@IsArray()
@IsString({ each: true })
error_logs: string[] | null;

@IsDateString()
created_at: string;

@IsDateString()
updated_at: string;
}

Apps

AppRef

export class AppRef {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
canonical_name: string;

@IsOptional()
@IsUrl()
logo: string | null;

@IsOptional()
@IsString()
type: string | null;

@IsBoolean()
is_favorite: boolean;

@IsBoolean()
is_approved: boolean;
}

App

export class App {
@IsUUID()
id: string;

@ValidateNested()
@Type(() => CatalogApp)
catalog_app: CatalogApp;

@IsBoolean()
is_favorite: boolean;

@IsBoolean()
is_approved: boolean;

@IsOptional()
@IsInt()
@Min(0)
license_count: number | null;

@IsDateString()
created_at: string;

@IsDateString()
updated_at: string;
}

UpdateAppDtoPATCH /apps/{id}

export class UpdateAppDto {
@IsOptional()
@IsBoolean()
is_favorite?: boolean;

@IsOptional()
@IsBoolean()
is_approved?: boolean;

@IsOptional()
@IsInt()
@Min(0)
license_count?: number | null;
}

BulkAppFailure

export class BulkAppFailure {
@IsUUID()
id: string;

@IsString()
error: string;
}

BulkAppResult

export class BulkAppResult {
@IsArray()
@IsUUID('4', { each: true })
succeeded: string[];

@IsArray()
@ValidateNested({ each: true })
@Type(() => BulkAppFailure)
failed: BulkAppFailure[];
}

FavoritesDtoPOST /apps/favorites and .../favorites/remove

export class FavoritesDto {
@IsArray()
@ArrayNotEmpty()
@IsUUID('4', { each: true })
app_ids: string[];
}

ApprovalDtoPOST /apps/approval and .../approval/reject

export class ApprovalDto {
@IsArray()
@ArrayNotEmpty()
@IsUUID('4', { each: true })
app_ids: string[];
}

Analytics — Shared

MetricWithDeltaDto

Shared wrapper used wherever a numeric metric is paired with an optional comparison-period change percentage. See MetricWithDeltaDto.

export class MetricWithDeltaDto {
@IsNumber()
@Min(0)
value: number;

@IsOptional()
@IsNumber()
change_pct: number | null;

@IsOptional()
@IsNumber()
@Min(0)
compare_value: number | null;
}

AnalyticsPeriod

Shared period object echoed in all aggregate analytics responses. See Response Period Object.

export class AnalyticsPeriod {
@IsDateString()
start_date: string;

@IsDateString()
end_date: string;

@IsOptional()
@IsDateString()
compare_start_date: string | null;

@IsOptional()
@IsDateString()
compare_end_date: string | null;
}

ActivityPeriod

Period object used by activity time-series endpoints (/activity). Uses start/end keys (no _date suffix) and does not support comparison periods.

export class ActivityPeriod {
@IsDateString()
start: string;

@IsDateString()
end: string;
}

DailyDataPoint

export class DailyDataPoint {
@IsDateString()
date: string;

@IsNumber()
@Min(0)
value: number;
}

ActivityTimeSeries

Returned by all /activity endpoints (User Activity, Device Activity, App Activity).

export class ActivityTimeSeries {
@IsString()
@IsNotEmpty()
metric: string;

@IsString()
@IsNotEmpty()
label: string;

@ValidateNested()
@Type(() => ActivityPeriod)
period: ActivityPeriod;

@IsArray()
@ValidateNested({ each: true })
@Type(() => DailyDataPoint)
data: DailyDataPoint[];
}

Analytics — Utilization

Shared DTOs used by the App Utilization Rankings, App Utilization Summary, and App Utilization endpoints.

RankedApp

export class RankedApp {
@ValidateNested()
@Type(() => AppRef)
app: AppRef;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
metric: MetricWithDeltaDto;
}

AppRanking

export class AppRanking {
@ValidateNested()
@Type(() => RankedApp)
leader: RankedApp;

@IsOptional()
@ValidateNested()
@Type(() => RankedApp)
biggest_increase: RankedApp | null;

@IsOptional()
@ValidateNested()
@Type(() => RankedApp)
biggest_decrease: RankedApp | null;
}

AppUtilizationRankingsResponse

export class AppUtilizationRankingsResponse {
@ValidateNested()
@Type(() => AnalyticsPeriod)
period: AnalyticsPeriod;

@ValidateNested()
@Type(() => AppRanking)
by_interactions: AppRanking;

@ValidateNested()
@Type(() => AppRanking)
by_time: AppRanking;

@ValidateNested()
@Type(() => AppRanking)
by_active_users: AppRanking;
}

AppUtilizationSummary

export class AppUtilizationSummary {
@ValidateNested()
@Type(() => AnalyticsPeriod)
period: AnalyticsPeriod;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
apps_used: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
apps_discovered: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
apps_dropped_off: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
categories_used: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
users: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
departments: MetricWithDeltaDto;
}

AppUtilization

Per-app row returned by App Utilization.

export class AppUtilization {
@ValidateNested()
@Type(() => App)
app: App;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
unique_users: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
active_time_ms: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
avg_time_ms_per_day: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
session_count: MetricWithDeltaDto;

@IsOptional()
@IsEnum(['heavy', 'medium', 'light'])
usage_level: 'heavy' | 'medium' | 'light' | null;

@IsOptional()
@IsEnum(['critical', 'medium', 'low'])
risk_level: 'critical' | 'medium' | 'low' | null;
}

TrendDataPoint

Per-bucket row returned by App Utilization Timeseries.

export class TrendDataPoint {
@IsDateString()
date: string;

@IsInt()
@Min(0)
unused_apps: number;

@IsInt()
@Min(0)
unapproved_apps: number;

@IsInt()
@Min(0)
ai_apps: number;

@IsInt()
@Min(0)
other_apps: number;
}

AppUtilizationTimeseriesResponse

export class AppUtilizationTimeseriesResponse {
@ValidateNested()
@Type(() => AnalyticsPeriod)
period: AnalyticsPeriod;

@IsArray()
@ValidateNested({ each: true })
@Type(() => TrendDataPoint)
data: TrendDataPoint[];
}

CategoryUtilization

Per-category row returned by App Utilization by Category.

export class CategoryUtilization {
@ValidateNested()
@Type(() => CatalogCategory)
category: CatalogCategory;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
app_count: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
user_count: MetricWithDeltaDto;
}

DepartmentUtilization

Per-department row returned by App Utilization by Department.

export class DepartmentUtilization {
@ValidateNested()
@Type(() => DepartmentRef)
department: DepartmentRef;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
user_count: MetricWithDeltaDto;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
app_count: MetricWithDeltaDto;
}

UserUtilization

Per-user row returned by App Utilization by User.

export class UserUtilization {
@ValidateNested()
@Type(() => UserRef)
user: UserRef;

@IsOptional()
@ValidateNested()
@Type(() => DepartmentRef)
department: DepartmentRef | null;

@ValidateNested()
@Type(() => MetricWithDeltaDto)
app_count: MetricWithDeltaDto;
}

Setup

DTOs returned by POST /v2/setup. No request body — inputs are derived from the LM bearer token claims.

SetupPartner

export class SetupPartner {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
lm_partner_id: string;

@IsString()
@IsNotEmpty()
name: string;

@IsBoolean()
created: boolean;
}

SetupClient

export class SetupClient {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
lm_client_id: string;

@IsString()
@IsNotEmpty()
name: string;

@IsBoolean()
created: boolean;
}

SetupPartnerUser

export class SetupPartnerUser {
@IsUUID()
id: string;

@IsString()
@IsNotEmpty()
lm_user_id: string;

@IsString()
@IsNotEmpty()
email: string;

@IsBoolean()
created: boolean;
}

SetupResponsePOST /v2/setup

export class SetupResponse {
@ValidateNested()
@Type(() => SetupPartner)
partner: SetupPartner;

@ValidateNested()
@Type(() => SetupClient)
client: SetupClient;

@ValidateNested()
@Type(() => SetupPartnerUser)
partner_user: SetupPartnerUser;
}

Paginated Response Wrappers

Generic wrappers you can use across all list endpoints:

export class PaginatedResponse<T> {
data: T[];

@IsInt()
@Min(0)
total_count: number;

@IsOptional()
@IsString()
next_cursor: string | null;
}

Usage examples

// List Users
class ListUsersResponse extends PaginatedResponse<User> {}

// List Departments
class ListDepartmentsResponse extends PaginatedResponse<Department> {}

// List Devices
class ListDevicesResponse extends PaginatedResponse<Device> {}

// List Apps
class ListAppsResponse extends PaginatedResponse<App> {}

// List Catalog Apps
class ListCatalogAppsResponse extends PaginatedResponse<CatalogApp> {}

// List Catalog Vendors
class ListCatalogVendorsResponse extends PaginatedResponse<CatalogVendor> {}

// List Catalog Categories
class ListCatalogCategoriesResponse extends PaginatedResponse<CatalogCategory> {}

// Device Users
class ListDeviceUsersResponse extends PaginatedResponse<DeviceUserRef> {}

// Device Deployments
class ListDeviceDeploymentsResponse extends PaginatedResponse<DeviceDeploymentRef> {}

// Catalog App URL Patterns
class ListUrlPatternsResponse extends PaginatedResponse<UrlPattern> {}

// Catalog App Desktop Aliases
class ListDesktopAliasesResponse extends PaginatedResponse<DesktopAlias> {}

// App Utilization (period + paginated list)
class AppUtilizationResponse extends PaginatedResponse<AppUtilization> {
@ValidateNested()
@Type(() => AnalyticsPeriod)
period: AnalyticsPeriod;
}

// App Utilization by Category
class AppUtilizationCategoriesResponse extends PaginatedResponse<CategoryUtilization> {
@ValidateNested()
@Type(() => AnalyticsPeriod)
period: AnalyticsPeriod;
}

// App Utilization by User
class AppUtilizationUsersResponse extends PaginatedResponse<UserUtilization> {
@ValidateNested()
@Type(() => AnalyticsPeriod)
period: AnalyticsPeriod;
}

// App Utilization by Department
class AppUtilizationDepartmentsResponse extends PaginatedResponse<DepartmentUtilization> {
@ValidateNested()
@Type(() => AnalyticsPeriod)
period: AnalyticsPeriod;
}