Skip to content

Booking flow

All paths below are relative to https://api.kisum.io/venues/public/v1/sites/{siteKey}. The full request and response fields are in the API reference.

Every request after the space list carries a spaceId, so the API always knows which space you mean. There are two ways to fill it in.

The website key covers all the venue’s spaces. GET /spaces returns them all, the form shows them in a select, and the visitor picks one:

const spaces = await call('/spaces');
// The visitor picks one; spaceId is the selected option's value.

The venue creates one website key per space and limits each key to that space. Your page for that space uses that key, and the space list comes back with exactly one space:

const [space] = await call('/spaces'); // Only the space this key covers.
const spaceId = space.id; // Used in every later request; no space field in the form.

The visitor chooses the space in your website’s own menu by opening that page. The form only asks for the date, the slot and package, and the contact details.

Slots, availability, quotes and booking requests accept only the spaces the key covers. Any other spaceId returns 404, even when that space exists and is published, so a one-space page cannot book the wrong space.

You can also hard-code the space ID instead of reading /spaces first, but then a space the venue replaces starts returning 404. Reading the list on page load is safer and costs one request.

GET /spaces

Returns the venue’s active spaces with a published listing: name, capacity, description, amenities, photos and layouts. Use id in the next requests.

GET /spaces/{spaceId}/slots

Returns the time slots a space can be booked for, such as an evening slot from 18:00 to 23:00, and the packages offered for each slot.

For each package:

  • hireFeeCents is the hire fee before tax.
  • hireFeeWithTaxCents is the hire fee including the tax the venue charges today. Tax rates can change, so show it as an estimate.
  • taxRateMissing is true when the venue has not set up tax for part of the fee yet; that part then has no tax in hireFeeWithTaxCents. Show the fee as “plus tax”.
  • showPrices is present when the fee drops as the organizer books more shows: one entry per step, fromShow and the rent netCents from that show on. showPricesAcrossBookings is true when the count runs across the organizer’s bookings within the venue’s loyalty window, false when it counts shows inside one booking.
  • deal describes the package’s deal in plain words, ready to print. conditions (each {label, value}, for example Rent fee / Higher of IDR 50,000,000 or 15% of ticket sales, per show, Venue share of F&B / 70%, Minimum F&B spend / IDR 30,000,000), cascade (one {label, value} per show or day step, for example Rent fee, show 2 / IDR 85,000,000 per show · 15% off; empty when the fee does not step) and notes (for example Shows are counted within a single booking.; the ticketing rule is not in deal). It holds no deposit, payment or cancellation term. Absent when the package has no rules.
  • ticketing is the package’s ticketing rule as data: exclusivity (exclusive or open) and, for an open package, minPartnerShareBps (minimum share through the venue’s channels). Absent when the package records no rule. Each site writes its own words for it.
  • dayPrices (fromDay, netCents) lists a rent stepped by booked day within one booking, like showPrices does by show. Absent otherwise.

Slots without a package are not returned. Slot times are in the venue’s time zone (timezone in GET /venue).

GET /spaces/{spaceId}/availability?from=2026-10-01&to=2026-10-31

Returns one entry per date. Each entry lists the slots with free: true or free: false, and how many requests already queue for them:

{
"date": "2026-10-01",
"slots": [
{ "slotId": "3f1c...", "free": true, "holds": 0 },
{ "slotId": "9b7e...", "free": true, "holds": 2 },
{ "slotId": "8a2d...", "free": false, "holds": 0 }
]
}
  • The range can cover up to 92 days.
  • A slot is not free when the venue has committed to a booking or an event on it, when the venue blocked it, or when it has already started.
  • holds is how many requests are waiting for an answer on that slot, including a request the venue answered with a counter-offer. A free slot with holds can still be requested: the new request joins the queue behind them, and the venue answers them in order. Tell the organizer where they would stand.
  • A slot with five holds is full and comes back free: false.
  • Match slotId with the slots from step 2. Ignore any slot that step 2 did not return.
POST /quote
{
"spaceId": "…",
"slotId": "…",
"packageId": "…",
"date": "2026-10-01"
}

Returns the price for the selected package, slot and date:

  • hireFeeCents: total before tax
  • taxCents: the tax the venue charges today
  • totalCents: total including that tax
  • taxRateMissing: true when the venue has not set up tax for part of the price yet; taxCents then leaves that part out, and the venue adds the tax when it invoices
  • dueNowCents: amount due after the contract is signed, before tax
  • lines: the price breakdown, before tax
  • payments: the payment instalments the venue will invoice if the booking is confirmed, before tax

Each payment has amountCents and dueBasis, which states when it is due:

dueBasisDue
after_signingAfter the contract is signed. offsetDays is the number of days after signing.
before_eventBefore the event. offsetDays is the number of days before the event.
before_onsaleBefore tickets go on sale. offsetDays is the number of days before the event.
after_settlementAfter the event is settled. offsetDays is the number of days after the event.
fixed_dateOn fixedDate.
deducted_from_ticket_salesDeducted from the event’s ticket sales.

The quote is for display only. It does not hold the date.

POST /booking-requests
{
"spaceId": "…",
"slotId": "…",
"packageId": "…",
"date": "2026-10-01",
"guest": {
"name": "Ana Putri",
"email": "ana@example.com",
"phone": "+62 812 0000 0000",
"company": "Sunset Live"
},
"message": "Album launch for 400 guests.",
"website": ""
}
  • guest.name and guest.email are required. guest.phone, guest.company and message are optional.
  • website is a spam protection field. Keep it hidden from visitors and always send it empty. See Spam protection.

A successful request returns 201:

{
"success": true,
"message": "Request sent. The venue will get back to you.",
"data": {
"reference": "TSB-2026-0042",
"status": "pending_approval",
"holdPosition": 2,
"holdExpiresAt": "2026-09-20T10:00:00Z"
}
}

reference is the booking number the guest quotes to the venue: the venue company’s three-letter code, the year of the event and the number of the booking in that year (TSB-2026-0042). The venue sees the same number.

Show the reference to the visitor. holdPosition is where the request stands in the queue for that date: 1 is answered first, and the venue works down the queue. If the venue confirms someone else in the meantime, or the date already carries five requests, the API returns 409. Ask the visitor to select another date.

The venue reviews the request in Kisum Venues and accepts or declines it. The venue contacts the visitor directly using the details in the request. The API does not send emails and does not report the decision back to your website.