AI Monorepo API
tRPC API Documentation
Analytics
Distinct talent, locations, and entry count for today's schedule.
{
today: any
}
{
talentCount: number
locationCount: number
scheduleCount: number
}
Roster size split into on-site (active) vs off-roster (hidden) talent.
{
total: number
active: number
hidden: number
}
Schedule count per day for the current week (MonβSun).
{
today: any
}
Array<{
date: string
value: number
}>
Distinct talent scheduled at least one day this week (MonβSun).
{
today: any
}
number
Unique talent count per location for the current week.
{
today: any
}
Array<{
name: string
value: number
}>
Count of roster talent missing each profile field.
Array<{
name: string
value: number
}>
Appointment
A schedule with its appointments and the derived day totals β the daily tracker detail summary (Due / Paid / Balance + the Credit/Paid/Miss state)
{
scheduleId: string
}
{
schedule: {
id: string
talentId: string
talentName: string
locationId: string
locationName: string
city: string
date: string | any
category: "Hotel" | "Airbnb" | "Condo"
talentBookOnFee: number | null
flatFee: number | null
bookOn: number | null
notes?: string | null
}
appointments: Array<{
id: string
scheduleId: string
startTime: string | null
clientId: string
clientName: string
menuId: string | null
menuLabel: string | null
fee: number
discount: number
bookedByUserId: string | null
bookerName: string | null
bookerPay: number
confirmed: boolean
services: Array<{
id: string
appointmentId: string
menuServiceId: string
serviceName: string
fee: number
}>
notes?: string | null
cancelledAt: string | any | null
}>
due: number
paid: number
balance: number
status: "credit" | "paid" | "miss"
cancellationIncome: number
}
One appointment for the edit form
{
id: string
}
{
id: string
scheduleId: string
startTime: string | null
clientId: string
clientName: string
menuId: string | null
menuLabel: string | null
fee: number
discount: number
bookedByUserId: string | null
bookerName: string | null
bookerPay: number
confirmed: boolean
services: Array<{
id: string
appointmentId: string
menuServiceId: string
serviceName: string
fee: number
}>
notes?: string | null
cancelledAt: string | any | null
}
A client's appointments in this brand (newest first) β the picker for applying a credit to a booking (LUX-113)
{
clientId: string
}
Array<{
id: string
date: string | any
startTime: string | null
talentName: string
locationName: string
}>
Books an appointment; fee and per-line service fees are captured from the menu catalog, never from the client
{
scheduleId: string
clientId: string
menuId: string
bookedByUserId: string
startTime?: string | null
discount: number
confirmed: boolean
notes?: string | null
services: Array<{
menuServiceId: string
}>
}
{
id: string
scheduleId: string
startTime: string | null
clientId: string
clientName: string
menuId: string | null
menuLabel: string | null
fee: number
discount: number
bookedByUserId: string | null
bookerName: string | null
bookerPay: number
confirmed: boolean
services: Array<{
id: string
appointmentId: string
menuServiceId: string
serviceName: string
fee: number
}>
notes?: string | null
cancelledAt: string | any | null
}
Historical import only (LUX-120): replaces a schedule-day's synthesized appointments + their payments, and upserts the day's book-on onto its daily report β one transaction, so the day lands whole or not at all (D92). The DOCUMENTED D67 EXCEPTION β the only write that accepts an explicit fee, because the sheet's total is history and re-capturing it from the talent's current Menu.fee would import today's price. Idempotent: only rows marked imported are replaced, never an operator's real booking. 404 unless the schedule belongs to the requesting company
{
scheduleId: string
clientId: string
bookedByUserId?: string | null
callCount: number
serviceTotal: number
payments: Array<{
method: "EMT" | "AmazonGiftCard" | "Cash"
amount: number
}>
bookOn: number
}
{
replaced: number
dayExisted: boolean
appointments: Array<{
id: string
scheduleId: string
startTime: string | null
clientId: string
clientName: string
menuId: string | null
menuLabel: string | null
fee: number
discount: number
bookedByUserId: string | null
bookerName: string | null
bookerPay: number
confirmed: boolean
services: Array<{
id: string
appointmentId: string
menuServiceId: string
serviceName: string
fee: number
}>
notes?: string | null
cancelledAt: string | any | null
}>
}
Edits an appointment; re-captures the fee and replaces the service lines
{
scheduleId: string
clientId: string
menuId: string
bookedByUserId: string
startTime?: string | null
discount: number
confirmed: boolean
notes?: string | null
services: Array<{
menuServiceId: string
}>
id: string
}
{
id: string
scheduleId: string
startTime: string | null
clientId: string
clientName: string
menuId: string | null
menuLabel: string | null
fee: number
discount: number
bookedByUserId: string | null
bookerName: string | null
bookerPay: number
confirmed: boolean
services: Array<{
id: string
appointmentId: string
menuServiceId: string
serviceName: string
fee: number
}>
notes?: string | null
cancelledAt: string | any | null
}
Removes an appointment
{
id: string
}
Schedules in a date range with the derived Due, Paid, Balance and the Credit/Paid/Miss state, computed server-side
{
startDate: any
endDate: any
}
Array<{
scheduleId: string
date: string | any
talentName: string
locationName: string
city: string
calls: number
due: number
paid: number
balance: number
status: "credit" | "paid" | "miss"
bookOn: number | null
cancellationIncome: number
}>
Every appointment in a date range across the company's talents, joined to its schedule for display β the browse-by-date list (loaded wide, filtered client-side)
{
startDate: any
endDate: any
}
Array<{
id: string
scheduleId: string
startTime: string | null
clientId: string
clientName: string
menuId: string | null
menuLabel: string | null
fee: number
discount: number
bookedByUserId: string | null
bookerName: string | null
bookerPay: number
confirmed: boolean
services: Array<{
id: string
appointmentId: string
menuServiceId: string
serviceName: string
fee: number
}>
notes?: string | null
cancelledAt: string | any | null
date: string | any
talentId: string
talentName: string
locationName: string
city: string
}>
Auth
Authenticate with email and password
{
email: string
password: string
}
{
token: string | null
user: {
id: string
email: string
name: string | null
image: string | null
emailVerified: boolean
}
}
Booker
Returns all bookers (Users with role 'booker'), name ascending, each with its pay rate (null until set)
Array<{
id: string
name: string
payRate: number | null
}>
Sets a booker's pay rate β whole dollars per booked appointment (D76); upserts by user. New appointments stamp this rate; past ones are unchanged
{
userId: string
amount: number
}
City
Returns the requesting company's cities in display order
Array<{
id: string
createdAt: string | any
updatedAt: string | any
name: string
sortOrder: number
}>
Batch-update the display order of city sections for the requesting company
{
orderedIds: string[]
}
Array<{
id: string
createdAt: string | any
updatedAt: string | any
name: string
sortOrder: number
}>
Onboards a city by name for the requesting company; returns the existing city if the name is already used
{
name: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string
sortOrder: number
}
Renames a city owned by the requesting company; 404 unless it belongs to the company, 409 if the name is already used
{
id: string
name: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string
sortOrder: number
}
Deletes a city owned by the requesting company; 404 unless it belongs to the company, 400 while it still has locations
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string
sortOrder: number
}
Client
Returns all clients (global across brands)
Array<{
id: string
createdAt: string | any
updatedAt: string | any
code: string
name: string
phone: string
email: string | null
ageRange: string | null
ethnicity: string | null
notes: string | null
cafHandle: string | null
perbHandle: string | null
isBlacklisted: boolean
blacklistReason: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues" | null
}>
Returns a client by ID, with the brands they booked through
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
code: string
name: string
phone: string
email: string | null
ageRange: string | null
ethnicity: string | null
notes: string | null
cafHandle: string | null
perbHandle: string | null
isBlacklisted: boolean
blacklistReason: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues" | null
brands: string[]
}
Creates a client β phone is the global dedup key
{
name: string
phone: string
email?: string | null
ageRange?: "20-30" | "30-40" | "40-50" | "50+" | null
ethnicity?: string | null
notes?: string | null
cafHandle?: string | null
perbHandle?: string | null
isBlacklisted?: boolean
blacklistReason?: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues" | null
}
{
id: string
createdAt: string | any
updatedAt: string | any
code: string
name: string
phone: string
email: string | null
ageRange: string | null
ethnicity: string | null
notes: string | null
cafHandle: string | null
perbHandle: string | null
isBlacklisted: boolean
blacklistReason: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues" | null
}
Updates a client
{
name?: string
phone?: string
email?: string | null
ageRange?: "20-30" | "30-40" | "40-50" | "50+" | null
ethnicity?: string | null
notes?: string | null
cafHandle?: string | null
perbHandle?: string | null
isBlacklisted?: boolean
blacklistReason?: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues" | null
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
code: string
name: string
phone: string
email: string | null
ageRange: string | null
ethnicity: string | null
notes: string | null
cafHandle: string | null
perbHandle: string | null
isBlacklisted: boolean
blacklistReason: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues" | null
}
Returns the ids of talents on a client's Don't-See list
{
clientId: string
}
string[]
Replaces a client's Don't-See list β the talents who won't see this client
{
clientId: string
talentIds: string[]
}
string[]
ClientCredit
A client's prepaid / cancellation credits in this brand, newest first
{
clientId: string
}
Array<{
id: string
clientId: string
amount: number
status: "held" | "applied" | "cancellationFee"
talentAmount: number | null
bookerFee: number | null
agencyAmount: number | null
note: string | null
createdAt: string | any
appliedBooking: {
id: string
date: string | any
talentName: string
locationName: string
} | any | null
cancelledBooking: {
id: string
date: string | any
talentName: string
locationName: string
} | any | null
}>
Records a client prepayment as a held credit (>= $50 minimum, D87) β never a Payment
{
clientId: string
amount: number
note?: string
}
{
id: string
clientId: string
amount: number
status: "held" | "applied" | "cancellationFee"
talentAmount: number | null
bookerFee: number | null
agencyAmount: number | null
note: string | null
createdAt: string | any
appliedBooking: {
id: string
date: string | any
talentName: string
locationName: string
} | any | null
cancelledBooking: {
id: string
date: string | any
talentName: string
locationName: string
} | any | null
}
Applies a held credit to a booking β creates a Payment(method:Credit) for the full amount so the tracker Paid rolls up (D87)
{
id: string
appointmentId: string
}
{
id: string
clientId: string
amount: number
status: "held" | "applied" | "cancellationFee"
talentAmount: number | null
bookerFee: number | null
agencyAmount: number | null
note: string | null
createdAt: string | any
appliedBooking: {
id: string
date: string | any
talentName: string
locationName: string
} | any | null
cancelledBooking: {
id: string
date: string | any
talentName: string
locationName: string
} | any | null
}
Uses a held credit as a cancellation fee behind a specific cancelled booking β stamps the talent Β½ / booker $25 / agency surplus split and links the booking so the talent-day income + booker-week $25 report; no Payment (D87/D95)
{
id: string
cancelledAppointmentId: string
}
{
id: string
clientId: string
amount: number
status: "held" | "applied" | "cancellationFee"
talentAmount: number | null
bookerFee: number | null
agencyAmount: number | null
note: string | null
createdAt: string | any
appliedBooking: {
id: string
date: string | any
talentName: string
locationName: string
} | any | null
cancelledBooking: {
id: string
date: string | any
talentName: string
locationName: string
} | any | null
}
Removes a mistaken held credit β a consumed (applied / cancellation-fee) credit is immutable
{
id: string
}
Company
Returns all companies
Array<{
id: string
createdAt: string | any
updatedAt: string | any
name: string
slug: string
defaultPhoneNumberId: string | null
imageBrand: "LuxWatermark" | "Clean"
}>
Returns the requesting company's default (house) phone, or null when unset β the public fallback for talent contact numbers
{
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
Creates a new company
{
name: string
slug: string
defaultPhoneNumberId?: string | null
imageBrand?: "LuxWatermark" | "Clean"
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string
slug: string
defaultPhoneNumberId: string | null
imageBrand: "LuxWatermark" | "Clean"
}
Updates a company
{
name?: string
slug?: string
defaultPhoneNumberId?: string | null
imageBrand?: "LuxWatermark" | "Clean"
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string
slug: string
defaultPhoneNumberId: string | null
imageBrand: "LuxWatermark" | "Clean"
}
Blocked β companies cannot be deleted via the API
{
id: string
}
Expense
Ad-hoc expenses in a date range (by the date incurred), newest first β the list + the weekly report money-out
{
startDate: any
endDate: any
}
Array<{
id: string
amount: number
category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
incurredOn: string | any
note: string | null
allocations: Array<{
locationId: string
locationName: string
city: string
amount: number
}>
}>
One expense with its allocations, or null when not this companyβs
{
id: string
}
{
id: string
amount: number
category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
incurredOn: string | any
note: string | null
allocations: Array<{
locationId: string
locationName: string
city: string
amount: number
}>
} | null
Records an expense across 0/1/many locations β the server splits the amount evenly (0 locations = a general cost); allocation shares are derived, never client-sent
{
amount: number
category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
incurredOn: any
note?: string
locationIds: string[]
}
{
id: string
amount: number
category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
incurredOn: string | any
note: string | null
allocations: Array<{
locationId: string
locationName: string
city: string
amount: number
}>
}
Updates an expense and replaces its allocation; 404 unless it belongs to the requesting company
{
amount: number
category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
incurredOn: any
note?: string
locationIds: string[]
id: string
}
{
id: string
amount: number
category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
incurredOn: string | any
note: string | null
allocations: Array<{
locationId: string
locationName: string
city: string
amount: number
}>
}
Removes an expense and its allocations
{
id: string
}
FinanceDashboard
Owner business-health roll-up over a period (day / week / month / quarter / year): gross (Ξ£ Due), expenses (ad-hoc + prorated fixed costs), net, and collected cash β each with a delta vs the prior period, plus a trend, by-city and by-category breakdown
{
periodKind: "day" | "week" | "month" | "quarter" | "year"
anchorDate: string
}
{
periodKind: "day" | "week" | "month" | "quarter" | "year"
range: {
startDate: string | any
endDate: string | any
}
kpis: {
gross: {
value: number
previous: number
delta: number
}
expenses: {
value: number
previous: number
delta: number
}
net: {
value: number
previous: number
delta: number
}
collectedCash: {
value: number
previous: number
delta: number
}
cashProfit: {
value: number
previous: number
delta: number
}
}
trend: Array<{
date: string | any
gross: number
expenses: number
net: number
collectedCash: number
}>
byCity: Array<{
city: string
gross: number
net: number
}>
businessWide: number
byCategory: Array<{
category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation" | "Rent" | "Utilities" | "Internet" | "Insurance" | "Misc"
amount: number
}>
bookerPay: number
}
Per-location leaderboard over a period: each non-Hotel locationβs revenue (Ξ£ Due), prorated fixed costs, allocated expenses, profit and booked-day utilization β ranked client-side by profit / margin / profit-per-booked-day
{
periodKind: "day" | "week" | "month" | "quarter" | "year"
anchorDate: string
}
Array<{
locationId: string
locationName: string
city: string
revenue: number
fixedCosts: number
allocatedExpenses: number
bookerPay: number
profit: number
bookedDays: number
daysInPeriod: number
}>
One locationβs monthly trend (revenue vs expenses), cost composition (fixed lines + assigned expenses), cumulative investment-vs-return (payback), and booked-day utilization over the last 12 months
{
locationId: string
anchorDate: string
}
{
locationId: string
locationName: string
city: string
months: Array<{
period: string
revenue: number
expenses: number
fixedCosts: number
allocatedExpenses: number
bookerPay: number
bookedDays: number
daysInMonth: number
}>
costComposition: {
rent: number
utilities: number
internet: number
insurance: number
cleaning: number
supplies: number
misc: number
allocatedExpenses: number
bookerPay: number
}
costCompositionByMonth: Array<{
rent: number
utilities: number
internet: number
insurance: number
cleaning: number
supplies: number
misc: number
allocatedExpenses: number
bookerPay: number
period: string
}>
investmentReturn: Array<{
period: string
cumulativeInvested: number
cumulativeRevenue: number
}>
}
DailyReport
Upserts a schedule-day's book-on (+ the airbnb/hotel per-date flat fee). The book-on is stored as sent β an editable per-day override (D64). 404 unless the schedule belongs to the requesting company
{
scheduleId: string
flatFee?: number | null
bookOn: number
}
{
id: string
scheduleId: string
flatFee: number | null
bookOn: number
}
File
Returns root images with failed processing status
any[]
Retries processing for a failed image by re-generating missing variants
{
imageId: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
fileId: string
talentId: string
variant: "Original" | "Thumbnail" | "Large"
imageBrand: "LuxWatermark" | "Clean" | null
status: "Processing" | "Completed" | "Failed"
errorMessage: string | null
width: number | null
height: number | null
sortOrder: number
sourceImageId: string | null
file: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
mimeType: string
size: number
blobKey: string
container: string
url: string | null
uploadedById: string | null
} | null
variants: any[]
}
Debug
Throws a test error for Sentry
Image
Returns all images for a talent belonging to the requesting company
{
talentId: string
}
any[]
Returns the thumbnail image URL for a talent belonging to the requesting company
{
talentId: string
}
{
url: string | null
variant: "Original" | "Thumbnail" | "Large" | null
}
Creates a new image
{
fileId: string
variant?: "Original" | "Thumbnail" | "Large"
imageBrand?: "LuxWatermark" | "Clean" | null
width?: number | null
height?: number | null
sortOrder?: number
talentId: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
fileId: string
talentId: string
variant: "Original" | "Thumbnail" | "Large"
imageBrand: "LuxWatermark" | "Clean" | null
status: "Processing" | "Completed" | "Failed"
errorMessage: string | null
width: number | null
height: number | null
sortOrder: number
sourceImageId: string | null
file: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
mimeType: string
size: number
blobKey: string
container: string
url: string | null
uploadedById: string | null
} | null
variants: any[]
}
Updates an existing image
{
width?: number | null
height?: number | null
sortOrder?: number
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
fileId: string
talentId: string
variant: "Original" | "Thumbnail" | "Large"
imageBrand: "LuxWatermark" | "Clean" | null
status: "Processing" | "Completed" | "Failed"
errorMessage: string | null
width: number | null
height: number | null
sortOrder: number
sourceImageId: string | null
file: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
mimeType: string
size: number
blobKey: string
container: string
url: string | null
uploadedById: string | null
} | null
variants: any[]
}
Batch-update sort order for a set of images
{
orderedIds: string[]
}
any[]
Returns a short-lived SAS URL for downloading the original blob
{
id: string
}
{
url: string
}
Re-derives a talent's photos for every brand their companies display (e.g. the clean set after adding a LUX model to VIP Kitty). Idempotent β only missing brand variants are rendered.
{
talentId: string
}
{
rendered: number
skipped: number
failed: number
}
Deletes an image and its variants from DB and blob storage
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
fileId: string
talentId: string
variant: "Original" | "Thumbnail" | "Large"
imageBrand: "LuxWatermark" | "Clean" | null
status: "Processing" | "Completed" | "Failed"
errorMessage: string | null
width: number | null
height: number | null
sortOrder: number
sourceImageId: string | null
file: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
mimeType: string
size: number
blobKey: string
container: string
url: string | null
uploadedById: string | null
} | null
variants: any[]
}
Location
Returns the requesting company's locations
Array<{
id: string
createdAt: string | any
updatedAt: string | any
city: string | any
name: string
category: "Hotel" | "Airbnb" | "Condo"
unitNumber: string | null
street: string | null
province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
postalCode: string | null
phoneNumberId: string | null
phoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
}>
Returns a location by ID; 404 unless it belongs to the requesting company
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
city: string | any
name: string
category: "Hotel" | "Airbnb" | "Condo"
unitNumber: string | null
street: string | null
province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
postalCode: string | null
phoneNumberId: string | null
phoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
}
Returns the requesting company's locations by city name
{
city: string
}
Array<{
id: string
createdAt: string | any
updatedAt: string | any
city: string | any
name: string
category: "Hotel" | "Airbnb" | "Condo"
unitNumber: string | null
street: string | null
province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
postalCode: string | null
phoneNumberId: string | null
phoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
}>
Creates a location owned by the requesting company
{
city: string
name: string
category: "Hotel" | "Airbnb" | "Condo"
unitNumber?: string | null
street?: string | null
province?: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
postalCode?: string | "" | null
phoneNumberId?: string | null
}
{
id: string
createdAt: string | any
updatedAt: string | any
city: string | any
name: string
category: "Hotel" | "Airbnb" | "Condo"
unitNumber: string | null
street: string | null
province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
postalCode: string | null
phoneNumberId: string | null
phoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
}
Batch-update the display order of locations within a city for the requesting company
{
orderedIds: string[]
}
Array<{
id: string
createdAt: string | any
updatedAt: string | any
city: string | any
name: string
category: "Hotel" | "Airbnb" | "Condo"
unitNumber: string | null
street: string | null
province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
postalCode: string | null
phoneNumberId: string | null
phoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
}>
Updates a location owned by the requesting company
{
city?: string
name?: string
category?: "Hotel" | "Airbnb" | "Condo"
unitNumber?: string | null
street?: string | null
province?: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
postalCode?: string | "" | null
phoneNumberId?: string | null
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
city: string | any
name: string
category: "Hotel" | "Airbnb" | "Condo"
unitNumber: string | null
street: string | null
province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
postalCode: string | null
phoneNumberId: string | null
phoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
}
Deletes a location owned by the requesting company
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
city: string | any
name: string
category: "Hotel" | "Airbnb" | "Condo"
unitNumber: string | null
street: string | null
province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
postalCode: string | null
phoneNumberId: string | null
phoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
}
LocationFixedCost
A location's operating costs for a month (YYYY-MM), or null when none are set
{
locationId: string
period: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
locationId: string
period: string
rent: number
utilities: number
internet: number
insurance: number
cleaning: number
supplies: number
misc: number
} | null
The most recent month with costs other than the given one β the source for "copy latest month"; null when no other month has costs
{
locationId: string
period: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
locationId: string
period: string
rent: number
utilities: number
internet: number
insurance: number
cleaning: number
supplies: number
misc: number
} | null
Upserts a month's operating costs; 404 unless the location belongs to the requesting company
{
locationId: string
period: string
rent: number
utilities: number
internet: number
insurance: number
cleaning: number
supplies: number
misc: number
}
{
id: string
createdAt: string | any
updatedAt: string | any
locationId: string
period: string
rent: number
utilities: number
internet: number
insurance: number
cleaning: number
supplies: number
misc: number
}
LocationNote
Returns the requesting company's location notes whose date falls in the window, scoped via location ownership.
{
startDate: any
endDate: any
}
Array<{
id: string
locationId: string
date: string | any
text: string
}>
Creates a note pinned to one of the requesting company's locations on a specific day.
{
locationId: string
date: any
text: string
}
{
id: string
locationId: string
date: string | any
text: string
}
Updates a note on one of the requesting company's locations.
{
text?: string
id: string
}
{
id: string
locationId: string
date: string | any
text: string
}
Deletes a note on one of the requesting company's locations.
{
id: string
}
{
id: string
locationId: string
date: string | any
text: string
}
LocationPnl
Per-location profit for a month: revenue (Ξ£ Due, incl. book-on) β fixed costs β allocated expenses β booker pay
{
period: string
}
Array<{
locationId: string
locationName: string
city: string
revenue: number
fixedCosts: number
allocatedExpenses: number
bookerPay: number
profit: number
}>
Payment
An appointment's recorded payment lines (the Payments card) β one or many per appointment, e.g. an e-transfer + cash split
{
appointmentId: string
}
Array<{
id: string
appointmentId: string
method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit"
amount: number
isDeposit: boolean
}>
Records a payment line against an appointment. Only the first line may be a deposit; the client comes from the appointment, never sent
{
appointmentId: string
method: "EMT" | "AmazonGiftCard" | "Cash"
amount: number
isDeposit: boolean
}
{
id: string
appointmentId: string
method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit"
amount: number
isDeposit: boolean
}
Removes a payment line
{
id: string
}
PhoneNumber
Returns all phone numbers
Array<{
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
}>
Returns a phone number by ID
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
}
Creates a new phone number
{
name?: string | null
number: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
}
Updates an existing phone number
{
name?: string | null
number?: string
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
}
Deletes a phone number
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
}
Review
Returns all reviews for a talent, newest first
{
talentId: string
}
Array<{
id: string
createdAt: string | any
updatedAt: string | any
talentId: string
content: string
createdByName: string | null
}>
Creates a new talent review
{
talentId: string
content: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
talentId: string
content: string
createdByName: string | null
}
Updates a review
{
content: string
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
talentId: string
content: string
createdByName: string | null
}
Deletes a review
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
talentId: string
content: string
createdByName: string | null
}
Schedule
Returns the requesting company's schedules for today with talent data
{
today: any
}
Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
talentId: string
talent: {
id: string
nickname: string
thumbnailUrl: string | null
}
}>
Returns pre-grouped visiting-soon entries (next 60 days)
{
today: any
}
Array<{
talentId: string
nickname: string
city: string
dateLabel: string
thumbnailUrl: string | null
}>
Returns the requesting company's schedules in a date range with talent and location data
{
startDate: any
endDate: any
}
Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
talentId: string
talent: {
id: string
nickname: string
thumbnailUrl: string | null
}
}>
Returns a week of the requesting company's schedules pre-grouped by city β location β date. Drops soft-deleted-location rows.
{
startDate: any
endDate: any
}
Array<{
city: string
locations: Array<{
locationId: string
locationName: string
deleted: boolean
days: Array<{
date: string | any
entries: Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
talentId: string
talent: {
id: string
nickname: string
thumbnailUrl: string | null
}
}>
}>
}>
}>
Returns all schedules for a talent
{
talentId: string
}
Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
notes: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
}>
Returns all schedules for a location
{
locationId: string
}
Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
notes: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
}>
Returns the admin schedule grid for a week in one call: cities β locations β date-bucketed entries. Includes every live location (empty ones carry days: []) plus soft-deleted locations that have rows in the window (flagged deleted). Replaces the old weekLocationsAdmin bucket list + per-location locationWeekAdmin fan-out β one server fetch, one client query.
{
startDate: any
endDate: any
}
Array<{
city: string
cityId: string
locations: Array<{
locationId: string
locationName: string
deleted: boolean
days: Array<{
date: string | any
entries: Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
notes: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
talentId: string
talent: {
id: string
nickname: string
thumbnailUrl: string | null
}
}>
}>
}>
}>
Returns the selected company's schedules in a date range (admin; location-ownership, no roster gate)
{
startDate: any
endDate: any
}
Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
notes: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
talentId: string
talent: {
id: string
nickname: string
thumbnailUrl: string | null
}
}>
Creates a new schedule
{
locationId: string
date: any
startTime?: string | null
endTime?: string | null
notes?: string | null
talentId: string
}
{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
notes: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
}
Get-or-create a schedule by its natural key (talent + location + date). Idempotent β returns the row and whether it was newly created. The historical import (LUX-120) uses this as its per-day anchor.
{
locationId: string
date: any
startTime?: string | null
endTime?: string | null
notes?: string | null
talentId: string
}
{
created: boolean
schedule: {
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
notes: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
}
}
Updates an existing schedule
{
locationId?: string
date?: any
startTime?: string | null
endTime?: string | null
notes?: string | null
id: string
}
{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
notes: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
}
Deletes a schedule
{
id: string
}
{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
notes: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
}
Service
Returns all services with talent counts
Array<{
id: string
name: string
createdAt: string | any
talentCount: number
}>
Returns a service by ID
{
id: string
}
{
id: string
name: string
createdAt: string | any
}
Creates a new service
{
name: string
}
{
id: string
name: string
createdAt: string | any
}
Updates a service
{
name?: string
id: string
}
{
id: string
name: string
createdAt: string | any
}
Deletes a service
{
id: string
}
{
id: string
name: string
createdAt: string | any
}
Tag
Returns all tags
Array<{
id: string
createdAt: string | any
updatedAt: string | any
name: string
}>
Returns a tag by ID
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
Creates a new tag
{
name: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
Updates a tag
{
name?: string
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
Deletes a tag
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
Talent
Returns the requesting companyβs talents for the public roster, including service names for the filter UI
Array<{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
age: number | null
height: string | null
weight: string | null
measurements: string | null
nationality: string | null
hair: string | null
eyes: string | null
tattoos: boolean | null
enhanced: boolean | null
cupSize: string | null
duos: boolean | null
tagline: string | null
bio: string | null
badge: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId: string | null
phoneNumberExpiresAt: string | any | null
defaultPhoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
tags: Array<{
tag: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
}>
images: any[]
menuServices: Array<{
service: {
name: string
}
}>
}>
Returns the requesting companyβs talents with images, sorted with today's available first
{
today: any
}
Array<{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
age: number | null
height: string | null
weight: string | null
measurements: string | null
nationality: string | null
hair: string | null
eyes: string | null
tattoos: boolean | null
enhanced: boolean | null
cupSize: string | null
duos: boolean | null
tagline: string | null
bio: string | null
badge: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId: string | null
phoneNumberExpiresAt: string | any | null
defaultPhoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
tags: Array<{
tag: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
}>
images: any[]
}>
Returns the requesting companyβs talents (with images) scheduled for today, including the city they are in today
{
today: any
}
Array<{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
age: number | null
height: string | null
weight: string | null
measurements: string | null
nationality: string | null
hair: string | null
eyes: string | null
tattoos: boolean | null
enhanced: boolean | null
cupSize: string | null
duos: boolean | null
tagline: string | null
bio: string | null
badge: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId: string | null
phoneNumberExpiresAt: string | any | null
defaultPhoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
tags: Array<{
tag: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
}>
images: any[]
city: string
startTime: string | null
endTime: string | null
}>
Returns a talent by ID with relations; 404 unless the talent belongs to the requesting company
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
age: number | null
height: string | null
weight: string | null
measurements: string | null
nationality: string | null
hair: string | null
eyes: string | null
tattoos: boolean | null
enhanced: boolean | null
cupSize: string | null
duos: boolean | null
tagline: string | null
bio: string | null
badge: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId: string | null
phoneNumberExpiresAt: string | any | null
defaultPhoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
tags: Array<{
tag: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
}>
menus: Array<{
id: string
createdAt: string | any
updatedAt: string | any
type: "Regular" | "Vip"
durationMinutes: number
price: number
}>
menuServices: Array<{
id: string
serviceId: string
excludedFromPromo: boolean
includedInVip: boolean
price: number | null
service: {
id: string
name: string
createdAt: string | any
}
}>
schedules: Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
}>
images: any[]
}
Returns a talent by nickname with relations; 404 unless the talent belongs to the requesting company
{
nickname: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
age: number | null
height: string | null
weight: string | null
measurements: string | null
nationality: string | null
hair: string | null
eyes: string | null
tattoos: boolean | null
enhanced: boolean | null
cupSize: string | null
duos: boolean | null
tagline: string | null
bio: string | null
badge: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId: string | null
phoneNumberExpiresAt: string | any | null
defaultPhoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
tags: Array<{
tag: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
}>
menus: Array<{
id: string
createdAt: string | any
updatedAt: string | any
type: "Regular" | "Vip"
durationMinutes: number
price: number
}>
menuServices: Array<{
id: string
serviceId: string
excludedFromPromo: boolean
includedInVip: boolean
price: number | null
service: {
id: string
name: string
createdAt: string | any
}
}>
schedules: Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
}>
images: any[]
}
Returns lightweight talent list (all companies) with a `member` flag for the requesting company
Array<{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
badge: "Visiting" | "Star" | "Vip" | "New" | null
tagline: string | null
member: boolean
}>
Returns a talent by nickname across all companies, with a `member` flag for the requesting company
{
nickname: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
age: number | null
height: string | null
weight: string | null
measurements: string | null
nationality: string | null
hair: string | null
eyes: string | null
tattoos: boolean | null
enhanced: boolean | null
cupSize: string | null
duos: boolean | null
tagline: string | null
bio: string | null
badge: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId: string | null
phoneNumberExpiresAt: string | any | null
defaultPhoneNumber?: {
id: string
createdAt: string | any
updatedAt: string | any
name: string | null
number: string
} | null
tags: Array<{
tag: {
id: string
createdAt: string | any
updatedAt: string | any
name: string
}
}>
menus: Array<{
id: string
createdAt: string | any
updatedAt: string | any
type: "Regular" | "Vip"
durationMinutes: number
price: number
}>
menuServices: Array<{
id: string
serviceId: string
excludedFromPromo: boolean
includedInVip: boolean
price: number | null
service: {
id: string
name: string
createdAt: string | any
}
}>
schedules: Array<{
id: string
locationId: string
date: string | any
startTime: string | null
endTime: string | null
notes: string | null
location: {
id: string
city: string | any
name: string
phoneNumberId: string | null
phoneNumber?: {
id: string
name: string | null
number: string
} | null
deletedAt: string | any | null
}
}>
images: any[]
member: boolean
}
Admin-only forum-ad notes for a talent
{
id: string
}
{
notes: string | null
}
Returns the companies a talent belongs to
{
talentId: string
}
Array<{
companyId: string
companySlug: string
companyName: string
}>
Adds a talent to or removes a talent from a company; returns the updated membership list
{
talentId: string
companyId: string
member: boolean
}
Array<{
companyId: string
companySlug: string
companyName: string
}>
Returns the ids of clients on a talent's Don't-See list
{
talentId: string
}
string[]
Replaces a talent's Don't-See list β the clients this talent won't see
{
talentId: string
clientIds: string[]
}
string[]
Creates a new talent
{
nickname: string
age?: number | null
height?: string | null
weight?: string | null
measurements?: string | null
nationality?: string | null
hair?: string | null
eyes?: string | null
tattoos?: boolean | null
enhanced?: boolean | null
cupSize?: string | null
duos?: boolean | null
tagline?: string | null
bio?: string | null
badge?: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId?: string | null
phoneNumberExpiresAt?: any | null
notes?: string | null
tags?: string[]
menus?: Array<{
type: "Regular" | "Vip"
durationMinutes: number
price: number
}>
menuServices?: Array<{
serviceId: string
price?: number | null
}>
images?: Array<{
fileId: string
variant?: "Original" | "Thumbnail" | "Large"
imageBrand?: "LuxWatermark" | "Clean" | null
width?: number | null
height?: number | null
sortOrder?: number
}>
}
{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
age: number | null
height: string | null
weight: string | null
measurements: string | null
nationality: string | null
hair: string | null
eyes: string | null
tattoos: boolean | null
enhanced: boolean | null
cupSize: string | null
duos: boolean | null
tagline: string | null
bio: string | null
badge: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId: string | null
phoneNumberExpiresAt: string | any | null
}
Updates an existing talent
{
nickname?: string
age?: number | null
height?: string | null
weight?: string | null
measurements?: string | null
nationality?: string | null
hair?: string | null
eyes?: string | null
tattoos?: boolean | null
enhanced?: boolean | null
cupSize?: string | null
duos?: boolean | null
tagline?: string | null
bio?: string | null
badge?: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId?: string | null
phoneNumberExpiresAt?: any | null
notes?: string | null
tags?: string[]
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
age: number | null
height: string | null
weight: string | null
measurements: string | null
nationality: string | null
hair: string | null
eyes: string | null
tattoos: boolean | null
enhanced: boolean | null
cupSize: string | null
duos: boolean | null
tagline: string | null
bio: string | null
badge: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId: string | null
phoneNumberExpiresAt: string | any | null
}
Deletes a talent
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
nickname: string
age: number | null
height: string | null
weight: string | null
measurements: string | null
nationality: string | null
hair: string | null
eyes: string | null
tattoos: boolean | null
enhanced: boolean | null
cupSize: string | null
duos: boolean | null
tagline: string | null
bio: string | null
badge: "Visiting" | "Star" | "Vip" | "New" | null
defaultPhoneNumberId: string | null
phoneNumberExpiresAt: string | any | null
}
User
Returns the authenticated user profile
{
id: string
createdAt: string | any
updatedAt: string | any
email: string
name: string | null
role: string | null
}
Creates a new user via the auth admin API
{
email: string
name: string
password: string
role: "user" | "admin" | "booker"
}
{
id: string
createdAt: string | any
updatedAt: string | any
email: string
name: string | null
role: string | null
}
Returns a user by their ID
{
id: string
}
{
id: string
createdAt: string | any
updatedAt: string | any
email: string
name: string | null
role: string | null
}
Updates an existing user
{
id: string
data: {
email?: string
name?: string
role?: "user" | "admin" | "booker"
}
}
{
id: string
createdAt: string | any
updatedAt: string | any
email: string
name: string | null
role: string | null
}
Sets a new password for a user via the auth admin API
{
userId: string
newPassword: string
}
Returns all users
Array<{
id: string
createdAt: string | any
updatedAt: string | any
email: string
name: string | null
role: string | null
}>
WeeklyReport
Collected cash (by rail, per city), booker pay, and expenses (by category) rolled up over a week β the MonβSun bounds are sent by the client
{
startDate: any
endDate: any
}
{
weekStart: string | any
weekEnd: string | any
moneyIn: {
cash: number
emt: number
giftCard: number
credit: number
total: number
}
bookerPay: number
cancellationAgency: number
expensesByCategory: Record<string, number>
totalExpenses: number
generalExpenses: number
totalOut: number
net: number
cities: Array<{
city: string
moneyIn: {
cash: number
emt: number
giftCard: number
credit: number
total: number
}
bookerPay: number
cancellationAgency: number
expenses: number
}>
}