Group availability and pricing
View .mdUse one catalog response for directory buttons, map popups, and group pages. Do not
recompute a group minimum from paginated property lists in each component.
These additive operations require a collection-wide rates.read grant. A
resource-scoped grant does not authorize an aggregate over other properties.
Choose an operation
Section titled “Choose an operation”| Operation | Use it for |
|---|---|
| GET bookable product groups | Browse canonical catalog groups and their membership. |
| GET bookable product group | Read one group’s catalog detail. |
| GET group availability | Compare availability and observed stay prices for specific dates and guests. |
| GET group from prices | Find observed stay prices across a 90-day arrival window, for an explicit stay length and guest count. |
Supported group scope
Section titled “Supported group scope”These are catalog group operations, not a separate building API. The current
pricing implementation supports static groups classified as BUILDING only.
Canonical NEIGHBORHOOD parents select their child buildings; they are not priced
as independent aggregates. Other classifications, unclassified groups, and dynamic
groups are not supported by these pricing reads. General catalog group reads do
not imply pricing support for every group. Classify groups using the
catalog classification guide.
Dated search
Section titled “Dated search”GET /v1/developer/collections/{collection}/groups/availability?checkIn=2027-01-11&checkOut=2027-01-16&guests=4&host=staging.example.comAuthorization: Bearer YOUR_DEVELOPER_KEYimport { createKismetClient } from '@kismet-tech/sdk/server';
const kismet = createKismetClient({ apiKey: process.env.KISMET_SERVER_KEY!, baseUrl: process.env.KISMET_API_BASE_URL!, // includes /v1 collection: 'your-collection',});
const result = await kismet.bookableProductGroup.availability({ checkIn: '2027-01-11', checkOut: '2027-01-16', guests: 4, host: 'staging.example.com', groupType: 'building', neighborhoodSlugs: ['your-neighborhood'], groupSlugs: ['another-building'],});groupSlug and neighborhoodSlug are repeatable REST parameters. The SDK uses
groupSlugs and neighborhoodSlugs arrays. Selections form a union: selected
neighborhoods expand through canonical parent IDs, then individually selected
buildings are added. Labels, slug conventions, and marketing regions never
define membership. Unrecognized or incorrectly classified selections return a
validation error. Only published inventory participates. Dynamic group membership
is not supported by this operation and returns an explicit error.
Undated “from” search
Section titled “Undated “from” search”GET /v1/developer/collections/{collection}/groups/from-prices?stayLength=5&guests=4&host=staging.example.comAuthorization: Bearer YOUR_DEVELOPER_KEYconst result = await kismet.bookableProductGroup.fromPrices({ guests: 4, stayLength: 5, host: 'staging.example.com',});The REST path is /v1/developer/collections/{collection}/groups/from-prices.
Both guests and stayLength are required. The response declares the 90-day
arrival window and winning stay dates. The current window starts on the UTC
calendar date, declared in meta.calendarDayTimezone; do not describe it as
the property’s local “today.” Full stays can depart after the arrival window.
Requests are bounded to 100 selected buildings and 1,000 unique properties.
Oversized requests fail rather than silently returning an incomplete minimum.
Display prices truthfully
Section titled “Display prices truthfully”- Each group record identifies itself with
groupId,groupSlug, andclassification.semanticType. The current pricing scope returnsBUILDING. The SDK tolerates older responses without classification; do not infer it from the slug or a display name. See classification filters. availabilityisavailable,unavailable, orunknown. Missing or stale evidence is not sold out. Availability is separate from price completeness.lowestStayis the single display price only when coverage is complete and the eligible prices are comparable. Otherwise show Check availability.lowestObservedStaysretains alternatives partitioned by currency, inclusion basis, and estimate/quote kind. These are observed candidates, not proof of an absolute minimum. Never take the numeric minimum across currencies.- Stay totals and average nightly prices are integer minor units. Read
included,excluded,unknownComponents,priceBasis, andpriceKind. Estimates are not chargeable quotes or reservation guarantees. - Respect
dataAsOfandexpiresAt. Partial responses expire immediately and use private/no-store HTTP caching.
Price coverage
Section titled “Price coverage”Kismet checks occupancy, inventory, arrival/departure closures, stay restrictions, rates, and freshness. Applications consume the normalized response regardless of the underlying inventory integration. Do not branch on provider names to decide whether to display a price.
Current coverage includes synchronized base rates, not every eligible rate plan.
The response therefore reports BASE_RATE_ONLY and
INCOMPLETE_RATE_PLAN_COVERAGE; lowestStay remains null even when qualified
base estimates are present. Do not label these estimates “lowest bookable rate.”
Use completeness, coverage reasons, and lowestStay as the display authority.
A successful HTTP response does not by itself mean a complete minimum price exists.
One display decision for every surface
Section titled “One display decision for every surface”Share the returned group record between the directory, map popup, and building
page. Do not substitute an observed candidate when lowestStay is withheld:
const group = result.data[0];if (!group) { // No matching published building. Render your empty state.} else if (group.availability === 'unavailable') { // Not available for this selection; this is not a missing-data state.} else if (group.completeness !== 'complete' || !group.lowestStay) { // Show "Check availability", with no single from-price.} else { const { currency, totalMinor, averageNightlyMinor, included, excluded } = group.lowestStay; // Format using the currency's minor-unit exponent (not always 2). // Show stay total, nightly average, and the returned inclusion information.}// Render a link only when group?.navigation.status === 'declared';// use group.navigation.url verbatim so staging never falls back to production.Request checklist and errors
Section titled “Request checklist and errors”| Parameter | Meaning |
|---|---|
checkIn, checkOut |
Required ISO calendar dates for the dated endpoint; departure must follow arrival. |
stayLength |
Required integer number of nights, 1–90, for the undated endpoint. |
guests |
Required integer occupancy, 1–100. |
host |
Required registered serving hostname, such as staging.example.com; not a URL with a path. |
groupType |
Optional; the supported value is building. |
groupSlug |
Repeat once per individually selected canonical building. |
neighborhoodSlug |
Repeat once per canonical neighborhood whose buildings should be included. |
Read non-success responses as application/problem+json; retain code and
requestId for support. A validation error, missing grant, or dependency failure
is not an empty result and must not become a “sold out” label. Check parameter
validation for 400, credentials for 401, collection-wide grants and permitted
origins for 403, and rate-limit guidance for 429. A 503 requires a retry or an
explicit unavailable-data state, not an invented price.
Links and reusable UI
Section titled “Links and reusable UI”host is a registered serving hostname, not an arbitrary redirect URL. Use
navigation.url for the building link: it comes from declared routes and keeps
the requested staging host, dates, and guests. navigation.status: "unmapped"
means no safe declared link is available; do not substitute the production host.
TEST/LIVE credentials and staging/production hosts are independent concepts.
Use the same result and selection state in all three surfaces. Fixture wiring is optional for API adoption; payment and checkout still use the trusted booking flow. No existing API or fixture is deprecated by these reads.