Skip to main content

Booking Requests

An experience or a rental product can be set to Request to book (booking_mode: "request"). Online bookings for it arrive as requests. Each one holds its time or its stock until the business answers or the reply deadline passes. Nothing is confirmed, and nothing is charged, until the request is approved.

An experience can also use booking_mode: "flexible_request". The customer proposes a date and start time instead of choosing a published departure. Its configured duration supplies the end time. The business can approve that time, decline it, or offer another date and start time.

A request is a booking with status: "requested", so it has the same ID as the booking it becomes. state shows where the request stands:

stateMeaning
waitingWaiting on the business to answer
offeredThe business offered a different time or different dates, and is waiting on the customer
approvedApproved and confirmed, still unpaid
confirmedApproved and paid
declinedDeclined by the business, or turned down by the customer
lapsedNobody answered before request.expires_at

Scopesโ€‹

requests:read to list and read requests. requests:write to approve, decline and suggest.

The request objectโ€‹

{
"id": 1234,
"booking_number": "1234",
"status": "requested",
"state": "waiting",
"type": "rental",
"is_flexible_time_request": false,
"experience": null,
"starts_at": "2026-09-18T00:00:00+00:00",
"ends_at": "2026-09-20T00:00:00+00:00",
"schedule_id": null,
"party_size": 0,
"items": [
{ "name": "Touring bike", "quantity": 2 }
],
"customer": { "id": 55, "name": "Jane Doe", "email": "jane.doe@example.com" },
"total": 120.0,
"total_formatted": "$120.00",
"currency": "usd",
"request": {
"message": "Two of us, first time out.",
"submitted_at": "2026-09-16T02:10:00+00:00",
"expires_at": "2026-09-17T02:10:00+00:00",
"decided_at": null,
"decline_reason": null,
"offered_at": null,
"card_on_file": false
}
}
FieldDescription
typeexperience for a scheduled departure, rental for products with a pickup and return
is_flexible_time_requesttrue when an experience customer proposed the time instead of choosing a published departure
starts_at / ends_atUTC. The departure for an experience; the pickup and return for a rental
schedule_id, party_size, experienceExperience requests only
itemsWhat the customer asked for: each bundle once, and each product not in a bundle
request.expires_atThe reply deadline. The time or stock is held until then
request.card_on_filetrue when a card was saved at request time and will be charged on approval

List requestsโ€‹

GET /v1/booking-requests
ParameterTypeDescription
statestringwaiting, offered, approved, declined or lapsed
searchstringA booking number (with or without #), or the customer's name or email
per_pageinteger1 to 100, default 25

Get a requestโ€‹

GET /v1/booking-requests/{id}

Approveโ€‹

POST /v1/booking-requests/{id}/approve

Confirms the booking after checking the time or stock is still free.

FieldTypeDescription
guide_staff_idintegerOptional. The staff member who leads a guided departure. Without it, a request for a customer-chosen start time gets any guide free and qualified at that time

The response carries a payment block:

payment.statusWhat happened
chargedThe saved card was charged
fell_back_to_linkThe card could not be charged, so the customer was emailed a payment link
collect_laterThe business takes no payments online and collects payment itself
nothing_dueNothing was due

Returns 409 slot_unavailable when the time or the stock has gone, or when no guide can run it.

Declineโ€‹

POST /v1/booking-requests/{id}/decline
FieldTypeDescription
reasonstringFor the business's own records
messagestringA note to the customer
alternative_schedule_idsinteger[]Experience requests only: up to 5 open departures to offer instead

Nothing is charged, and the time or stock is released straight away.

Suggest something elseโ€‹

POST /v1/booking-requests/{id}/suggest

For a scheduled experience request, send schedule_id: another published departure of the same experience.

For a flexible experience request, send proposed_start_at. The experience duration supplies the new end time. ISO 8601 values with an offset are read as that instant. Values without an offset are read in the shop's time zone. The start must fit the shop's opening hours and finish by closing; List Request Start Times returns the times that do.

For a rental request, send pickup_at and return_at (ISO 8601; a time with no offset is read in the shop's time zone). The products are checked for the new dates and the total is recalculated.

FieldTypeDescription
schedule_idintegerExperience requests
proposed_start_atdatetimeFlexible experience requests
pickup_atdatetimeRental requests, with return_at
return_atdatetimeRental requests, after pickup_at
notestringA note to the customer

The request moves to offered, and its deadline restarts on the business's offer window. The customer confirms from the link in their email.

curl -X POST "https://app.equipdash.com/api/v1/booking-requests/1234/suggest" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"pickup_at": "2026-09-19T00:00:00+00:00", "return_at": "2026-09-21T00:00:00+00:00"}'

Webhooksโ€‹

booking_request.created, booking_request.approved and booking_request.declined. A lapse also sends booking_request.declined.