Federated Search
Cross-app search index for tenant-owned resources.
The Federated Search service maintains an org-scoped search index that traverses application boundaries. Each Caldera app upserts the resources it owns (properties, bookings, partners, journeys, payouts) and consumers query a single endpoint that returns results across all of them.
When to use
- A unified "global search" UI in xAdmin that surfaces matches across Lettings + Concierge.
- An autocomplete dropdown in a partner portal that needs to find a property by partial name.
- A WhatsApp bot that helps an agent locate a guest's booking by typing a name fragment.
The platform performs an ILIKE search over title + keywords. Results are at most 20 per query and ranked by an optional caller-supplied rank. Queries shorter than 2 characters return an empty array.
Endpoints
POST /api/v1/search/index — Upsert a resource into the index
GET /api/v1/search/query — Query the index
Index a resource
{
"app": "lettings",
"entityType": "PROPERTY",
"entityId": "prop_abc",
"title": "Lekki Penthouse",
"subtitle": "3-bed, oceanfront, Lagos",
"keywords": "lekki lagos penthouse 3 bedroom oceanfront luxury",
"rank": 100,
"metadata": { "pricePerNightNGN": 75000 }
}
Accepted asynchronously (HTTP 202). The actual write is performed by the inngest worker; results may take a few seconds to appear in queries. Re-indexing the same (app, entityType, entityId) upserts in place — no duplicates accumulate.
Query
GET /api/v1/search/query?q=lekki&app=lettings
| Query param | Description |
|---|---|
q (required) | Search term — minimum 2 characters. |
app (optional) | Restrict to a single app. |
Response:
{
"results": [
{
"id": "idx_abc",
"organizationId": "org_xyz",
"app": "lettings",
"entityType": "PROPERTY",
"entityId": "prop_abc",
"title": "Lekki Penthouse",
"subtitle": "3-bed, oceanfront, Lagos",
"keywords": "lekki lagos penthouse …",
"rank": 100,
"metadata": { "pricePerNightNGN": 75000 },
"indexedAt": "2026-05-01T12:00:00Z"
}
]
}
Indexing tips
- Re-index whenever the underlying record's display fields change (title rename, status transitions that affect visibility).
- Drop the
metadataobject as small as practical — it round-trips on every query result. - Use
rankto surface featured / high-traffic results first. The platform sorts by rank desc, thenindexedAtdesc. - Queries are case-insensitive. Both
keywordsand the search term are folded.
SDK usage
See the SDK reference for typed examples in TypeScript, Python, and Go.
Scopes required
| Endpoint | Scope |
|---|---|
POST /api/v1/search/index | search:write |
GET /api/v1/search/query | search:read |