Scheduling & dispatch

Schedule work orders onto calendars or boards by technician, crew, asset, or location. Use the client.scheduling resource to list blocks, schedule or reassign work (drag-and-drop style), validate slots, and unschedule. Set tenant context before calling these methods.

Overview

The client.scheduling resource provides:

  • Views – List schedule blocks for the current tenant, optionally filtered by technician, crew, asset, or location. Use for calendar/board UIs; filter by date range in the client.
  • Schedule – Create or replace a schedule block for a work order (assign to a technician or crew, set start/end time).
  • Update – Change a block’s time, technician/crew, or location/asset (reassign or move on the board).
  • Validate – Check a candidate slot for shift conflicts, schedule block conflicts, and SLA (due date). Returns a list of issues (warning/error/info).
  • Unschedule – Remove the schedule block for a work order (by block id or work order id). Assignments are left as-is; only the slot is removed.

One block per work order is assumed: scheduling again for the same work order replaces the existing block.

List by technician, crew, asset, location

List schedule blocks from the appropriate view. Apply date-range filtering in the client (e.g. filter rows where start_at/end_at fall in the visible range).

client.scheduling.listScheduleBlocks()

await client.setTenant(tenantId)
const blocks = await client.scheduling.listScheduleBlocks()
// Returns ScheduleBlockRow[] (all blocks for tenant)

client.scheduling.listScheduleByTechnician(technicianId?)

const byTech = await client.scheduling.listScheduleByTechnician()
const forOne = await client.scheduling.listScheduleByTechnician('uuid-of-technician')
// Returns ScheduleBlockRow[]

client.scheduling.listScheduleByCrew(crewId?)

const byCrew = await client.scheduling.listScheduleByCrew()
const forOne = await client.scheduling.listScheduleByCrew('uuid-of-crew')
// Returns ScheduleBlockRow[]

client.scheduling.listScheduleByAsset(assetId?) / listScheduleByLocation(locationId?)

const byAsset = await client.scheduling.listScheduleByAsset('uuid-of-asset')
const byLocation = await client.scheduling.listScheduleByLocation('uuid-of-location')
// Returns ScheduleBlockRow[]

Each row includes work_order_title, work_order_status, work_order_priority, work_order_due_date, and effective_location_id / effective_asset_id for display.

Schedule work order

Create a schedule block for a work order. Exactly one of technicianId or crewId must be set. Replaces any existing block for that work order.

client.scheduling.scheduleWorkOrder(params)

const blockId = await client.scheduling.scheduleWorkOrder({
  workOrderId: 'uuid-of-work-order',
  technicianId: 'uuid-of-technician', // or crewId, not both
  startAt: '2026-03-15T08:00:00Z',
  endAt: '2026-03-15T10:00:00Z',
  locationId: null,   // optional; defaults from work order
  assetId: null,      // optional; defaults from work order
})
// Returns string (new schedule block id)
  • Name
    workOrderId
    Description
    Required. Work order UUID.
  • Name
    technicianId
    Description
    Optional. Technician UUID. Exactly one of technicianId or crewId required.
  • Name
    crewId
    Description
    Optional. Crew UUID. Exactly one of technicianId or crewId required.
  • Name
    startAt
    Description
    Required. Block start (ISO timestamptz).
  • Name
    endAt
    Description
    Required. Block end (ISO timestamptz). Must be after startAt.
  • Name
    locationId
    Description
    Optional. Override location for board grouping.
  • Name
    assetId
    Description
    Optional. Override asset for board grouping.

Update schedule block

Update a block’s time, technician/crew, or location/asset. Use for drag-and-drop reassignment or rescheduling.

client.scheduling.updateScheduleBlock(params)

await client.scheduling.updateScheduleBlock({
  scheduleBlockId: 'uuid-of-block',
  startAt: '2026-03-15T09:00:00Z',
  endAt: '2026-03-15T11:00:00Z',
  technicianId: 'uuid-of-another-technician', // optional; maintains technician XOR crew
})
// Returns string (schedule block id)
  • Name
    scheduleBlockId
    Description
    Required. Schedule block UUID.
  • Name
    technicianId
    Description
    Optional. New technician. Cannot set both technicianId and crewId.
  • Name
    crewId
    Description
    Optional. New crew. Cannot set both technicianId and crewId.
  • Name
    startAt
    Description
    Optional. New block start.
  • Name
    endAt
    Description
    Optional. New block end.
  • Name
    locationId
    Description
    Optional. New location for board.
  • Name
    assetId
    Description
    Optional. New asset for board.

Validate schedule

Check a candidate slot for conflicts and SLA. Pass technician (and optionally work order and exclude block id when updating). Returns a list of issues: conflict, sla, priority, or input errors.

client.scheduling.validateSchedule(params)

const issues = await client.scheduling.validateSchedule({
  technicianId: 'uuid-of-technician',
  startAt: '2026-03-15T08:00:00Z',
  endAt: '2026-03-15T10:00:00Z',
  workOrderId: 'uuid-of-work-order',  // optional; for SLA and priority
  excludeBlockId: 'uuid-of-block',    // optional; when updating, exclude this block from conflict check
})
// Returns ValidateScheduleIssueRow[] { check_type, severity, message }
  • Name
    technicianId
    Description
    Optional. Technician UUID. Validation runs for technician only (crew can be extended later).
  • Name
    crewId
    Description
    Optional. Crew UUID. Currently no conflict/availability checks for crew-only.
  • Name
    startAt
    Description
    Optional. Candidate slot start.
  • Name
    endAt
    Description
    Optional. Candidate slot end.
  • Name
    workOrderId
    Description
    Optional. Work order for SLA (due_date) and priority.
  • Name
    excludeBlockId
    Description
    Optional. When updating a block, pass its id to avoid self-conflict.

Severity values: error, warning, info. Check types: conflict, sla, priority, input.

Unschedule work order

Remove the schedule block for a work order. You can pass the schedule block id or the work order id. Work order assignments are not removed; only the scheduled slot is deleted.

client.scheduling.unscheduleWorkOrder(params)

await client.scheduling.unscheduleWorkOrder({ scheduleBlockId: 'uuid-of-block' })
// or
await client.scheduling.unscheduleWorkOrder({ workOrderId: 'uuid-of-work-order' })
  • Name
    scheduleBlockId
    Description
    Optional. Schedule block UUID to delete.
  • Name
    workOrderId
    Description
    Optional. Work order UUID; deletes the block for that work order. One of scheduleBlockId or workOrderId must be set.

Was this page helpful?