Service for reading a bookable product's availability and creating guest or
signed-in buyer reservations. Accessible via lynkow.reservations.
Requires a publishable key: pass publishableKey to createClient(...) so
every request carries it. Reservation routes reject calls without a valid key.
A product without an online deposit is confirmed immediately. Use book
for a deposit-aware result: a required deposit returns a pending reservation plus
an opaque hosted-checkout URL, and refreshPayment confirms the status after
the buyer returns. Anti-spam honeypot fields are injected automatically on
book and bookings.create; on reCAPTCHA-protected storefronts pass
options.recaptchaToken. When the same client has a customer session from
customers.activation.confirm() / customers.login() or a customerToken seed, booking
creation automatically attaches it as Authorization: Bearer; the booking then
appears in customers.me() immediately. Guest requests remain unchanged when no
customer token is present. Availability and reservation offerings are not cached:
availability changes on every booking, while a merchant can change or archive an
offering at any time.
Access via: lynkow.reservations
Methods
5 methods
availability
availability(productIdOrSlug: string, filters: AvailabilityFilters): Promise<AvailabilityResponse>Retrieves the computed open slots for a bookable product across a date range. Not cached: availability changes as other buyers book.
Parameter | Type | Description |
|---|---|---|
|
| The bookable product's |
|
| AvailabilityFilters: |
Returns: Promise<AvailabilityResponse>
const { slots, timezone } = await lynkow.reservations.availability('sunset-dinner-cruise', {
from: '2026-07-10',
to: '2026-07-17',
partySize: 2,
})book
book(productIdOrSlug: string, data: BookingCreateData, options?: SubmitOptions & BaseRequestOptions): Promise<BookingDepositResult>Creates a reservation and returns the deposit-aware buyer confirmation. A product
without an online deposit returns the existing confirmed booking shape. When a
deposit is required and available, the reservation is pending and deposit
contains the opaque hosted-checkout URL, payment reference, and guest capability.
Anti-spam fields and the shared customer session are handled exactly like
bookings.create. Existing consumers may keep using that nested method for the
original no-deposit flow; this additive method exposes the new result shape.
Parameter | Type | Description |
|---|---|---|
|
| The bookable product's |
|
| BookingCreateData: chosen slot, party size, buyer contact, and optional resource or offering ids. |
|
| Optional anti-spam and request options, including |
Returns: Promise<BookingDepositResult>
const result = await lynkow.reservations.book('chef-table', {
startsAt: '2026-07-10T18:00:00.000Z',
partySize: 2,
guestName: 'Alice Martin',
guestEmail: '[email protected]',
})
if (result.deposit) {
window.location.assign(result.deposit.checkoutUrl)
}offerings
offerings(productIdOrSlug: string): Promise<ReservationOffering[]>Lists a bookable product's live reservation offerings so the buyer can compare their prices, effective durations, and party-size bounds before choosing a slot. Not cached: a merchant can change a price or duration, or archive an offering, at any time.
A product with no live offerings returns an empty array, so an existing single-price storefront can keep its current booking flow. Once this array is non-empty, BookingCreateData.offeringId is required by the server for that product while offering selection is enabled.
Parameter | Type | Description |
|---|---|---|
|
| The bookable product's |
Returns: Promise<ReservationOffering[]>
const offerings = await lynkow.reservations.offerings('haircut')
for (const offering of offerings) {
console.log(`${offering.label}: ${offering.priceCents} cents, ${offering.durationMin} min`)
}refreshPayment
refreshPayment(paymentId: string, captureToken?: string, options?: BaseRequestOptions): Promise<PaymentRefreshResult>Reconciles a reservation deposit after the buyer returns from hosted checkout. The operation is idempotent and safe to poll. Guests pass the opaque capability returned by book; an authenticated owning customer may omit it because the shared customer session is attached automatically.
Parameter | Type | Description |
|---|---|---|
|
| Opaque payment reference ( |
|
| Optional guest capability from BookingDeposit.captureToken. Required when no owning-customer session is available. |
|
| Optional locale and raw |
Returns: Promise<PaymentRefreshResult>
const result = await lynkow.reservations.book('chef-table', {
startsAt: '2026-07-10T18:00:00.000Z',
partySize: 2,
guestName: 'Alice Martin',
guestEmail: '[email protected]',
})
if (!result.deposit) return
const refreshed = await lynkow.reservations.refreshPayment(
result.deposit.paymentId,
result.deposit.captureToken,
)
if (refreshed.bookingStatus === 'confirmed') {
showConfirmation()
}resources
resources(productIdOrSlug: string): Promise<ReservationResource[]>Lists a bookable product's selectable resources (e.g. stylists, rooms) so the buyer can pick a specific one before booking. Not cached: the pool and the merchant's selection mode can change.
The list is populated only when the merchant sets the product to
customer_optional mode with a resource pool. In auto mode, or for a
non-pooled product, the server returns an empty array, so the storefront
renders no picker. Each returned id is echoed back as
BookingCreateData.resourceId on bookings.create to request that resource.
Parameter | Type | Description |
|---|---|---|
|
| The bookable product's |
Returns: Promise<ReservationResource[]>
// Empty array when the product auto-assigns (auto mode) or has no pool.
const resources = await lynkow.reservations.resources('haircut')
for (const r of resources) {
console.log(`${r.name} (${r.id})`)
}
// Pick a slot, then book the resource the buyer chose (omit resourceId to auto-assign).
const { slots } = await lynkow.reservations.availability('haircut', { from: '2026-07-10', to: '2026-07-17' })
const booking = await lynkow.reservations.bookings.create('haircut', {
startsAt: slots[0].startsAt,
partySize: 1,
guestName: 'Alice Martin',
guestEmail: '[email protected]',
resourceId: resources[0]?.id,
})