Analytics
Free aggregates and rankings over the same corpus — counts and group keys, never record identity.
The analytics plane answers questions about the shape of a market without selling you the records behind it. It is free — every endpoint under /analytics costs zero credits — and it never returns a project id, name, address, contact or document.
| Endpoint | Method | What it does |
|---|---|---|
/analytics/datasets | GET | Self-description: what you can group by, which metrics exist, which are rankable, the ceilings, and a notAnswerable list. |
/analytics/aggregate | POST | Group-by with metrics over the published dimensions. |
/analytics/rankings | POST | A leaderboard with a minimum denominator and a comparison baseline. |
Ask where apartment development concentrates — for zero credits
curl -X POST 'https://api.boardwalkai.com/api/v1/analytics/aggregate' \
-H 'Authorization: Bearer bwk_live_YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{
"dataset": "projects",
"groupBy": [
"city"
],
"metrics": [
"count",
"unitCountSum"
],
"filters": {
"states": [
"UT"
],
"assetClasses": [
"Apartment Building"
]
}
}'Response · HTTP 200
{
"data": {
"dataset": "projects",
"groupBy": [
"city"
],
"groups": [
{
"keys": {
"city": "Salt Lake City"
},
"metrics": {
"count": 142,
"unitCountSum": 18240
},
"coverage": {
"count": 1,
"unitCountSum": 0.9718
}
},
{
"keys": {
"city": "Provo"
},
"metrics": {
"count": 64,
"unitCountSum": 7112
},
"coverage": {
"count": 1,
"unitCountSum": 0.9531
}
}
],
"totals": {
"count": 412,
"unitCountSum": 51230
},
"suppressed": {
"groups": 3,
"records": 9,
"floorK": 5
}
},
"meta": {
"schemaVersion": "2026-08-13",
"suppressionFloorK": 5,
"credits": {
"charged": 0
},
"requestId": "req_01K1QF3M0000EXAMPLE0001"
}
}We were not able to execute this call while writing the page, so treat the body as indicative of the shape rather than as a captured response. If it disagrees with what you receive, what you receive is correct — please tell us.
Default date window
If you omit a meeting-date filter, analytics applies the same default as search: roughly the last year (dateRange=last_1_year). That shows up in meta.appliedDefaults and a default_date_window_applied warning — pass dateRange=all (or an explicit meetingDateFrom / meetingDateTo) when you want the full history. There is no silent default state filter. appliedFilters.states only appears when you sent a state filter. Plan geography ceilings live under meta.geographicScope.enforcedStateIds, not as a fake client filter.
Filters and groupBy use the same state
filters.states and groupBy: ["state"] both mean meeting jurisdiction (the same RediSearch state_id search uses). Send abbreviations, names, or numeric ids — we resolve them to ids for the lookup and echo the mapping in meta.resolvedFrom.
Small groups are suppressed
A group with fewer members than the suppression floor is not returned as its own row. The count of withheld groups and records is under data.suppressed (groups, records, floorK). That stops the free plane being used to reconstruct individual records, and stops a leaderboard whose top row has a denominator of one.
Use /rankings rather than assembling a leaderboard from /aggregate. A ranking carries a minimum denominator and a baseline; a hand-rolled one has neither.
The intended workflow
- 1Aggregate to find where the activity is. Free.
- 2Count the records in the narrowed set. Free.
- 3Search — and pay for — only the records you will act on.
Ready to make a call?
A free Boardwalk trial includes API access and a sandbox key. Counting, taxonomy, location lookups and the analytics plane cost nothing, so you can evaluate the data before you spend a credit.