Skip to main content
POST
/
api
/
calendar
/
v1
/
public
/
bookings
/
confirmation
/
{confirmation_number}
/
reschedule
Reschedule Booking
curl --request POST \
  --url https://api.example.com/api/calendar/v1/public/bookings/confirmation/{confirmation_number}/reschedule \
  --header 'Content-Type: application/json' \
  --data '
{
  "start_at": "<string>",
  "end_at": "<string>",
  "timezone": "<string>",
  "notes": "<string>"
}
'
{
  "400": {},
  "403": {},
  "404": {},
  "409": {},
  "422": {},
  "booking": {
    "id": "<string>",
    "confirmation_number": "<string>",
    "status": "<string>",
    "start_at": "<string>",
    "end_at": "<string>",
    "service_name": "<string>",
    "organization_name": "<string>",
    "location": {}
  }
}

Endpoint

POST https://api.kordless.ai/api/calendar/v1/public/bookings/confirmation/{confirmation_number}/reschedule
Reschedules an existing booking to a new time slot. This endpoint uses contact verification, allowing customers to reschedule their own bookings.

Authentication

This endpoint uses confirmation number + contact verification instead of an API key.
confirmation_number
string
required
The booking confirmation number (case-insensitive)Example: BOOK_ABC123XYZ
contact
string
required
Email or phone number used when bookingExamples: [email protected] or +1234567890

Request Body

start_at
string
required
New start time in ISO 8601 format (UTC)Example: 2025-12-05T10:00:00Z
end_at
string
required
New end time in ISO 8601 format (UTC)Example: 2025-12-05T11:00:00Z
timezone
string
IANA timezone for display (optional, keeps original if not provided)Example: America/New_York
notes
string
Updated notes (optional)

Response

booking
object
The updated booking

Examples

curl -X POST "https://api.kordless.ai/api/calendar/v1/public/bookings/confirmation/BOOK_ABC123XYZ/[email protected]" \
  -H "Content-Type: application/json" \
  -d '{
    "start_at": "2025-12-05T10:00:00Z",
    "end_at": "2025-12-05T11:00:00Z",
    "timezone": "America/New_York"
  }'

Response Example

{
  "booking": {
    "id": "book_abc123xyz",
    "confirmation_number": "BOOK_ABC123XYZ",
    "status": "confirmed",
    "organization_slug": "acme-salon",
    "organization_name": "Acme Salon",
    "start_at": "2025-12-05T10:00:00Z",
    "end_at": "2025-12-05T11:00:00Z",
    "service_id": "haircut",
    "service_slug": "haircut",
    "service_name": "Haircut",
    "contact": {
      "name": "Jane Doe",
      "email": "[email protected]",
      "phone": "+1234567890"
    },
    "location": {
      "type": "onsite",
      "value": "123 Main St, Suite 100"
    },
    "timezone": "America/New_York"
  }
}

Complete Reschedule Flow

const API_KEY = process.env.KORDLESS_API_KEY;

async function handleReschedule(confirmationNumber, contactInfo) {
  // 1. Look up the current booking
  const { booking } = await lookupBooking(confirmationNumber, contactInfo);

  // 2. Get available slots for rescheduling
  const params = new URLSearchParams({
    from: new Date().toISOString(),
    to: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
    partySize: '1',
    contact: contactInfo
  });

  const slotsResponse = await fetch(
    `https://api.kordless.ai/api/calendar/v1/public/bookings/confirmation/${confirmationNumber}/availability?${params}`
  );
  const { slots } = await slotsResponse.json();

  // 3. Show available slots to customer
  const selectedSlot = await showSlotPicker(slots);

  // 4. Reschedule to selected slot
  const { booking: updated } = await rescheduleBooking(
    confirmationNumber,
    contactInfo,
    {
      startsAt: selectedSlot.startsAt,
      endsAt: selectedSlot.endsAt
    }
  );

  // 5. Show confirmation
  showConfirmation({
    message: 'Your booking has been rescheduled',
    newDate: formatDate(updated.start_at),
    newTime: formatTime(updated.start_at)
  });

  // 6. Send confirmation email
  await sendRescheduleConfirmation(updated);
}

Get Availability for Rescheduling

Use the special availability endpoint that uses confirmation number instead of API key:
async function getAvailabilityForReschedule(confirmationNumber, contactInfo, dateRange) {
  const params = new URLSearchParams({
    from: dateRange.start,
    to: dateRange.end,
    partySize: '1',
    contact: contactInfo
  });

  const response = await fetch(
    `https://api.kordless.ai/api/calendar/v1/public/bookings/confirmation/${confirmationNumber}/availability?${params}`
  );

  if (!response.ok) {
    throw new Error('Could not fetch availability');
  }

  return await response.json();
}

Best Practices

Always verify the new time slot is available:
const { slots } = await getAvailabilityForReschedule(
  confirmationNumber,
  contactInfo,
  { start: nextWeekStart, end: nextWeekEnd }
);

// Show only available slots to customer
const selectedSlot = await showSlotPicker(slots);

// Reschedule to verified slot
await rescheduleBooking(confirmationNumber, contactInfo, selectedSlot);
The slot might be taken between selection and submission:
try {
  await rescheduleBooking(confirmationNumber, contactInfo, newTime);
} catch (error) {
  if (error.status === 409) {
    // Refresh availability
    const { slots } = await getAvailabilityForReschedule(...);
    showError('That time was just booked. Please select another.');
    showSlotPicker(slots);
  }
}
Always notify the customer of the change:
const { booking } = await rescheduleBooking(...);

await sendEmail({
  to: booking.contact.email,
  subject: 'Booking Rescheduled',
  body: `
    Your appointment has been rescheduled.

    NEW DATE: ${formatDate(booking.start_at)}
    NEW TIME: ${formatTime(booking.start_at)}

    Confirmation #: ${booking.confirmation_number}
    Service: ${booking.service_name}
    Location: ${booking.location.value}
  `
});
Ensure the new time slot has the same duration:
// Calculate original duration
const original = await lookupBooking(confirmationNumber, contactInfo);
const duration = new Date(original.booking.end_at) - new Date(original.booking.start_at);

// Apply same duration to new start
const newStart = new Date(selectedSlot.startsAt);
const newEnd = new Date(newStart.getTime() + duration);

await rescheduleBooking(confirmationNumber, contactInfo, {
  startsAt: newStart.toISOString(),
  endsAt: newEnd.toISOString()
});

Errors

400
Bad Request
Invalid request data
{
  "detail": "start_at is required"
}
403
Forbidden
Contact doesn’t match booking
{
  "detail": "We could not verify that booking with the provided contact information."
}
404
Not Found
Booking not found
{
  "detail": "Booking not found"
}
409
Conflict
New time slot not available
{
  "detail": "Time slot is no longer available"
}
422
Unprocessable Entity
Cannot reschedule (e.g., already canceled)
{
  "detail": "Cannot reschedule a canceled booking"
}