Skip to main content

Appointments

A service appointment is a scheduled booking for a service. The recommended flow is to query available slots first, then create the appointment.

Query available slots (TypeScript)

Slot availability is demonstrated in the TypeScript SDK guide.

import { ServiceCandidateSlot } from 'wiil-core-js';

const slotResponse = await client.serviceAppointments.getAvailableSlots({
serviceId: 'service_123',
localDate: '2026-06-22',
providerId: 'person_123',
maxResults: 20,
});

console.log(`Available slots: ${slotResponse.slots.length}`);

A slot carries UTC timestamps (startTimeUtcSec / endTimeUtcSec) to pass directly into create.

Create

const slot = slotResponse.slots[0];
// API expects UTC seconds
const duration = Math.round((slot.endTimeUtcSec - slot.startTimeUtcSec) / 60);

const appointment = await client.serviceAppointments.create({
businessServiceId: 'service_123',
customerId: 'cust_456',
startTime: slot.startTimeUtcSec,
endTime: slot.endTimeUtcSec,
duration: duration,
totalPrice: 80.00,
depositPaid: 20.00,
});

Get

const appointment = await client.serviceAppointments.get('appointment_123');

Get by customer / by service

const byCustomer = await client.serviceAppointments.getByCustomer('cust_123', { page: 1, pageSize: 20 });
const byService = await client.serviceAppointments.getByService('service_123', { page: 1, pageSize: 20 });

Update status

import { AppointmentStatus } from 'wiil-core-js';

const confirmed = await client.serviceAppointments.updateStatus('appointment_123', AppointmentStatus.CONFIRMED);

The standard progression is pending → confirmed → completed.

Cancel

const cancelled = await client.serviceAppointments.cancel(
'appointment_123',
{ cancelReason: 'Customer requested cancellation' }
);

Reschedule

// API expects UTC seconds
const newStartTime = Math.floor(Date.now() / 1000) + (48 * 60 * 60);
const newEndTime = newStartTime + (60 * 60);

const rescheduled = await client.serviceAppointments.reschedule(
'appointment_123',
{ startTime: newStartTime, endTime: newEndTime }
);

List, by provider, by date range, delete (TypeScript)

const all = await client.serviceAppointments.list();
const byProvider = await client.serviceAppointments.getByProvider('person_123', { page: 1, pageSize: 20 });

// API expects UTC seconds
const startDate = Math.floor(Date.now() / 1000);
const endDate = startDate + (7 * 24 * 60 * 60);
const inRange = await client.serviceAppointments.getByDateRange(startDate, endDate, { page: 1, pageSize: 50 });

await client.serviceAppointments.delete('appointment_123');

ServiceAppointment fields

FieldTypeRequiredDescription
businessServiceIdstringYesID of the service being booked
customerIdstringYesCustomer ID
startTimenumberYesStart time (Unix timestamp)
endTimenumberNoEnd time (Unix timestamp)
durationnumberNoDuration in minutes (default: 30)
totalPricenumberNoTotal price for the service
depositPaidnumberYesDeposit amount paid (default: 0)
statusenumYespending, confirmed, cancelled, completed, no_show
providerIdstring | nullNoAssigned ServicePerson ID
Time units

In TypeScript, getAvailableSlots returns UTC seconds — pass slot.startTimeUtcSec directly to create.