Quickstart
Sign up, mint a key, and make your first successful call — including a metered one — in about five minutes.
Four steps. The first three cost nothing, so you will know the key works and what your query costs before you spend a credit.
1. Get a key
Sign up — a free trial includes API access — then mint a key on your API settings page. You do not need a paid subscription to create a key; entitlement is checked when you call, not when you mint.
Keys carry their environment in the prefix. bwk_test_ is a sandbox key; bwk_live_ reads the production corpus and spends credits. Keys issued before the Boardwalk rename begin with csk_ and keep working indefinitely — there is nothing you need to do.
2. Prove the key works, for free
List the states you can filter by
curl 'https://api.boardwalkai.com/api/v1/locations/states' \
-H 'Authorization: Bearer bwk_live_YOUR_KEY'Response · HTTP 200
{
"data": [
{
"id": 44,
"name": "Utah",
"abbreviation": "UT",
"projectCount": 41822
},
{
"id": 6,
"name": "Colorado",
"abbreviation": "CO",
"projectCount": 18304
},
{
"id": 3,
"name": "Arizona",
"abbreviation": "AZ",
"projectCount": 15977
}
],
"meta": {
"count": 3
}
}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.
A 200 here means your key is good. If you get 401, the credential did not reach us — check that the header is Authorization: Bearer … and that you copied the whole key.
3. Ask what your real query would cost
Add one filter and the same query becomes affordable
curl 'https://api.boardwalkai.com/api/v1/projects/count?states=UT&assetClasses=Apartment%20Building&meetingDateFrom=2026-05-01&totalUnitCountMin=50' \
-H 'Authorization: Bearer bwk_live_YOUR_KEY'Response · HTTP 200
{
"data": {
"matchCount": 250,
"matchCountIsExact": true,
"matchCountBasis": "enumerated",
"countedAs": "distinct_projects",
"scanCeiling": 10000,
"billable": {
"records": 250,
"credits": 250,
"creditRate": 1,
"isUpperBound": true,
"nonBillable": {
"alreadyDeliveredUnchanged": 0,
"ledgerApplied": true
}
},
"affordability": {
"affordable": true,
"blockReason": null,
"shortfallCredits": 0,
"maxAffordableRecords": 500,
"boundBy": "period_balance",
"unlimited": false
},
"ordering": {
"sort": "meetingDate",
"order": "desc",
"tiebreak": null,
"meaning": "Most recent meeting evidence first — the date of the meeting the record was extracted from, not when Boardwalk ingested it and not when the project was created."
},
"truncation": {
"policy": "refuse",
"wouldTruncate": false,
"deliverableRecords": null,
"explanation": "This request fits inside the remaining balance, so every matching record is delivered."
}
},
"meta": {
"schemaVersion": "2026-08-02",
"representation": "standard",
"deliveryMode": "all",
"credits": {
"limit": 500,
"used": 0,
"remaining": 500,
"charged": 0,
"periodStart": "2026-08-01",
"periodEnd": "2026-08-31",
"isTeamPool": true
},
"appliedFilters": {
"states": [
44
],
"assetClasses": [
"Apartment Building"
],
"meetingDateFrom": "2026-05-01T00:00:00+00:00",
"totalUnitCountMin": 50
},
"appliedDefaults": [],
"resolvedFrom": {
"states": {
"UT": 44
}
},
"warnings": [
{
"code": "filter_evidence_unconfirmed",
"message": "These filters currently match our full index. A returned record with a null value for the attribute you filtered on is a record we could not confirm.",
"params": [
"assetClasses",
"totalUnitCountMin"
]
}
]
},
"links": {
"self": "https://api.boardwalkai.com/api/v1/projects/count?states=UT&assetClasses=Apartment%20Building&meetingDateFrom=2026-05-01&totalUnitCountMin=50",
"search": "https://api.boardwalkai.com/api/v1/projects/search?states=UT&assetClasses=Apartment%20Building&meetingDateFrom=2026-05-01&totalUnitCountMin=50",
"docs": "https://boardwalkai.com/docs/api/budgets/"
}
}The response shape on this page is the one the endpoint builds — the keys, their nesting and their types are asserted against the shipping code by a test. The numbers inside it are the scenario being walked through, not a measurement of the corpus.
This step is not a best practice, it is how the product works. A request that costs more than your balance is refused, not truncated, so counting first is how you avoid a 402. Read affordability.affordable and billable.credits.
4. Make the metered call
Your first metered call
curl 'https://api.boardwalkai.com/api/v1/projects/search?states=UT&assetClasses=Apartment%20Building&limit=1' \
-H 'Authorization: Bearer bwk_live_YOUR_KEY'Response · HTTP 200
{
"data": [
{
"id": 184203,
"recordType": "project",
"projectName": "Alta Ridge Phase II",
"projectHeadline": "Planning Commission approved 240 apartments with conditions",
"boardwalkLink": "https://boardwalkai.com/map/#project=184203",
"mergedFrom": [
184203,
184987
],
"createdAt": "2026-05-04T00:00:00Z",
"lastUpdated": "2026-06-18T09:22:41Z",
"meetingDate": "2026-06-17",
"delivery": {
"alreadyExported": false,
"updatedSinceExport": null,
"lastExportedAt": null,
"billed": true
},
"address": "3600 S Constitution Blvd, West Valley City, UT",
"city": "West Valley City",
"county": "Salt Lake",
"state": "UT",
"postalCode": "84119",
"latitude": 40.6916,
"longitude": -112.0011,
"locationPrecision": "address",
"locationPrecisionLabel": "Address",
"isApproximate": false,
"parcelApn": [
"15-27-301-004"
],
"propertyType": "residential",
"propertyTypeLabel": "Residential",
"propertySubtype": "multifamily",
"propertySubtypeLabel": "Multifamily",
"assetClass": "Apartment Building",
"assetClassLabel": "Apartment Building",
"status": "approved_with_conditions",
"statusLabel": "Approved with Conditions",
"statusDetail": "The commission approved the preliminary plat subject to eight conditions.",
"requestType": "final_plat",
"requestTypeLabel": "Final Plat",
"decisionBody": "Planning Commission",
"caseNumbers": [
"PLAT-2026-0142"
],
"acreage": 9.8,
"unitCount": [
{
"count": 240,
"type": "apartment",
"typeLabel": "Apartment"
}
],
"totalUnitCount": 240,
"existingZoning": "A-1",
"proposedZoning": "RM-16",
"isRezone": true,
"constructionType": "new_building",
"constructionTypeLabel": "New Building",
"ownerType": "private",
"ownerTypeLabel": "Private",
"constructionDescription": "A 240-unit garden-style apartment community on 9.8 acres.",
"developerCompany": "Alta Ridge Development LLC",
"developerCompanyRole": "developer",
"developerCompanyRoleLabel": "Developer",
"contacts": [
{
"name": "Rachel Okafor",
"title": "Director of Development",
"role": "developer",
"roleLabel": "Developer",
"partyClass": "external",
"partyClassLabel": "External Party",
"entityType": "person",
"company": "Alta Ridge Development LLC",
"email": "r.okafor@example.com",
"emailConfidence": "high",
"emailSource": "filing",
"phone": "+1-555-0142",
"phoneConfidence": "high",
"phoneSource": "filing",
"linkedinUrl": null,
"linkedinConfidence": null,
"linkedinSource": null,
"contactProvenance": "filing",
"enrichmentSource": null,
"enrichedAt": null,
"enrichmentStatus": "not_requested",
"contactsWithheldReason": null
}
],
"contactEnrichment": {
"status": "not_requested",
"statusLabel": "Not Requested",
"attemptedAt": null,
"contactsFound": 0,
"source": "registry"
},
"publicOfficials": [
{
"name": "Dana Whitfield",
"title": "Senior Planner",
"role": "city_planner",
"roleLabel": "City Planner",
"partyClass": "government",
"organization": "West Valley City"
}
],
"contactSummary": {
"externalCount": 1,
"governmentCount": 1,
"unclassifiedCount": 0,
"withEmail": 1,
"withPhone": 1,
"withLinkedin": 0,
"enrichedCount": 0,
"lowConfidenceWithheld": 0,
"withheldCount": 0,
"withheldReason": null
},
"keyFacts": [
{
"fact": "240 apartment units across six buildings",
"category": "unit_mix",
"categoryLabel": "Unit Mix"
}
],
"evidence": "Commissioner Reyes moved to approve subject to conditions 1-8.",
"voteSummary": {
"yes": 2,
"no": 1,
"abstain": 0,
"absent": 1,
"total": 4,
"isUnanimous": false,
"meetingDate": "2026-06-17"
}
}
],
"meta": {
"schemaVersion": "2026-08-02",
"representation": "standard",
"total": 1,
"limit": 1,
"offset": 0,
"creditsUsed": 1,
"creditsRemaining": 299,
"trialTruncation": null,
"searchMethod": "redisearch",
"appliedFilters": {
"states": [
44
],
"assetClasses": [
"Apartment Building"
]
},
"appliedDefaults": [
"dateRange=last_1_year"
],
"resolvedFrom": {
"states": {
"UT": 44
}
},
"warnings": [
{
"code": "default_date_window_applied",
"message": "No date filter was given, so the last 12 months of meetings were searched — the same window the product shows. Pass dateRange=all to search everything.",
"params": [
"meetingDateFrom"
]
},
{
"code": "filter_evidence_unconfirmed",
"message": "These filters currently match our full index. A returned record with a null value for the attribute you filtered on is a record we could not confirm.",
"params": [
"assetClasses"
]
}
],
"matchCount": 250,
"matchCountIsExact": true,
"duplicatesCollapsed": 0,
"collapseApplied": true,
"delivery": {
"mode": "all",
"notPreviouslyExported": 1,
"previouslyExported": 0,
"updatedSinceExport": 0,
"billed": 1,
"notRebilled": 0,
"ledgerApplied": true
}
}
}Record bodies on this page were produced by running Boardwalk's production response mapper over a documented sample project, so the field set, the labels and the empty fields are exactly what the API emits. The project itself is a sample, not a real filing.
One record, one credit. Two things to notice on your first response: meta.creditsRemaining has gone down by exactly one, and the record carries a delivery block. That block is why pulling this same record again tomorrow, if it has not changed, is free.
What you just spent
| Step | Endpoint | Credits |
|---|---|---|
| 1 | Minting a key | 0 |
| 2 | GET /locations/states | 0 |
| 3 | GET /projects/count | 0 |
| 4 | GET /projects/search?limit=1 | 1 |
| Total | 1 |
Where to go next
Ready to make a call?
A free Boardwalk trial includes API access and a sandbox key. Counting, filtering, the location tree and the analytics plane cost nothing, so you can evaluate the data before you spend a credit.