AI Monorepo API

tRPC API Documentation

228
Total Endpoints
228
Public Endpoints
116 Queries • 110 Mutations
0
Protected Endpoints
0 Queries • 0 Mutations
Showing 228 of 228 endpoints

Analytics

query
Scheduled Today analytics.scheduledToday
Analytics

Distinct talent, locations, and entry count for today's schedule.

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
{
  talentCount: number  // Unique talents working today
  locationCount: number  // Unique locations active today
  scheduleCount: number  // Total schedule entries today
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/analytics.scheduledToday?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Talent Count analytics.talentCount
Analytics

Roster size split into on-site (active) vs off-roster (hidden) talent.

Output Schema
TypeScript
{
  total: number  // Total talents in the system
  active: number  // Talents on this company's public site (members)
  hidden: number  // Talents not on this company's site (off-roster)
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/analytics.talentCount' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Weekly Breakdown analytics.weeklyBreakdown
Analytics

Schedule count per day for the current week (Mon–Sun).

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  date: string  // ISO date string
  value: number  // Numeric value
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/analytics.weeklyBreakdown?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Weekly Talent Count analytics.weeklyTalentCount
Analytics

Distinct talent scheduled at least one day this week (Mon–Sun).

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
number
Code Examples
Shell
curl -X GET '{{BASE_URL}}/analytics.weeklyTalentCount?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Week by City analytics.weekByCity
Analytics

Distinct talent and expected calls per city for the current week.

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  city: string  // City name
  talents: number  // Distinct talent scheduled in this city this week
  expectedCalls: number  // Calls this week's scheduled days are expected to take here
  days: Array<{
    date: string  // ISO date string
    expectedCalls: number  // Calls this day is expected to take here
  }>  // The seven days Mon–Sun, zero-filled where nothing is on
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/analytics.weekByCity?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Year to Date Calls analytics.yearToDateCalls
Analytics

Calls per day since January 1 — what we took, what the roster's averages predict, and what we took on the same date a year earlier.

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  date: string  // ISO date string
  actual: number  // Calls taken on this date
  expected: number  // Calls the scheduled roster's other days predict for this date
  lastYear: number  // Calls taken on the same calendar date a year earlier
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/analytics.yearToDateCalls?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Incomplete Profiles analytics.incompleteProfiles
Analytics

Count of roster talent missing each profile field.

Output Schema
TypeScript
Array<{
  name: "Photos" | "Bio" | "Tagline" | "Age" | "Height" | "Weight" | "Measurements" | "Fees" | "Menus" | "Services" | "Notes" | "Reviews"  // Profile field the completeness audit checks
  talents: string[]  // Nicknames of the talent missing this field, A–Z
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/analytics.incompleteProfiles' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Talent Stats analytics.talentStats
Analytics

Each talent's all-time booking rhythm: calls per day worked, the same split by weekday, and the hours her calls start.

Output Schema
TypeScript
Array<{
  talentId: string  // UUID identifier
  nickname: string  // Talent display name
  totalCalls: number  // Bookings taken across every day worked
  daysWorked: number  // Distinct calendar days worked — two locations in a day is one
  avgPerDay: number  // Calls per day worked, 0 when she has none
  busiestWeekday: number | null  // Weekday with her highest average, null when she has no days
  busiestHour: number | null  // Hour with her most bookings, null when none carry a time
  byWeekday: Array<{
    weekday: number  // Day of week, 0 = Sunday
    calls: number  // Bookings taken on this weekday
    daysWorked: number  // Distinct days worked on this weekday
    avgPerDay: number  // Calls per day worked, 0 when she never works this weekday
  }>  // All seven weekdays, zero-filled
  byHour: Array<{
    hour: number  // Hour of day, 0–23
    calls: number  // Bookings starting within this hour
  }>  // All 24 hours, zero-filled
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/analytics.talentStats' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Booker Stats analytics.bookerStats
Analytics

Each booker's weekly reach across the roster for the last 52 weeks: calls booked over the distinct talent they were spread over, which reads her effort rather than the draw of whoever she booked.

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  bookerId: string  // Unique identifier
  name: string  // Booker display name
  bookings: number  // Calls booked across the whole window
  talents: number  // Distinct talent booked across the whole window
  avgPerTalent: number  // The window's own bookings / talents — not a mean of the weeks
  weeks: Array<{
    weekStart: string  // ISO date of the week's Monday
    bookings: number  // Calls she booked in this week
    talents: number  // Distinct talent those calls were spread over this week
    avgPerTalent: number  // bookings / talents, 0 when she booked nobody that week
  }>  // Every week in the window, zero-filled, oldest first
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/analytics.bookerStats?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Announcement

mutation
Send Announcement announcement.create
Announcement

Broadcasts an office announcement to every talent login as an in-app notification.

Input Schema
TypeScript
{
  title: string  // Headline in the feed
  body: string  // Full message, shown only inside the app
}
Output Schema
TypeScript
{
  recipients: number
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/announcement.create' \
  -H 'Content-Type: application/json' \
  -d '{"title":"string","body":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List Sent Announcements announcement.list
Announcement

Past office announcements, newest first, with recipient counts.

Output Schema
TypeScript
Array<{
  entityId: string  // UUID identifier
  title: string
  body: string | null
  sentAt: string | any  // When the blast went out
  recipients: number
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/announcement.list' \
  -H 'Content-Type: application/json'
Test Endpoint

Appointment

query
Appointments by Schedule appointment.bySchedule
Appointment

A schedule with its appointments and the derived day totals — the daily tracker detail summary (Due / Paid / Balance + the Credit/Paid/Miss state)

Input Schema
TypeScript
{
  scheduleId: string  // UUID identifier
}
Output Schema
TypeScript
{
  schedule: {
    id: string  // Unique identifier
    talentId: string  // Unique identifier
    talentName: string
    locationId: string  // Unique identifier
    locationName: string
    locationDeleted: boolean  // True when the venue has been retired — the day still opens, deleting a location never moves the books
    city: string
    date: string | any  // Date in YYYY-MM-DD format
    category: "Hotel" | "Airbnb" | "Condo"  // Venue type — the book-on gate (D64/D65)
    talentBookOnFee: number | null  // Talent's profile rate — the condo default; not used at airbnb/hotels
    condoChargedToday: boolean  // True when an earlier condo row on this calendar date resolved to a POSITIVE book-on — her profile rate or an operator's own figure; it does not say the profile rate was charged, and a negative reimbursement credit (D92/D99) does not count. A condo row then defaults to $0 (D112); an airbnb/hotel row is unaffected, its half being per-stay, on the stay's first day (LUX-316). The day form previews the same default the tracker applies
    flatFee: number | null  // Airbnb/hotel per-date room cost from the stored DailyReport, or null
    bookOn: number | null  // Resolved book-on — the stored snapshot, else the computed default; negative when it credits the talent for accommodation she paid herself (D92/D99)
    stayExpenseId: string | null  // The Accommodation expense this day's room figures were written from (LUX-316); null when typed by hand or never entered
    notes?: string | null
    envelopeDroppedAt: string | any | null  // When the talent declared her day closed out — envelope handed in (LUX-274); read-only, moves no money
  }
  appointments: Array<{
    id: string  // Unique identifier
    scheduleId: string  // Unique identifier
    startTime: string | null  // HH:MM, or null when unset
    clientId: string  // Unique identifier
    clientName: string  // Client's name, or their code when they have none (denormalized)
    menuId: string | null  // null on an imported historical row
    menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
    fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
    discount: number  // Reduces what is owed; defaults to 0
    bookedByUserId: string | null  // null when an imported row had no resolvable booker
    bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
    bookerPay: number  // Stored booker pay; rate/basis is a later phase (LUX-79)
    paidToUserId: string | null  // Who the booking fee goes to — the booker on shift on the appointment's day. Null while a prebook's day has no coverage written yet (wrap-up/cancellation settle it, falling back to whoever booked), or on an imported row without one
    payeeName: string | null  // Payee display name (denormalized); null when unresolved
    confirmed: boolean  // The end client has confirmed this booking
    services: Array<{
      id: string  // Unique identifier
      appointmentId: string  // Unique identifier
      menuServiceId: string  // Unique identifier
      serviceName: string  // Service name (denormalized from the catalog)
      fee: number  // Stored per-line fee — $0 since D105 (extras are the talent's own money, never house Due); non-zero only on rows captured before D105
    }>
    notes?: string | null  // Free-form appointment notes (distinct from the client notes)
    cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
    isCarrier: boolean  // A synthesized carrier booking (LUX-206) — exists only so a money-only day's payments have an appointment to hang on; not a call, every call count skips it
    isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
    wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
    wrapUpNoShow: boolean  // She reported the client never showed for this booking
    wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
    wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
    wrapUpExtras: Array<{
      menuServiceId: string  // Unique identifier
      name: string  // Service name as it read at report time
      price: number  // Catalog price at report time
    }>  // Add-ons she reported selling, priced as at report time
    wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
    paid: number  // Σ payment.amount against this appointment
  }>  // Appointments for a schedule, each with its own collected total
  due: number  // Σ(fee − discount) + service fees + book-on
  paid: number  // Σ payment.amount — what was collected
  balance: number  // Paid + applied carried credit − Due (signed, D110)
  status: "credit" | "paid" | "miss"
  cancellationIncome: number  // Σ talent ½ of kept cancellation fees behind this day's bookings (D95) — income, separate from Due/Paid
  carriedCredit: {
    amount: number
    from: string | any[]
  }
  creditPaidOut: number  // Σ carried-credit payouts dated this day for this talent (LUX-341/D113) — its own line, outside Due/Paid/balance
  creditRemaining: number  // The credit leaving this row after the day's payouts — max(0, balance − creditPaidOut); what a Pay out can still hand back (LUX-341)
  creditFate: {
    spent: Array<{
      date: string | any  // Date in YYYY-MM-DD format
      amount: number
      kind: "applied" | "paidOut"
    }>
    carrying: number
  }
  settledBy: {
    client: number
    envelope: number
    credit: number
    hotelShare: number
  }
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/appointment.bySchedule?input=%7B%22scheduleId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Appointments by Date appointment.byDate
Appointment

A day's live appointments across every schedule — the booking grid's one read (LUX-246); cancelled and carrier rows never appear

Input Schema
TypeScript
{
  date: any  // The grid day
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  scheduleId: string  // Unique identifier
  startTime: string | null  // HH:MM, or null when unset
  clientId: string  // Unique identifier
  clientName: string  // Client's name, or their code when they have none (denormalized)
  menuId: string | null  // null on an imported historical row
  menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
  fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
  discount: number  // Reduces what is owed; defaults to 0
  bookedByUserId: string | null  // null when an imported row had no resolvable booker
  bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
  bookerPay: number  // Stored booker pay; rate/basis is a later phase (LUX-79)
  paidToUserId: string | null  // Who the booking fee goes to — the booker on shift on the appointment's day. Null while a prebook's day has no coverage written yet (wrap-up/cancellation settle it, falling back to whoever booked), or on an imported row without one
  payeeName: string | null  // Payee display name (denormalized); null when unresolved
  confirmed: boolean  // The end client has confirmed this booking
  services: Array<{
    id: string  // Unique identifier
    appointmentId: string  // Unique identifier
    menuServiceId: string  // Unique identifier
    serviceName: string  // Service name (denormalized from the catalog)
    fee: number  // Stored per-line fee — $0 since D105 (extras are the talent's own money, never house Due); non-zero only on rows captured before D105
  }>
  notes?: string | null  // Free-form appointment notes (distinct from the client notes)
  cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
  isCarrier: boolean  // A synthesized carrier booking (LUX-206) — exists only so a money-only day's payments have an appointment to hang on; not a call, every call count skips it
  isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
  wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
  wrapUpNoShow: boolean  // She reported the client never showed for this booking
  wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
  wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
  wrapUpExtras: Array<{
    menuServiceId: string  // Unique identifier
    name: string  // Service name as it read at report time
    price: number  // Catalog price at report time
  }>  // Add-ons she reported selling, priced as at report time
  wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
  paid: number  // Σ payment.amount against this appointment
  durationMinutes: number | null  // The menu's duration; null on an imported row without a menu
  menuType: string | null  // Menu type (Vip/Regular); null when imported
  menuPrice: number | null  // Menu catalog price; null when imported
  price: number  // What the client pays — menu price + extras under the VIP-inclusion rule, computed at read from today's catalog (no price is captured at write, D105)
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/appointment.byDate?input=%7B%22date%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Appointment by Id appointment.byId
Appointment

One appointment for the edit form

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  scheduleId: string  // Unique identifier
  startTime: string | null  // HH:MM, or null when unset
  clientId: string  // Unique identifier
  clientName: string  // Client's name, or their code when they have none (denormalized)
  menuId: string | null  // null on an imported historical row
  menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
  fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
  discount: number  // Reduces what is owed; defaults to 0
  bookedByUserId: string | null  // null when an imported row had no resolvable booker
  bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
  bookerPay: number  // Stored booker pay; rate/basis is a later phase (LUX-79)
  paidToUserId: string | null  // Who the booking fee goes to — the booker on shift on the appointment's day. Null while a prebook's day has no coverage written yet (wrap-up/cancellation settle it, falling back to whoever booked), or on an imported row without one
  payeeName: string | null  // Payee display name (denormalized); null when unresolved
  confirmed: boolean  // The end client has confirmed this booking
  services: Array<{
    id: string  // Unique identifier
    appointmentId: string  // Unique identifier
    menuServiceId: string  // Unique identifier
    serviceName: string  // Service name (denormalized from the catalog)
    fee: number  // Stored per-line fee — $0 since D105 (extras are the talent's own money, never house Due); non-zero only on rows captured before D105
  }>
  notes?: string | null  // Free-form appointment notes (distinct from the client notes)
  cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
  isCarrier: boolean  // A synthesized carrier booking (LUX-206) — exists only so a money-only day's payments have an appointment to hang on; not a call, every call count skips it
  isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
  wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
  wrapUpNoShow: boolean  // She reported the client never showed for this booking
  wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
  wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
  wrapUpExtras: Array<{
    menuServiceId: string  // Unique identifier
    name: string  // Service name as it read at report time
    price: number  // Catalog price at report time
  }>  // Add-ons she reported selling, priced as at report time
  wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/appointment.byId?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Appointments by Client appointment.byClient
Appointment

A client's appointments in this brand (newest first) — the picker for applying a credit to a booking (LUX-113)

Input Schema
TypeScript
{
  clientId: string  // UUID identifier
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  date: string | any  // Date in YYYY-MM-DD format
  startTime: string | null  // HH:MM, or null when unset
  talentName: string
  locationName: string
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/appointment.byClient?input=%7B%22clientId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Appointment appointment.create
Appointment

Books an appointment; fee and per-line service fees are captured from the menu catalog, never from the client

Input Schema
TypeScript
{
  scheduleId: string  // UUID identifier
  clientId: string  // UUID identifier
  menuId: string  // UUID identifier
  bookedByUserId?: string  // Unique identifier
  phoneNumberId?: string | null
  paidToUserId?: string | null
  startTime?: string | null
  discount: number
  confirmed: boolean
  isIndy: boolean
  notes?: string | null
  services: Array<{
    menuServiceId: string  // UUID identifier
  }>
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  scheduleId: string  // Unique identifier
  startTime: string | null  // HH:MM, or null when unset
  clientId: string  // Unique identifier
  clientName: string  // Client's name, or their code when they have none (denormalized)
  menuId: string | null  // null on an imported historical row
  menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
  fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
  discount: number  // Reduces what is owed; defaults to 0
  bookedByUserId: string | null  // null when an imported row had no resolvable booker
  bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
  bookerPay: number  // Stored booker pay; rate/basis is a later phase (LUX-79)
  paidToUserId: string | null  // Who the booking fee goes to — the booker on shift on the appointment's day. Null while a prebook's day has no coverage written yet (wrap-up/cancellation settle it, falling back to whoever booked), or on an imported row without one
  payeeName: string | null  // Payee display name (denormalized); null when unresolved
  confirmed: boolean  // The end client has confirmed this booking
  services: Array<{
    id: string  // Unique identifier
    appointmentId: string  // Unique identifier
    menuServiceId: string  // Unique identifier
    serviceName: string  // Service name (denormalized from the catalog)
    fee: number  // Stored per-line fee — $0 since D105 (extras are the talent's own money, never house Due); non-zero only on rows captured before D105
  }>
  notes?: string | null  // Free-form appointment notes (distinct from the client notes)
  cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
  isCarrier: boolean  // A synthesized carrier booking (LUX-206) — exists only so a money-only day's payments have an appointment to hang on; not a call, every call count skips it
  isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
  wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
  wrapUpNoShow: boolean  // She reported the client never showed for this booking
  wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
  wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
  wrapUpExtras: Array<{
    menuServiceId: string  // Unique identifier
    name: string  // Service name as it read at report time
    price: number  // Catalog price at report time
  }>  // Add-ons she reported selling, priced as at report time
  wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/appointment.create' \
  -H 'Content-Type: application/json' \
  -d '{"scheduleId":"string","clientId":"string","menuId":"string","discount":0,"confirmed":true,"isIndy":true,"services":[{"menuServiceId":"string"}]}'
Test Endpoint
Optional fields (click to add):
bookedByUserId phoneNumberId paidToUserId startTime notes
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Import a Day of Appointments appointment.importDay
Appointment

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

Input Schema
TypeScript
{
  scheduleId: string  // UUID identifier
  clientId: string  // The Unknown placeholder client (D39)
  bookedByUserId?: string | null  // Resolved col-G booker, else null — the day owns the remainder
  callCount: number  // Col C — how many calls the day took; one appointment per call
  serviceTotal: number  // Col K — the day's fee total, split across the calls server-side
  payments: Array<{
    method: "EMT" | "AmazonGiftCard" | "Cash" | "TalentCredit" | "HotelShare"
    amount: number
  }>  // The day's EMT/Amazon/Cash totals (D74), plus any talent credit settling it — ride the first call, since the sheet says only what the DAY took
  bookOn: number  // Col J — the day's book-on, upserted onto its DailyReport inside the same transaction so an import can never write the calls without the book-on (D92)
  bookerSplit: Array<{
    bookedByUserId: string  // Unique identifier
    calls: number  // How many of the day's calls this booker took
  }>  // Calls within the day booked by someone other than `bookedByUserId`; the remainder stays with the day's booker
  calls?: Array<{
    fee: number  // This call's own fee, as the source states it
    startTime?: string | null  // 'HH:MM' when the source records one, else null
    notes?: string | null  // The source line as written — duration + service, for an operator to audit against
    isIndy: boolean  // Indy call (LUX-239) — the talent booked it herself, so the booker earns nothing on it
    menuId?: string | null  // The rate this call was booked at. The source names it plainly — 'HH PSE' is the talent's 30-minute Vip row — and the SAME row already supplies `fee`, so withholding the id here only left the booking unnamed in the UI. Server-verified against the schedule's talent; null when the source gives no type
  }>  // The day's calls line by line, when the source has that detail. Omitted (the xlsx) keeps the even split of `serviceTotal` across `callCount`
  cancellations: Array<{
    fee: number  // What the booking would have earned — recorded on the row, excluded from Due
    deposit: number  // The kept deposit, split talent/booker/agency
    startTime?: string | null
    notes?: string | null
    method?: "EMT" | "AmazonGiftCard" | "Cash" | "TalentCredit" | "HotelShare" | null  // How the deposit arrived, when the source says. Left null rather than guessed — a guessed backfill is invented finance
  }>  // The day's cancelled bookings whose deposit was kept — outside `callCount`/`serviceTotal` by design
}
Output Schema
TypeScript
{
  replaced: number  // Synthesized rows deleted before this write
  dayExisted: boolean  // Whether the day's report already existed — true on a re-import even with no rows to replace
  appointments: Array<{
    id: string  // Unique identifier
    scheduleId: string  // Unique identifier
    startTime: string | null  // HH:MM, or null when unset
    clientId: string  // Unique identifier
    clientName: string  // Client's name, or their code when they have none (denormalized)
    menuId: string | null  // null on an imported historical row
    menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
    fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
    discount: number  // Reduces what is owed; defaults to 0
    bookedByUserId: string | null  // null when an imported row had no resolvable booker
    bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
    bookerPay: number  // Stored booker pay; rate/basis is a later phase (LUX-79)
    paidToUserId: string | null  // Who the booking fee goes to — the booker on shift on the appointment's day. Null while a prebook's day has no coverage written yet (wrap-up/cancellation settle it, falling back to whoever booked), or on an imported row without one
    payeeName: string | null  // Payee display name (denormalized); null when unresolved
    confirmed: boolean  // The end client has confirmed this booking
    services: Array<{
      id: string  // Unique identifier
      appointmentId: string  // Unique identifier
      menuServiceId: string  // Unique identifier
      serviceName: string  // Service name (denormalized from the catalog)
      fee: number  // Stored per-line fee — $0 since D105 (extras are the talent's own money, never house Due); non-zero only on rows captured before D105
    }>
    notes?: string | null  // Free-form appointment notes (distinct from the client notes)
    cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
    isCarrier: boolean  // A synthesized carrier booking (LUX-206) — exists only so a money-only day's payments have an appointment to hang on; not a call, every call count skips it
    isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
    wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
    wrapUpNoShow: boolean  // She reported the client never showed for this booking
    wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
    wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
    wrapUpExtras: Array<{
      menuServiceId: string  // Unique identifier
      name: string  // Service name as it read at report time
      price: number  // Catalog price at report time
    }>  // Add-ons she reported selling, priced as at report time
    wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
  }>
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/appointment.importDay' \
  -H 'Content-Type: application/json' \
  -d '{"scheduleId":"string","clientId":"string","callCount":0,"serviceTotal":0,"payments":[{"method":"EMT","amount":0}],"bookOn":0,"bookerSplit":[{"bookedByUserId":"string","calls":0}],"cancellations":[{"fee":0,"deposit":0}]}'
Test Endpoint
Optional fields (click to add):
bookedByUserId calls
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Appointment appointment.update
Appointment

Edits an appointment; re-captures the fee and replaces the service lines

Input Schema
TypeScript
{
  scheduleId: string  // UUID identifier
  clientId: string  // UUID identifier
  menuId: string  // UUID identifier
  bookedByUserId?: string  // Unique identifier
  phoneNumberId?: string | null
  paidToUserId?: string | null
  startTime?: string | null
  discount?: number
  confirmed?: boolean
  isIndy?: boolean
  notes?: string | null
  services?: Array<{
    menuServiceId: string  // UUID identifier
  }>
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  scheduleId: string  // Unique identifier
  startTime: string | null  // HH:MM, or null when unset
  clientId: string  // Unique identifier
  clientName: string  // Client's name, or their code when they have none (denormalized)
  menuId: string | null  // null on an imported historical row
  menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
  fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
  discount: number  // Reduces what is owed; defaults to 0
  bookedByUserId: string | null  // null when an imported row had no resolvable booker
  bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
  bookerPay: number  // Stored booker pay; rate/basis is a later phase (LUX-79)
  paidToUserId: string | null  // Who the booking fee goes to — the booker on shift on the appointment's day. Null while a prebook's day has no coverage written yet (wrap-up/cancellation settle it, falling back to whoever booked), or on an imported row without one
  payeeName: string | null  // Payee display name (denormalized); null when unresolved
  confirmed: boolean  // The end client has confirmed this booking
  services: Array<{
    id: string  // Unique identifier
    appointmentId: string  // Unique identifier
    menuServiceId: string  // Unique identifier
    serviceName: string  // Service name (denormalized from the catalog)
    fee: number  // Stored per-line fee — $0 since D105 (extras are the talent's own money, never house Due); non-zero only on rows captured before D105
  }>
  notes?: string | null  // Free-form appointment notes (distinct from the client notes)
  cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
  isCarrier: boolean  // A synthesized carrier booking (LUX-206) — exists only so a money-only day's payments have an appointment to hang on; not a call, every call count skips it
  isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
  wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
  wrapUpNoShow: boolean  // She reported the client never showed for this booking
  wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
  wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
  wrapUpExtras: Array<{
    menuServiceId: string  // Unique identifier
    name: string  // Service name as it read at report time
    price: number  // Catalog price at report time
  }>  // Add-ons she reported selling, priced as at report time
  wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/appointment.update' \
  -H 'Content-Type: application/json' \
  -d '{"scheduleId":"string","clientId":"string","menuId":"string","id":"string"}'
Test Endpoint
Optional fields (click to add):
bookedByUserId phoneNumberId paidToUserId startTime discount confirmed isIndy notes services
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Cancel Appointment appointment.cancel
Appointment

Client-cancelled: soft-cancels the booking and, in the same transaction, moves any recorded money — kept as a validated-split cancellation fee, held as a client credit, or sent back via a refund request in the office queue (LUX-310)

Input Schema
TypeScript
{
  id: string  // UUID identifier
  outcome: "cancel"
} | {
  id: string  // UUID identifier
  outcome: "fee"
  total: number  // The recorded sum the operator saw
  split: {
    talent: number
    booker: number
    agency: number
  }
} | {
  id: string  // UUID identifier
  outcome: "credit"
  total: number  // The recorded sum the operator saw
} | {
  id: string  // UUID identifier
  outcome: "refund"
  total: number  // The recorded sum the operator saw
  refundAmount: number
  refundEmail: string  // Where the money goes back to — required
  split?: {
    talent: number
    booker: number
    agency: number
  }  // Required when total − refundAmount > 0
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  scheduleId: string  // Unique identifier
  startTime: string | null  // HH:MM, or null when unset
  clientId: string  // Unique identifier
  clientName: string  // Client's name, or their code when they have none (denormalized)
  menuId: string | null  // null on an imported historical row
  menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
  fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
  discount: number  // Reduces what is owed; defaults to 0
  bookedByUserId: string | null  // null when an imported row had no resolvable booker
  bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
  bookerPay: number  // Stored booker pay; rate/basis is a later phase (LUX-79)
  paidToUserId: string | null  // Who the booking fee goes to — the booker on shift on the appointment's day. Null while a prebook's day has no coverage written yet (wrap-up/cancellation settle it, falling back to whoever booked), or on an imported row without one
  payeeName: string | null  // Payee display name (denormalized); null when unresolved
  confirmed: boolean  // The end client has confirmed this booking
  services: Array<{
    id: string  // Unique identifier
    appointmentId: string  // Unique identifier
    menuServiceId: string  // Unique identifier
    serviceName: string  // Service name (denormalized from the catalog)
    fee: number  // Stored per-line fee — $0 since D105 (extras are the talent's own money, never house Due); non-zero only on rows captured before D105
  }>
  notes?: string | null  // Free-form appointment notes (distinct from the client notes)
  cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
  isCarrier: boolean  // A synthesized carrier booking (LUX-206) — exists only so a money-only day's payments have an appointment to hang on; not a call, every call count skips it
  isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
  wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
  wrapUpNoShow: boolean  // She reported the client never showed for this booking
  wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
  wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
  wrapUpExtras: Array<{
    menuServiceId: string  // Unique identifier
    name: string  // Service name as it read at report time
    price: number  // Catalog price at report time
  }>  // Add-ons she reported selling, priced as at report time
  wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/appointment.cancel' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string","outcome":"cancel"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Appointment appointment.delete
Appointment

Removes an appointment

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/appointment.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Daily Tracker List appointment.dailyTrackerList
Appointment

Schedules in a date range with the derived Due, Paid, Balance and the Credit/Paid/Miss state, computed server-side. An admin reads the whole range; a booker reads the same rows clamped to ±1 week of today (LUX-235/LUX-282)

Input Schema
TypeScript
{
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  scheduleId: string  // Unique identifier
  date: string | any  // Date in YYYY-MM-DD format
  talentName: string
  locationName: string
  city: string
  calls: number  // Live appointment count for the day — cancelled (D95) and carrier (LUX-206) bookings excluded
  due: number  // Σ(fee − discount) + Σ service fees + book-on
  paid: number  // Σ payment.amount — what was collected
  balance: number  // Paid + applied carried credit − Due (signed, D110)
  status: "credit" | "paid" | "miss"
  bookOn: number | null
  cancellationIncome: number  // Σ talent ½ of kept cancellation fees behind the day's bookings (D95)
  unlinkedRoomCharge: boolean  // A hotel/Airbnb day carrying a stored room figure with no Accommodation expense behind it (LUX-316) — typed by hand instead of entered once on the expense; never set on history before the link shipped
  creditFate: {
    spent: Array<{
      date: string | any  // Date in YYYY-MM-DD format
      amount: number
      kind: "applied" | "paidOut"
    }>
    carrying: number
  }
  settledBy: {
    client: number
    envelope: number
    credit: number
    hotelShare: number
  }
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/appointment.dailyTrackerList?input=%7B%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Appointments by Date Range appointment.byDateRange
Appointment

One page of appointments across the company's talents, joined to its schedule for display — the browse-by-date list. Every filter (date range, talent, search) is applied server-side; omitting both date bounds is 'All dates'

Input Schema
TypeScript
{
  page: number  // 1-based page number
  pageSize: number  // Rows per page
  startDate?: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate?: any  // YYYY-MM-DD string parsed to UTC midnight Date
  talentId?: string  // Narrow to one talent (the daily-tracker deep link)
  search?: string  // Substring match over talent, client, location and city
}
Output Schema
TypeScript
{
  items: Array<{
    id: string  // Unique identifier
    scheduleId: string  // Unique identifier
    startTime: string | null  // HH:MM, or null when unset
    clientId: string  // Unique identifier
    clientName: string  // Client's name, or their code when they have none (denormalized)
    menuId: string | null  // null on an imported historical row
    menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
    fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
    discount: number  // Reduces what is owed; defaults to 0
    bookedByUserId: string | null  // null when an imported row had no resolvable booker
    bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
    bookerPay: number  // Stored booker pay; rate/basis is a later phase (LUX-79)
    paidToUserId: string | null  // Who the booking fee goes to — the booker on shift on the appointment's day. Null while a prebook's day has no coverage written yet (wrap-up/cancellation settle it, falling back to whoever booked), or on an imported row without one
    payeeName: string | null  // Payee display name (denormalized); null when unresolved
    confirmed: boolean  // The end client has confirmed this booking
    services: Array<{
      id: string  // Unique identifier
      appointmentId: string  // Unique identifier
      menuServiceId: string  // Unique identifier
      serviceName: string  // Service name (denormalized from the catalog)
      fee: number  // Stored per-line fee — $0 since D105 (extras are the talent's own money, never house Due); non-zero only on rows captured before D105
    }>
    notes?: string | null  // Free-form appointment notes (distinct from the client notes)
    cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
    isCarrier: boolean  // A synthesized carrier booking (LUX-206) — exists only so a money-only day's payments have an appointment to hang on; not a call, every call count skips it
    isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
    wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
    wrapUpNoShow: boolean  // She reported the client never showed for this booking
    wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
    wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
    wrapUpExtras: Array<{
      menuServiceId: string  // Unique identifier
      name: string  // Service name as it read at report time
      price: number  // Catalog price at report time
    }>  // Add-ons she reported selling, priced as at report time
    wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
    date: string | any  // Date in YYYY-MM-DD format
    talentId: string  // Unique identifier
    talentName: string
    locationName: string
    city: string
  }>
  total: number  // Rows matching the query, across all pages
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/appointment.byDateRange?input=%7B%22page%22%3A0%2C%22pageSize%22%3A0%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
Optional fields (click to add):
startDate endDate talentId search
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Auth

mutation
Login auth.login
Auth

Authenticate with email and password

Input Schema
TypeScript
{
  email: string  // Email address
  password: string  // Account password (min 8 characters)
}
Output Schema
TypeScript
{
  token: string | null  // Session token
  user: {
    id: string  // User identifier
    email: string  // Email address
    name: string | null
    image: string | null  // Profile image URL
    emailVerified: boolean  // Whether email has been verified
  }
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/auth.login' \
  -H 'Content-Type: application/json' \
  -d '{"email":"string","password":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Booker

query
List Bookers booker.list
Bookers

Returns all bookers (Users with role 'booker'), name ascending, each with its pay rate (null until set)

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  name: string  // Booker's display name
  payRate: number | null  // Whole dollars paid per booked appointment; null until set (D76)
  active: boolean  // False once deactivated — she keeps her history but can no longer sign in or be scheduled (LUX-250)
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/booker.list' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Set Booker Active booker.setActive
Bookers

Deactivates a booker or brings her back (LUX-250). Deactivating ends her login and clears her phone coverage from `today` on; her bookings, pay rate and payroll history are untouched, and the days she already worked stay on the grid. Bookers only — any other role is NOT_FOUND. Deactivating your own account is FORBIDDEN

Input Schema
TypeScript
{
  userId: string  // Unique identifier
  active: boolean
  today: any  // The caller's calendar today — deactivating clears her coverage from this date on, and leaves the days already worked. Sent by the client so the server never guesses the timezone
}
Output Schema
TypeScript
any
Code Examples
Shell
curl -X POST '{{BASE_URL}}/booker.setActive' \
  -H 'Content-Type: application/json' \
  -d '{"userId":"string","active":true,"today":"value"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Set Booker Pay Rate booker.setPayRate
Bookers

Sets a booker's pay rate — whole dollars per booked appointment (D76); upserts by user. New appointments stamp this rate; past ones are unchanged

Input Schema
TypeScript
{
  userId: string  // Unique identifier
  amount: number
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/booker.setPayRate' \
  -H 'Content-Type: application/json' \
  -d '{"userId":"string","amount":0}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Booker Payroll booker.payroll
Bookers

Per-booker Mon–Sun weeks: calls booked, pay owed (Σ stamped bookerPay), and whether the week has been paid — most recent first (D76/D77)

Output Schema
TypeScript
Array<{
  userId: string  // Unique identifier
  bookerName: string  // Booker's display name
  weekStart: string | any  // The week's Monday (D77)
  weekEnd: string | any  // The week's Sunday
  calls: number  // Booked appointments credited to her this week (cancelled ones excluded, D95)
  amount: number  // Σ the stamped bookerPay for those calls, plus the week cancellation fees (D76/D95)
  cancellationPay: number  // The part of `amount` that came from kept cancellation fees rather than calls (D95)
  paidOn: string | any | null  // The day she was paid; null until the week is confirmed
  paidAmount: number | null  // What was paid, snapshotted at confirm; null until confirmed
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/booker.payroll' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Confirm Booker Paid booker.confirmPaid
Bookers

Marks one booker's Mon–Sun week as paid, snapshotting the amount the server computes for that week; confirming the same week again overwrites rather than double-paying

Input Schema
TypeScript
{
  userId: string  // Unique identifier
  weekStart: string | any  // Date in YYYY-MM-DD format
  paidOn: string | any  // The day the money changed hands
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/booker.confirmPaid' \
  -H 'Content-Type: application/json' \
  -d '{"userId":"string","weekStart":"string","paidOn":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Mark Booker Unpaid booker.markUnpaid
Bookers

Un-marks one booker's Mon–Sun week, deleting the payment record so the week reads as outstanding again (LUX-319). Deletes rather than zeroes: the row's existence is the paid flag, so a $0 overwrite would still assert a payout happened. A week that was never confirmed is NOT_FOUND

Input Schema
TypeScript
{
  userId: string  // Unique identifier
  weekStart: string | any  // Date in YYYY-MM-DD format
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/booker.markUnpaid' \
  -H 'Content-Type: application/json' \
  -d '{"userId":"string","weekStart":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

BookerSchedule

query
List Booker Schedule bookerSchedule.list
Bookers

Returns booker coverage entries for an inclusive date range, date then startsAt ascending

Input Schema
TypeScript
{
  from: any  // YYYY-MM-DD string parsed to UTC midnight Date
  to: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  id: string  // UUID identifier
  userId: string  // Unique identifier
  phoneNumberId: string  // UUID identifier
  date: string | any  // Date in YYYY-MM-DD format
  startsAt: string  // Takeover time 'HH:MM'; '00:00' = the day's first booker
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/bookerSchedule.list?input=%7B%22from%22%3A%22value%22%2C%22to%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Set Booker Schedule Day bookerSchedule.setDay
Bookers

Replaces one number+date's coverage wholesale — the final list of takeovers for that day; empty clears it

Input Schema
TypeScript
{
  phoneNumberId: string  // UUID identifier
  date: any  // YYYY-MM-DD string parsed to UTC midnight Date
  shifts: Array<{
    userId: string  // Unique identifier
    startsAt: string  // Takeover time 'HH:MM'; '00:00' = the day's first booker
  }>
}
Output Schema
TypeScript
any
Code Examples
Shell
curl -X POST '{{BASE_URL}}/bookerSchedule.setDay' \
  -H 'Content-Type: application/json' \
  -d '{"phoneNumberId":"string","date":"value","shifts":[{"userId":"string","startsAt":"string"}]}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Booker Payee Drift bookerSchedule.payeeDrift
Bookers

Bookings on one line's day whose stored payee is not the booker now covering that line, grouped by (paid-to-today → should-earn) with a count and both names (LUX-318). Indy calls are skipped and cancelled ones included; bookings in a Mon–Sun week either side has already been paid for are reported as `settledSkipped` rather than offered

Input Schema
TypeScript
{
  phoneNumberId: string  // UUID identifier
  date: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
{
  groups: Array<{
    fromUserId: string  // Unique identifier
    fromName: string  // Who those bookings are paid to today
    toUserId: string  // Unique identifier
    toName: string  // Who the day's coverage now says earns them
    count: number  // Bookings in this group
  }>
  settledSkipped: number  // Drifted bookings deliberately left alone because either side of the move already has a BookerWeeklyPayment for that Mon–Sun week. Counted rather than dropped silently — an offer that quietly under-reports reads as "all clear"
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/bookerSchedule.payeeDrift?input=%7B%22phoneNumberId%22%3A%22string%22%2C%22date%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Reassign Booker Payees bookerSchedule.reassignPayees
Bookers

Re-stamps the payee and booker pay on that line-day's drifted bookings to the booker the coverage now names (LUX-318). The drift is recomputed server-side and never read off the request — this moves money, so a stale screen cannot decide what it moves

Input Schema
TypeScript
{
  phoneNumberId: string  // UUID identifier
  date: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
{
  reassigned: number  // Bookings whose payee and stamped booker pay were moved
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/bookerSchedule.reassignPayees' \
  -H 'Content-Type: application/json' \
  -d '{"phoneNumberId":"string","date":"value"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Booking Day Coverage bookerSchedule.dayCoverage
Bookers

Every schedule on the day with the bookers covering its line (LUX-330): the talent's profile number while live on that day, else the venue's. Empty `coveredBy` = no line, or a line nobody covers — such a column shows for everyone

Input Schema
TypeScript
{
  date: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  scheduleId: string  // Unique identifier
  coveredBy: string[]
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/bookerSchedule.dayCoverage?input=%7B%22date%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Booker Home bookerSchedule.home
Bookers

The booker's landing page (LUX-335): today's talent on the lines she covers (or nobody covers) with venue, hours and her history's expectation, the distinct venues, the summed expectation, and who arrives on her lines tomorrow through today+7 — a talent's first day with no such day before it. An admin sees every line. `today` is the caller's calendar day

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
{
  today: Array<{
    scheduleId: string  // Unique identifier
    talentId: string  // Unique identifier
    nickname: string
    date: string | any  // Date in YYYY-MM-DD format
    venue: string
    city: string
    startTime: string | null
    endTime: string | null
    expected: number | null  // Her average for this weekday, null when she has no history
    basis: "weekday" | "overall"  // Which average `expected` came from — 'overall' is the fallback
    sampleDays: number  // Days worked behind `expected` — the reference point it needs
  }>
  locations: Array<{
    venue: string
    city: string
  }>  // Distinct venues among today's rows
  expectedCalls: number  // Sum of today's expectations, two decimals
  arriving: Array<{
    scheduleId: string  // Unique identifier
    talentId: string  // Unique identifier
    nickname: string
    date: string | any  // Date in YYYY-MM-DD format
    venue: string
    city: string
    startTime: string | null
    endTime: string | null
  }>  // First day on her lines for each talent not there the day before, tomorrow through today+7
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/bookerSchedule.home?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

City

query
List Cities city.list
Cities

Returns the requesting company's cities in display order

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // City name
  sortOrder: number  // Display sort order
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/city.list' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Reorder Cities city.reorder
Cities

Batch-update the display order of city sections for the requesting company

Input Schema
TypeScript
{
  orderedIds: string[]  // City IDs in the desired display order
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // City name
  sortOrder: number  // Display sort order
}>
Code Examples
Shell
curl -X POST '{{BASE_URL}}/city.reorder' \
  -H 'Content-Type: application/json' \
  -d '{"orderedIds":["string"]}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create City city.create
Cities

Onboards a city by name for the requesting company; returns the existing city if the name is already used

Input Schema
TypeScript
{
  name: string  // City name
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // City name
  sortOrder: number  // Display sort order
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/city.create' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Rename City city.rename
Cities

Renames a city owned by the requesting company; 404 unless it belongs to the company, 409 if the name is already used

Input Schema
TypeScript
{
  id: string  // UUID identifier
  name: string  // City name
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // City name
  sortOrder: number  // Display sort order
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/city.rename' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string","name":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete City city.delete
Cities

Deletes a city owned by the requesting company; 404 unless it belongs to the company, 400 while it still has locations

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // City name
  sortOrder: number  // Display sort order
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/city.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Client

query
List Clients client.list
Clients

One page of clients (global across brands), identity fields only, with the total matching the search

Input Schema
TypeScript
{
  page: number  // 1-based page number
  pageSize: number  // Rows per page
  search?: string  // Substring match over name, code, phone and CAF handle
}
Output Schema
TypeScript
{
  items: Array<{
    id: string  // Unique identifier
    code: string  // Immutable client code — the human identity
    name: string | null  // Client's full name
    phone: string  // Phone number in E.164, e.g. +14035550101
    cafHandle: string | null
    perbHandle: string | null
    isBlacklisted: boolean  // Whether the client is blacklisted across all brands
    isConfirmed: boolean  // Whether the client has used the service before (no deposit asked)
  }>
  total: number  // Rows matching the query, across all pages
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/client.list?input=%7B%22page%22%3A0%2C%22pageSize%22%3A0%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
Optional fields (click to add):
search
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List All Clients client.listAll
Clients

Returns every client unpaginated, identity fields only — for the importer’s phone dedup index; the admin list uses `client.list`

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  code: string  // Immutable client code — the human identity
  name: string | null  // Client's full name
  phone: string  // Phone number in E.164, e.g. +14035550101
  cafHandle: string | null
  perbHandle: string | null
  isBlacklisted: boolean  // Whether the client is blacklisted across all brands
  isConfirmed: boolean  // Whether the client has used the service before (no deposit asked)
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/client.listAll' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Get Clients by IDs client.byIds
Clients

Returns the named clients in the list projection. Ids are deduped and unknown ids are OMITTED, so the result may be shorter than the input — it is never an error

Input Schema
TypeScript
{
  ids: string[]
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  code: string  // Immutable client code — the human identity
  name: string | null  // Client's full name
  phone: string  // Phone number in E.164, e.g. +14035550101
  cafHandle: string | null
  perbHandle: string | null
  isBlacklisted: boolean  // Whether the client is blacklisted across all brands
  isConfirmed: boolean  // Whether the client has used the service before (no deposit asked)
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/client.byIds?input=%7B%22ids%22%3A%5B%22string%22%5D%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Client by ID client.byId
Clients

Returns a client by ID, with the brands they booked through

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  code: string  // Immutable client code — the human identity
  name: string | null  // Client's full name
  phone: string  // Phone number in E.164, e.g. +14035550101
  email: string | null  // Email address
  city: string | null
  ageRange: string | null
  ethnicity: string | null
  notes: string | null
  cafHandle: string | null
  perbHandle: string | null
  isBlacklisted: boolean  // Whether the client is blacklisted across all brands
  blacklistReason: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues" | null
  isConfirmed: boolean  // Whether the client has used the service before (no deposit asked)
  brands: string[]  // Distinct company names the client has booked through
  otherPhones: string[]  // Their other phone numbers, E.164 each
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/client.byId?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Client Booking History client.visits
Clients

How many times a client has booked and the few bookings that matter while answering them — upcoming soonest-first, then recent past. Across every brand, cancellations excluded. `today` is the caller's local date.

Input Schema
TypeScript
{
  clientId: string  // UUID identifier
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
{
  total: number  // Bookings, ever, any brand
  cancelled: number  // Soft-cancelled bookings, ever, any brand (LUX-310) — how often this client cancels vs attends. Deleted bookings never count
  visits: Array<{
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    startTime: string | null  // HH:MM, or null when unset
    talentName: string
    locationName: string | null
    city: string | null
    upcoming: boolean  // Falls on the caller's today or later. Resolved here rather than by comparing clocks in the browser, and by DATE not timestamp — a booking at 10am is still today's booking at 3pm, which is exactly when an operator is asked about it
    locationId: string | null  // Feeds the quick chat arrival-instructions actions (LUX-211). Null when the location was deleted
  }>  // At most 3: every upcoming booking soonest-first, then recent past to fill. Empty when they have never booked
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/client.visits?input=%7B%22clientId%22%3A%22string%22%2C%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Client Booking Profile client.bookingProfile
Clients

What a client usually books, ranked most-requested first: package, extras, and the talent they book. Counts exactly what `client.visits` counts — every non-cancelled booking across every brand, upcoming included — so the two never disagree.

Input Schema
TypeScript
{
  clientId: string  // UUID identifier
}
Output Schema
TypeScript
{
  total: number  // Bookings, ever, any brand, cancellations excluded — the same figure `client.visits` reports
  firstBookedAt: string | any | null  // Their earliest booking ever — how long we have known them, exact regardless of how many they have. Null when they have never booked
  packages: Array<{
    label: string
    count: number
  }>  // Menu booked, most-taken first, labelled "60 min VIP". A booking imported without a menu (LUX-120) counts in `total` but appears in no line here — there is no package to name
  extras: Array<{
    label: string
    count: number
  }>  // Add-ons booked, most-requested first. Empty is common
  talent: Array<{
    label: string
    count: number
    lastBooked: string | any  // Their latest booking with this talent. NOT necessarily in the past — a booking for Friday dates them Friday, so a caller rendering this must say "next" rather than "last" for a future date
  }>  // Who they have seen, most-booked first
  visits: Array<{
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    startTime: string | null  // HH:MM, or null when unset
    talentName: string
    locationName: string | null
    city: string | null
    menuLabel: string | null  // What was booked, as "60 min VIP". Null on a booking the historical import synthesized (LUX-120), which records no package — the ranking above omits those rows for the same reason
    extras: string[]  // Add-ons on this booking, unranked and unordered — the ranking is `extras` above, which answers what they USUALLY take. This answers what they took that night
  }>  // The most recent bookings, newest first, so the same read that ranks them can also list them. Capped — `total` above is the exact figure, this is a sample of it. No `upcoming` flag: that is a function of the caller's today, and this procedure deliberately takes no `today` so its count cannot drift from `client.visits`'; a caller wanting the distinction compares `date` against its own
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/client.bookingProfile?input=%7B%22clientId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Client client.create
Clients

Creates a client — phone is the global dedup key

Input Schema
TypeScript
{
  name?: any | null
  phone: string  // Phone number in E.164, e.g. +14035550101 — the dedup key
  email?: string | null
  city?: 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
  isConfirmed?: boolean  // Whether the client has used the service before (no deposit asked)
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  code: string  // Immutable client code — the human identity
  name: string | null  // Client's full name
  phone: string  // Phone number in E.164, e.g. +14035550101
  email: string | null  // Email address
  city: string | null
  ageRange: string | null
  ethnicity: string | null
  notes: string | null
  cafHandle: string | null
  perbHandle: string | null
  isBlacklisted: boolean  // Whether the client is blacklisted across all brands
  blacklistReason: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues" | null
  isConfirmed: boolean  // Whether the client has used the service before (no deposit asked)
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/client.create' \
  -H 'Content-Type: application/json' \
  -d '{"phone":"string"}'
Test Endpoint
Optional fields (click to add):
name email city ageRange ethnicity notes cafHandle perbHandle isBlacklisted blacklistReason isConfirmed
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Client client.update
Clients

Updates a client

Input Schema
TypeScript
{
  name?: any | null
  phone?: string  // Phone number in E.164, e.g. +14035550101 — the dedup key
  email?: string | null
  city?: 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
  isConfirmed?: boolean  // Whether the client has used the service before (no deposit asked)
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  code: string  // Immutable client code — the human identity
  name: string | null  // Client's full name
  phone: string  // Phone number in E.164, e.g. +14035550101
  email: string | null  // Email address
  city: string | null
  ageRange: string | null
  ethnicity: string | null
  notes: string | null
  cafHandle: string | null
  perbHandle: string | null
  isBlacklisted: boolean  // Whether the client is blacklisted across all brands
  blacklistReason: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues" | null
  isConfirmed: boolean  // Whether the client has used the service before (no deposit asked)
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/client.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
name phone email city ageRange ethnicity notes cafHandle perbHandle isBlacklisted blacklistReason isConfirmed
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Merge Client Profiles client.merge
Clients

Folds one client profile into another and retires it: bookings, credits, conversations and the Don't-See list move to the surviving client, whose code and phone are kept, and the retired profile's number stays linked so texts from it resolve to the survivor. Irreversible.

Input Schema
TypeScript
{
  keepClientId: string  // The profile that survives
  mergeClientId: string  // The profile that is retired
}
Output Schema
TypeScript
{
  keptCode: string  // The client code that survived
  retiredCode: string  // The client code that no longer exists
  linkedPhone: string  // The retired profile’s number, now linked to the survivor
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/client.merge' \
  -H 'Content-Type: application/json' \
  -d '{"keepClientId":"string","mergeClientId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List Client Exclusions client.listExclusions
Clients

Returns the ids of talents on a client's Don't-See list

Input Schema
TypeScript
{
  clientId: string  // UUID identifier
}
Output Schema
TypeScript
string[]
Code Examples
Shell
curl -X GET '{{BASE_URL}}/client.listExclusions?input=%7B%22clientId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Add Client Exclusions client.addExclusions
Clients

Adds talents to a client's Don't-See list, removing none — returns how many were new

Input Schema
TypeScript
{
  clientId: string  // The client whose Don’t-See list is added to
  talentIds: string[]  // Talents who won't see this client (added; none are removed)
}
Output Schema
TypeScript
{
  added: number  // Rows this call created
  talentIds: string[]  // The whole list after the add
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/client.addExclusions' \
  -H 'Content-Type: application/json' \
  -d '{"clientId":"string","talentIds":["string"]}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Mark Client Confirmed client.markConfirmed
Clients

Marks a client as confirmed, never the reverse — returns whether this call changed it

Input Schema
TypeScript
{
  clientId: string  // The client to mark as confirmed
}
Output Schema
TypeScript
{
  promoted: boolean  // Whether this call changed the client (false if already confirmed)
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/client.markConfirmed' \
  -H 'Content-Type: application/json' \
  -d '{"clientId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Mark Client Blacklisted client.markBlacklisted
Clients

Blocks a client who carries no reason, never re-categorizing one who does — returns whether this call changed it

Input Schema
TypeScript
{
  clientId: string  // The client to block, if they carry no reason
  blacklistReason: "NoShow" | "TimeWaster" | "Aggressive" | "NoDeposit" | "NonCooperative" | "HygieneIssues"  // The category to record — applied only when the client has none
}
Output Schema
TypeScript
{
  blocked: boolean  // Whether this call changed the client (false if a reason was already set)
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/client.markBlacklisted' \
  -H 'Content-Type: application/json' \
  -d '{"clientId":"string","blacklistReason":"NoShow"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Set Client City client.setCity
Clients

Places a client who has no city, never moving one who does — returns whether this call changed it

Input Schema
TypeScript
{
  clientId: string  // The client to place, if they carry no city
  city: string  // The city to record — applied only when the client has none
}
Output Schema
TypeScript
{
  filled: boolean  // Whether this call changed the client (false if a city was already set)
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/client.setCity' \
  -H 'Content-Type: application/json' \
  -d '{"clientId":"string","city":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Set Client Exclusions client.setExclusions
Clients

Replaces a client's Don't-See list — the talents who won't see this client

Input Schema
TypeScript
{
  clientId: string  // The client whose Don’t-See list is set
  talentIds: string[]  // Talents who won't see this client (replaces the whole list)
}
Output Schema
TypeScript
string[]
Code Examples
Shell
curl -X POST '{{BASE_URL}}/client.setExclusions' \
  -H 'Content-Type: application/json' \
  -d '{"clientId":"string","talentIds":["string"]}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

ClientCredit

query
Client Credits clientCredit.byClient
ClientCredit

A client's prepaid / cancellation credits in this brand, newest first

Input Schema
TypeScript
{
  clientId: string  // UUID identifier
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  clientId: string  // Unique identifier
  amount: number
  method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare" | null  // How the deposit arrived; null on rows written before it was captured
  status: "held" | "applied" | "cancellationFee"
  talentAmount: number | null
  bookerFee: number | null
  agencyAmount: number | null
  note: string | null
  createdAt: string | any  // ISO 8601 timestamp
  appliedBooking: {
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    talentName: string
    locationName: string
  } | any | null
  cancelledBooking: {
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    talentName: string
    locationName: string
  } | any | null
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/clientCredit.byClient?input=%7B%22clientId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Record Client Credit clientCredit.create
ClientCredit

Records a client prepayment as a held credit (>= $50 minimum, D87) — never a Payment

Input Schema
TypeScript
{
  clientId: string  // UUID identifier
  amount: number
  method: "EMT" | "AmazonGiftCard" | "Cash"
  note?: string
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  clientId: string  // Unique identifier
  amount: number
  method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare" | null  // How the deposit arrived; null on rows written before it was captured
  status: "held" | "applied" | "cancellationFee"
  talentAmount: number | null
  bookerFee: number | null
  agencyAmount: number | null
  note: string | null
  createdAt: string | any  // ISO 8601 timestamp
  appliedBooking: {
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    talentName: string
    locationName: string
  } | any | null
  cancelledBooking: {
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    talentName: string
    locationName: string
  } | any | null
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/clientCredit.create' \
  -H 'Content-Type: application/json' \
  -d '{"clientId":"string","amount":0,"method":"EMT"}'
Test Endpoint
Optional fields (click to add):
note
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Apply Client Credit clientCredit.applyToBooking
ClientCredit

Applies a held credit to a booking — creates a Payment(method:Credit) for the full amount so the tracker Paid rolls up (D87)

Input Schema
TypeScript
{
  id: string  // UUID identifier
  appointmentId: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  clientId: string  // Unique identifier
  amount: number
  method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare" | null  // How the deposit arrived; null on rows written before it was captured
  status: "held" | "applied" | "cancellationFee"
  talentAmount: number | null
  bookerFee: number | null
  agencyAmount: number | null
  note: string | null
  createdAt: string | any  // ISO 8601 timestamp
  appliedBooking: {
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    talentName: string
    locationName: string
  } | any | null
  cancelledBooking: {
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    talentName: string
    locationName: string
  } | any | null
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/clientCredit.applyToBooking' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string","appointmentId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Elect Cancellation Fee clientCredit.electCancellationFee
ClientCredit

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)

Input Schema
TypeScript
{
  id: string  // UUID identifier
  cancelledAppointmentId: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  clientId: string  // Unique identifier
  amount: number
  method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare" | null  // How the deposit arrived; null on rows written before it was captured
  status: "held" | "applied" | "cancellationFee"
  talentAmount: number | null
  bookerFee: number | null
  agencyAmount: number | null
  note: string | null
  createdAt: string | any  // ISO 8601 timestamp
  appliedBooking: {
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    talentName: string
    locationName: string
  } | any | null
  cancelledBooking: {
    id: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    talentName: string
    locationName: string
  } | any | null
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/clientCredit.electCancellationFee' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string","cancelledAppointmentId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Client Credit clientCredit.delete
ClientCredit

Removes a mistaken held credit — a consumed (applied / cancellation-fee) credit is immutable

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/clientCredit.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Company

query
List Companies company.list
Companies

Returns all companies

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // Company display name
  slug: string  // URL-safe unique slug, sent as the x-company-slug header
  defaultPhoneNumberId: string | null  // Company default (house) phone number id
  imageBrand: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean"  // Which image brand this company displays; Clean = no watermark
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/company.list' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Current Company Default Phone company.currentDefaultPhone
Companies

Returns the requesting company's default (house) phone, or null when unset — the public fallback for talent contact numbers

Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string | null
  number: string  // Phone number
  usedForMessages: boolean  // Whether this number is used for messages
} | null
Code Examples
Shell
curl -X GET '{{BASE_URL}}/company.currentDefaultPhone' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Create Company company.create
Companies

Creates a new company

Input Schema
TypeScript
{
  name: string  // Company display name
  slug: string  // URL-safe unique slug, sent as the x-company-slug header
  defaultPhoneNumberId?: string | null  // Company default (house) phone number id
  imageBrand?: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean"  // Which image brand this company displays; Clean = no watermark
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // Company display name
  slug: string  // URL-safe unique slug, sent as the x-company-slug header
  defaultPhoneNumberId: string | null  // Company default (house) phone number id
  imageBrand: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean"  // Which image brand this company displays; Clean = no watermark
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/company.create' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string","slug":"string"}'
Test Endpoint
Optional fields (click to add):
defaultPhoneNumberId imageBrand
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Company company.update
Companies

Updates a company

Input Schema
TypeScript
{
  name?: string  // Company display name
  slug?: string  // URL-safe unique slug, sent as the x-company-slug header
  defaultPhoneNumberId?: string | null  // Company default (house) phone number id
  imageBrand?: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean"  // Which image brand this company displays; Clean = no watermark
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // Company display name
  slug: string  // URL-safe unique slug, sent as the x-company-slug header
  defaultPhoneNumberId: string | null  // Company default (house) phone number id
  imageBrand: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean"  // Which image brand this company displays; Clean = no watermark
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/company.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
name slug defaultPhoneNumberId imageBrand
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Company company.delete
Companies

Blocked — companies cannot be deleted via the API

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/company.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Events

subscription
Live Change Stream events.onChange
Events

SSE stream that emits whenever something changed that other operators should see — an SMS, a booking, a payment, a roster edit. Carries the topic only; refetch on event.

Code Examples
Shell
curl -X POST '{{BASE_URL}}/events.onChange' \
  -H 'Content-Type: application/json'
Test Endpoint

Expense

query
Expenses by Date Range expense.byDateRange
Expense

Ad-hoc expenses in a date range (by the date incurred), newest first — the list + the weekly report money-out

Input Schema
TypeScript
{
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  amount: number
  category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
  incurredOn: string | any  // Date in YYYY-MM-DD format
  note: string | null
  payrollUserId: string | null  // Counts toward this user's payroll (LUX-214); null = nobody's
  allocations: Array<{
    locationId: string  // Unique identifier
    locationName: string
    city: string
    category: "Hotel" | "Airbnb" | "Condo"  // Venue type — an Accommodation at a hotel/Airbnb is a stay (LUX-316)
    amount: number
  }>
  stay: {
    scheduleId: string  // Unique identifier
    talentId: string  // Unique identifier
    talentName: string
    date: string | any  // Date in YYYY-MM-DD format
    bookOn: number
  } | null  // The first-day report this room bill charges, or null — an Accommodation at a hotel with no stay charges no talent
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/expense.byDateRange?input=%7B%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Expense expense.byId
Expense

One expense with its allocations, or null when not this company’s

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  amount: number
  category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
  incurredOn: string | any  // Date in YYYY-MM-DD format
  note: string | null
  payrollUserId: string | null  // Counts toward this user's payroll (LUX-214); null = nobody's
  allocations: Array<{
    locationId: string  // Unique identifier
    locationName: string
    city: string
    category: "Hotel" | "Airbnb" | "Condo"  // Venue type — an Accommodation at a hotel/Airbnb is a stay (LUX-316)
    amount: number
  }>
  stay: {
    scheduleId: string  // Unique identifier
    talentId: string  // Unique identifier
    talentName: string
    date: string | any  // Date in YYYY-MM-DD format
    bookOn: number
  } | null  // The first-day report this room bill charges, or null — an Accommodation at a hotel with no stay charges no talent
} | null
Code Examples
Shell
curl -X GET '{{BASE_URL}}/expense.byId?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Expense expense.create
Expense

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. A payroll association must be someone who can be paid: talent and deactivated logins are BAD_REQUEST (LUX-302). With `stayScheduleId`, also writes the stay's first-day book-on (½ the amount, LUX-316) in the same transaction — BAD_REQUEST at a condo or a venue the expense is not for, CONFLICT when that day already carries another bill

Input Schema
TypeScript
{
  amount: number  // Whole dollars
  category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
  incurredOn: any  // YYYY-MM-DD string parsed to UTC midnight Date
  note?: string
  locationIds: string[]
  payrollUserId?: string | null
  stayScheduleId?: string | null
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  amount: number
  category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
  incurredOn: string | any  // Date in YYYY-MM-DD format
  note: string | null
  payrollUserId: string | null  // Counts toward this user's payroll (LUX-214); null = nobody's
  allocations: Array<{
    locationId: string  // Unique identifier
    locationName: string
    city: string
    category: "Hotel" | "Airbnb" | "Condo"  // Venue type — an Accommodation at a hotel/Airbnb is a stay (LUX-316)
    amount: number
  }>
  stay: {
    scheduleId: string  // Unique identifier
    talentId: string  // Unique identifier
    talentName: string
    date: string | any  // Date in YYYY-MM-DD format
    bookOn: number
  } | null  // The first-day report this room bill charges, or null — an Accommodation at a hotel with no stay charges no talent
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/expense.create' \
  -H 'Content-Type: application/json' \
  -d '{"amount":0,"category":"Admin","incurredOn":"value","locationIds":["string"]}'
Test Endpoint
Optional fields (click to add):
note payrollUserId stayScheduleId
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Expense expense.update
Expense

Updates an expense and replaces its allocation; 404 unless it belongs to the requesting company. Changing the payroll association re-checks it (LUX-302); re-sending the stored one does not, so an expense already tagged to talent stays editable

Input Schema
TypeScript
{
  amount: number  // Whole dollars
  category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
  incurredOn: any  // YYYY-MM-DD string parsed to UTC midnight Date
  note?: string
  locationIds?: string[]
  payrollUserId?: string | null
  stayScheduleId?: string | null
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  amount: number
  category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
  incurredOn: string | any  // Date in YYYY-MM-DD format
  note: string | null
  payrollUserId: string | null  // Counts toward this user's payroll (LUX-214); null = nobody's
  allocations: Array<{
    locationId: string  // Unique identifier
    locationName: string
    city: string
    category: "Hotel" | "Airbnb" | "Condo"  // Venue type — an Accommodation at a hotel/Airbnb is a stay (LUX-316)
    amount: number
  }>
  stay: {
    scheduleId: string  // Unique identifier
    talentId: string  // Unique identifier
    talentName: string
    date: string | any  // Date in YYYY-MM-DD format
    bookOn: number
  } | null  // The first-day report this room bill charges, or null — an Accommodation at a hotel with no stay charges no talent
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/expense.update' \
  -H 'Content-Type: application/json' \
  -d '{"amount":0,"category":"Admin","incurredOn":"value","id":"string"}'
Test Endpoint
Optional fields (click to add):
note locationIds payrollUserId stayScheduleId
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Stay Days expense.stayDays
Expense

A talent's schedule days at one venue within ±6 months of a date, with each day's stored room figures — the expense form derives the stay and its first day from these (LUX-316)

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
  talentId: string  // UUID identifier
  around: any  // ±6 months of this date
}
Output Schema
TypeScript
Array<{
  scheduleId: string  // Unique identifier
  date: string | any  // Date in YYYY-MM-DD format
  flatFee: number | null
  storedBookOn: number | null
  stayExpenseId: string | null  // The expense whose stay already sits on this day, if any
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/expense.stayDays?input=%7B%22locationId%22%3A%22string%22%2C%22talentId%22%3A%22string%22%2C%22around%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Expense expense.delete
Expense

Removes an expense and its allocations; a stay's first-day charge goes with it (LUX-316)

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/expense.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

TalentCreditPayout

mutation
Pay Out Talent Credit talentCreditPayout.create
TalentCreditPayout

Records cash handed back to a talent against her carried credit on a date (LUX-341) — stops the carry from that date, shows on the day page outside Due/Paid/balance, and is money out in the payout week on its own line

Input Schema
TypeScript
{
  talentId: string  // UUID identifier
  date: any  // YYYY-MM-DD string parsed to UTC midnight Date
  amount: number
  note?: string
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  talentId: string  // Unique identifier
  date: string | any  // Date in YYYY-MM-DD format
  amount: number
  note: string | null
  createdAt: string | any  // ISO 8601 timestamp
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talentCreditPayout.create' \
  -H 'Content-Type: application/json' \
  -d '{"talentId":"string","date":"value","amount":0}'
Test Endpoint
Optional fields (click to add):
note
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

FinanceDashboard

query
Finance Dashboard financeDashboard.byPeriod
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

Input Schema
TypeScript
{
  periodKind: "day" | "week" | "month" | "quarter" | "year"
  anchorDate: string  // The caller's calendar today (YYYY-MM-DD) — the period is resolved around it, sent by the client so the server never guesses the timezone
}
Output Schema
TypeScript
{
  periodKind: "day" | "week" | "month" | "quarter" | "year"
  range: {
    startDate: string | any  // Date in YYYY-MM-DD format
    endDate: string | any  // Date in YYYY-MM-DD format
  }
  kpis: {
    gross: {
      value: number
      previous: number
      delta: number
    }  // Revenue owed — Σ Due (D85)
    expenses: {
      value: number
      previous: number
      delta: number
    }  // Ad-hoc expenses + prorated fixed costs + booker pay (D91)
    net: {
      value: number
      previous: number
      delta: number
    }  // Gross − expenses — accrual (D85)
    collectedCash: {
      value: number
      previous: number
      delta: number
    }  // Payments collected in-period
    cashProfit: {
      value: number
      previous: number
      delta: number
    }  // collectedCash − expenses − talent credit paid out (D113) — the cash-basis profit the client keeps in her own P&L (D91)
  }
  trend: Array<{
    date: string | any  // The bucket end date — the series x-axis label
    gross: number
    expenses: number
    net: number
    collectedCash: number
  }>
  byCity: Array<{
    city: string
    gross: number
    spend: number  // What the city cost over the period — every location in it, hotels included
    net: number
  }>
  businessWide: number  // Unallocated ad-hoc expenses (admin, owner payouts) tied to no city — the by-city column reconciles as company net = Σ(city nets) − businessWide (D101)
  byCategory: Array<{
    category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation" | "Rent" | "Utilities" | "Internet" | "Insurance" | "Misc"
    amount: number
  }>  // The "Where the money went" breakdown: every ExpenseCategory (Cleaning & Supplies combine their one-off + monthly-fixed halves, D102) plus the fixed-only lines (rent/utilities/internet/insurance/misc). Σ(amount) + bookerPay == the Expenses total, so no cost is missing from the chart (LUX-155 #1)
  bookerPay: number  // Σ the stamped Appointment.bookerPay for the period (D76/D91) — its own expense line beside byCategory, since it is not an ExpenseCategory
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/financeDashboard.byPeriod?input=%7B%22periodKind%22%3A%22day%22%2C%22anchorDate%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Finance Locations financeDashboard.locations
FinanceDashboard

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

Input Schema
TypeScript
{
  periodKind: "day" | "week" | "month" | "quarter" | "year"
  anchorDate: string  // The caller's calendar today (YYYY-MM-DD) — the period is resolved around it, sent by the client so the server never guesses the timezone
}
Output Schema
TypeScript
Array<{
  locationId: string  // Unique identifier
  locationName: string
  city: string
  revenue: number  // Σ Due for the period (D85), signed
  collectedCash: number  // Σ payments taken against the period's bookings — the client's Paid (D91/D98)
  fixedCosts: number  // LocationFixedCost prorated to the period by day-overlap (D86)
  allocatedExpenses: number  // Σ ExpenseAllocation.amount (D80)
  bookerPay: number  // Σ the stamped Appointment.bookerPay for the period (D76/D91)
  profit: number  // Earned: revenue − fixedCosts − allocatedExpenses − bookerPay; negative in a loss
  cashProfit: number  // Cash: collectedCash − the same expenses (D91/D98) — what the rail ranks on
  bookedDays: number  // Distinct Schedule dates for the location in the period (D88)
  daysInPeriod: number  // Calendar days in the period — the utilization denominator
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/financeDashboard.locations?input=%7B%22periodKind%22%3A%22day%22%2C%22anchorDate%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Finance Location Detail financeDashboard.locationDetail
FinanceDashboard

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

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
  anchorDate: string  // The caller's calendar today (YYYY-MM-DD) — the series ends at its month, sent by the client so the server never guesses the timezone
}
Output Schema
TypeScript
{
  locationId: string  // Unique identifier
  locationName: string
  city: string
  months: Array<{
    period: string  // Period in YYYY-MM format
    revenue: number  // Σ Due for the month (D85), signed
    expenses: number  // fixedCosts + allocatedExpenses + bookerPay (D91)
    fixedCosts: number  // Σ LocationFixedCost lines for the month
    allocatedExpenses: number  // Σ ExpenseAllocation.amount — supplies & assigned expenses (D80)
    bookerPay: number  // Σ the stamped Appointment.bookerPay for the month (D76/D91)
    bookedDays: number
    daysInMonth: number
  }>
  costComposition: {
    rent: number  // Amount in whole dollars
    utilities: number  // Amount in whole dollars
    internet: number  // Amount in whole dollars
    insurance: number  // Amount in whole dollars
    cleaning: number  // Amount in whole dollars
    supplies: number  // Amount in whole dollars
    misc: number  // Amount in whole dollars
    allocatedExpenses: number  // Σ ExpenseAllocation.amount over the window — assigned supplies & expenses (D80)
    bookerPay: number  // Σ the stamped Appointment.bookerPay over the window (D76/D91)
  }
  costCompositionByMonth: Array<{
    rent: number  // Amount in whole dollars
    utilities: number  // Amount in whole dollars
    internet: number  // Amount in whole dollars
    insurance: number  // Amount in whole dollars
    cleaning: number  // Amount in whole dollars
    supplies: number  // Amount in whole dollars
    misc: number  // Amount in whole dollars
    allocatedExpenses: number  // Σ ExpenseAllocation.amount over the window — assigned supplies & expenses (D80)
    bookerPay: number  // Σ the stamped Appointment.bookerPay over the window (D76/D91)
    period: string  // Period in YYYY-MM format
  }>  // Per-month cost breakdown for the stacked composition chart (D89)
  investmentReturn: Array<{
    period: string  // Period in YYYY-MM format
    cumulativeInvested: number  // Running Σ (fixedCosts + allocatedExpenses + bookerPay) to date (D91)
    cumulativeRevenue: number  // Running Σ revenue (Σ Due, D85) to date
  }>
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/financeDashboard.locationDetail?input=%7B%22locationId%22%3A%22string%22%2C%22anchorDate%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

DailyReport

mutation
Save Daily Report dailyReport.save
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

Input Schema
TypeScript
{
  scheduleId: string  // UUID identifier
  flatFee?: number | null
  bookOn: number
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  scheduleId: string  // Unique identifier
  flatFee: number | null  // Airbnb/hotel per-date room cost; null for a condo
  bookOn: number  // The book-on that applied for the day (the stored snapshot, D15/D16); negative when it credits the talent for accommodation she paid herself (D92/D99)
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/dailyReport.save' \
  -H 'Content-Type: application/json' \
  -d '{"scheduleId":"string","bookOn":0}'
Test Endpoint
Optional fields (click to add):
flatFee
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

File

query
List Failed Images file.listFailed
Files

Returns root images with failed processing status

Output Schema
TypeScript
any[]
Code Examples
Shell
curl -X GET '{{BASE_URL}}/file.listFailed' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Retry Image Processing file.retryProcessing
Files

Retries processing for a failed image by re-generating missing variants

Input Schema
TypeScript
{
  imageId: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  fileId: string  // Unique identifier
  talentId: string  // Unique identifier
  variant: "Original" | "Thumbnail" | "Large"
  imageBrand: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean" | null
  status: "Processing" | "Completed" | "Failed"
  errorMessage: string | null
  width: number | null  // Image width in pixels
  height: number | null  // Image height in pixels
  sortOrder: number  // Display sort order
  sourceImageId: string | null
  file: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string  // Original file name
    mimeType: string  // MIME type (e.g. image/jpeg)
    size: number  // File size in bytes
    blobKey: string  // Blob key within Azure container
    container: string  // Azure Blob Storage container name
    url: string | null  // Public or SAS URL
    uploadedById: string | null
  } | null
  variants: any[]
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/file.retryProcessing' \
  -H 'Content-Type: application/json' \
  -d '{"imageId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Debug

query
Sentry Test debug.sentryTest
Debug

Throws a test error for Sentry

Code Examples
Shell
curl -X GET '{{BASE_URL}}/debug.sentryTest' \
  -H 'Content-Type: application/json'
Test Endpoint

Image

query
Get Images by Talent image.byTalent
Images

Returns all images for a talent belonging to the requesting company

Input Schema
TypeScript
{
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
any[]
Code Examples
Shell
curl -X GET '{{BASE_URL}}/image.byTalent?input=%7B%22talentId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Talent Thumbnails image.thumbnails
Images

Returns talentId → thumbnail URL for the requesting company's talents, in the company's image brand

Output Schema
TypeScript
Record<string, string | null>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/image.thumbnails' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Get Talent Thumbnails (Admin) image.thumbnailsAll
Images

Returns talentId → thumbnail URL across all companies' talents, in the requesting company's image brand — the admin lists show non-members too

Output Schema
TypeScript
Record<string, string | null>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/image.thumbnailsAll' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Create Image image.create
Images

Creates a new image

Input Schema
TypeScript
{
  fileId: string  // ID of the uploaded File
  variant?: "Original" | "Thumbnail" | "Large"
  imageBrand?: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean" | null
  width?: number | null  // Image width in pixels
  height?: number | null  // Image height in pixels
  sortOrder?: number  // Display sort order
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  fileId: string  // Unique identifier
  talentId: string  // Unique identifier
  variant: "Original" | "Thumbnail" | "Large"
  imageBrand: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean" | null
  status: "Processing" | "Completed" | "Failed"
  errorMessage: string | null
  width: number | null  // Image width in pixels
  height: number | null  // Image height in pixels
  sortOrder: number  // Display sort order
  sourceImageId: string | null
  file: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string  // Original file name
    mimeType: string  // MIME type (e.g. image/jpeg)
    size: number  // File size in bytes
    blobKey: string  // Blob key within Azure container
    container: string  // Azure Blob Storage container name
    url: string | null  // Public or SAS URL
    uploadedById: string | null
  } | null
  variants: any[]
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/image.create' \
  -H 'Content-Type: application/json' \
  -d '{"fileId":"string","talentId":"string"}'
Test Endpoint
Optional fields (click to add):
variant imageBrand width height sortOrder
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Image image.update
Images

Updates an existing image

Input Schema
TypeScript
{
  width?: number | null  // Image width in pixels
  height?: number | null  // Image height in pixels
  sortOrder?: number  // Display sort order
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  fileId: string  // Unique identifier
  talentId: string  // Unique identifier
  variant: "Original" | "Thumbnail" | "Large"
  imageBrand: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean" | null
  status: "Processing" | "Completed" | "Failed"
  errorMessage: string | null
  width: number | null  // Image width in pixels
  height: number | null  // Image height in pixels
  sortOrder: number  // Display sort order
  sourceImageId: string | null
  file: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string  // Original file name
    mimeType: string  // MIME type (e.g. image/jpeg)
    size: number  // File size in bytes
    blobKey: string  // Blob key within Azure container
    container: string  // Azure Blob Storage container name
    url: string | null  // Public or SAS URL
    uploadedById: string | null
  } | null
  variants: any[]
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/image.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
width height sortOrder
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Reorder Images image.reorder
Images

Batch-update sort order for a set of images

Input Schema
TypeScript
{
  orderedIds: string[]  // Image IDs in the desired display order
}
Output Schema
TypeScript
any[]
Code Examples
Shell
curl -X POST '{{BASE_URL}}/image.reorder' \
  -H 'Content-Type: application/json' \
  -d '{"orderedIds":["string"]}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Image Download URL image.downloadUrl
Images

Returns a short-lived SAS URL for downloading the original blob

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  url: string  // Short-lived SAS URL for downloading the blob
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/image.downloadUrl?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Reprocess Talent Images image.reprocessForTalent
Images

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.

Input Schema
TypeScript
{
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
{
  rendered: number  // Root images that got a missing brand
  skipped: number  // Roots skipped (no backing blob/uploader)
  failed: number  // Roots that errored during render/upload
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/image.reprocessForTalent' \
  -H 'Content-Type: application/json' \
  -d '{"talentId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Image image.delete
Images

Deletes an image and its variants from DB and blob storage

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  fileId: string  // Unique identifier
  talentId: string  // Unique identifier
  variant: "Original" | "Thumbnail" | "Large"
  imageBrand: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean" | null
  status: "Processing" | "Completed" | "Failed"
  errorMessage: string | null
  width: number | null  // Image width in pixels
  height: number | null  // Image height in pixels
  sortOrder: number  // Display sort order
  sourceImageId: string | null
  file: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string  // Original file name
    mimeType: string  // MIME type (e.g. image/jpeg)
    size: number  // File size in bytes
    blobKey: string  // Blob key within Azure container
    container: string  // Azure Blob Storage container name
    url: string | null  // Public or SAS URL
    uploadedById: string | null
  } | null
  variants: any[]
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/image.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Location

query
List Locations location.list
Locations

Returns the requesting company's locations

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  city: string | any  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName: string | null  // Hotel name (operator-only)
  unitNumber: string | null  // Unit / suite number
  street: string | null  // Street address
  province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null  // Province / territory
  postalCode: string | null  // Postal code (reported as stored)
  phoneNumberId: string | null  // Phone number record ID
  phoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  capacity: number  // Max talent scheduled per day
  arrivalInstructions1: string | null
  arrivalInstructions2: string | null
  emergencyPlan: string | null
  garbageLocation: string | null
  checkInInstructions: string | null
  checkOutInstructions: string | null
  safeLocation: string | null
  parkingInstructions: string | null
  wifi: string | null
  additionalInfo: string | null
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/location.list' \
  -H 'Content-Type: application/json'
Test Endpoint
query
List Locations for the Schedule Grid location.listForScheduleGrid
Locations

Returns every live location as a schedule-grid bucket (id, display name, city), ordered city-then-location, with no schedule entries. Condos past their move-out date are excluded (LUX-240) — an ended tenancy takes no new bookings; weeks where it has rows still show it via schedule.weekEntriesAdmin. Takes no date range: it is the same for every week, so the schedule page paints its location list before any week loads and keeps it across week switches. Pair with schedule.weekEntriesAdmin, which supplies that week's days.

Output Schema
TypeScript
Array<{
  locationId: string  // Unique identifier
  locationName: string  // Display name for the location (already formatted)
  city: string
  cityId: string  // City record ID (for reordering city sections)
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/location.listForScheduleGrid' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Get Location by ID location.byId
Locations

Returns a location by ID; 404 unless it belongs to the requesting company

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  city: string | any  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName: string | null  // Hotel name (operator-only)
  unitNumber: string | null  // Unit / suite number
  street: string | null  // Street address
  province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null  // Province / territory
  postalCode: string | null  // Postal code (reported as stored)
  phoneNumberId: string | null  // Phone number record ID
  phoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  capacity: number  // Max talent scheduled per day
  arrivalInstructions1: string | null
  arrivalInstructions2: string | null
  emergencyPlan: string | null
  garbageLocation: string | null
  checkInInstructions: string | null
  checkOutInstructions: string | null
  safeLocation: string | null
  parkingInstructions: string | null
  wifi: string | null
  additionalInfo: string | null
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/location.byId?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Location location.create
Locations

Creates a location owned by the requesting company

Input Schema
TypeScript
{
  city: string  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName?: string | null
  unitNumber?: string | null
  street?: string | null
  province?: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
  postalCode?: string | "" | null
  arrivalInstructions1?: string | null  // Arrival instructions — Location #1
  arrivalInstructions2?: string | null  // Arrival instructions — Location #2
  emergencyPlan?: string | null  // Emergency plan (shut-offs, electrical panel, …)
  garbageLocation?: string | null  // Where the garbage goes
  checkInInstructions?: string | null  // Check-in instructions
  checkOutInstructions?: string | null  // Check-out instructions
  safeLocation?: string | null  // Where the safe is
  parkingInstructions?: string | null  // Parking instructions
  wifi?: string | null  // WiFi network and password
  additionalInfo?: string | null  // Additional info
  houseGuidelines?: string[]  // House guidelines, in display order
  faq?: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  capacity?: number  // Max talent scheduled per day
  phoneNumberId?: string | null  // Phone number record ID
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  city: string | any  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName: string | null  // Hotel name (operator-only)
  unitNumber: string | null  // Unit / suite number
  street: string | null  // Street address
  province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null  // Province / territory
  postalCode: string | null  // Postal code (reported as stored)
  phoneNumberId: string | null  // Phone number record ID
  phoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  capacity: number  // Max talent scheduled per day
  arrivalInstructions1: string | null
  arrivalInstructions2: string | null
  emergencyPlan: string | null
  garbageLocation: string | null
  checkInInstructions: string | null
  checkOutInstructions: string | null
  safeLocation: string | null
  parkingInstructions: string | null
  wifi: string | null
  additionalInfo: string | null
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/location.create' \
  -H 'Content-Type: application/json' \
  -d '{"city":"string","name":"string","category":"Hotel"}'
Test Endpoint
Optional fields (click to add):
hotelName unitNumber street province postalCode arrivalInstructions1 arrivalInstructions2 emergencyPlan garbageLocation checkInInstructions checkOutInstructions safeLocation parkingInstructions wifi additionalInfo houseGuidelines faq capacity phoneNumberId
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Reorder Locations location.reorder
Locations

Batch-update the display order of locations within a city for the requesting company

Input Schema
TypeScript
{
  orderedIds: string[]  // Location IDs in the desired display order (within one city)
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  city: string | any  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName: string | null  // Hotel name (operator-only)
  unitNumber: string | null  // Unit / suite number
  street: string | null  // Street address
  province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null  // Province / territory
  postalCode: string | null  // Postal code (reported as stored)
  phoneNumberId: string | null  // Phone number record ID
  phoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  capacity: number  // Max talent scheduled per day
  arrivalInstructions1: string | null
  arrivalInstructions2: string | null
  emergencyPlan: string | null
  garbageLocation: string | null
  checkInInstructions: string | null
  checkOutInstructions: string | null
  safeLocation: string | null
  parkingInstructions: string | null
  wifi: string | null
  additionalInfo: string | null
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
}>
Code Examples
Shell
curl -X POST '{{BASE_URL}}/location.reorder' \
  -H 'Content-Type: application/json' \
  -d '{"orderedIds":["string"]}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Location location.update
Locations

Updates a location owned by the requesting company

Input Schema
TypeScript
{
  city?: string  // City name
  name?: string  // Location name within the city
  category?: "Hotel" | "Airbnb" | "Condo"
  hotelName?: string | null
  unitNumber?: string | null
  street?: string | null
  province?: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null
  postalCode?: string | "" | null
  arrivalInstructions1?: string | null  // Arrival instructions — Location #1
  arrivalInstructions2?: string | null  // Arrival instructions — Location #2
  emergencyPlan?: string | null  // Emergency plan (shut-offs, electrical panel, …)
  garbageLocation?: string | null  // Where the garbage goes
  checkInInstructions?: string | null  // Check-in instructions
  checkOutInstructions?: string | null  // Check-out instructions
  safeLocation?: string | null  // Where the safe is
  parkingInstructions?: string | null  // Parking instructions
  wifi?: string | null  // WiFi network and password
  additionalInfo?: string | null  // Additional info
  houseGuidelines?: string[]  // House guidelines, in display order
  faq?: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  capacity?: number  // Max talent scheduled per day
  phoneNumberId?: string | null  // Phone number record ID
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  city: string | any  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName: string | null  // Hotel name (operator-only)
  unitNumber: string | null  // Unit / suite number
  street: string | null  // Street address
  province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null  // Province / territory
  postalCode: string | null  // Postal code (reported as stored)
  phoneNumberId: string | null  // Phone number record ID
  phoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  capacity: number  // Max talent scheduled per day
  arrivalInstructions1: string | null
  arrivalInstructions2: string | null
  emergencyPlan: string | null
  garbageLocation: string | null
  checkInInstructions: string | null
  checkOutInstructions: string | null
  safeLocation: string | null
  parkingInstructions: string | null
  wifi: string | null
  additionalInfo: string | null
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/location.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
city name category hotelName unitNumber street province postalCode arrivalInstructions1 arrivalInstructions2 emergencyPlan garbageLocation checkInInstructions checkOutInstructions safeLocation parkingInstructions wifi additionalInfo houseGuidelines faq capacity phoneNumberId
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
End Location Tenancy location.endTenancy
Locations

Ends a condo's tenancy at a move-out date, or resumes it with null — a dated deactivation, never a delete (D104). Condo only: Airbnb/Hotel are always active

Input Schema
TypeScript
{
  id: string  // UUID identifier
  tenancyEndedAt: any | null  // Move-out date (YYYY-MM-DD), or null to resume the tenancy
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  city: string | any  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName: string | null  // Hotel name (operator-only)
  unitNumber: string | null  // Unit / suite number
  street: string | null  // Street address
  province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null  // Province / territory
  postalCode: string | null  // Postal code (reported as stored)
  phoneNumberId: string | null  // Phone number record ID
  phoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  capacity: number  // Max talent scheduled per day
  arrivalInstructions1: string | null
  arrivalInstructions2: string | null
  emergencyPlan: string | null
  garbageLocation: string | null
  checkInInstructions: string | null
  checkOutInstructions: string | null
  safeLocation: string | null
  parkingInstructions: string | null
  wifi: string | null
  additionalInfo: string | null
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/location.endTenancy' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string","tenancyEndedAt":"value"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List Emergency-Plan Media location.emergencyMedia
Locations

Returns a location's emergency-plan pictures/videos (LUX-212); scoped to the requesting company

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  file: {
    name: string  // Original file name
    mimeType: string  // MIME type (e.g. image/jpeg)
    url: string | null  // Public blob URL
  }
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/location.emergencyMedia?input=%7B%22locationId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Emergency-Plan Media location.deleteEmergencyMedia
Locations

Deletes one emergency-plan picture/video, including its blob; 404 unless its location belongs to the requesting company

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  file: {
    name: string  // Original file name
    mimeType: string  // MIME type (e.g. image/jpeg)
    url: string | null  // Public blob URL
  }
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/location.deleteEmergencyMedia' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Location location.delete
Locations

Deletes a location owned by the requesting company

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  city: string | any  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName: string | null  // Hotel name (operator-only)
  unitNumber: string | null  // Unit / suite number
  street: string | null  // Street address
  province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null  // Province / territory
  postalCode: string | null  // Postal code (reported as stored)
  phoneNumberId: string | null  // Phone number record ID
  phoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  capacity: number  // Max talent scheduled per day
  arrivalInstructions1: string | null
  arrivalInstructions2: string | null
  emergencyPlan: string | null
  garbageLocation: string | null
  checkInInstructions: string | null
  checkOutInstructions: string | null
  safeLocation: string | null
  parkingInstructions: string | null
  wifi: string | null
  additionalInfo: string | null
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/location.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Merge Locations location.merge
Locations

Folds one location into another while imported duplicates are cleaned up (LUX-265): every schedule, note, cost and expense on `mergeLocationId` moves to `keepLocationId`, then the retired location is soft-deleted so finance keeps its history. A schedule day the same talent already has at the survivor keeps the survivor's daily report and takes the retired day's bookings; a fixed-cost month or expense allocation held by both is summed. NOT_FOUND unless both are live locations of the requesting company

Input Schema
TypeScript
{
  keepLocationId: string  // The location that survives
  mergeLocationId: string  // The location that is retired
}
Output Schema
TypeScript
{
  keptName: string  // The location that survived
  retiredName: string  // The location that is now deleted
  schedulesMoved: number  // Schedule days moved to the surviving location
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/location.merge' \
  -H 'Content-Type: application/json' \
  -d '{"keepLocationId":"string","mergeLocationId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List Deleted Locations location.listDeleted
Locations

The requesting company's soft-deleted locations, recoverable via location.restore (LUX-203)

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  city: string | any  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName: string | null  // Hotel name (operator-only)
  unitNumber: string | null  // Unit / suite number
  street: string | null  // Street address
  province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null  // Province / territory
  postalCode: string | null  // Postal code (reported as stored)
  phoneNumberId: string | null  // Phone number record ID
  phoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  capacity: number  // Max talent scheduled per day
  arrivalInstructions1: string | null
  arrivalInstructions2: string | null
  emergencyPlan: string | null
  garbageLocation: string | null
  checkInInstructions: string | null
  checkOutInstructions: string | null
  safeLocation: string | null
  parkingInstructions: string | null
  wifi: string | null
  additionalInfo: string | null
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
  deletedAt: string | any  // When the location was deleted
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/location.listDeleted' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Restore Location location.restore
Locations

Restores a soft-deleted location owned by the requesting company (LUX-203); NOT_FOUND when the id is not deleted or not owned

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  city: string | any  // City name
  name: string  // Location name within the city
  category: "Hotel" | "Airbnb" | "Condo"
  hotelName: string | null  // Hotel name (operator-only)
  unitNumber: string | null  // Unit / suite number
  street: string | null  // Street address
  province: "AB" | "BC" | "MB" | "NB" | "NL" | "NS" | "NT" | "NU" | "ON" | "PE" | "QC" | "SK" | "YT" | null  // Province / territory
  postalCode: string | null  // Postal code (reported as stored)
  phoneNumberId: string | null  // Phone number record ID
  phoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  capacity: number  // Max talent scheduled per day
  arrivalInstructions1: string | null
  arrivalInstructions2: string | null
  emergencyPlan: string | null
  garbageLocation: string | null
  checkInInstructions: string | null
  checkOutInstructions: string | null
  safeLocation: string | null
  parkingInstructions: string | null
  wifi: string | null
  additionalInfo: string | null
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>  // FAQ question/answer pairs, in display order
  tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/location.restore' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

LocationFixedCost

query
Get Location Fixed Costs locationFixedCost.byPeriod
LocationFixedCost

A location's operating costs for a month (YYYY-MM), or null when none are set

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
  period: string  // Period in YYYY-MM format
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  locationId: string  // Owning location ID
  period: string  // Period in YYYY-MM format
  rent: number  // Amount in whole dollars
  utilities: number  // Amount in whole dollars
  internet: number  // Amount in whole dollars
  insurance: number  // Amount in whole dollars
  cleaning: number  // Amount in whole dollars
  supplies: number  // Amount in whole dollars
  misc: number  // Amount in whole dollars
} | null
Code Examples
Shell
curl -X GET '{{BASE_URL}}/locationFixedCost.byPeriod?input=%7B%22locationId%22%3A%22string%22%2C%22period%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Latest Fixed Costs (excluding a month) locationFixedCost.latest
LocationFixedCost

The nearest month with costs — the most recent one before the given month, or failing that the nearest later one (backfill) — the source for "copy latest month"; null when no other month has costs

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
  period: string  // Period in YYYY-MM format
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  locationId: string  // Owning location ID
  period: string  // Period in YYYY-MM format
  rent: number  // Amount in whole dollars
  utilities: number  // Amount in whole dollars
  internet: number  // Amount in whole dollars
  insurance: number  // Amount in whole dollars
  cleaning: number  // Amount in whole dollars
  supplies: number  // Amount in whole dollars
  misc: number  // Amount in whole dollars
} | null
Code Examples
Shell
curl -X GET '{{BASE_URL}}/locationFixedCost.latest?input=%7B%22locationId%22%3A%22string%22%2C%22period%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Save Location Fixed Costs locationFixedCost.save
LocationFixedCost

Upserts a month's operating costs; 404 unless the location belongs to the requesting company

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
  period: string  // Period in YYYY-MM format
  rent: number  // Amount in whole dollars
  utilities: number  // Amount in whole dollars
  internet: number  // Amount in whole dollars
  insurance: number  // Amount in whole dollars
  cleaning: number  // Amount in whole dollars
  supplies: number  // Amount in whole dollars
  misc: number  // Amount in whole dollars
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  locationId: string  // Owning location ID
  period: string  // Period in YYYY-MM format
  rent: number  // Amount in whole dollars
  utilities: number  // Amount in whole dollars
  internet: number  // Amount in whole dollars
  insurance: number  // Amount in whole dollars
  cleaning: number  // Amount in whole dollars
  supplies: number  // Amount in whole dollars
  misc: number  // Amount in whole dollars
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/locationFixedCost.save' \
  -H 'Content-Type: application/json' \
  -d '{"locationId":"string","period":"string","rent":0,"utilities":0,"internet":0,"insurance":0,"cleaning":0,"supplies":0,"misc":0}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

LocationNote

query
Get Location Notes for a Week (Admin) locationNote.week
Location Notes

Returns the requesting company's location notes whose date falls in the window, scoped via location ownership.

Input Schema
TypeScript
{
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  locationId: string  // Unique identifier
  date: string | any  // Note date
  text: string  // Note text
  createdByName: string | null  // Display name of the user who wrote it; null for a legacy row
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/locationNote.week?input=%7B%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Location Note History for a Day (Admin) locationNote.history
Location Notes

Every add, edit and delete a location's day has seen — including notes that were deleted. Newest first, scoped via location ownership.

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
  date: any  // Note date
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  noteId: string  // Unique identifier
  action: "Created" | "Updated" | "Deleted"  // What happened to the note
  text: string  // Note text
  createdByName: string | null  // Display name of the user who wrote it; null for a legacy row
  createdAt: string | any  // When the change was made
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/locationNote.history?input=%7B%22locationId%22%3A%22string%22%2C%22date%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Location Note locationNote.create
Location Notes

Creates a note pinned to one of the requesting company's locations on a specific day.

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
  date: any  // Note date
  text: string  // Note text
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  locationId: string  // Unique identifier
  date: string | any  // Note date
  text: string  // Note text
  createdByName: string | null  // Display name of the user who wrote it; null for a legacy row
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/locationNote.create' \
  -H 'Content-Type: application/json' \
  -d '{"locationId":"string","date":"value","text":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Location Note locationNote.update
Location Notes

Updates a note on one of the requesting company's locations.

Input Schema
TypeScript
{
  text?: string  // Note text
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  locationId: string  // Unique identifier
  date: string | any  // Note date
  text: string  // Note text
  createdByName: string | null  // Display name of the user who wrote it; null for a legacy row
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/locationNote.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
text
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Location Note locationNote.delete
Location Notes

Deletes a note on one of the requesting company's locations.

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  locationId: string  // Unique identifier
  date: string | any  // Note date
  text: string  // Note text
  createdByName: string | null  // Display name of the user who wrote it; null for a legacy row
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/locationNote.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

LocationPnl

query
Location P&L locationPnl.byPeriod
LocationPnl

Per-location profit for a month on both bases — earned (Σ Due, incl. book-on) and cash (Σ Paid) — each less fixed costs, allocated expenses and booker pay, plus the off-roster reconciling line

Input Schema
TypeScript
{
  period: string  // Period in YYYY-MM format
}
Output Schema
TypeScript
{
  rows: Array<{
    locationId: string  // Unique identifier
    locationName: string
    city: string
    revenue: number  // Σ Due for the month — the FEE owed incl. book-on (D85)
    collectedCash: number  // Σ payments taken against the month's bookings — the client's Paid (D91/D98)
    fixedCosts: number  // Σ LocationFixedCost lines for the period
    allocatedExpenses: number  // Σ ExpenseAllocation.amount for the month
    bookerPay: number  // Σ the stamped Appointment.bookerPay for the month (D76/D91)
    profit: number  // Earned: revenue − fixedCosts − allocatedExpenses − bookerPay; negative in a loss month
    cashProfit: number  // Cash: collectedCash − the same expenses — the client's own Profit = Paid − Expenses (D91/D98)
  }>  // One row per location on the brand's books, for the month
  offRoster: {
    revenue: number  // Σ Due for the month — the FEE owed incl. book-on (D85)
    collectedCash: number  // Σ payments taken against the month's bookings — the client's Paid (D91/D98)
    fixedCosts: number  // Σ LocationFixedCost lines for the period
    allocatedExpenses: number  // Σ ExpenseAllocation.amount for the month
    bookerPay: number  // Σ the stamped Appointment.bookerPay for the month (D76/D91)
    profit: number  // Earned: revenue − fixedCosts − allocatedExpenses − bookerPay; negative in a loss month
    cashProfit: number  // Cash: collectedCash − the same expenses — the client's own Profit = Paid − Expenses (D91/D98)
  }  // Σ the money of the locations the roster omits — the reconciling line (D91)
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/locationPnl.byPeriod?input=%7B%22period%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Menu

MenuService

Notification

query
List Notifications notification.list
Notification

One page of the signed-in user’s notifications, newest first.

Input Schema
TypeScript
{
  page: number  // 1-based page number
  pageSize: number  // Rows per page
}
Output Schema
TypeScript
{
  items: Array<{
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    type: "SmsReceived" | "TalentChangeRequested" | "BookingCreated" | "Announcement" | "TalentChangeDecided"
    entityId: string  // Id of the entity the type points at, e.g. an SMS thread
    title: string  // Snapshot taken when the event happened
    body: string | null
    readAt: string | any | null  // Null while unread
  }>
  total: number  // Rows matching the query, across all pages
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/notification.list?input=%7B%22page%22%3A0%2C%22pageSize%22%3A0%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Read One Notification notification.byId
Notification

One of the signed-in user's notifications by id — null for anyone else's.

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  type: "SmsReceived" | "TalentChangeRequested" | "BookingCreated" | "Announcement" | "TalentChangeDecided"
  entityId: string  // Id of the entity the type points at, e.g. an SMS thread
  title: string  // Snapshot taken when the event happened
  body: string | null
  readAt: string | any | null  // Null while unread
} | null
Code Examples
Shell
curl -X GET '{{BASE_URL}}/notification.byId?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Count Unread Notifications notification.unreadCount
Notification

How many notifications the signed-in user has not read.

Output Schema
TypeScript
{
  count: number
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/notification.unreadCount' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Mark a Notification Read notification.markRead
Notification

Marks one of the signed-in user’s notifications read. Idempotent.

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
any
Code Examples
Shell
curl -X POST '{{BASE_URL}}/notification.markRead' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Mark All Notifications Read notification.markAllRead
Notification

Marks every unread notification of the signed-in user.

Output Schema
TypeScript
any
Code Examples
Shell
curl -X POST '{{BASE_URL}}/notification.markAllRead' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Web Push Public Key notification.pushPublicKey
Notification

VAPID public key the browser subscribes under; null while web push is unconfigured.

Output Schema
TypeScript
{
  publicKey: string | null
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/notification.pushPublicKey' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Subscribe Web Push notification.subscribePush
Notification

Registers this browser’s push subscription for the signed-in user. Idempotent per endpoint.

Input Schema
TypeScript
{
  endpoint: string
  keys: {
    p256dh: string
    auth: string
  }
}
Output Schema
TypeScript
any
Code Examples
Shell
curl -X POST '{{BASE_URL}}/notification.subscribePush' \
  -H 'Content-Type: application/json' \
  -d '{"endpoint":"string","keys":{"p256dh":"string","auth":"string"}}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Unsubscribe Web Push notification.unsubscribePush
Notification

Removes this browser’s push subscription. Another user’s endpoint is a silent no-op.

Input Schema
TypeScript
{
  endpoint: string
}
Output Schema
TypeScript
any
Code Examples
Shell
curl -X POST '{{BASE_URL}}/notification.unsubscribePush' \
  -H 'Content-Type: application/json' \
  -d '{"endpoint":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Send a Test Push notification.sendTestPush
Notification

Fires one diagnostic web push at every device the user has subscribed — no notification row, no gates. The counts say which leg failed.

Input Schema
TypeScript
{
  userId: string  // Unique identifier
}
Output Schema
TypeScript
{
  configured: boolean  // False while VAPID env is unset
  devices: number  // Push subscriptions the user has
  delivered: number  // Sends the push service accepted
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/notification.sendTestPush' \
  -H 'Content-Type: application/json' \
  -d '{"userId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
subscription
Notification Stream notification.onNew
Notification

SSE stream that emits whenever the signed-in user gets a notification.

Code Examples
Shell
curl -X POST '{{BASE_URL}}/notification.onNew' \
  -H 'Content-Type: application/json'
Test Endpoint

Payment

query
Payments by Appointment payment.byAppointment
Payment

An appointment's recorded payment lines (the Payments card) — one or many per appointment, e.g. an e-transfer + cash split

Input Schema
TypeScript
{
  appointmentId: string  // UUID identifier
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  appointmentId: string  // Unique identifier
  method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare"
  amount: number  // Whole dollars collected
  isDeposit: boolean  // A recorded deposit; the balance is settled later
  emtSenderName: string | null  // The name the e-transfer came under — null on non-EMT lines and on EMT lines where it was not keyed
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/payment.byAppointment?input=%7B%22appointmentId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Record Payment payment.create
Payment

Records a payment line against an appointment. Only the first line may be a deposit; the client comes from the appointment, never sent

Input Schema
TypeScript
{
  appointmentId: string  // UUID identifier
  method: "EMT" | "AmazonGiftCard" | "Cash"
  amount: number  // Whole dollars collected
  isDeposit: boolean
  emtSenderName?: string  // The name the e-transfer came under
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  appointmentId: string  // Unique identifier
  method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare"
  amount: number  // Whole dollars collected
  isDeposit: boolean  // A recorded deposit; the balance is settled later
  emtSenderName: string | null  // The name the e-transfer came under — null on non-EMT lines and on EMT lines where it was not keyed
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/payment.create' \
  -H 'Content-Type: application/json' \
  -d '{"appointmentId":"string","method":"EMT","amount":0,"isDeposit":true}'
Test Endpoint
Optional fields (click to add):
emtSenderName
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Record Payment on a Day payment.createForSchedule
Payment

Records the talent's day envelope — cash or e-transfer for the whole day — against a schedule-day (LUX-206, LUX-340), whether or not the day has bookings; a client's own payment for a call goes on the call via Record Payment. The day's carrier booking is found-or-created (the import's money-only-day rule) and the line lands on it; carriers are skipped by every call count

Input Schema
TypeScript
{
  scheduleId: string  // UUID identifier
  method: "Cash" | "EMT"
  amount: number  // Whole dollars collected
  emtSenderName?: string  // The name the e-transfer came under
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  appointmentId: string  // Unique identifier
  method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare"
  amount: number  // Whole dollars collected
  isDeposit: boolean  // A recorded deposit; the balance is settled later
  emtSenderName: string | null  // The name the e-transfer came under — null on non-EMT lines and on EMT lines where it was not keyed
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/payment.createForSchedule' \
  -H 'Content-Type: application/json' \
  -d '{"scheduleId":"string","method":"Cash","amount":0}'
Test Endpoint
Optional fields (click to add):
emtSenderName
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Payment payment.delete
Payment

Removes a payment line

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/payment.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Payroll

query
My Payroll payroll.me
Payroll

The requesting user's own payroll: their booker Mon–Sun weeks (same aggregation as the admin Booker Payroll screen, filtered to them) and the expenses tagged to their payroll — never anyone else's

Output Schema
TypeScript
{
  weeks: Array<{
    userId: string  // Unique identifier
    bookerName: string  // Booker's display name
    weekStart: string | any  // The week's Monday (D77)
    weekEnd: string | any  // The week's Sunday
    calls: number  // Booked appointments credited to her this week (cancelled ones excluded, D95)
    amount: number  // Σ the stamped bookerPay for those calls, plus the week cancellation fees (D76/D95)
    cancellationPay: number  // The part of `amount` that came from kept cancellation fees rather than calls (D95)
    paidOn: string | any | null  // The day she was paid; null until the week is confirmed
    paidAmount: number | null  // What was paid, snapshotted at confirm; null until confirmed
  }>  // The requesting user’s own booker weeks, most recent first
  expenses: Array<{
    id: string  // Unique identifier
    amount: number
    category: "Admin" | "Cleaning" | "Photoshoot" | "Marketing" | "Owner" | "Supplies" | "InitialSetup" | "Accommodation"
    incurredOn: string | any  // Date in YYYY-MM-DD format
    note: string | null
    payrollUserId: string | null  // Counts toward this user's payroll (LUX-214); null = nobody's
    allocations: Array<{
      locationId: string  // Unique identifier
      locationName: string
      city: string
      category: "Hotel" | "Airbnb" | "Condo"  // Venue type — an Accommodation at a hotel/Airbnb is a stay (LUX-316)
      amount: number
    }>
    stay: {
      scheduleId: string  // Unique identifier
      talentId: string  // Unique identifier
      talentName: string
      date: string | any  // Date in YYYY-MM-DD format
      bookOn: number
    } | null  // The first-day report this room bill charges, or null — an Accommodation at a hotel with no stay charges no talent
  }>  // Expenses tagged to the requesting user’s payroll, newest first
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/payroll.me' \
  -H 'Content-Type: application/json'
Test Endpoint

PhoneNumber

query
List Phone Numbers phoneNumber.list
Phone Numbers

Returns all phone numbers

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string | null
  number: string  // Phone number
  usedForMessages: boolean  // Whether this number is used for messages
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/phoneNumber.list' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Get Phone Number by ID phoneNumber.getById
Phone Numbers

Returns a phone number by ID

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string | null
  number: string  // Phone number
  usedForMessages: boolean  // Whether this number is used for messages
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/phoneNumber.getById?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Phone Number phoneNumber.create
Phone Numbers

Creates a new phone number

Input Schema
TypeScript
{
  name?: string | null
  number: string  // Phone number (stored as 10 NANP national digits)
  usedForMessages?: boolean  // Whether this number is used for messages
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string | null
  number: string  // Phone number
  usedForMessages: boolean  // Whether this number is used for messages
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/phoneNumber.create' \
  -H 'Content-Type: application/json' \
  -d '{"number":"string"}'
Test Endpoint
Optional fields (click to add):
name usedForMessages
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Phone Number phoneNumber.update
Phone Numbers

Updates an existing phone number

Input Schema
TypeScript
{
  name?: string | null
  number?: string  // Phone number (stored as 10 NANP national digits)
  usedForMessages?: boolean  // Whether this number is used for messages
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string | null
  number: string  // Phone number
  usedForMessages: boolean  // Whether this number is used for messages
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/phoneNumber.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
name number usedForMessages
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Phone Number phoneNumber.delete
Phone Numbers

Deletes a phone number

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string | null
  number: string  // Phone number
  usedForMessages: boolean  // Whether this number is used for messages
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/phoneNumber.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Review

query
List Reviews by Talent review.byTalent
Reviews

Returns all reviews for a talent, newest first

Input Schema
TypeScript
{
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  talentId: string  // Unique identifier
  content: string  // Review content (rich-text HTML)
  createdByName: string | null  // Display name of admin who created the review
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/review.byTalent?input=%7B%22talentId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Review review.create
Reviews

Creates a new talent review

Input Schema
TypeScript
{
  talentId: string  // UUID identifier
  content: string  // Review content (rich-text HTML)
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  talentId: string  // Unique identifier
  content: string  // Review content (rich-text HTML)
  createdByName: string | null  // Display name of admin who created the review
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/review.create' \
  -H 'Content-Type: application/json' \
  -d '{"talentId":"string","content":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Review review.update
Reviews

Updates a review

Input Schema
TypeScript
{
  content: string  // Review content (rich-text HTML)
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  talentId: string  // Unique identifier
  content: string  // Review content (rich-text HTML)
  createdByName: string | null  // Display name of admin who created the review
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/review.update' \
  -H 'Content-Type: application/json' \
  -d '{"content":"string","id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Review review.delete
Reviews

Deletes a review

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  talentId: string  // Unique identifier
  content: string  // Review content (rich-text HTML)
  createdByName: string | null  // Display name of admin who created the review
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/review.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Schedule

query
Get Today's Schedules schedule.forToday
Schedules

Returns the requesting company's schedules for today with talent data

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  date: string | any  // Schedule date
  startTime: string | null  // Start time
  endTime: string | null  // End time
  location: {
    id: string  // Unique identifier
    city: string | any  // City name
    name: string  // Location name within the city
    phoneNumberId: string | null  // Phone number record ID
    phoneNumber?: {
      id: string  // Unique identifier
      name: string | null
      number: string  // Phone number
      usedForMessages: boolean  // Whether this number is used for messages
    } | null
    tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
    deletedAt: string | any | null
  }
  talentId: string  // Unique identifier
  talent: {
    id: string  // Unique identifier
    nickname: string
  }
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.forToday?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Visiting Soon schedule.visitingSoon
Schedules

Returns pre-grouped visiting-soon entries (next 60 days)

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  talentId: string  // Unique identifier
  nickname: string
  city: string
  dateLabel: string  // Formatted date range, e.g. "Mar.16-22"
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.visitingSoon?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Schedules by Date Range schedule.byDateRange
Schedules

Returns the requesting company's schedules in a date range with talent and location data

Input Schema
TypeScript
{
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  date: string | any  // Schedule date
  startTime: string | null  // Start time
  endTime: string | null  // End time
  location: {
    id: string  // Unique identifier
    city: string | any  // City name
    name: string  // Location name within the city
    phoneNumberId: string | null  // Phone number record ID
    phoneNumber?: {
      id: string  // Unique identifier
      name: string | null
      number: string  // Phone number
      usedForMessages: boolean  // Whether this number is used for messages
    } | null
    tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
    deletedAt: string | any | null
  }
  talentId: string  // Unique identifier
  talent: {
    id: string  // Unique identifier
    nickname: string
  }
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.byDateRange?input=%7B%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Week Grid (Public) schedule.weekGrid
Schedules

Returns a week of the requesting company's schedules pre-grouped by city → location → date. Drops soft-deleted-location rows.

Input Schema
TypeScript
{
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  city: string
  locations: Array<{
    locationId: string  // Unique identifier
    locationName: string  // Display name for the location (already formatted)
    deleted: boolean  // Always `false` on the public path (filtered server-side)
    days: Array<{
      date: string | any  // Date in YYYY-MM-DD format
      entries: Array<{
        id: string  // Unique identifier
        locationId: string  // Unique identifier
        date: string | any  // Schedule date
        startTime: string | null  // Start time
        endTime: string | null  // End time
        location: {
          id: string  // Unique identifier
          city: string | any  // City name
          name: string  // Location name within the city
          phoneNumberId: string | null  // Phone number record ID
          phoneNumber?: {
            id: string  // Unique identifier
            name: string | null
            number: string  // Phone number
            usedForMessages: boolean  // Whether this number is used for messages
          } | null
          tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
          deletedAt: string | any | null
        }
        talentId: string  // Unique identifier
        talent: {
          id: string  // Unique identifier
          nickname: string
        }
      }>
    }>
  }>
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.weekGrid?input=%7B%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Schedules by Talent schedule.byTalent
Schedules

Returns all schedules for a talent

Input Schema
TypeScript
{
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  date: string | any  // Schedule date
  startTime: string | null  // Start time
  endTime: string | null  // End time
  notes: string | null  // Optional notes
  location: {
    id: string  // Unique identifier
    city: string | any  // City name
    name: string  // Location name within the city
    phoneNumberId: string | null  // Phone number record ID
    phoneNumber?: {
      id: string  // Unique identifier
      name: string | null
      number: string  // Phone number
      usedForMessages: boolean  // Whether this number is used for messages
    } | null
    tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
    deletedAt: string | any | null
  }
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.byTalent?input=%7B%22talentId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Schedules by Location schedule.byLocation
Schedules

Returns all schedules for a location

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  date: string | any  // Schedule date
  startTime: string | null  // Start time
  endTime: string | null  // End time
  notes: string | null  // Optional notes
  location: {
    id: string  // Unique identifier
    city: string | any  // City name
    name: string  // Location name within the city
    phoneNumberId: string | null  // Phone number record ID
    phoneNumber?: {
      id: string  // Unique identifier
      name: string | null
      number: string  // Phone number
      usedForMessages: boolean  // Whether this number is used for messages
    } | null
    tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
    deletedAt: string | any | null
  }
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.byLocation?input=%7B%22locationId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Week Entries (Admin) schedule.weekEntriesAdmin
Schedules

Returns a week's schedule entries bucketed by date, one bucket per POPULATED location — the locations without rows come from location.listForScheduleGrid. Soft-deleted locations appear only when they have rows in the window (flagged deleted), carrying their city so the client can place them.

Input Schema
TypeScript
{
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  locationId: string  // Unique identifier
  locationName: string  // Display name for the location (already formatted)
  city: string
  cityId: string  // City record ID (for reordering city sections)
  deleted: boolean  // True when the location is soft-deleted (has rows in window)
  days: Array<{
    date: string | any  // Date in YYYY-MM-DD format
    entries: Array<{
      id: string  // Unique identifier
      locationId: string  // Unique identifier
      date: string | any  // Schedule date
      startTime: string | null  // Start time
      endTime: string | null  // End time
      notes: string | null  // Optional notes
      location: {
        id: string  // Unique identifier
        city: string | any  // City name
        name: string  // Location name within the city
        phoneNumberId: string | null  // Phone number record ID
        phoneNumber?: {
          id: string  // Unique identifier
          name: string | null
          number: string  // Phone number
          usedForMessages: boolean  // Whether this number is used for messages
        } | null
        tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
        deletedAt: string | any | null
      }
      talentId: string  // Unique identifier
      talent: {
        id: string  // Unique identifier
        nickname: string
      }
    }>
  }>
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.weekEntriesAdmin?input=%7B%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Week Booking Counts (Admin) schedule.weekBookingsAdmin
Schedules

How booked each scheduled day in the window is: the live calls actually taken on it, and what the talent's history says to expect there. One row per schedule, keyed by `scheduleId` so it joins onto schedule.weekEntriesAdmin. `expected` is null for a talent who has never worked — an absence, not a forecast of none.

Input Schema
TypeScript
{
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  scheduleId: string  // Unique identifier
  booked: number  // Live calls on this scheduled day; cancelled ones excluded
  expected: number | null  // Her average for this weekday, null when she has no history
  basis: "weekday" | "overall"  // Which average `expected` came from — 'overall' is the fallback
  sampleDays: number  // Days worked behind `expected` — the reference point it needs
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.weekBookingsAdmin?input=%7B%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Location Booking History (Admin) schedule.locationHistoryAdmin
Schedules

A location's all-time booking history: every talent who has worked it with her calls-per-day there, best first, and each weekday's norm (null under three samples — an absence, not a norm of zero). Feeds the schedule grid's day hover card.

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
}
Output Schema
TypeScript
{
  talent: Array<{
    talentId: string  // Unique identifier
    nickname: string  // Talent display name
    avgHere: number  // Calls per day worked at this location, all time
    daysHere: number  // Days worked at this location
  }>  // Everyone who has worked here, best average first
  weekdays: Array<{
    weekday: number  // Day of week, 0 = Sunday
    avg: number | null  // Calls this location takes on this weekday, null under 3 samples
    sampleDays: number  // Distinct dates of this weekday behind `avg`
  }>  // All seven weekdays, zero-filled
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.locationHistoryAdmin?input=%7B%22locationId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Location Ranking (Admin) schedule.locationRankingAdmin
Schedules

Every location that has ever been staffed, ranked by all-time calls per staffed calendar date, best first. Feeds the Talent dashboard location list; pair with schedule.locationHistoryAdmin for one location’s detail.

Output Schema
TypeScript
Array<{
  locationId: string  // Unique identifier
  name: string  // Location display name
  avgPerDay: number  // Calls per staffed calendar date here, all time
  daysWorked: number  // Distinct calendar dates anyone worked here
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.locationRankingAdmin' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Get Schedules by Date Range (Admin) schedule.byDateRangeAll
Schedules

Returns the selected company's schedules in a date range (admin; location-ownership, no roster gate)

Input Schema
TypeScript
{
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  date: string | any  // Schedule date
  startTime: string | null  // Start time
  endTime: string | null  // End time
  notes: string | null  // Optional notes
  location: {
    id: string  // Unique identifier
    city: string | any  // City name
    name: string  // Location name within the city
    phoneNumberId: string | null  // Phone number record ID
    phoneNumber?: {
      id: string  // Unique identifier
      name: string | null
      number: string  // Phone number
      usedForMessages: boolean  // Whether this number is used for messages
    } | null
    tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
    deletedAt: string | any | null
  }
  talentId: string  // Unique identifier
  talent: {
    id: string  // Unique identifier
    nickname: string
  }
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/schedule.byDateRangeAll?input=%7B%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Schedule schedule.create
Schedules

Creates a new schedule

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
  date: any  // Schedule date
  startTime?: string | null  // Start time
  endTime?: string | null  // End time
  notes?: string | null  // Optional notes
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  date: string | any  // Schedule date
  startTime: string | null  // Start time
  endTime: string | null  // End time
  notes: string | null  // Optional notes
  location: {
    id: string  // Unique identifier
    city: string | any  // City name
    name: string  // Location name within the city
    phoneNumberId: string | null  // Phone number record ID
    phoneNumber?: {
      id: string  // Unique identifier
      name: string | null
      number: string  // Phone number
      usedForMessages: boolean  // Whether this number is used for messages
    } | null
    tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
    deletedAt: string | any | null
  }
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/schedule.create' \
  -H 'Content-Type: application/json' \
  -d '{"locationId":"string","date":"value","talentId":"string"}'
Test Endpoint
Optional fields (click to add):
startTime endTime notes
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Upsert Schedule schedule.upsert
Schedules

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.

Input Schema
TypeScript
{
  locationId: string  // UUID identifier
  date: any  // Schedule date
  startTime?: string | null  // Start time
  endTime?: string | null  // End time
  notes?: string | null  // Optional notes
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
{
  created: boolean  // True when a new schedule row was created
  schedule: {
    id: string  // Unique identifier
    locationId: string  // Unique identifier
    date: string | any  // Schedule date
    startTime: string | null  // Start time
    endTime: string | null  // End time
    notes: string | null  // Optional notes
    location: {
      id: string  // Unique identifier
      city: string | any  // City name
      name: string  // Location name within the city
      phoneNumberId: string | null  // Phone number record ID
      phoneNumber?: {
        id: string  // Unique identifier
        name: string | null
        number: string  // Phone number
        usedForMessages: boolean  // Whether this number is used for messages
      } | null
      tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
      deletedAt: string | any | null
    }
  }
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/schedule.upsert' \
  -H 'Content-Type: application/json' \
  -d '{"locationId":"string","date":"value","talentId":"string"}'
Test Endpoint
Optional fields (click to add):
startTime endTime notes
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Schedule schedule.update
Schedules

Updates an existing schedule. Passing `talentId` re-points the day to another talent (LUX-188) — its appointments and money hang off the schedule, so they follow. Rejects a re-point onto an occupied (talent, location, date) with CONFLICT rather than merging two days.

Input Schema
TypeScript
{
  talentId?: string  // UUID identifier
  locationId?: string  // UUID identifier
  date?: any  // Schedule date
  startTime?: string | null  // Start time
  endTime?: string | null  // End time
  notes?: string | null  // Optional notes
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  date: string | any  // Schedule date
  startTime: string | null  // Start time
  endTime: string | null  // End time
  notes: string | null  // Optional notes
  location: {
    id: string  // Unique identifier
    city: string | any  // City name
    name: string  // Location name within the city
    phoneNumberId: string | null  // Phone number record ID
    phoneNumber?: {
      id: string  // Unique identifier
      name: string | null
      number: string  // Phone number
      usedForMessages: boolean  // Whether this number is used for messages
    } | null
    tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
    deletedAt: string | any | null
  }
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/schedule.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
talentId locationId date startTime endTime notes
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Schedule schedule.delete
Schedules

Deletes a schedule

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  locationId: string  // Unique identifier
  date: string | any  // Schedule date
  startTime: string | null  // Start time
  endTime: string | null  // End time
  notes: string | null  // Optional notes
  location: {
    id: string  // Unique identifier
    city: string | any  // City name
    name: string  // Location name within the city
    phoneNumberId: string | null  // Phone number record ID
    phoneNumber?: {
      id: string  // Unique identifier
      name: string | null
      number: string  // Phone number
      usedForMessages: boolean  // Whether this number is used for messages
    } | null
    tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
    deletedAt: string | any | null
  }
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/schedule.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Service

query
List Services service.list
Services

Returns all services with talent counts

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  name: string  // Service name
  createdAt: string | any  // Record creation timestamp
  talentCount: number  // Number of talent profiles using this service
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/service.list' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Get Service by ID service.byId
Services

Returns a service by ID

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  name: string  // Service name
  createdAt: string | any  // Record creation timestamp
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/service.byId?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Service service.create
Services

Creates a new service

Input Schema
TypeScript
{
  name: string  // Service name
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  name: string  // Service name
  createdAt: string | any  // Record creation timestamp
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/service.create' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Service service.update
Services

Updates a service

Input Schema
TypeScript
{
  name?: string  // Service name
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  name: string  // Service name
  createdAt: string | any  // Record creation timestamp
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/service.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
name
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Service service.delete
Services

Deletes a service

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  name: string  // Service name
  createdAt: string | any  // Record creation timestamp
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/service.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

MessageRewrite

query
List Message Rewrites messageRewrite.list
Message Rewrites

Returns all message rewrite rules

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  word: string | null
  replacement: string  // Carrier-safe text sent in its place
  serviceId: string | null  // Linked service, if any
  createdAt: string | any  // Record creation timestamp
  service: {
    id: string  // UUID identifier
    name: string
  } | null  // Linked service whose current name is the matched word
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/messageRewrite.list' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Get Message Rewrite by ID messageRewrite.byId
Message Rewrites

Returns a message rewrite rule by ID

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  word: string | null
  replacement: string  // Carrier-safe text sent in its place
  serviceId: string | null  // Linked service, if any
  createdAt: string | any  // Record creation timestamp
  service: {
    id: string  // UUID identifier
    name: string
  } | null  // Linked service whose current name is the matched word
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/messageRewrite.byId?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Message Rewrite messageRewrite.create
Message Rewrites

Creates a new message rewrite rule

Input Schema
TypeScript
{
  word?: string | null
  replacement: string  // Carrier-safe text sent in its place
  serviceId?: string | null
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  word: string | null
  replacement: string  // Carrier-safe text sent in its place
  serviceId: string | null  // Linked service, if any
  createdAt: string | any  // Record creation timestamp
  service: {
    id: string  // UUID identifier
    name: string
  } | null  // Linked service whose current name is the matched word
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/messageRewrite.create' \
  -H 'Content-Type: application/json' \
  -d '{"replacement":"string"}'
Test Endpoint
Optional fields (click to add):
word serviceId
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Message Rewrite messageRewrite.update
Message Rewrites

Updates a message rewrite rule

Input Schema
TypeScript
{
  word?: string | null
  replacement: string  // Carrier-safe text sent in its place
  serviceId?: string | null
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  word: string | null
  replacement: string  // Carrier-safe text sent in its place
  serviceId: string | null  // Linked service, if any
  createdAt: string | any  // Record creation timestamp
  service: {
    id: string  // UUID identifier
    name: string
  } | null  // Linked service whose current name is the matched word
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/messageRewrite.update' \
  -H 'Content-Type: application/json' \
  -d '{"replacement":"string","id":"string"}'
Test Endpoint
Optional fields (click to add):
word serviceId
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Message Rewrite messageRewrite.delete
Message Rewrites

Deletes a message rewrite rule

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  word: string | null
  replacement: string  // Carrier-safe text sent in its place
  serviceId: string | null  // Linked service, if any
  createdAt: string | any  // Record creation timestamp
  service: {
    id: string  // UUID identifier
    name: string
  } | null  // Linked service whose current name is the matched word
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/messageRewrite.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Sms

query
List SMS Messages sms.list
SMS

One page of SMS messages, newest first, optionally filtered to one of our lines or one client. Renders both the inbox and a single thread.

Input Schema
TypeScript
{
  page: number  // 1-based page number
  pageSize: number  // Rows per page
  phoneNumberId?: string  // Only messages on this line of ours
  clientId?: string  // Only messages with this client
}
Output Schema
TypeScript
{
  items: Array<{
    id: string  // Unique identifier
    threadId: string  // The conversation it belongs to. Read it off a reply rather than assuming: a send after a number change opens the thread the answer will arrive in.
    direction: "Inbound" | "Outbound"
    status: "Received" | "Queued" | "Sent" | "Delivered" | "Undelivered" | "Failed"
    errorCode: number | null  // The provider's error code on a failed delivery — Telnyx 40300; historical rows carry Twilio codes like 21610
    fromNumber: string  // Sender at the time it was sent
    toNumber: string  // Recipient at the time it was sent — our line on an inbound, the client on an outbound
    body: string
    readAt: string | any | null  // Global read state, not per-user
    createdAt: string | any  // ISO 8601 timestamp
    client: {
      id: string  // Unique identifier
      code: string  // Immutable client code — the human identity
      name: string | null
      phone: string  // Phone number in E.164, e.g. +14035550101
      isConfirmed: boolean
      isBlacklisted: boolean  // Standing, carried here so a rail of conversations can show it without a query per row
      hasLinkedNumbers: boolean  // Whether this client texts from more than one number
    } | null  // The client who sent it, as they are now
    phoneNumber: {
      id: string  // Unique identifier
      name: string | null  // Line label, e.g. the city
      number: string
    } | null  // The line it arrived on, as it is now
    sentBy: {
      id: string  // Unique identifier
      name: string
    } | null  // The user who sent it from the portal; null for anything inbound
  }>
  total: number  // Rows matching the query, across all pages
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/sms.list?input=%7B%22page%22%3A0%2C%22pageSize%22%3A0%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
Optional fields (click to add):
phoneNumberId clientId
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List SMS Conversations sms.listThreads
SMS

One page of conversations — a client and one of our lines — most recently active first, each with its newest message and unread count.

Input Schema
TypeScript
{
  page: number  // 1-based page number
  pageSize: number  // Rows per page
  phoneNumberId?: string  // Only conversations on this line of ours
  search?: string  // Matches a client's name, code or phone
}
Output Schema
TypeScript
{
  items: Array<{
    id: string  // Unique identifier
    clientId: string | null  // null = sender was unattributable
    phoneNumberId: string | null  // null = not one of our lines
    unreadCount: number  // Inbound and still unread, in this conversation
    lastMessage: {
      id: string  // Unique identifier
      threadId: string  // The conversation it belongs to. Read it off a reply rather than assuming: a send after a number change opens the thread the answer will arrive in.
      direction: "Inbound" | "Outbound"
      status: "Received" | "Queued" | "Sent" | "Delivered" | "Undelivered" | "Failed"
      errorCode: number | null  // The provider's error code on a failed delivery — Telnyx 40300; historical rows carry Twilio codes like 21610
      fromNumber: string  // Sender at the time it was sent
      toNumber: string  // Recipient at the time it was sent — our line on an inbound, the client on an outbound
      body: string
      readAt: string | any | null  // Global read state, not per-user
      createdAt: string | any  // ISO 8601 timestamp
      client: {
        id: string  // Unique identifier
        code: string  // Immutable client code — the human identity
        name: string | null
        phone: string  // Phone number in E.164, e.g. +14035550101
        isConfirmed: boolean
        isBlacklisted: boolean  // Standing, carried here so a rail of conversations can show it without a query per row
        hasLinkedNumbers: boolean  // Whether this client texts from more than one number
      } | null  // The client who sent it, as they are now
      phoneNumber: {
        id: string  // Unique identifier
        name: string | null  // Line label, e.g. the city
        number: string
      } | null  // The line it arrived on, as it is now
      sentBy: {
        id: string  // Unique identifier
        name: string
      } | null  // The user who sent it from the portal; null for anything inbound
    }  // Newest message — carries the client, the line and the preview
  }>
  total: number  // Rows matching the query, across all pages
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/sms.listThreads?input=%7B%22page%22%3A0%2C%22pageSize%22%3A0%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
Optional fields (click to add):
phoneNumberId search
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Count Unread Messages sms.unreadCount
SMS

Inbound messages nobody has read yet, across the whole inbox — the sidebar badge. Read state is global.

Output Schema
TypeScript
{
  count: number
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/sms.unreadCount' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Read an SMS Conversation sms.threadMessages
SMS

One conversation, oldest-first within the page. Page 1 is the most recent messages.

Input Schema
TypeScript
{
  page: number  // 1-based page number
  pageSize: number  // Rows per page
  threadId: string  // UUID identifier
}
Output Schema
TypeScript
{
  items: Array<{
    id: string  // Unique identifier
    threadId: string  // The conversation it belongs to. Read it off a reply rather than assuming: a send after a number change opens the thread the answer will arrive in.
    direction: "Inbound" | "Outbound"
    status: "Received" | "Queued" | "Sent" | "Delivered" | "Undelivered" | "Failed"
    errorCode: number | null  // The provider's error code on a failed delivery — Telnyx 40300; historical rows carry Twilio codes like 21610
    fromNumber: string  // Sender at the time it was sent
    toNumber: string  // Recipient at the time it was sent — our line on an inbound, the client on an outbound
    body: string
    readAt: string | any | null  // Global read state, not per-user
    createdAt: string | any  // ISO 8601 timestamp
    client: {
      id: string  // Unique identifier
      code: string  // Immutable client code — the human identity
      name: string | null
      phone: string  // Phone number in E.164, e.g. +14035550101
      isConfirmed: boolean
      isBlacklisted: boolean  // Standing, carried here so a rail of conversations can show it without a query per row
      hasLinkedNumbers: boolean  // Whether this client texts from more than one number
    } | null  // The client who sent it, as they are now
    phoneNumber: {
      id: string  // Unique identifier
      name: string | null  // Line label, e.g. the city
      number: string
    } | null  // The line it arrived on, as it is now
    sentBy: {
      id: string  // Unique identifier
      name: string
    } | null  // The user who sent it from the portal; null for anything inbound
  }>
  total: number  // Rows matching the query, across all pages
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/sms.threadMessages?input=%7B%22page%22%3A0%2C%22pageSize%22%3A0%2C%22threadId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
SMS Conversation Timeline Events sms.threadEvents
SMS

The non-message rows of one conversation, oldest first — the client's bookings and payments. Client-scoped, not thread-scoped: nothing records which conversation an event belongs to, so a client who texts two of our lines sees the same event on both. Imported rows are excluded from both, cancelled bookings from the bookings; a payment on a cancelled booking still shows, and system-created credit payments do not.

Input Schema
TypeScript
{
  threadId: string  // UUID identifier
}
Output Schema
TypeScript
{
  events: Array<{
    type: "booking" | "payment"  // What happened
    id: string  // The row itself — a booking carries a deposit and a balance, so two pills of one appointment differ only here
    at: string | any  // When it was recorded — where the pill sits in the conversation
    appointmentId: string  // The booking the pill opens — for a payment, the one it settles
    talentName: string  // Talent's nickname (denormalized)
    date: string | any  // The day booked, which is rarely the day it was booked on
    startTime?: string | null  // Bookings only — HH:MM when one was set, else absent. Never a schedule default: that is the talent's working hours, not a time anyone chose for this booking
    amount?: number  // Payments only — whole dollars collected
    isDeposit?: boolean  // Payments only — balance settled later (D34)
    method?: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare"  // Payments only — the rail it arrived on; never `Credit` here
  }>  // Oldest first. Empty for a thread whose sender was never identified — an event belongs to a client, and that thread has none
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/sms.threadEvents?input=%7B%22threadId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Mark an SMS Conversation Read sms.markThreadRead
SMS

Clears the unread flag on every inbound message in one conversation. Read state is global — the inbox is one shared queue.

Input Schema
TypeScript
{
  threadId: string  // UUID identifier
}
Output Schema
TypeScript
{
  count: number  // Messages newly marked read
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/sms.markThreadRead' \
  -H 'Content-Type: application/json' \
  -d '{"threadId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Reply to an SMS Conversation sms.reply
SMS

Sends a text to a client from one of our lines and records it against the sending user.

Input Schema
TypeScript
{
  threadId: string  // UUID identifier
  body: string  // Message text — 1600 is the provider’s hard ceiling per message
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  threadId: string  // The conversation it belongs to. Read it off a reply rather than assuming: a send after a number change opens the thread the answer will arrive in.
  direction: "Inbound" | "Outbound"
  status: "Received" | "Queued" | "Sent" | "Delivered" | "Undelivered" | "Failed"
  errorCode: number | null  // The provider's error code on a failed delivery — Telnyx 40300; historical rows carry Twilio codes like 21610
  fromNumber: string  // Sender at the time it was sent
  toNumber: string  // Recipient at the time it was sent — our line on an inbound, the client on an outbound
  body: string
  readAt: string | any | null  // Global read state, not per-user
  createdAt: string | any  // ISO 8601 timestamp
  client: {
    id: string  // Unique identifier
    code: string  // Immutable client code — the human identity
    name: string | null
    phone: string  // Phone number in E.164, e.g. +14035550101
    isConfirmed: boolean
    isBlacklisted: boolean  // Standing, carried here so a rail of conversations can show it without a query per row
    hasLinkedNumbers: boolean  // Whether this client texts from more than one number
  } | null  // The client who sent it, as they are now
  phoneNumber: {
    id: string  // Unique identifier
    name: string | null  // Line label, e.g. the city
    number: string
  } | null  // The line it arrived on, as it is now
  sentBy: {
    id: string  // Unique identifier
    name: string
  } | null  // The user who sent it from the portal; null for anything inbound
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/sms.reply' \
  -H 'Content-Type: application/json' \
  -d '{"threadId":"string","body":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Tag

query
List Tags tag.list
Tags

Returns all tags

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // Tag name
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/tag.list' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Get Tag by ID tag.byId
Tags

Returns a tag by ID

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // Tag name
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/tag.byId?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Tag tag.create
Tags

Creates a new tag

Input Schema
TypeScript
{
  name: string  // Tag name
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // Tag name
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/tag.create' \
  -H 'Content-Type: application/json' \
  -d '{"name":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Tag tag.update
Tags

Updates a tag

Input Schema
TypeScript
{
  name?: string  // Tag name
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // Tag name
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/tag.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
name
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Tag tag.delete
Tags

Deletes a tag

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  name: string  // Tag name
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/tag.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

Talent

query
List Talents talent.list
Talents

Returns the requesting company’s talents for the public roster, including service names for the filter UI

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  age: number | null  // Age in years
  height: string | null  // Height
  weight: string | null  // Weight
  measurements: string | null  // Body measurements
  nationality: string | null  // Nationality
  hair: string | null  // Hair color/style
  eyes: string | null  // Eye color
  tattoos: boolean | null  // Has tattoos
  enhanced: boolean | null  // Has cosmetic enhancements
  cupSize: string | null  // Cup size (VIPKitty-only)
  duos: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline: string | null  // Short promotional headline
  bio: string | null  // Full bio text
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  tags: Array<{
    tag: {
      id: string  // Unique identifier
      createdAt: string | any  // Record creation timestamp
      updatedAt: string | any  // Record last-update timestamp
      name: string  // Tag name
    }
  }>
  images: any[]
  menuServices: Array<{
    service: {
      name: string
    }
  }>
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.list' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Available Today talent.availableToday
Talents

Returns the requesting company’s talents (with images) scheduled for today, including the city they are in today

Input Schema
TypeScript
{
  today: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  age: number | null  // Age in years
  height: string | null  // Height
  weight: string | null  // Weight
  measurements: string | null  // Body measurements
  nationality: string | null  // Nationality
  hair: string | null  // Hair color/style
  eyes: string | null  // Eye color
  tattoos: boolean | null  // Has tattoos
  enhanced: boolean | null  // Has cosmetic enhancements
  cupSize: string | null  // Cup size (VIPKitty-only)
  duos: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline: string | null  // Short promotional headline
  bio: string | null  // Full bio text
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  tags: Array<{
    tag: {
      id: string  // Unique identifier
      createdAt: string | any  // Record creation timestamp
      updatedAt: string | any  // Record last-update timestamp
      name: string  // Tag name
    }
  }>
  images: any[]
  city: string  // City the talent is in today
  startTime: string | null  // Today's start time (HH:MM) if known
  endTime: string | null  // Today's end time (HH:MM) if known
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.availableToday?input=%7B%22today%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Talent by ID talent.byId
Talents

Returns a talent by ID with relations; 404 unless the talent belongs to the requesting company

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  age: number | null  // Age in years
  height: string | null  // Height
  weight: string | null  // Weight
  measurements: string | null  // Body measurements
  nationality: string | null  // Nationality
  hair: string | null  // Hair color/style
  eyes: string | null  // Eye color
  tattoos: boolean | null  // Has tattoos
  enhanced: boolean | null  // Has cosmetic enhancements
  cupSize: string | null  // Cup size (VIPKitty-only)
  duos: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline: string | null  // Short promotional headline
  bio: string | null  // Full bio text
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  defaultPhoneNumberId: string | null  // Default phone number ID
  phoneNumberStartsAt: string | any | null  // Phone number assignment start (slot 1)
  phoneNumberExpiresAt: string | any | null  // Phone number expiration date
  phoneNumber2Id: string | null  // Phone number ID (slot 2)
  phoneNumber2StartsAt: string | any | null  // Phone number assignment start (slot 2)
  phoneNumber2ExpiresAt: string | any | null  // Phone number expiration date (slot 2)
  defaultPhoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  phoneNumber2?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  tags: Array<{
    tag: {
      id: string  // Unique identifier
      createdAt: string | any  // Record creation timestamp
      updatedAt: string | any  // Record last-update timestamp
      name: string  // Tag name
    }
  }>
  menus: Array<{
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    type: "Regular" | "Vip"
    durationMinutes: number  // Session duration in minutes
    price: number  // Price in whole dollars
  }>
  menuServices: Array<{
    id: string  // Unique identifier
    serviceId: string  // Unique identifier
    excludedFromPromo: boolean  // Excluded from promo package
    includedInVip: boolean  // Included in all VIP appointments
    price: number | null
    service: {
      id: string  // Unique identifier
      name: string  // Service name
      createdAt: string | any  // Record creation timestamp
    }
    hiddenAt?: string | any | null  // Set when the service was retired from her menu (LUX-343, D114). Only reads that ask for retired rows ever see a value.
  }>
  schedules: Array<{
    id: string  // Unique identifier
    locationId: string  // Unique identifier
    date: string | any  // Schedule date
    startTime: string | null  // Start time
    endTime: string | null  // End time
    location: {
      id: string  // Unique identifier
      city: string | any  // City name
      name: string  // Location name within the city
      phoneNumberId: string | null  // Phone number record ID
      phoneNumber?: {
        id: string  // Unique identifier
        name: string | null
        number: string  // Phone number
        usedForMessages: boolean  // Whether this number is used for messages
      } | null
      tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
      deletedAt: string | any | null
    }
  }>
  images: any[]
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.byId?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Talent by Nickname talent.byNickname
Talents

Returns a talent by nickname with relations; 404 unless the talent belongs to the requesting company

Input Schema
TypeScript
{
  nickname: string
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  age: number | null  // Age in years
  height: string | null  // Height
  weight: string | null  // Weight
  measurements: string | null  // Body measurements
  nationality: string | null  // Nationality
  hair: string | null  // Hair color/style
  eyes: string | null  // Eye color
  tattoos: boolean | null  // Has tattoos
  enhanced: boolean | null  // Has cosmetic enhancements
  cupSize: string | null  // Cup size (VIPKitty-only)
  duos: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline: string | null  // Short promotional headline
  bio: string | null  // Full bio text
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  defaultPhoneNumberId: string | null  // Default phone number ID
  phoneNumberStartsAt: string | any | null  // Phone number assignment start (slot 1)
  phoneNumberExpiresAt: string | any | null  // Phone number expiration date
  phoneNumber2Id: string | null  // Phone number ID (slot 2)
  phoneNumber2StartsAt: string | any | null  // Phone number assignment start (slot 2)
  phoneNumber2ExpiresAt: string | any | null  // Phone number expiration date (slot 2)
  defaultPhoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  phoneNumber2?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  tags: Array<{
    tag: {
      id: string  // Unique identifier
      createdAt: string | any  // Record creation timestamp
      updatedAt: string | any  // Record last-update timestamp
      name: string  // Tag name
    }
  }>
  menus: Array<{
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    type: "Regular" | "Vip"
    durationMinutes: number  // Session duration in minutes
    price: number  // Price in whole dollars
  }>
  menuServices: Array<{
    id: string  // Unique identifier
    serviceId: string  // Unique identifier
    excludedFromPromo: boolean  // Excluded from promo package
    includedInVip: boolean  // Included in all VIP appointments
    price: number | null
    service: {
      id: string  // Unique identifier
      name: string  // Service name
      createdAt: string | any  // Record creation timestamp
    }
    hiddenAt?: string | any | null  // Set when the service was retired from her menu (LUX-343, D114). Only reads that ask for retired rows ever see a value.
  }>
  schedules: Array<{
    id: string  // Unique identifier
    locationId: string  // Unique identifier
    date: string | any  // Schedule date
    startTime: string | null  // Start time
    endTime: string | null  // End time
    location: {
      id: string  // Unique identifier
      city: string | any  // City name
      name: string  // Location name within the city
      phoneNumberId: string | null  // Phone number record ID
      phoneNumber?: {
        id: string  // Unique identifier
        name: string | null
        number: string  // Phone number
        usedForMessages: boolean  // Whether this number is used for messages
      } | null
      tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
      deletedAt: string | any | null
    }
  }>
  images: any[]
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.byNickname?input=%7B%22nickname%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List Talent Summaries talent.listSummary
Talents

Returns lightweight talent list (all companies) with a `member` flag for the requesting company

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  tagline: string | null  // Short promotional headline
  member: boolean  // Member of the requesting company (shown on its public site)
  companies: string[]  // Slugs of every company she is a member of — lets the client decide brand-specific things (which public site to link) without an extra request
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.listSummary' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Get Talent by Nickname (Admin) talent.byNicknameAll
Talents

Returns a talent by nickname across all companies, with a `member` flag for the requesting company

Input Schema
TypeScript
{
  nickname: string
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  age: number | null  // Age in years
  height: string | null  // Height
  weight: string | null  // Weight
  measurements: string | null  // Body measurements
  nationality: string | null  // Nationality
  hair: string | null  // Hair color/style
  eyes: string | null  // Eye color
  tattoos: boolean | null  // Has tattoos
  enhanced: boolean | null  // Has cosmetic enhancements
  cupSize: string | null  // Cup size (VIPKitty-only)
  duos: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline: string | null  // Short promotional headline
  bio: string | null  // Full bio text
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  defaultPhoneNumberId: string | null  // Default phone number ID
  phoneNumberStartsAt: string | any | null  // Phone number assignment start (slot 1)
  phoneNumberExpiresAt: string | any | null  // Phone number expiration date
  phoneNumber2Id: string | null  // Phone number ID (slot 2)
  phoneNumber2StartsAt: string | any | null  // Phone number assignment start (slot 2)
  phoneNumber2ExpiresAt: string | any | null  // Phone number expiration date (slot 2)
  defaultPhoneNumber?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  phoneNumber2?: {
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    name: string | null
    number: string  // Phone number
    usedForMessages: boolean  // Whether this number is used for messages
  } | null
  tags: Array<{
    tag: {
      id: string  // Unique identifier
      createdAt: string | any  // Record creation timestamp
      updatedAt: string | any  // Record last-update timestamp
      name: string  // Tag name
    }
  }>
  menus: Array<{
    id: string  // Unique identifier
    createdAt: string | any  // Record creation timestamp
    updatedAt: string | any  // Record last-update timestamp
    type: "Regular" | "Vip"
    durationMinutes: number  // Session duration in minutes
    price: number  // Price in whole dollars
  }>
  menuServices: Array<{
    id: string  // Unique identifier
    serviceId: string  // Unique identifier
    excludedFromPromo: boolean  // Excluded from promo package
    includedInVip: boolean  // Included in all VIP appointments
    price: number | null
    service: {
      id: string  // Unique identifier
      name: string  // Service name
      createdAt: string | any  // Record creation timestamp
    }
    hiddenAt?: string | any | null  // Set when the service was retired from her menu (LUX-343, D114). Only reads that ask for retired rows ever see a value.
  }>
  schedules: Array<{
    id: string  // Unique identifier
    locationId: string  // Unique identifier
    date: string | any  // Schedule date
    startTime: string | null  // Start time
    endTime: string | null  // End time
    notes: string | null  // Optional notes
    location: {
      id: string  // Unique identifier
      city: string | any  // City name
      name: string  // Location name within the city
      phoneNumberId: string | null  // Phone number record ID
      phoneNumber?: {
        id: string  // Unique identifier
        name: string | null
        number: string  // Phone number
        usedForMessages: boolean  // Whether this number is used for messages
      } | null
      tenancyEndedAt: string | any | null  // Condo move-out date; null while the tenancy is live
      deletedAt: string | any | null
    }
  }>
  images: any[]
  member: boolean  // Member of the requesting company (shown on its public site)
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.byNicknameAll?input=%7B%22nickname%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Talent Notes (Admin) talent.notesById
Talents

Admin-only forum-ad notes for a talent

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  notes: string | null  // Admin-only forum-ad template
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.notesById?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List Talent Memberships talent.memberships
Talents

Returns the companies a talent belongs to

Input Schema
TypeScript
{
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
Array<{
  companyId: string  // Company the talent belongs to
  companySlug: string  // URL-safe unique slug, sent as the x-company-slug header
  companyName: string  // Company display name
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.memberships?input=%7B%22talentId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Set Talent Membership talent.setMembership
Talents

Adds a talent to or removes a talent from a company; returns the updated membership list

Input Schema
TypeScript
{
  talentId: string  // Talent to add to or remove from a company
  companyId: string  // Target company
  member: boolean  // true adds the membership, false removes it
}
Output Schema
TypeScript
Array<{
  companyId: string  // Company the talent belongs to
  companySlug: string  // URL-safe unique slug, sent as the x-company-slug header
  companyName: string  // Company display name
}>
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.setMembership' \
  -H 'Content-Type: application/json' \
  -d '{"talentId":"string","companyId":"string","member":true}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List Talent Exclusions talent.listExclusions
Talents

Returns the ids of clients on a talent's Don't-See list

Input Schema
TypeScript
{
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
string[]
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.listExclusions?input=%7B%22talentId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Set Talent Exclusions talent.setExclusions
Talents

Replaces a talent's Don't-See list — the clients this talent won't see

Input Schema
TypeScript
{
  talentId: string  // The talent whose Don't-See list is set
  clientIds: string[]  // Clients this talent won't see (replaces the whole list)
}
Output Schema
TypeScript
string[]
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.setExclusions' \
  -H 'Content-Type: application/json' \
  -d '{"talentId":"string","clientIds":["string"]}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get Talent Login talent.login
Talents

Returns the linked login's phone number — null means the talent cannot sign in to the staff portal

Input Schema
TypeScript
{
  talentId: string  // UUID identifier
}
Output Schema
TypeScript
{
  phoneNumber: string | null  // The linked login's phone — null means no staff-portal access
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.login?input=%7B%22talentId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Set Talent Login Phone talent.setLoginPhone
Talents

Sets or removes the phone number this talent signs in to the staff portal with (LUX-276). Setting a number mints a login if she has none; removing it revokes her sessions

Input Schema
TypeScript
{
  talentId: string  // The talent whose portal login is set
  phoneNumber: any | null  // Login phone in E.164 — null removes staff-portal access
}
Output Schema
TypeScript
{
  phoneNumber: string | null  // The linked login's phone — null means no staff-portal access
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.setLoginPhone' \
  -H 'Content-Type: application/json' \
  -d '{"talentId":"string","phoneNumber":"value"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
My Talent Profile talent.me
Talents

The requesting user's own talent profile — the talent linked to their account, never anyone else's; null for an admin with no talent link. Carries the slugs of every brand she is a member of, so the portal can show brand-specific fields

Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  age: number | null  // Age in years
  height: string | null  // Height
  weight: string | null  // Weight
  measurements: string | null  // Body measurements
  nationality: string | null  // Nationality
  hair: string | null  // Hair color/style
  eyes: string | null  // Eye color
  tattoos: boolean | null  // Has tattoos
  enhanced: boolean | null  // Has cosmetic enhancements
  cupSize: string | null  // Cup size (VIPKitty-only)
  duos: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline: string | null  // Short promotional headline
  bio: string | null  // Full bio text
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  defaultPhoneNumberId: string | null  // Default phone number ID
  phoneNumberStartsAt: string | any | null  // Phone number assignment start (slot 1)
  phoneNumberExpiresAt: string | any | null  // Phone number expiration date
  phoneNumber2Id: string | null  // Phone number ID (slot 2)
  phoneNumber2StartsAt: string | any | null  // Phone number assignment start (slot 2)
  phoneNumber2ExpiresAt: string | any | null  // Phone number expiration date (slot 2)
  bookingPushEnabled: boolean  // Her switch on the booking push (LUX-283)
  companies: string[]  // Slugs of every company she is a member of
} | null
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.me' \
  -H 'Content-Type: application/json'
Test Endpoint
query
My Schedule Week talent.mySchedule
Talents

The requesting talent's own Mon–Sun week: each scheduled day's venue, shift times, live booking count, her own book-on fee, and her line for the day with the bookers covering it

Input Schema
TypeScript
{
  weekStart: any  // Any day of the wanted week — resolved to its Mon–Sun bounds server-side
}
Output Schema
TypeScript
{
  startDate: string | any  // Date in YYYY-MM-DD format
  endDate: string | any  // Date in YYYY-MM-DD format
  days: Array<{
    scheduleId: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    locationId: string  // Deep-link key into the talent's Locations screen
    line: string | null  // Her line for the day (LUX-331): her profile number while live on the day, else the venue's — the no-hint fallback of the resolution that picks a booking's payee (`bookingLine`, LUX-328); null only when neither her profile nor the venue supplies one
    lineCoverage: Array<{
      startsAt: string  // Takeover time 'HH:MM'; '00:00' = the day's first booker
      bookerName: string  // The booker's work name
    }>  // Who covers her line that day, earliest takeover first; empty when nobody does
    locationName: string
    city: string
    street: string | null  // Street address; null when unset
    startTime: string | null  // HH:MM shift start, or null
    endTime: string | null  // HH:MM shift end, or null
    bookingCount: number  // Live bookings that day — cancelled and carrier rows excluded
    bookOnFee: number | null  // Her own book-on fee for the day, in whole dollars — the flat fee off her profile's fees tab; null when the office has not set one
    envelopeDroppedAt: string | any | null  // When she declared the day closed out — envelope handed in (LUX-274); null while open
  }>  // The week's scheduled days, earliest first
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.mySchedule?input=%7B%22weekStart%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
My Tour Calendar Month talent.myTourCalendar
Talents

The requesting talent's own scheduled days over one calendar month — the Tours calendar's schedule side (LUX-268)

Input Schema
TypeScript
{
  month: string  // The wanted calendar month, YYYY-MM
}
Output Schema
TypeScript
{
  startDate: string | any  // Date in YYYY-MM-DD format
  endDate: string | any  // Date in YYYY-MM-DD format
  days: Array<{
    scheduleId: string  // Unique identifier
    date: string | any  // Date in YYYY-MM-DD format
    locationId: string  // Deep-link key into the talent's Locations screen
    line: string | null  // Her line for the day (LUX-331): her profile number while live on the day, else the venue's — the no-hint fallback of the resolution that picks a booking's payee (`bookingLine`, LUX-328); null only when neither her profile nor the venue supplies one
    lineCoverage: Array<{
      startsAt: string  // Takeover time 'HH:MM'; '00:00' = the day's first booker
      bookerName: string  // The booker's work name
    }>  // Who covers her line that day, earliest takeover first; empty when nobody does
    locationName: string
    city: string
    street: string | null  // Street address; null when unset
    startTime: string | null  // HH:MM shift start, or null
    endTime: string | null  // HH:MM shift end, or null
    bookingCount: number  // Live bookings that day — cancelled and carrier rows excluded
    bookOnFee: number | null  // Her own book-on fee for the day, in whole dollars — the flat fee off her profile's fees tab; null when the office has not set one
    envelopeDroppedAt: string | any | null  // When she declared the day closed out — envelope handed in (LUX-274); null while open
  }>  // The week's scheduled days, earliest first
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.myTourCalendar?input=%7B%22month%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
My Locations talent.myLocations
Talents

The venues on the requesting talent's own roster, each with its talent-facing content: getting-in text, parking, WiFi, garbage and safe locations, house guidelines, FAQ and the emergency plan with its pictures

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  name: string
  city: string  // The venue's city — the design's area line
  street: string | null  // Street address; null when unset
  unitNumber: string | null  // Unit / suite number
  phone: string | null  // The venue's own line (the ☎ call target); null when unset
  checkInInstructions: string | null  // The "getting in" text; null until the office writes it
  checkOutInstructions: string | null  // The "heading out" text; null until the office writes it
  parkingInstructions: string | null  // Where she parks; null until the office writes it
  wifi: string | null  // The venue's network and password; null until the office writes it
  garbageLocation: string | null  // Where the garbage goes; null until the office writes it
  safeLocation: string | null  // Where the safe is; null until the office writes it
  houseGuidelines: string[]  // House guidelines, in display order
  faq: Array<{
    question: string
    answer: string
  }>
  emergencyPlan: string | null  // What to do when something goes wrong here — shut-offs, panel; null until the office writes it
  emergencyMedia: Array<{
    id: string  // Unique identifier
    url: string  // The picture or video itself
    mimeType: string  // Tells a video apart from a picture at render
  }>  // Pictures of what the plan refers to, oldest first
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.myLocations' \
  -H 'Content-Type: application/json'
Test Endpoint
query
My Appointments talent.myAppointments
Talents

The requesting talent's own bookings on one day, each with its client display, services, payments and owed/paid balance

Input Schema
TypeScript
{
  date: any  // The day to list
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  scheduleId: string  // Unique identifier
  startTime: string | null  // HH:MM, or null when unset
  clientName: string  // Client's name, or their code when they have none (denormalized)
  menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
  fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
  discount: number  // Reduces what is owed; defaults to 0
  confirmed: boolean  // The end client has confirmed this booking
  notes?: string | null  // Free-form appointment notes (distinct from the client notes)
  cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
  bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
  isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
  wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
  wrapUpNoShow: boolean  // She reported the client never showed for this booking
  wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
  wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
  wrapUpExtras: Array<{
    menuServiceId: string  // Unique identifier
    name: string  // Service name as it read at report time
    price: number  // Catalog price at report time
  }>  // Add-ons she reported selling, priced as at report time
  wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
  clientCode: string  // The client's short spoken code (D52)
  date: string | any  // The booking's day (from its schedule)
  locationId: string  // Deep-link key into the talent's Locations screen
  locationName: string
  services: Array<{
    id: string  // Unique identifier
    serviceName: string
    price: number  // The talent's own money for this add-on (D105); $0 when VIP-included
  }>
  payments: Array<{
    id: string  // Unique identifier
    method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare"
    amount: number  // Whole dollars collected
    isDeposit: boolean  // A recorded deposit; the balance is settled later
  }>
  owed: number  // fee − discount + captured service fees — the office-side Due (signed, like the tracker); post-D105 extras are her own money and stay out
  paid: number  // Σ payment.amount against this booking
  balance: number  // paid − owed
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.myAppointments?input=%7B%22date%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
My Carried Credit talent.myCarriedCredit
Talents

The requesting talent's balance carried into a day from her earlier days (LUX-292/D110) — Wrap My Day nets "you owe" against it. Date-grained: it carries into the whole date, without the admin tracker's per-sibling and keyed-line netting (no keyed lines exist after D110; legacy days may read differently here than there)

Input Schema
TypeScript
{
  date: any  // The day to list
}
Output Schema
TypeScript
{
  amount: number
  from: string | any[]
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.myCarriedCredit?input=%7B%22date%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
My Appointment talent.myAppointment
Talents

One of the requesting talent's own bookings — NOT_FOUND when it isn't theirs

Input Schema
TypeScript
{
  appointmentId: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  scheduleId: string  // Unique identifier
  startTime: string | null  // HH:MM, or null when unset
  clientName: string  // Client's name, or their code when they have none (denormalized)
  menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
  fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
  discount: number  // Reduces what is owed; defaults to 0
  confirmed: boolean  // The end client has confirmed this booking
  notes?: string | null  // Free-form appointment notes (distinct from the client notes)
  cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
  bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
  isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
  wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
  wrapUpNoShow: boolean  // She reported the client never showed for this booking
  wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
  wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
  wrapUpExtras: Array<{
    menuServiceId: string  // Unique identifier
    name: string  // Service name as it read at report time
    price: number  // Catalog price at report time
  }>  // Add-ons she reported selling, priced as at report time
  wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
  clientCode: string  // The client's short spoken code (D52)
  date: string | any  // The booking's day (from its schedule)
  locationId: string  // Deep-link key into the talent's Locations screen
  locationName: string
  services: Array<{
    id: string  // Unique identifier
    serviceName: string
    price: number  // The talent's own money for this add-on (D105); $0 when VIP-included
  }>
  payments: Array<{
    id: string  // Unique identifier
    method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare"
    amount: number  // Whole dollars collected
    isDeposit: boolean  // A recorded deposit; the balance is settled later
  }>
  owed: number  // fee − discount + captured service fees — the office-side Due (signed, like the tracker); post-D105 extras are her own money and stay out
  paid: number  // Σ payment.amount against this booking
  balance: number  // paid − owed
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.myAppointment?input=%7B%22appointmentId%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
My Pay talent.myPay
Talents

The requesting talent's own pay period (week/month/year): services/extras/cancellation totals and the per-booking breakdown

Input Schema
TypeScript
{
  date: any  // Any day of the wanted pay period — resolved to its calendar bounds
  period: "week" | "month" | "year"  // The period grain containing `date`
}
Output Schema
TypeScript
{
  startDate: string | any  // Date in YYYY-MM-DD format
  endDate: string | any  // Date in YYYY-MM-DD format
  services: number  // Σ client-paid package money over live bookings — menu catalog price, or recorded payments minus extras when imported (her side, not the agency fee)
  extras: number  // Σ the talent's own add-on money over live bookings (D105 — captured fee, else catalog price, VIP inclusions $0)
  cancellations: number  // Σ talent half of kept cancellation fees (D87/D95)
  fees: number  // What she hands the agency: Σ (fee − discount) over live bookings + the resolved book-on per venue-day worked (D64/D83 — stored snapshot, else the category default) — signed, since a discount may exceed its fee
  total: number  // Her net: services + extras + cancellations − fees
  rows: Array<{
    appointmentId: string  // The booking behind this row — a cancellation-fee row carries the cancelled booking
    date: string | any  // Date in YYYY-MM-DD format
    clientCode: string
    clientName: string
    service: string  // Menu package label, or "Cancellation fee" for a kept deposit
    locationName: string
    methods: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare"[]  // Distinct payment methods recorded on the booking
    total: number  // What the booking brought in client-side (LUX-225 flip): catalog price + charged extras, or recorded payments when imported; a cancellation-fee row stays her half of the kept deposit
    startTime: string | null  // HH:MM booking start — null on a cancellation-fee row
    wrappedUpAt: string | any | null  // When she closed the booking out (LUX-262) — null while it still needs a wrap-up, so its money isn't final; also null on a cancellation-fee row, which never wraps
  }>  // Per-booking breakdown, oldest first
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.myPay?input=%7B%22date%22%3A%22value%22%2C%22period%22%3A%22week%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
My Extras talent.myExtras
Talents

The requesting talent's own priced add-ons, for the wrap-up screen's chips

Output Schema
TypeScript
Array<{
  menuServiceId: string  // Unique identifier
  name: string
  price: number
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.myExtras' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Wrap Up Appointment talent.wrapUpAppointment
Talents

Close out one of the requesting talent's own bookings: what she actually provided, the add-ons she sold and a private note for the office. Same-day or past only, once per booking, and never a pay change — a reported difference is flagged, not recalculated

Input Schema
TypeScript
{
  appointmentId: string  // UUID identifier
  today: any  // The talent's own current calendar date
  noShow: boolean  // The client never showed — the call is closed out with nothing provided
  extraMinutes: 0 | 15 | 30  // Minutes over the booked duration: 0 = as booked
  extras: string[]  // menuServiceIds she reported selling — from her own catalog; the server prices them
  notes?: string  // Her private note for the office
  cashReceived: number | null  // Whole dollars the client handed her; null = not reported
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  scheduleId: string  // Unique identifier
  startTime: string | null  // HH:MM, or null when unset
  clientName: string  // Client's name, or their code when they have none (denormalized)
  menuLabel: string | null  // Menu package label, e.g. "60 min VIP" (denormalized). An imported row has no menu, so it falls back to the source line the call was written as ("HH PSE"); null only when the source named nothing either
  fee: number  // Talent's fee owed — captured from Menu.fee, or the sheet's historical total on an import (D67 exception)
  discount: number  // Reduces what is owed; defaults to 0
  confirmed: boolean  // The end client has confirmed this booking
  notes?: string | null  // Free-form appointment notes (distinct from the client notes)
  cancelledAt: string | any | null  // Set when the booking was cancelled and kept as a cancellation fee (D95); null = live. A cancelled booking drops out of Due and booker pay and shows only as a note.
  bookerName: string | null  // Booker display name (denormalized); null when imported/unresolved
  isIndy: boolean  // An indy call (LUX-239) — the talent booked it themselves. A normal call everywhere except booker pay: bookerPay is stamped 0 and the payroll rollup skips it
  wrappedUpAt: string | any | null  // When the talent finalized her wrap-up; null = still open
  wrapUpNoShow: boolean  // She reported the client never showed for this booking
  wrapUpExtraMinutes: number  // Reported minutes over the booked duration: 0, 15 or 30
  wrapUpNotes: string | null  // Her private wrap-up note for the office (distinct from the booking notes)
  wrapUpExtras: Array<{
    menuServiceId: string  // Unique identifier
    name: string  // Service name as it read at report time
    price: number  // Catalog price at report time
  }>  // Add-ons she reported selling, priced as at report time
  wrapUpCashReceived: number | null  // Whole dollars the client handed her (LUX-224); null = not reported
  clientCode: string  // The client's short spoken code (D52)
  date: string | any  // The booking's day (from its schedule)
  locationId: string  // Deep-link key into the talent's Locations screen
  locationName: string
  services: Array<{
    id: string  // Unique identifier
    serviceName: string
    price: number  // The talent's own money for this add-on (D105); $0 when VIP-included
  }>
  payments: Array<{
    id: string  // Unique identifier
    method: "EMT" | "AmazonGiftCard" | "Cash" | "Credit" | "TalentCredit" | "HotelShare"
    amount: number  // Whole dollars collected
    isDeposit: boolean  // A recorded deposit; the balance is settled later
  }>
  owed: number  // fee − discount + captured service fees — the office-side Due (signed, like the tracker); post-D105 extras are her own money and stay out
  paid: number  // Σ payment.amount against this booking
  balance: number  // paid − owed
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.wrapUpAppointment' \
  -H 'Content-Type: application/json' \
  -d '{"appointmentId":"string","today":"value","noShow":true,"extraMinutes":0,"extras":["string"],"cashReceived":0}'
Test Endpoint
Optional fields (click to add):
notes
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Drop Envelope talent.dropEnvelope
Talents

Close out the requesting talent's own scheduled day — she declares the cash envelope handed in. Same-day or past only, once per day, and never a money change: the office sees the flag on the daily tracker

Input Schema
TypeScript
{
  scheduleId: string  // Her own shift row for the day
  today: any  // The talent's own current calendar date
}
Output Schema
TypeScript
{
  envelopeDroppedAt: string | any  // ISO 8601 timestamp
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.dropEnvelope' \
  -H 'Content-Type: application/json' \
  -d '{"scheduleId":"string","today":"value"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Set Booking Push talent.setBookingPush
Talents

The requesting talent's own booking-push switch — on, a phone ping for every booking added to her day; off, the in-app record only. Wrapping up her day turns it off; nothing but this call turns it back on

Input Schema
TypeScript
{
  enabled: boolean  // Her booking-push switch (LUX-283)
}
Output Schema
TypeScript
any
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.setBookingPush' \
  -H 'Content-Type: application/json' \
  -d '{"enabled":true}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create Talent talent.create
Talents

Creates a new talent

Input Schema
TypeScript
{
  nickname: string  // Unique display name
  age?: number | null  // Age in years
  height?: string | null  // Height
  weight?: string | null  // Weight
  measurements?: string | null  // Body measurements
  nationality?: string | null  // Nationality
  hair?: string | null  // Hair color/style
  eyes?: string | null  // Eye color
  tattoos?: boolean | null  // Has tattoos
  enhanced?: boolean | null  // Has cosmetic enhancements
  cupSize?: string | null  // Cup size (VIPKitty-only)
  duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline?: string | null  // Short promotional headline
  bio?: string | null  // Full bio text
  badge?: "Visiting" | "Star" | "Vip" | "New" | null
  defaultPhoneNumberId?: string | null  // Default phone number ID
  phoneNumberStartsAt?: any | null
  phoneNumberExpiresAt?: any | null
  phoneNumber2Id?: string | null  // Phone number ID (slot 2)
  phoneNumber2StartsAt?: any | null
  phoneNumber2ExpiresAt?: any | null
  notes?: string | null  // Admin-only forum-ad template
  tags?: string[]  // Tag IDs
  menus?: Array<{
    type: "Regular" | "Vip"
    durationMinutes: number  // Session duration in minutes
    price: number  // Price in whole dollars
  }>
  menuServices?: Array<{
    serviceId: string  // UUID identifier
    price?: number | null
  }>
  images?: Array<{
    fileId: string  // ID of the uploaded File
    variant?: "Original" | "Thumbnail" | "Large"
    imageBrand?: "LuxWatermark" | "GgwWatermark" | "VipKittyWatermark" | "Clean" | null
    width?: number | null  // Image width in pixels
    height?: number | null  // Image height in pixels
    sortOrder?: number  // Display sort order
  }>
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  age: number | null  // Age in years
  height: string | null  // Height
  weight: string | null  // Weight
  measurements: string | null  // Body measurements
  nationality: string | null  // Nationality
  hair: string | null  // Hair color/style
  eyes: string | null  // Eye color
  tattoos: boolean | null  // Has tattoos
  enhanced: boolean | null  // Has cosmetic enhancements
  cupSize: string | null  // Cup size (VIPKitty-only)
  duos: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline: string | null  // Short promotional headline
  bio: string | null  // Full bio text
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  defaultPhoneNumberId: string | null  // Default phone number ID
  phoneNumberStartsAt: string | any | null  // Phone number assignment start (slot 1)
  phoneNumberExpiresAt: string | any | null  // Phone number expiration date
  phoneNumber2Id: string | null  // Phone number ID (slot 2)
  phoneNumber2StartsAt: string | any | null  // Phone number assignment start (slot 2)
  phoneNumber2ExpiresAt: string | any | null  // Phone number expiration date (slot 2)
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.create' \
  -H 'Content-Type: application/json' \
  -d '{"nickname":"string"}'
Test Endpoint
Optional fields (click to add):
age height weight measurements nationality hair eyes tattoos enhanced cupSize duos tagline bio badge defaultPhoneNumberId phoneNumberStartsAt phoneNumberExpiresAt phoneNumber2Id phoneNumber2StartsAt phoneNumber2ExpiresAt notes tags menus menuServices images
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update Talent talent.update
Talents

Updates an existing talent

Input Schema
TypeScript
{
  nickname?: string  // Unique display name
  age?: number | null  // Age in years
  height?: string | null  // Height
  weight?: string | null  // Weight
  measurements?: string | null  // Body measurements
  nationality?: string | null  // Nationality
  hair?: string | null  // Hair color/style
  eyes?: string | null  // Eye color
  tattoos?: boolean | null  // Has tattoos
  enhanced?: boolean | null  // Has cosmetic enhancements
  cupSize?: string | null  // Cup size (VIPKitty-only)
  duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline?: string | null  // Short promotional headline
  bio?: string | null  // Full bio text
  badge?: "Visiting" | "Star" | "Vip" | "New" | null
  defaultPhoneNumberId?: string | null  // Default phone number ID
  phoneNumberStartsAt?: any | null
  phoneNumberExpiresAt?: any | null
  phoneNumber2Id?: string | null  // Phone number ID (slot 2)
  phoneNumber2StartsAt?: any | null
  phoneNumber2ExpiresAt?: any | null
  notes?: string | null  // Admin-only forum-ad template
  tags?: string[]  // Tag IDs
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  age: number | null  // Age in years
  height: string | null  // Height
  weight: string | null  // Weight
  measurements: string | null  // Body measurements
  nationality: string | null  // Nationality
  hair: string | null  // Hair color/style
  eyes: string | null  // Eye color
  tattoos: boolean | null  // Has tattoos
  enhanced: boolean | null  // Has cosmetic enhancements
  cupSize: string | null  // Cup size (VIPKitty-only)
  duos: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline: string | null  // Short promotional headline
  bio: string | null  // Full bio text
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  defaultPhoneNumberId: string | null  // Default phone number ID
  phoneNumberStartsAt: string | any | null  // Phone number assignment start (slot 1)
  phoneNumberExpiresAt: string | any | null  // Phone number expiration date
  phoneNumber2Id: string | null  // Phone number ID (slot 2)
  phoneNumber2StartsAt: string | any | null  // Phone number assignment start (slot 2)
  phoneNumber2ExpiresAt: string | any | null  // Phone number expiration date (slot 2)
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
Optional fields (click to add):
nickname age height weight measurements nationality hair eyes tattoos enhanced cupSize duos tagline bio badge defaultPhoneNumberId phoneNumberStartsAt phoneNumberExpiresAt phoneNumber2Id phoneNumber2StartsAt phoneNumber2ExpiresAt notes tags
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Delete Talent talent.delete
Talents

Deletes a talent

Input Schema
TypeScript
{
  id: string  // UUID identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  nickname: string  // Unique display name
  age: number | null  // Age in years
  height: string | null  // Height
  weight: string | null  // Weight
  measurements: string | null  // Body measurements
  nationality: string | null  // Nationality
  hair: string | null  // Hair color/style
  eyes: string | null  // Eye color
  tattoos: boolean | null  // Has tattoos
  enhanced: boolean | null  // Has cosmetic enhancements
  cupSize: string | null  // Cup size (VIPKitty-only)
  duos: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline: string | null  // Short promotional headline
  bio: string | null  // Full bio text
  badge: "Visiting" | "Star" | "Vip" | "New" | null
  defaultPhoneNumberId: string | null  // Default phone number ID
  phoneNumberStartsAt: string | any | null  // Phone number assignment start (slot 1)
  phoneNumberExpiresAt: string | any | null  // Phone number expiration date
  phoneNumber2Id: string | null  // Phone number ID (slot 2)
  phoneNumber2StartsAt: string | any | null  // Phone number assignment start (slot 2)
  phoneNumber2ExpiresAt: string | any | null  // Phone number expiration date (slot 2)
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.delete' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Send a Change Request talent.createRequest
Talents

Asks the office for a schedule change, a tour in one of the company cities, supplies for one of her own venues, an edit to her own profile or anything else. A request is a ticket — it never edits the schedule or the profile

Input Schema
TypeScript
{
  type: "scheduleChange" | "profileChange" | "tour" | "supplies" | "other"
  startDate?: "" | string
  endDate?: "" | string
  cityId?: string | null
  locationId?: string | null
  note?: string | null
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  type: "timeOff" | "scheduleChange" | "profileChange" | "profileEdit" | "tour" | "supplies" | "other" | "refund"
  status: "open" | "approved" | "declined"
  talentId: string | null  // Null once the talent is deleted
  talentName: string | null  // Snapshot taken when the request was sent; null on a refund row (LUX-310)
  startDate: string | any | null
  endDate: string | any | null
  cityId: string | null  // Null unless the ask was a tour
  cityName: string | null  // Snapshot taken when the request was sent
  locationId: string | null  // Null unless the ask was for supplies
  locationName: string | null  // Snapshot taken when the request was sent
  note: string | null
  payload: {
    from: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // Her record when she asked
    to: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // What she is asking it to become
  } | null  // The proposed edit on a profileEdit; null on every other type
  clientId: string | null  // Null once the client is deleted
  clientName: string | null  // Snapshot taken when the refund was requested
  appointmentId: string | null  // The cancelled booking the money was recorded on
  refundAmount: number | null
  refundEmail: string | null
  refundPaidAt: string | any | null  // When the money was sent back; null while unpaid
  decisionNote: string | null
  decidedAt: string | any | null  // Null while open
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.createRequest' \
  -H 'Content-Type: application/json' \
  -d '{"type":"scheduleChange"}'
Test Endpoint
Optional fields (click to add):
startDate endDate cityId locationId note
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Request a Profile Edit talent.requestProfileEdit
Talents

Asks the office to change the requesting talent's own safe profile fields. Nothing is written here: the proposed change rides on a change request, and only an approval applies it. The schema's picked allowlist is the whole proposable surface — admin-owned fields (nickname, badge, notes, fees, phone assignment) are not in it, and phone stays in the SMS-verify flow. Identity comes off the session's talent link, never input

Input Schema
TypeScript
{
  age?: number | null  // Age in years
  height?: string | null  // Height
  weight?: string | null  // Weight
  measurements?: string | null  // Body measurements
  nationality?: string | null  // Nationality
  hair?: string | null  // Hair color/style
  eyes?: string | null  // Eye color
  tattoos?: boolean | null  // Has tattoos
  enhanced?: boolean | null  // Has cosmetic enhancements
  cupSize?: string | null  // Cup size (VIPKitty-only)
  duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
  tagline?: string | null  // Short promotional headline
  bio?: string | null  // Full bio text
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  type: "timeOff" | "scheduleChange" | "profileChange" | "profileEdit" | "tour" | "supplies" | "other" | "refund"
  status: "open" | "approved" | "declined"
  talentId: string | null  // Null once the talent is deleted
  talentName: string | null  // Snapshot taken when the request was sent; null on a refund row (LUX-310)
  startDate: string | any | null
  endDate: string | any | null
  cityId: string | null  // Null unless the ask was a tour
  cityName: string | null  // Snapshot taken when the request was sent
  locationId: string | null  // Null unless the ask was for supplies
  locationName: string | null  // Snapshot taken when the request was sent
  note: string | null
  payload: {
    from: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // Her record when she asked
    to: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // What she is asking it to become
  } | null  // The proposed edit on a profileEdit; null on every other type
  clientId: string | null  // Null once the client is deleted
  clientName: string | null  // Snapshot taken when the refund was requested
  appointmentId: string | null  // The cancelled booking the money was recorded on
  refundAmount: number | null
  refundEmail: string | null
  refundPaidAt: string | any | null  // When the money was sent back; null while unpaid
  decisionNote: string | null
  decidedAt: string | any | null  // Null while open
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.requestProfileEdit' \
  -H 'Content-Type: application/json' \
  -d '{}'
Test Endpoint
Optional fields (click to add):
age height weight measurements nationality hair eyes tattoos enhanced cupSize duos tagline bio
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
My Change Requests talent.myRequests
Talents

The requesting talent's own change requests, newest first, each with the office's answer once decided

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  type: "timeOff" | "scheduleChange" | "profileChange" | "profileEdit" | "tour" | "supplies" | "other" | "refund"
  status: "open" | "approved" | "declined"
  talentId: string | null  // Null once the talent is deleted
  talentName: string | null  // Snapshot taken when the request was sent; null on a refund row (LUX-310)
  startDate: string | any | null
  endDate: string | any | null
  cityId: string | null  // Null unless the ask was a tour
  cityName: string | null  // Snapshot taken when the request was sent
  locationId: string | null  // Null unless the ask was for supplies
  locationName: string | null  // Snapshot taken when the request was sent
  note: string | null
  payload: {
    from: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // Her record when she asked
    to: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // What she is asking it to become
  } | null  // The proposed edit on a profileEdit; null on every other type
  clientId: string | null  // Null once the client is deleted
  clientName: string | null  // Snapshot taken when the refund was requested
  appointmentId: string | null  // The cancelled booking the money was recorded on
  refundAmount: number | null
  refundEmail: string | null
  refundPaidAt: string | any | null  // When the money was sent back; null while unpaid
  decisionNote: string | null
  decidedAt: string | any | null  // Null while open
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.myRequests' \
  -H 'Content-Type: application/json'
Test Endpoint
query
Tour Capacity Preview talent.capacityPreview
Talents

The days a tour ask would land over the city's capacity (LUX-271) — advisory only, the form shows it as a warning and the request always goes through

Input Schema
TypeScript
{
  cityId: string  // UUID identifier
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
{
  days: Array<{
    date: string | any  // Date in YYYY-MM-DD format
    scheduled: number  // Talent already scheduled in the city that day
    capacity: number  // The city's summed daily capacity
  }>  // Only the over-capacity days, earliest first; empty = all clear
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.capacityPreview?input=%7B%22cityId%22%3A%22string%22%2C%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Talent Change Request Queue talent.requestQueue
Talents

Change requests from talent for the requesting company, newest first, optionally filtered by status

Input Schema
TypeScript
{
  status?: "open" | "approved" | "declined"
}
Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  type: "timeOff" | "scheduleChange" | "profileChange" | "profileEdit" | "tour" | "supplies" | "other" | "refund"
  status: "open" | "approved" | "declined"
  talentId: string | null  // Null once the talent is deleted
  talentName: string | null  // Snapshot taken when the request was sent; null on a refund row (LUX-310)
  startDate: string | any | null
  endDate: string | any | null
  cityId: string | null  // Null unless the ask was a tour
  cityName: string | null  // Snapshot taken when the request was sent
  locationId: string | null  // Null unless the ask was for supplies
  locationName: string | null  // Snapshot taken when the request was sent
  note: string | null
  payload: {
    from: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // Her record when she asked
    to: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // What she is asking it to become
  } | null  // The proposed edit on a profileEdit; null on every other type
  clientId: string | null  // Null once the client is deleted
  clientName: string | null  // Snapshot taken when the refund was requested
  appointmentId: string | null  // The cancelled booking the money was recorded on
  refundAmount: number | null
  refundEmail: string | null
  refundPaidAt: string | any | null  // When the money was sent back; null while unpaid
  decisionNote: string | null
  decidedAt: string | any | null  // Null while open
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/talent.requestQueue?input=%7B%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
Optional fields (click to add):
status
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Decide a Change Request talent.decideRequest
Talents

Approves or declines an open change request with an optional note. Approving does not touch the schedule — the office applies that by hand. The exception is a profile edit, which carries the change itself: approving writes it to her profile in the same transaction, and declining leaves the profile untouched

Input Schema
TypeScript
{
  id: string  // UUID identifier
  status: "approved" | "declined"
  decisionNote?: string
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  type: "timeOff" | "scheduleChange" | "profileChange" | "profileEdit" | "tour" | "supplies" | "other" | "refund"
  status: "open" | "approved" | "declined"
  talentId: string | null  // Null once the talent is deleted
  talentName: string | null  // Snapshot taken when the request was sent; null on a refund row (LUX-310)
  startDate: string | any | null
  endDate: string | any | null
  cityId: string | null  // Null unless the ask was a tour
  cityName: string | null  // Snapshot taken when the request was sent
  locationId: string | null  // Null unless the ask was for supplies
  locationName: string | null  // Snapshot taken when the request was sent
  note: string | null
  payload: {
    from: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // Her record when she asked
    to: {
      age?: number | null  // Age in years
      height?: string | null  // Height
      weight?: string | null  // Weight
      measurements?: string | null  // Body measurements
      nationality?: string | null  // Nationality
      hair?: string | null  // Hair color/style
      eyes?: string | null  // Eye color
      tattoos?: boolean | null  // Has tattoos
      enhanced?: boolean | null  // Has cosmetic enhancements
      cupSize?: string | null  // Cup size (VIPKitty-only)
      duos?: boolean | null  // Available for couples/duos (VIPKitty-only)
      tagline?: string | null  // Short promotional headline
      bio?: string | null  // Full bio text
    }  // What she is asking it to become
  } | null  // The proposed edit on a profileEdit; null on every other type
  clientId: string | null  // Null once the client is deleted
  clientName: string | null  // Snapshot taken when the refund was requested
  appointmentId: string | null  // The cancelled booking the money was recorded on
  refundAmount: number | null
  refundEmail: string | null
  refundPaidAt: string | any | null  // When the money was sent back; null while unpaid
  decisionNote: string | null
  decidedAt: string | any | null  // Null while open
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/talent.decideRequest' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string","status":"approved"}'
Test Endpoint
Optional fields (click to add):
decisionNote
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.

User

query
Get Current User user.me
Users

Returns the authenticated user profile

Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  email: string  // Email address
  name: string | null
  role: string | null  // User role — admin, booker, talent, support or user
  phoneNumber?: string | null  // Login phone number, E.164
  talentId?: string | null  // Linked talent id — the performer this account acts as
  seenTours: string[]  // Onboarding tour ids this user has completed or dismissed
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/user.me' \
  -H 'Content-Type: application/json'
Test Endpoint
mutation
Update Own Profile user.updateSelf
Users

Updates the authenticated user profile (name, email) — the settings page. Role and phone are out of reach: role changes are admin-only, phone changes go through the SMS-verify flow.

Input Schema
TypeScript
{
  email?: string  // Email address
  name?: string  // User's display name
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  email: string  // Email address
  name: string | null
  role: string | null  // User role — admin, booker, talent, support or user
  phoneNumber?: string | null  // Login phone number, E.164
  talentId?: string | null  // Linked talent id — the performer this account acts as
  seenTours: string[]  // Onboarding tour ids this user has completed or dismissed
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/user.updateSelf' \
  -H 'Content-Type: application/json' \
  -d '{}'
Test Endpoint
Optional fields (click to add):
email name
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Mark Tour Seen user.markTourSeen
Users

Records an onboarding tour as seen so it never auto-starts again. A no-op while impersonating — standing in as someone must not mark their tours.

Input Schema
TypeScript
{
  tourId: "welcome-admin" | "welcome-booker" | "notifications" | "complete-profile"  // Tour registry id
}
Output Schema
TypeScript
any
Code Examples
Shell
curl -X POST '{{BASE_URL}}/user.markTourSeen' \
  -H 'Content-Type: application/json' \
  -d '{"tourId":"welcome-admin"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Create User user.create
Users

Creates a new user via the auth admin API

Input Schema
TypeScript
{
  email: string  // Email address
  name: string  // User's display name
  password: string  // Account password (min 8 characters)
  role: "user" | "admin" | "booker" | "talent" | "support"  // User role — booker marks staff who take bookings, talent performs, support keeps the locations running
  payRate?: number | null  // Whole dollars per booked appointment; bookers only (D76)
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  email: string  // Email address
  name: string | null
  role: string | null  // User role — admin, booker, talent, support or user
  phoneNumber?: string | null  // Login phone number, E.164
  talentId?: string | null  // Linked talent id — the performer this account acts as
  seenTours: string[]  // Onboarding tour ids this user has completed or dismissed
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/user.create' \
  -H 'Content-Type: application/json' \
  -d '{"email":"string","name":"string","password":"string","role":"user"}'
Test Endpoint
Optional fields (click to add):
payRate
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
Get User by ID user.getById
Users

Returns a user by their ID

Input Schema
TypeScript
{
  id: string  // Unique identifier
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  email: string  // Email address
  name: string | null
  role: string | null  // User role — admin, booker, talent, support or user
  phoneNumber?: string | null  // Login phone number, E.164
  talentId?: string | null  // Linked talent id — the performer this account acts as
  seenTours: string[]  // Onboarding tour ids this user has completed or dismissed
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/user.getById?input=%7B%22id%22%3A%22string%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Update User user.update
Users

Updates an existing user

Input Schema
TypeScript
{
  id: string  // Unique identifier
  data: {
    email?: string  // Email address
    name?: string  // User's display name
    role?: "user" | "admin" | "booker" | "talent" | "support"  // User role — booker marks staff who take bookings, talent performs, support keeps the locations running
    phoneNumber?: any | null
    talentId?: string | null  // Linked talent id — the performer this account acts as
  }
}
Output Schema
TypeScript
{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  email: string  // Email address
  name: string | null
  role: string | null  // User role — admin, booker, talent, support or user
  phoneNumber?: string | null  // Login phone number, E.164
  talentId?: string | null  // Linked talent id — the performer this account acts as
  seenTours: string[]  // Onboarding tour ids this user has completed or dismissed
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/user.update' \
  -H 'Content-Type: application/json' \
  -d '{"id":"string","data":{}}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Set User Password user.setPassword
Users

Sets a new password for a user via the auth admin API

Input Schema
TypeScript
{
  userId: string  // Unique identifier
  newPassword: string
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/user.setPassword' \
  -H 'Content-Type: application/json' \
  -d '{"userId":"string","newPassword":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
mutation
Merge Users user.merge
Users

Folds one user into another and deletes it: bookings, sent texts, payroll rows and uploads move to the survivor; overlapping weekly-payment receipts are summed. The retired login (sessions, passkeys) is destroyed. Irreversible.

Input Schema
TypeScript
{
  keepUserId: string  // The user that survives
  mergeUserId: string  // The user that is retired
}
Output Schema
TypeScript
{
  keptName: string  // The user that survived
  retiredName: string  // The user that no longer exists
  appointmentsMoved: number  // Bookings re-pointed to the survivor
}
Code Examples
Shell
curl -X POST '{{BASE_URL}}/user.merge' \
  -H 'Content-Type: application/json' \
  -d '{"keepUserId":"string","mergeUserId":"string"}'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.
query
List Users user.list
Users

Returns all users

Output Schema
TypeScript
Array<{
  id: string  // Unique identifier
  createdAt: string | any  // Record creation timestamp
  updatedAt: string | any  // Record last-update timestamp
  email: string  // Email address
  name: string | null
  role: string | null  // User role — admin, booker, talent, support or user
  phoneNumber?: string | null  // Login phone number, E.164
  banned?: boolean | null  // Deactivated — no login, no pay
}>
Code Examples
Shell
curl -X GET '{{BASE_URL}}/user.list' \
  -H 'Content-Type: application/json'
Test Endpoint

WeeklyReport

query
Weekly Report weeklyReport.byWeek
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

Input Schema
TypeScript
{
  startDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
  endDate: any  // YYYY-MM-DD string parsed to UTC midnight Date
}
Output Schema
TypeScript
{
  weekStart: string | any  // Date in YYYY-MM-DD format
  weekEnd: string | any  // Date in YYYY-MM-DD format
  moneyIn: {
    cash: number
    emt: number
    giftCard: number
    credit: number
    total: number
  }
  bookerPay: number
  cancellationAgency: number
  talentCredit: number
  expensesByCategory: Record<string, number>
  totalExpenses: number
  generalExpenses: number
  creditPaidOut: number
  totalOut: number
  net: number  // Whole dollars; negative in a loss week
  cities: Array<{
    city: string
    moneyIn: {
      cash: number
      emt: number
      giftCard: number
      credit: number
      total: number
    }
    bookerPay: number
    cancellationAgency: number
    talentCredit: number
    expenses: number
  }>
}
Code Examples
Shell
curl -X GET '{{BASE_URL}}/weeklyReport.byWeek?input=%7B%22startDate%22%3A%22value%22%2C%22endDate%22%3A%22value%22%7D' \
  -H 'Content-Type: application/json'
Test Endpoint
💡 Tip: Schema is pre-filled with required fields. Click badges above to add optional fields.