Changelog
Every change to the API contract, newest first.
Entries are generated from config/api-changelog.yaml and are also available as JSON at /api/changelog.json for machine consumption. Read the versioning policy for what each change type means for your integration.
changed2026-08-02schema 2026-08-02
One rate everywhere: 1 credit per record delivered, including AI search and including contact enrichment.
AI search previously charged a different rate from structured search. It no longer does — a record confirmed by a natural-language query costs the same as one matched by a filter, and candidates that were reviewed and rejected cost nothing. Contact enrichment is inside the same credit: a record costs 1 credit whether or not you asked for contacts and whether or not we found any. No representation affects the price.
Affects: GET /projects/search · GET /projects/{id} · POST /projects/ai-search · POST /projects/ai-search/jobs
added2026-08-02schema 2026-08-02
Free cost preview: GET /projects/count returns a quote before you spend anything.
Takes the same filters as the metered search route and returns matchCount, the billable record count, the credits required, and whether your balance covers it. Free on every plan, and it answers even when your balance is zero. A 402 now carries the same quote object in error.details.quote, along with a countUrl that prices the exact filter set that was refused.
Affects: GET /projects/count · GET /projects/search
changed2026-08-02schema 2026-08-02
A paid request that costs more than your balance is refused, not partially delivered.
Requests that would exceed the balance return 402 with a quote and deliver nothing. Nothing is charged. Free-trial keys are the documented exception — they deliver what the trial balance affords and report it in meta.trialTruncation.
Affects: GET /projects/search · POST /projects/ai-search/jobs
added2026-08-02schema 2026-08-02
Delivery state on every record, and no charge for an unchanged re-delivery.
Every record carries delivery.alreadyExported, delivery.updatedSinceExport, delivery.lastExportedAt and delivery.billed, on the API and in the CSV export alike. A record this pool already holds, which has not changed since, is delivered again without a charge. meta.delivery totals it per response.
Affects: GET /projects/search · GET /projects/sync · GET /alerts/{alertId}/matches · CSV export
added2026-08-02schema 2026-08-02
Incremental sync — GET /projects/sync walks by cursor in last-updated order, losslessly.
Offset paging over a changing dataset can skip records. The sync feed cannot, and it refuses sort, order, offset and page because a caller-chosen ordering would break that guarantee while appearing to work.
Affects: GET /projects/sync
added2026-08-02schema 2026-08-02
Alerts over the API — saved searches on a cadence. Configuration free, delivery billed.
Create, list, update, preview, run and delete alert rules; read delivery history and the records each run delivered. Everything except delivery is free.
Affects: /alerts
added2026-08-02schema 2026-08-02
A free analytics plane — counts, group-bys and rankings that never return record identity.
/analytics/datasets describes what can and cannot be answered; /analytics/aggregate and /analytics/rankings answer it. Free, with a small-group suppression floor.
Affects: /analytics
changed2026-08-02schema 2026-08-02
Responses are now an explicit allow-list, and project ids are integers.
The record payload is a declared contract rather than whatever the serving cache happened to hold. Every field is declared with a type, a unit and a description; a field that is not declared cannot be emitted. Project ids are JSON integers, not numeric strings. Timestamps are ISO-8601. Enums ship as a frozen machine token plus a human label.
Affects: GET /projects/search · GET /projects/{id} · GET /projects/sync
changed2026-08-02schema 2026-08-02
Values are held to Boardwalk's current extraction standard, or the field is empty.
A value produced by a superseded extraction no longer appears in any served field. Where the current standard produced nothing, the field is empty rather than backfilled. Some records therefore carry fewer values than they did. Filtering is not yet held to the same standard — see /docs/api/data-availability/, which will be updated when that lands.
Affects: GET /projects/search · GET /projects/{id} · GET /projects/sync
changed2026-08-02schema 2026-08-02
Strict input: an unknown query parameter is a 400 that costs nothing, rather than being silently ignored.
Dropping an unrecognised filter silently would run a broader query than was asked for and bill the difference. Unknown parameters, out-of-enum values and unresolvable place names are now refused with the offending parameter named.
Affects: GET /projects/search · GET /projects/count · GET /projects/sync
changed2026-08-02schema 2026-08-02
API keys: bwk_live_ and bwk_test_ prefixes, team ownership, and 24-hour rotation overlap.
New keys carry their environment in the prefix. Keys issued before the Boardwalk rename begin with csk_ and are accepted indefinitely. Keys are held by the team and attributed to their creator, several may be held at once, and a rotated key keeps working for 24 hours while its responses carry X-Boardwalk-Key-Rotating and a Warning header. A lapsed subscription keeps its keys and receives 402 subscription_required.
Affects: All endpoints
added2026-08-02schema 2026-08-02
Contact enrichment over the API, inside the same credit, as a per-request toggle.
include=contacts on an asynchronous request. Government staff contact details are never returned on any tier; free-trial keys receive names and titles with contact channels withheld and a stated reason. Coverage is narrower than our project coverage and there is no freshness guarantee — both are documented rather than implied.
Affects: POST /projects/ai-search/jobs
added2026-08-02schema 2026-08-02
Per-key rate limits with headers, ULID request ids, and idempotency on billable requests.
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 also carries Retry-After. Every response carries X-Request-Id, which is echoed if you supply your own, and which appears in our logs and on your usage row. An Idempotency-Key on a billable request replays the original result instead of charging twice.
Affects: All endpoints
removed2026-08-02schema 2026-08-02
Removed from responses: image references, source-document file paths, and pipeline-version markers.
These were never part of a declared contract and are no longer emitted. If you were reading one, it was reading an internal implementation detail out of a cache blob.
Affects: GET /projects/search · GET /projects/{id} · GET /documents/{id}
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.