Directories: Totals That Match the List
The condo and new development directories show a number next to every area and developer, and that number is what you get when you pick it, also with price, bedrooms or delivery year filters on. Every area also keeps how many condos, communities and new developments it holds, so any section of your website can say "84 condos in Aventura" without another search. Both are in the Site API and in the website widgets.
What you can build
| Piece | What is new | Use it to |
|---|---|---|
| GET /v1/condos/directory/buildings | facets=1 returns facets | Show beside each area or developer what picking it lists, with the other filters applied |
| GET /v1/areas | directory on every area | Show "84 condos in Aventura" in an areas section |
GET /v1/libraries/:id | The same directory on area items | The same, from an areas library of the site |
usePandaDirectory() | facets (areas, developers) | Draw your own area and developer lists with the right totals |
BuildingDetail variant="panda" | listingViews prop | Choose which views the units list offers |
All of it is additive: nothing that already worked changes shape. Requests use the public key of your website (see Getting Started).
Totals per area and developer
Send facets=1 on the first page (offset=0) of the directory search and the response carries facets next to the page. facets.areascounts the matches of every area, keyed by the area's upper-case name (the query of the areas). With forceNewdev=1, facets.developers is a list of { name, count } per developer; without it the list is empty.
Each count is computed with the same search as the list and every filter except its own dimension: areas ignore the area filter and developers the developer filter. So facets.areas.BRICKELL is the totalyou get after selecting Brickell, with price, bedrooms, delivery year and the rest still applied. This example lists new developments from $1M; Brickell's count is the projects of Brickell from $1M.
curl --get "https://api.pandaidx.com/v1/condos/directory/buildings" \--data "key=$PANDA_PUBLIC_KEY" \--data "forceNewdev=1" \--data "minprice=1000000" \--data "facets=1" \--data "limit=24"
{"data": [ ... ],"total": 61,"hasMore": true,"facets": {"areas": { "BRICKELL": 14, "MIAMI BEACH": 9, "SUNNY ISLES BEACH": 7 },"developers": [{ "name": "Related Group", "count": 11 },{ "name": "Fortune International", "count": 4 }]}}
Facets are computed for each request, so ask for them once per filter change and not on every "load more" page. With no filter set, use the unfiltered numbers instead (buildingCount of each area in Directory Bootstrap, or directory below). Every parameter is in Condo Directory Search.
Totals per area in any section
Every area of GET /v1/areas has a directory field: { condos, communities, newDevelopments }. condos and communities count the buildings with a published asking price, like the Condos and Communities tabs of /condos; newDevelopments counts the projects of /new-developments. The area items of an areas library (GET /v1/libraries/:id) carry the same field.
curl --get "https://api.pandaidx.com/v1/areas" \--data "key=$PANDA_PUBLIC_KEY" \--data "placement=homepage"
{"placement": "homepage","libraries": [{"title": "Miami Areas","areas": [{"query": "BRICKELL","name": "Brickell","directory": { "condos": 65, "communities": 0, "newDevelopments": 22 },"paths": { "forSale": "/for-sale/brickell", ... }}]}]}
directory is recalculated every hour and is null until the first run has counted the area: show the area without the number in that case.
Widgets: usePandaDirectory
Inside PandaDirectoryRoot, usePandaDirectory() returns facets with the same two parts: facets.areas["AVENTURA"] next to each area and facets.developers in the list of developers. It is null before the first search and on the landing (no filter), so fall back to buildingCount and developers there. This is a directory built by hand, with the filters and the results of the widget and your own area pills:
"use client"import { PandaDirectoryRoot, usePandaDirectory, type PandaDirectoryData } from "@pandaidx/widgets/client"// Area pills with the total each one lists under the other filters (price, beds, delivery year...).const AreaPills = ({ areas }: { areas: PandaDirectoryData["allAreas"] }) => {const { facets, query, handleSubmit } = usePandaDirectory()return (<ul className="flex flex-wrap gap-2">{areas.map((area) => {// facets is null on the landing (no filter) and before the first search: fall back to buildingCount.const count = facets ? (facets.areas[area.query] ?? 0) : Number(area.buildingCount ?? 0)if (facets && count === 0) return nullconst selected = query.selectedAreas.includes(area.query)return (<li key={area._id}><button type="button" aria-pressed={selected} onClick={() => handleSubmit({ selectedAreas: selected ? [] : [area.query] })}><span className="capitalize">{area.query.toLowerCase()}</span> <span>{count}</span></button></li>)})}</ul>)}export const CondosView = ({ data }: { data: PandaDirectoryData }) => (<PandaDirectoryRoot data={data} detailHref="/condos/{slug}"><AreaPills areas={data.allAreas} /></PandaDirectoryRoot>)
const DeveloperList = () => {const { developers, facets, handleSubmit } = usePandaDirectory()// facets is null on the landing and before the first search: `developers` (every developer, A to Z) fills in.const list = facets ? facets.developers : developersreturn (<ul>{list.map((developer) => (<li key={developer.name}><button type="button" onClick={() => handleSubmit({ developer: developer.name })}>{developer.name} <span>{developer.count}</span></button></li>))}</ul>)}
Widgets: building page
BuildingDetail with variant="panda" takes listingViews, the views its units list offers: grid (big photos), cards (two per row) and list (table). The default offers the three and opens on cards; passing a single view hides the toggle. In the amenities, long lists now go under the title, aligned to the left, and short values like "Yes" stay beside it. That one needs no prop.
import { BuildingDetail } from "@pandaidx/widgets/client"// Units list in cards (2 per row) and a list; the big photo grid is not offered.<BuildingDetail variant="panda" data={data} listingViews={["cards", "list"]} />
Availability
- The API changes are in production.
directorystarts asnulland fills in with the first run of the hourly worker (minute 25 of each hour). facetsofusePandaDirectoryandlistingViewsneed@pandaidx/widgets1.14.0 or later. A website made with the AI Builder gets it from Update widgets; the AI Builder already knows the new pieces.