The free sandbox
What 50 record-export credits and 5 Find Contact Info lookups buy, which endpoints cost nothing, and the two ways a trial key behaves differently.
Who this is for
You are evaluating. You want to know whether the data is any good before anyone signs anything.
What you get
A free Boardwalk trial includes API access, a balance of 50 record-export credits (search, CSV, MCP — mix and match), and 5 Find Contact Info lookups. The two grants do not share a pool. Create your key under Settings → API after you sign up. Trial credits do not reset monthly — they are a one-off evaluation budget.
Billable — 1 credit per project unlocked
| Method | Path | Cost | Notes |
|---|---|---|---|
| POST | /enrichments | 1 credit / project unlocked | County, State, and National: 1 credit per project the first time this account receives email or phone for it. Standalone API Only: included on records this pool has already purchased — unpurchased ids are skipped as notPurchased. A live free trial spends the separate 5-lookup grant (not the 50 record-export credits). Empty lookups cost nothing. Credits are charged when the job delivers contacts, not when it is queued. |
Free — 0 credits
| Method | Path | Cost | Notes |
|---|---|---|---|
| GET | /account/credits | Free | Free. Your balance, your plan, your rate limit and your enrichment allowance. |
| GET | /account/preferences | Free | Free. The account's saved search preferences (types, geography, website). |
| PATCH | /account/preferences | Free | Free. Update the account's saved search preferences. |
| GET | /alerts | Free | Free. Configuring alerts never costs credits; only delivered records do. |
| POST | /alerts | Free | Free. |
| GET | /alerts/{alertId} | Free | Free. |
| PATCH | /alerts/{alertId} | Free | Free. |
| DELETE | /alerts/{alertId} | Free | Free. |
| GET | /alerts/{alertId}/deliveries | Free | Free. The delivery history and what each run charged. |
| GET | /alerts/{alertId}/deliveries/{deliveryId} | Free | Free. |
| POST | /alerts/{alertId}/dismissals/{projectId} | Free | Free. Dismissing a match stops it being re-offered. |
| DELETE | /alerts/{alertId}/dismissals/{projectId} | Free | Free. |
| GET | /alerts/{alertId}/matches | Free | Free, every time. Omit deliveryId to read every match except dismissed (pending review included) — the same set the website table shows. Passing a deliveryId re-reads a past API run. Neither path charges. |
| POST, GET | /alerts/{alertId}/preview | Free | Free. Preview returns how many records a rule would deliver and what that would cost, not the records themselves. |
| POST | /alerts/{alertId}/run | Free | Free. A manual run delivers matching records at no credit cost. Finding contact info on those records is a separate enrichment. |
| POST | /analytics/aggregate | Free | Free. POST only (GET returns 404/405). Returns counts and group keys, never a project id, name, address, contact or document. |
| GET | /analytics/datasets | Free | Free. GET only. What the analytics plane can and cannot answer, self-described. |
| POST | /analytics/rankings | Free | Free. POST only (GET returns 405). Same small-group suppression floor as /aggregate. |
| GET | /documents/{id} | Free | County, State, and National: free. Standalone API Only and the free trial: 1 credit per source document the first time this pool receives it. |
| GET | /enrichments/{id} | Free | Free to poll. Progress counts for a submitted enrichment job. |
| POST | /exports | Free | Free to queue a product CSV. Pass alertId, listId, or projectIds to export a saved set (optional extra filters stay inside those ids). Omit all three and the body is a new search. Find Contact Info on those rows is 1 credit per project the first time this account receives email or phone for it. |
| GET | /exports | Free | Free. Lists export jobs for your team (including jobs queued with POST /exports or format=csv on search). |
| GET | /exports/{id} | Free | Free. Poll job status until ready. |
| GET | /exports/{id}/download | Free | Free re-download of a ready product-core CSV. Rows are free to queue. Find Contact Info on those rows, if you asked for it, was 1 credit per project unlocked. |
| GET | /health | Free | Free and unauthenticated. A liveness probe, not part of the record contract: its response shape carries no schema guarantee and can change without a schema-version bump, which is why it is deliberately absent from the OpenAPI document. Do not generate a client against it or parse its body. |
| GET | /lists | Free | Free. Every list your membership resolves — your own and the ones shared with you. |
| POST | /lists | Free | Free. Creates a named membership list (the "new list" option on save). |
| GET | /lists/{listId} | Free | Free. One list's configuration and share state, plus results.billable.credits — what a full /results pull would charge right now. This is the free preflight for /results. |
| POST | /lists/{listId}/projects | Free | Free. Adds project ids to a membership-backed list. Idempotent per id. |
| DELETE | /lists/{listId}/projects/{projectId} | Free | Free. Removes a project from a membership-backed list. |
| GET | /lists/{listId}/results | Free | County, State, and National: free. Standalone API Only and the free trial: 1 credit per delivered record that is new to this pool or changed since last delivery; unchanged owned records are free. Alert companions return the same match set as the alert (every match except dismissed, pending review included). Extra search filters apply only inside those existing ids. Filter and polygon lists return stored criteria plus a search link. |
| GET | /locations/cities/{id} | Free | Free. |
| GET | /locations/counties/{id} | Free | Free. |
| GET | /locations/states | Free | Free. Resolve the ids you filter with. |
| GET | /locations/states/{id} | Free | Free. |
| GET | /locations/states/{id}/counties | Free | Free. |
| GET | /locations/states/{stateId}/counties/{countyId}/cities | Free | Free. |
| POST | /projects/ai-search | Free | Not part of the public API — you cannot call this with an API key. Any bwk_live_/csk_ key is refused with 400 invalid_request (error.param: "endpoint", details.asyncEndpoint) before anything is parsed; use POST /projects/ai-search/jobs instead. On the session-authenticated web product this path is free, like structured search. |
| POST | /projects/ai-search/jobs | Free | County, State, and National: free. Standalone API Only and the free trial: credits are reserved at 1 per requested record and settled against confirmed matches. Finding contact info on those records is a separate enrichment job (included on API Only after the record is purchased). |
| GET | /projects/ai-search/jobs/{id} | Free | Polling is free. The records the job delivers were charged when the job settled, not when you read them. |
| DELETE | /projects/ai-search/jobs/{id} | Free | Cancelling is free and gives credits back, never takes them: a queued job refunds its full reservation immediately; a running job settles at the next batch boundary, charging only confirmed records and refunding the rest. |
| GET | /projects/count | Free | Free, always, including when your balance is zero. How many projects match. On API Only and the trial it also prices the set; on County, State, and National, search is free. |
| GET | /projects/search | Free | County, State, and National: free. Standalone API Only and the free trial: 1 credit per delivered record that is new to this pool or changed since last delivery; unchanged owned records are free. format=csv queues the full filter match and returns HTTP 202 with poll/download URLs. Find Contact Info is billed separately on County/State/National, and included on API Only records already purchased. |
| GET | /projects/sync | Free | County, State, and National: free. Standalone API Only and the free trial: 1 credit per new or changed record; unchanged owned records bill 0. |
| GET | /projects/{id} | Free | County, State, and National: free. Standalone API Only and the free trial: 1 credit the first time this pool receives the record. Email, phone, and LinkedIn stay withheld until Find Contact Info has unlocked the project (included on API Only after the record is purchased). |
| GET | /reference/decision-bodies | Free | Free. Canonical values accepted by the decisionBodies filter. |
| GET | /reference/owner-types | Free | Free. The owner-type vocabulary used by alert criteria and CSV output. Not accepted as a /projects/search filter — the ownerTypes filter was withdrawn on 2026-08-27. |
| GET | /reference/request-types | Free | Free. Canonical values accepted by the requestTypes filter. |
| GET | /reference/statuses | Free | Free. Canonical status filter tokens plus display aliases (e.g. scheduled). |
| GET | /taxonomy | Free | Free. The complete Building Type tree. |
| GET | /taxonomy/action-categories | Free | Free. |
| GET | /taxonomy/action-types | Free | Free. |
| GET | /taxonomy/asset-classes | Free | Free. |
| GET | /taxonomy/project-types | Free | Free. |
| GET | /taxonomy/subtypes | Free | Free. |
Evaluate without spending
The whole planning surface is free, on a trial key and a paid key alike. You can establish coverage, vocabulary and result sizes for your market before spending a single credit:
GET /locations/*— is your market covered, and what are its ids?GET /taxonomy/*— what Building Type and Application Type labels can I filter with?GET /projects/count— how many records match your real query, and what would they cost?POST /analytics/aggregate— what does the shape of the market look like, without buying any records at all?
Count a narrower query
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",
"collapseApplied": true,
"duplicatesCollapsed": 0,
"scanCeiling": 10000,
"billable": {
"records": 250,
"credits": 0,
"creditRate": 0,
"isUpperBound": true,
"nonBillable": {
"alreadyDeliveredUnchanged": 0,
"ledgerApplied": true
}
},
"affordability": {
"affordable": true,
"blockReason": null,
"shortfallCredits": 0,
"maxAffordableRecords": 9223372036854776000,
"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": "The whole match set fits inside the remaining balance: page through the metered route and every page will be delivered in full until the set is exhausted."
}
},
"meta": {
"schemaVersion": "2026-09-16",
"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": [
1
],
"assetClasses": [
"Apartment Building"
],
"meetingDateFrom": "2026-05-01T00:00:00+00:00",
"totalUnitCountMin": 50
},
"appliedDefaults": [
"taxonomyMatchMode=primary_only",
"includeGovernmentDecisions=false",
"leadTypes=private",
"sort=meetingDate",
"order=desc"
],
"resolvedFrom": {
"states": [
{
"input": "UT",
"id": 1
}
]
},
"warnings": []
},
"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.
That call cost nothing and told you the query matches 250 records — more than 50 trial credits cover, so a trial pull of this set comes back truncated rather than whole. Now you know exactly what 50 trial credits will and will not cover.
The two differences you need to know about
The second difference is contact data. On a trial key, external parties' contact channels — email, phone, LinkedIn — stay withheld on ordinary search until you spend a Find Contact Info lookup (POST /enrichments or include=contacts). The record says so rather than pretending the filing had none:
The same record on a free-trial key
curl 'https://api.boardwalkai.com/api/v1/projects/search?states=UT&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
],
"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"
],
"inOpportunityZone": true,
"inFemaFloodZone": false,
"propertyType": "residential",
"propertyTypeLabel": "Residential",
"propertySubtype": "multifamily",
"propertySubtypeLabel": "Multifamily",
"assetClass": "Apartment Building",
"assetClassLabel": "Apartment Building",
"leadType": "private",
"leadTypeLabel": "Private",
"stage": "entitlement",
"stageLabel": "Entitlement",
"landUses": [
{
"type": "residential",
"typeLabel": "Residential",
"subtype": "multifamily",
"subtypeLabel": "Multifamily",
"assetClass": "Apartment Building",
"assetClassLabel": "Apartment Building",
"matchedOn": []
}
],
"status": "approved_with_conditions",
"statusLabel": "Approved with Conditions",
"statusSummary": "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,
"squareFootage": null,
"unitMix": [
{
"count": 240,
"type": "apartment",
"typeLabel": "Apartment"
}
],
"totalUnitCount": 240,
"bedroomCount": null,
"buildingStories": null,
"floorCount": null,
"buildingHeightFeet": null,
"parkingSpaces": 372,
"existingZoning": "A-1",
"proposedZoning": "RM-16",
"isRezone": true,
"constructionType": "new_building",
"constructionTypeLabel": "New Building",
"projectSize": null,
"projectSizeLabel": null,
"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": null,
"emailSource": null,
"phone": null,
"phoneSource": null,
"linkedinUrl": null,
"linkedinSource": null,
"contactProvenance": null,
"enrichmentSource": null,
"enrichedAt": null,
"enrichmentStatus": "not_requested",
"contactsWithheldReason": "free_tier"
}
],
"contactEnrichment": {
"status": "not_requested",
"statusLabel": "Not Requested",
"attemptedAt": null,
"contactsFound": 0,
"source": "registry"
},
"companyEnrichment": [],
"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": 0,
"withPhone": 0,
"withLinkedin": 0,
"enrichedCount": 0,
"lowConfidenceWithheld": 0,
"withheldCount": 1,
"withheldReason": "free_tier"
},
"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.",
"summary": "A 240-unit garden-style apartment community on 9.8 acres.",
"voteSummary": {
"yes": 2,
"no": 1,
"abstain": 0,
"absent": 1,
"total": 4,
"isUnanimous": false,
"meetingDate": "2026-06-17"
},
"sourceDocumentUrl": "https://www.example-city.gov/media/agendas/2026-06-17-planning-commission-packet.pdf"
}
],
"meta": {
"schemaVersion": "2026-09-16",
"representation": "standard",
"total": 1,
"pageCount": 1,
"hasMore": true,
"limit": 1,
"offset": 0,
"creditsUsed": 1,
"creditsRemaining": 99,
"trialTruncation": null,
"searchMethod": "redisearch",
"appliedFilters": {
"states": [
1
]
},
"appliedDefaults": [
"taxonomyMatchMode=primary_only",
"includeGovernmentDecisions=false",
"leadTypes=private",
"dateRange=last_1_year",
"sort=meetingDate",
"order=desc"
],
"resolvedFrom": {
"states": [
{
"input": "UT",
"id": 1
}
]
},
"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"
]
}
],
"matchCount": null,
"matchCountIsExact": false,
"matchCountBasis": "not_computed",
"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.
Look at contactSummary.withheldCount and withheldReason, and at contactsWithheldReason on the party itself. The names, titles, roles and companies are all there — enough to judge whether the contact data is worth paying for, which is the point of an evaluation. Government staff contact details are never returned on any tier, trial or paid.
Next
Ready to make a call?
A free Boardwalk trial includes API access, 50 record-export credits (search, CSV, MCP), and 5 Find Contact Info lookups. Counting, taxonomy, location lookups and the analytics plane cost nothing, so you can evaluate the data before you spend a credit.