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;
}
UpdateUserDto — PATCH /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[];
}
CreateDepartmentDto — POST /departments
export class CreateDepartmentDto {
@IsString()
@IsNotEmpty()
name: string;
@IsOptional()
@IsString()
description?: string | null;
}
UpdateDepartmentDto — PATCH /departments/{id}
export class UpdateDepartmentDto {
@IsOptional()
@IsString()
@IsNotEmpty()
name?: string;
@IsOptional()
@IsString()
description?: string | null;
}
BulkMembersDto — POST /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;
}
UpdateAppDto — PATCH /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[];
}
FavoritesDto — POST /apps/favorites and .../favorites/remove
export class FavoritesDto {
@IsArray()
@ArrayNotEmpty()
@IsUUID('4', { each: true })
app_ids: string[];
}
ApprovalDto — POST /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;
}
SetupResponse — POST /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;
}