Skip to main content

Get Booking

Retrieve a single booking by its ID.

Endpointโ€‹

GET /v1/bookings/{id}

Authenticationโ€‹

Requires an API key with the bookings:read scope.

Parametersโ€‹

ParameterTypeLocationDescription
idintegerpathThe booking ID

Responseโ€‹

Success (200 OK)โ€‹

{
"data": {
"id": 123,
"type": "rental",
"line_types": ["rental"],
"status": "confirmed",
"payment_status": "partial",
"source": "Online Booking",
"quote": null,
"attribution": {
"gclid": "EAIaIQobChMI...",
"gbraid": null,
"wbraid": null,
"fbclid": null,
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "summer-rentals",
"utm_term": null,
"utm_content": null,
"landing_url": "https://example.com/book?gclid=EAIaIQobChMI...",
"ref": "summer-flyer"
},
"start_date": "2026-01-15T09:00:00+00:00",
"end_date": "2026-01-17T17:00:00+00:00",
"duration_label": "3 Days / 2 Nights",
"multi_day": true,
"checked_in_at": null,
"completed_at": null,
"no_show_at": null,
"no_show_by": null,
"no_show_emails": true,
"currency": "USD",
"pricing": {
"subtotal": 250.00,
"total": 281.00,
"discount": {
"enabled": true,
"type": "percentage",
"value": 10
},
"payment_method_discount": null,
"promo_code": {
"code": "SUMMER10",
"amount": 15.00
},
"voucher": null,
"taxes": [
{
"name": "GST",
"rate": 10,
"amount": 21.00,
"included_in_price": false
}
],
"security_deposit": 50.00
},
"pickup_location": {
"id": 1,
"name": "Main Store",
"address": "123 Beach Road, Bondi NSW 2026, AU"
},
"return_location": {
"id": 1,
"name": "Main Store",
"address": "123 Beach Road, Bondi NSW 2026, AU"
},
"customer": {
"id": 456,
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"phone": "0412345678",
"phone_country_code": "+61"
},
"products": [
{
"id": 1,
"product_id": 10,
"product_name": "Mountain Bike",
"variation_id": 20,
"variation_name": "Large",
"bundle_in_booking_id": null,
"content_picks": [],
"fulfillment_status": "confirmed",
"quantity": 2,
"shortage_quantity": 1,
"rental_start": "2026-01-15T09:00:00+00:00",
"rental_end": "2026-01-17T17:00:00+00:00",
"price": 100.00,
"interval_units": "day",
"price_per_interval": 50.00,
"max_schedule_interval": null,
"additional_units": null,
"additional_unit_price": null,
"picked_up": null,
"returned": null
}
],
"experiences": [
{
"id": 55,
"experience_id": 3,
"experience_name": "Guided Coastal Excursion",
"schedule_id": 45,
"start_at": "2026-11-21T01:30:00+00:00",
"end_at": "2026-11-21T03:00:00+00:00",
"booking_option_id": 4321,
"booking_option_label": "Group class",
"unit_name": null,
"unit_name_plural": null,
"unit_summary": null,
"rate_category_id": null,
"quantity": 3,
"max_participants": 2,
"booked_participants": 6,
"actual_participants": 6,
"unit_price": 279.00,
"price": 809.10,
"below_min_fee_amount": null,
"below_min_fee_label": null,
"volume_discount_amount": 27.90,
"extras": [],
"package_choices": []
}
],
"bundles": [],
"payments": [
{
"id": 789,
"amount": 100.00,
"payment_method": "credit_card",
"offline_method": null,
"status": "completed",
"transaction_id": "txn_abc123",
"payment_provider": "stripe",
"gateway_reference": "pi_3Nabc123",
"gateway_refund_reference": null,
"stripe_fee": 3.20,
"stripe_fee_tax": 0.32,
"platform_fee": 1.00,
"payout_id": "po_1Nexample",
"reference": null,
"payment_date": "2026-01-10T00:00:00+00:00",
"created_at": "2026-01-10T14:30:00+00:00"
}
],
"custom_charges": [
{
"id": 1,
"description": "Delivery fee",
"quantity": 1,
"unit_price": 20.00,
"price": 20.00
}
],
"tags": [
{
"id": 1,
"name": "VIP"
}
],
"notes": [
{
"id": 1,
"text": "Customer requested early pickup",
"created_by": {
"id": 5,
"name": "Jane Smith"
},
"created_at": "2026-01-10T10:00:00+00:00"
}
],
"custom_fields": [
{
"field_id": 1,
"label": "License Number",
"field_type": "text",
"value": "DL-123456",
"formatted_value": "DL-123456"
}
],
"created_at": "2026-01-10T09:00:00+00:00",
"updated_at": "2026-01-10T14:30:00+00:00"
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-01-15T12:00:00+00:00"
}
}

Cancelled Bookingโ€‹

Cancelled bookings include additional cancellation details:

{
"data": {
"id": 123,
"status": "cancelled",
"cancellation": {
"reason": "change_in_travel_plans",
"notes": "Customer rescheduling for next month"
},
...
}
}

Response Fieldsโ€‹

Bookingโ€‹

FieldTypeDescription
idintegerUnique booking identifier
typestringrental or experience
statusstringSee Booking Status
payment_statusstringunpaid, partial, paid, refunded
sourcestringWhere the booking was created (e.g., "Online Booking", "POS")
quoteobject|nullPresent when the booking began life as a quote: id, quote_number (e.g. "Q-123"), accepted_at (ISO 8601). The quote endpoints still serve its proposal history. null for bookings that never were a quote
start_datestringISO 8601 datetime
end_datestringISO 8601 datetime. For a multi-day experience departure this is the return instant (a later day)
rental_windowobject|nullWhen the gear is out, as start and end ISO 8601 datetimes. On a booking with gear and an activity, start_date and end_date cover both, and this is the gear's part. null when the booking has no gear
duration_labelstringOwner-facing duration. For a multi-day experience departure this is the trip length in tour-operator phrasing (days first, nights = days โˆ’ 1), e.g. "3 Days / 2 Nights"; otherwise the elapsed duration
multi_daybooleantrue when this is a multi-day experience departure (one booking spanning several days)
checked_in_atstringnull
completed_atstringnull
no_show_atstring|nullWhen staff marked the booking as a no-show (ISO 8601). null unless status is no_show. One person in a group is on participants[].no_show_at instead
no_show_byobject|nullWho marked it: id and name. null when it was marked with an API key, which has no person behind it
no_show_emailsboolean|nulltrue when marking the whole booking now makes it read no_show, so email_customer would send the We missed you email. false when part of it already went ahead and the mark would leave it as it is. Use it to decide whether to offer an "Email the customer" choice
currencystringISO 4217 currency code
pricingobjectPricing breakdown
pickup_locationobject|nullPickup location (id, name, address)
return_locationobject|nullReturn location (id, name, address)
customerobjectCustomer details
productsarrayProducts in booking (rentals). Each line carries shortage_quantity โ€” see Shortage on a rental line
experiencesarrayExperiences in booking. Each line carries start_at and end_at (ISO 8601, UTC): when it actually runs. On an open-window experience that is the start chosen for that day and that start plus the experience length; otherwise the session's own start, and its start plus the experience length. A booking can hold the same experience on several days, one line per day
bundlesarrayBundles in booking
paymentsarrayPayment transactions
passes_soldarrayPasses bought on this booking: id, name, holder_name, code, price, visits_total (null = unlimited), visits_left, status. Single-booking responses only
gift_cards_soldarrayGift cards bought on this booking: id, amount, currency, recipient_name, recipient_email, message, status (pending until paid, then issued; cancelled if the booking is cancelled first), voucher_id and code (both null until issued), issued_at. Single-booking responses only
custom_chargesarrayAdditional charges
tagsarrayAssociated tags
notesarrayStaff notes
cancellationobjectOnly present for cancelled bookings
custom_fieldsarrayCustom field values for this booking
participantsarrayPer-participant rows (experiences and multi-person rentals). Each carries a waivers array (see Participant Waiver Status), plus gear_sizes and missing (see Participant Sizes and Missing Answers). checked_in_at and no_show_at say whether the person came; no_show_at is null once they check in. Use id with Mark a No Show
payment_providerstringThe gateway this shop takes card payments on: stripe, paystack, rapyd, authorizenet or tilopay. Read it before building a card form, rather than assuming Stripe
security_deposit_statusstringSecurity-deposit lifecycle: none, held, charged, released, captured. The amount lives on pricing.security_deposit.
deposit_saved_card_availablebooleantrue when the card from an online checkout was saved and the deposit can be held on it without the customer present
card_readers_availablebooleanfalse when the shop's payment provider has no card readers, so in-person card collection is not offered. Only Stripe offers them today
has_booking_requestbooleantrue when the booking came in as a request, so GET /v1/booking-requests/{id} returns it. Single-booking responses only
fit_ticket_availablebooleantrue when an item or experience on the booking takes a fit (set on it or on its product type), so GET /v1/bookings/{id}/fit-ticket returns one rather than 422. Single-booking responses only
security_deposit_lotsarrayPresent on single-booking responses when the deposit is split into parts (e.g. a group where each participant pays their own). One entry per part โ€” see Split Security Deposits. Empty array when not split.
created_atstringISO 8601 datetime
updated_atstringISO 8601 datetime

Rental fulfillment and inventoryโ€‹

Each product line carries fulfillment_status: confirmed, picked_up, returned, cancelled, or no_show. Use it for the line's status. Tracked rentals record pickup and return on their inventory_items; the line's picked_up and returned timestamps can remain null.

inventory_items contains stock reserved directly for that rental's booking and selected variation. It excludes reservations for extras, linked kit contents, and experience gear, even when they use the same product. Each item carries its inventory-log id, inventory_id, identifier, location, quantity, picked_up, and returned. Read these item timestamps when offering partial pickup or return.

fulfillment_items is present on single-booking responses. It groups each rental's own stock, extras, and linked kit parts for pickup and return. Use these rows when presenting individual or group selection; each row supplies its kind, quantity, product_name, inventory-log id (or a pib_ line ID for untracked stock), fulfillment_status, and pickup and return timestamps. Completed rows remain visible. Repeated lines for the same product keep their own stock rows.

rate_label describes the saved quoted rate, for example day for a daily rate or a named duration for a total price. rate_mode is perUnit or total for saved quotes, and null on older lines. Show price_per_interval with rate_label, and use price for the line total. Later catalog edits do not change a saved quote's wording.

Payment Fieldsโ€‹

Each entry in payments names the gateway that took the money:

FieldTypeDescription
payment_providerstringstripe, paystack, rapyd, authorizenet or tilopay
gateway_referencestring|nullThe gateway's own id for the payment (a Stripe PaymentIntent, a Paystack reference, a Rapyd payment id, an Authorize.net transaction id or a Tilopay order number). null for cash, bank transfer and other offline payments
gateway_refund_referencestring|nullThe gateway's own id for a refund, which is a separate transaction from the payment it reverses. null on payment rows and on offline refunds
stripe_feenumber|nullThe fee Stripe took on this payment
stripe_fee_taxnumber|nullThe tax Stripe charged on its fee (for example GST or VAT), where Stripe charges one
platform_feenumber|nullThe EquipDash fee taken from this payment
payout_idstring|nullThe Stripe payout this payment went out in (po_...)

stripe_fee, stripe_fee_tax, platform_fee and payout_id are null until Stripe has settled the charge, and always null on payments not taken through Stripe.

Split Security Depositsโ€‹

A booking's security deposit can be collected in multiple parts, each with its own amount and lifecycle, optionally linked to a participant. When split, the booking-level security_deposit_status is an aggregate (held while any part is held, released once every part is released, and so on) and security_deposit_lots carries the detail:

"security_deposit_lots": [
{
"id": 12,
"name": "Jane Doe",
"booking_participant_id": 45,
"participant_email": "jane.doe@example.com",
"amount": 200.00,
"status": "held",
"hold_error": null,
"taken_by": "Cash"
}
]
FieldTypeDescription
idintegerThe deposit part's identifier
namestringDisplay name โ€” the linked participant's name, or a custom label
booking_participant_idinteger|nullThe participant paying this part, when linked
participant_emailstring|nullThat participant's email (used for payment links)
amountnumberThis part's amount
statusstringnone, held, charged, released, captured
hold_errorstring|nullLast collection failure for this part (e.g. a card decline)
taken_bystring|nullHow the part was collected (Card, Cash, โ€ฆ) once held/charged

Participant Waiver Statusโ€‹

Each participant carries a waivers array โ€” one entry per waiver/form that applies to the booking โ€” so you can render per-person completion exactly like the dashboard:

"waivers": [
{ "form_id": 5, "form_name": "Liability Waiver", "signed": true, "on_file": false, "valid_until": null, "response_id": 91 },
{ "form_id": 8, "form_name": "Membership Consent", "signed": true, "on_file": true, "valid_until": "2027-07-22", "response_id": 74 },
{ "form_id": 9, "form_name": "Health Declaration", "signed": false, "on_file": false, "valid_until": null, "response_id": null }
]
FieldTypeDescription
form_idintegerThe waiver/form identifier
form_namestringThe waiver/form name
signedbooleantrue when this participant has satisfied the form โ€” by a signature on this booking or a still-valid consent on file. Never re-ask when true
on_filebooleantrue when signed is satisfied by a consent on file โ€” a still-valid signature carried over from an earlier booking โ€” rather than a fresh signature on this booking
valid_untilstring|nullDate (YYYY-MM-DD) the consent on file remains valid through; null unless on_file is true
response_idinteger|nullThe satisfying form response id (use with the waiver response endpoints to fetch the signed record); null when unsatisfied

Participant Sizes and Missing Answersโ€‹

When an experience on the booking asks each person their size of an item, or asks a question of the shop's own, each participant carries what they gave and what is still to come:

{
"id": 45,
"first_name": "Jane",
"last_name": "Doe",
"gear_sizes": [
{ "product_id": 41, "item": "Wetsuit", "size": "M" }
],
"missing": ["Helmet size", "Can you swim 50m?"]
}
FieldTypeDescription
gear_sizesarrayOne row per item this person gave a size for: product_id, item (the item's name) and size. A size given for an item the experience no longer asks about stays here. Empty when there are none
missingstring[]The questions this person has not answered yet, by label: sizes and the shop's own questions. Empty when nothing is missing

The answers to the shop's own questions are in custom_fields. A booking can be saved with something still missing; set it later with Update Participant. What each experience asks is listed by List Questions.

Pricing Objectโ€‹

FieldTypeDescription
subtotalnumberPrice before tax.
totalnumberTotal including tax.
discountobjectManual discount on the booking (enabled, and when enabled type, value, amount).
payment_method_discountobject|nullThe in-person payment-method discount (cash / debit / bank transfer). null when none is applied, otherwise { "rate": <percent>, "amount": <currency>, "label": <string> }. Apply or clear it with PUT /v1/bookings/{id}/payment-method-discount.
promo_codeobject|nullApplied promo code (code, amount) or null.
voucherobject|nullApplied voucher / gift card (code, amount) or null.
taxesarrayTax lines: name, rate, amount, included_in_price.
security_depositnumber|nullSecurity-deposit amount, or null when none.

Custom Fieldsโ€‹

FieldTypeDescription
field_idintegerCustom field definition ID
labelstringField display label
field_typestringField type: text, textarea, number, date, datetime
valuestring|nullRaw value
formatted_valuestring|nullFormatted value for display
tip

Custom field definitions can be retrieved via GET /v1/settings/custom-fields.

Booking Statusโ€‹

StatusDescription
draftBooking is being created
confirmedBooking is confirmed, awaiting pickup/check-in
picked_upCustomer has picked up items (rental)
checked_inCustomer has checked in (experience)
returnedItems have been returned (rental)
completedBooking is complete
no_showThe customer never came. The seat stays sold, the revenue is kept, the rental items are free for other bookings, and any balance is still due. See Mark a No Show
cancelledBooking has been cancelled

Shortage on a rental lineโ€‹

Each entry in products reports how much of the line was covered by stock the shop actually had:

FieldTypeDescription
shortage_quantityintegerHow many units of this line were sold past on-hand stock. 0 means the line was fully covered by real stock

A non-zero value means the product is set to keep selling when sold out and this booking used part of that allowance โ€” the shop needs to source that many extra units before the pickup date. The line is a normal confirmed line in every other respect; quantity is still the full quantity booked, not the covered part.

When the gear is outโ€‹

A booking that holds gear and an activity (a lesson, a tour) has a start_date and end_date that cover both. Each entry in products carries the gear's own window:

FieldTypeDescription
rental_startstring|nullISO 8601 datetime the gear is picked up
rental_endstring|nullISO 8601 datetime the gear is due back

Both are null on lines saved before these fields existed. Read the booking's rental_window for those.

Group booking rules on an experience lineโ€‹

A group-priced experience line reports its quantity in groups (quantity), with max_participants people covered per group. When the experience carries booking rules, the line also returns:

FieldTypeDescription
below_min_fee_amountnumber|nullFee charged once because the line has fewer groups than the experience's minimum. null when no fee applied
below_min_fee_labelstring|nullThe shop's name for that fee. null = show the localized default ("Small-group fee")
volume_discount_amountnumber|nullMoney taken off for booking multiple groups. null when no discount applied

Both amounts are already folded into price โ€” the fee added, the discount subtracted. Render them as sub-lines for transparency; never add or subtract them from price again.

The booking option on an experience lineโ€‹

When the shop sells an experience more than one way, the line says which way it was sold as. See Booking options.

FieldTypeDescription
booking_option_idinteger|nullThe booking option this line was sold as. null on a line taken before the shop set its options up
booking_option_labelstring|nullThe option's name as it read when the booking was taken. Null unless the shop sells that experience more than one way - see the note below

The label is a snapshot, so renaming the option or retiring it never rewrites an existing booking. A shop that sells its experience one way still gets both fields filled, with the single option it has.

Lines sold per unitโ€‹

FieldTypeDescription
unit_namestring|nullWhat each group was sold as ("canoe"), when the experience is priced per unit. null on an ordinary group or per-person line
unit_name_pluralstring|nullThe plural that goes with it ("canoes"). null when unit_name is null
unit_summarystring|nullThe line as the shop reads it: "2 canoes ยท 4 people", or "3 canoes" when the experience has no people limit per canoe and no headcount was asked. null when unit_name is null

Both are a snapshot of the word the line was sold under, so renaming it on the experience never rewrites a booking. When unit_name is set, quantity is the number of units and booked_participants is the number of people: "quantity": 2, "booked_participants": 4 reads as 2 canoes, 4 people. When it is null, quantity means what it always has.

Options picked inside a kitโ€‹

A kit is a product made of other products (a camping kit holds a tent, sleeping bags and a cooler). When the shop lets the customer pick the option for a part, each line in products says what was picked.

FieldTypeDescription
content_picksarrayOne entry per part the customer picked an option for: {"part_id": 957, "part": "YETI Tundra (Cooler)", "option": "65 QT", "text": "YETI Tundra (Cooler): 65 QT"}. Empty on a line that is not a kit, or when nothing was picked

text is the line the shop's own screens and emails print. To set the options when creating a booking, send content_variations on the product line (see Create a booking).

A booking on several daysโ€‹

FieldTypeDescription
check_in_dayobject|nullOn a booking with the same activity on several days, the day the next check-in call checks in: today, else the most recent day missed, else the next day to come. Same shape as day_to_check_in. null on a one-day booking and once every day is checked in
day_to_check_inobject|nullOn a booking with the same activity on several days, the day still to check in, dated today or later: {"date": "2026-11-23", "starts_at": "2026-11-23T00:00:00+00:00"}. null on a one-day booking and once no day is still to come (the booking can then be completed)

Errorsโ€‹

StatusCodeDescription
401authentication_requiredNo API key provided
401invalid_api_keyInvalid API key
403insufficient_scopeAPI key lacks bookings:read scope
403forbiddenBooking belongs to different supplier
404resource_not_foundBooking does not exist

Example Requestโ€‹

curl -X GET "https://app.equipdash.com/api/v1/bookings/123" \
-H "Authorization: Bearer eqd_live_abc123xyz789..."

Example Error Responseโ€‹

{
"error": {
"code": "resource_not_found",
"message": "The requested booking was not found."
},
"meta": {
"request_id": "req_def456"
}
}