API Reference
Resources
Manage staff resources, capacity, and organization membership records.
REST /api/v1API key authentication5 endpoints
GET
/api/v1/resourcesList resources with optional filters
Query schema
const listQuerySchema = z.object({
isActive: z
.string()
.transform((v) => v === 'true')
.optional(),
roleId: z.string().uuid().optional(),
disciplineId: z.string().uuid().optional(),
homeOfficeId: z.string().uuid().optional(),
skillGroupIds: z.array(z.string().uuid()).optional(),
search: z.string().optional(),
limit: z.coerce.number().int().min(1).max(100).default(50),
offset: z.coerce.number().int().min(0).default(0),
});Response200JSON response with data and pagination envelopes.
POST
/api/v1/resourcesCreate a new resource
JSON body schema
const salaryPeriodSchema = z.enum(['hour', 'day', 'week', 'month', 'year']);
const createBodySchema = z.object({
name: z.string().min(1),
email: z.string().email().optional(),
phone: z.string().optional(),
jobTitle: z.string().optional(),
roleId: z.string().uuid().optional(),
disciplineId: z.string().uuid().optional(),
employmentType: z.string().optional(),
startDate: z.string().optional(),
endDate: z.string().optional(),
countryCode: z.string().optional(),
regionCode: z.string().optional(),
homeOfficeId: z.string().uuid().optional(),
skillGroupIds: z.array(z.string().uuid()).optional(),
tags: z.array(z.string()).optional(),
salary: z.number().min(0).optional(),
salaryPeriod: salaryPeriodSchema.optional(),
externalUserId: z.string().optional(),
});Response201JSON response with a data envelope.
DELETE
/api/v1/resources/:idDelete a resource (soft delete)
Path parametersid: string
Response204No response body.
GET
/api/v1/resources/:idGet a single resource
Path parametersid: string
Response200JSON response with a data envelope.
PATCH
/api/v1/resources/:idUpdate a resource
Path parametersid: string
JSON body schema
const salaryPeriodSchema = z.enum(['hour', 'day', 'week', 'month', 'year']);
const updateBodySchema = z.object({
name: z.string().min(1).optional(),
email: z.string().email().nullable().optional(),
phone: z.string().nullable().optional(),
jobTitle: z.string().nullable().optional(),
roleId: z.string().uuid().nullable().optional(),
disciplineId: z.string().uuid().nullable().optional(),
employmentType: z.string().optional(),
startDate: z.string().nullable().optional(),
endDate: z.string().nullable().optional(),
countryCode: z.string().nullable().optional(),
regionCode: z.string().nullable().optional(),
homeOfficeId: z.string().uuid().nullable().optional(),
skillGroupIds: z.array(z.string().uuid()).optional(),
tags: z.array(z.string()).optional(),
isActive: z.boolean().optional(),
salary: z.number().min(0).nullable().optional(),
salaryPeriod: salaryPeriodSchema.nullable().optional(),
externalUserId: z.string().nullable().optional(),
});Response200JSON response with a data envelope.