Search bookable products
View .mdBuild a results page with dates, guest count, and catalog filters. Add an optional natural-language query when visitors want to describe their ideal stay. Both modes use bookableProduct.search() and return cards in ranked. Without a query, no AI retrieval runs. Search does not create a binding quote or authorize a booking.
Optional-query browsing and cursor pagination require the unified-search API extension (v0.7.49) and an SDK build containing these options. Older deployments support the existing query/topK call only; do not silently fall back to a different result set.
Set up access
Section titled “Set up access”Create a collection-scoped installation with search.read using Create an application and key. A browser can use an origin-bound publishable key. A backend can use a restricted server key. TEST and LIVE are separate installations; use TEST for rehearsals.
Search with the SDK
Section titled “Search with the SDK”import { createKismetClient } from '@kismet-tech/sdk';
const kismet = createKismetClient({ apiKey: publishableKey, collection: 'coastal-stays', baseUrl: 'https://api.ksmt.app/v1',});
const result = await kismet.bookableProduct.search({ query: 'quiet beach home with a pool', checkIn: '2027-01-11', checkOut: '2027-01-16', guests: 4, limit: 12,});
for (const hit of result.ranked) { console.log(hit.product.name, hit.product.servingUrl, hit.price?.stay);}Send both dates or neither. Explicit dates and guest count take precedence over facts inferred from the query. The operation reference describes validation and limits.
Browse without a natural-language query
Section titled “Browse without a natural-language query”const filters = { checkIn: '2027-01-11', checkOut: '2027-01-16', guests: 4, minBedrooms: 2, petsAllowed: true, sort: 'name-asc' as const, limit: 12,};const first = await kismet.bookableProduct.search(filters);const next = first.page?.nextCursor ? await kismet.bookableProduct.search({ ...filters, cursor: first.page.nextCursor }) : null;Use group or building to narrow a catalog; minBedrooms, minBathrooms, and petsAllowed are explicit filters. They narrow the authorized published inventory before semantic retrieval. An explicit minimum bedroom count or pet filter takes precedence over the corresponding inferred criterion.
The default sort is recommended without a query and relevance with one. You can also choose name-asc, bedrooms, or sleeps; bedrooms and sleeps put larger properties first. relevance requires a query. Price, map-bound, and arbitrary amenity filters are not fields on this operation.
Page a stable result set
Section titled “Page a stable result set”limitis 1–50 (default 24 for structured browsing). Supplying it opts a semantic query into pagination.- Repeat the same query, dates, filters, sort, and limit with each
cursor. Do not use a cursor after changing a filter. - Results are held for five minutes.
INVALID_CURSORmeans the snapshot expired, parameters changed, or publication/membership changed: clear the cursor and start again. page.totalcounts this search’s result set. Semantic retrieval is bounded, not an exhaustive inventory listing. Structured browsing covers the eligible published catalog; narrow scopes over 1,000 products with a group or building.- Dated availability and pricing are evaluated before pagination. Pages preserve their order and price snapshot; always recheck current availability and price at checkout.
- Existing
query/topKcalls keep their bounded legacy behavior. Do not combinetopKwithlimit.
For a vacation-rental site, use group to search a destination. For an apartment-style collection, use building to search units in a building. Neither requires a separate search implementation.
Equivalent server-side REST request:
curl https://api.ksmt.app/v1/developer/collections/coastal-stays/search \ -H "Authorization: Bearer $KISMET_SECRET_KEY" \ -H 'Content-Type: application/json' \ -d '{"query":"quiet beach home with a pool","checkIn":"2027-01-11","checkOut":"2027-01-16","guests":4,"limit":12}'Render truthful cards
Section titled “Render truthful cards”- Preserve
rankedorder and returned relaxation flags; a relevance score is not availability. - Paginated results include
available:truemeans the synced stay rules fit,nullmeans unknown or no dates. Known-unavailable homes are excluded before paging; never label unknown inventory as sold out. Dated search supports 1–90 nights and up to 16 guests. mode: 'structured'has a score of zero meaning unscored, not low quality. Structured cards may have noservingUrlor undated price; use your own property route and omit missing prices.- Use
product.bathrooms,location, andhomeCollectionwhen present. Do not infer collection membership from names or URLs. price.stay.totalBeforeTaxMinorincludes required fees but excludes taxes.nightlyMinoris the corresponding nightly display amount. Amounts are integer minor units with a currency; do not compare different currencies.price.nightlyFromis an undated indicative amount with its own horizon. Do not substitute it for a missing dated stay price.- Null or absent prices mean no price to display, not zero or sold out. Recheck availability and current pricing through the supported checkout path.
- Older API responses may omit newer card or capture fields. The SDK preserves those omissions rather than inventing defaults.
Optionally record the search on a guest journey
Section titled “Optionally record the search on a guest journey”Pass the existing canonical kid_ session as guestSessionId when available. Do not generate a session just to make capture succeed. A same-origin backend handling a signed-in guest can instead pass its server-held guest access token as guestAccessToken; the SDK sends it in X-Kismet-Guest-Token, not in JSON or a URL. A guest token takes precedence over a supplied session ID.
Search still returns discovery results when no journey can be recorded. Inspect capture separately:
| Result | Meaning |
|---|---|
recorded: true, reason: null |
The ask was recorded on the guest journey. |
no_guest_session |
No guest session was supplied. |
invalid_guest_session |
The supplied guest identity could not be verified. |
no_active_journey |
There is no eligible active journey for this session. |
environment_mismatch |
TEST capture would attach to live guest activity and was refused. |
capture_failed |
Capture failed; discovery results remain usable. |
structured_search |
No natural-language ask was supplied; no ask was recorded. |
continuation_page |
This page continues an existing search; no duplicate ask was recorded. |
TEST asks are sandbox activity and appear only in Developer mode. Capture does not grant marketing consent, enroll a member, or imply a booking. It is also separate from the event ledger and webhook destinations: do not assume every recorded search emits an external webhook.
Verify your integration
Section titled “Verify your integration”Test an undated query, a complete date pair, unknown pricing, an empty result, and a response with relaxed matching. Verify request dates/guests, ranking, currency, and fee/tax labels. For capture, check the response and the correct TEST or LIVE journey; a successful HTTP response alone does not prove capture or semantic ranking.