Skip to main content
Docs / The credit model

Core concepts

The credit model

Two meters: export records, the same monthly cap on every County, State, and National plan, and Find Contact Info credits, which follow the geography.

What that covers

RuleDetail
Geography limits where, not how manyA state plan covers that state. A county plan covers those counties. National and API Only are nationwide. GET /locations/states marks each state entitled: true or false. A filter outside that set is 403 geographic_access_denied. The export cap is the same on County, State, and National.
Representation does not change the priceA new or changed record is 1 export record in compact, standard, or full. Find Contact Info is still a separate credit.
A record pull is a deliverySearch, project detail, sync, a source document, a CSV row, and the same calls over MCP each deliver a record. The first time it is new or changed, it counts. Pulling it again with no change does not.
Counts and previews are freeGET /projects/count and other sizing calls deliver no project record, so they use neither counter.
Find Contact Info is the other counter1 credit per project the first time this account receives email, phone, or a personal LinkedIn profile. A lookup that finds nothing costs 0. It never spends an export record.
Errors are freeA refused request, including 429 export_limit_reached, leaves both balances exactly where they were.
Zero results are freeA query that matches nothing costs nothing.
Duplicates are collapsed before billingTwo filings for one development are one record. Find Contact Info charges once for that project.
Unchanged redelivery is freeA project this account already received, with no change since, is free to re-read, re-export, or list again. The file still includes the row.
Two pools, not oneExport records are shared by the API, MCP, CSV, and the app. Find Contact Info credits are shared by CSV, POST /enrichments, and MCP create_enrichment. Spending one pool does not spend the other.

Every endpoint, and what it costs

Billable: 1 credit per project unlocked

MethodPathCostNotes
POST/enrichments1 credit / project unlockedCounty, State, and National: 1 credit per project the first time this account receives email, phone, or a personal LinkedIn profile 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. The maximum is held when queued, excluding already-unlocked projects; completion charges qualifying deliveries and releases the rest. Company links and names alone do not qualify.

Free: 0 credits

MethodPathCostNotes
GET/account/creditsFreeFree. Your plan, your Find Contact Info allowance, and exportCredits (limit, used, remaining, resetsAt) for the shared 100,000 export records a month.
GET/account/preferencesFreeFree. The account's saved search preferences (types, geography, website).
PATCH/account/preferencesFreeFree. Update the account's saved search preferences.
GET/alertsFreeFree. Configuring alerts never costs credits; only delivered records do.
POST/alertsFreeFree.
GET/alerts/{alertId}FreeFree.
PATCH/alerts/{alertId}FreeFree.
DELETE/alerts/{alertId}FreeFree.
GET/alerts/{alertId}/deliveriesFreeFree. The delivery history and what each run charged.
GET/alerts/{alertId}/deliveries/{deliveryId}FreeFree.
POST/alerts/{alertId}/dismissals/{projectId}FreeFree. Dismissing a match stops it being re-offered.
DELETE/alerts/{alertId}/dismissals/{projectId}FreeFree.
GET/alerts/{alertId}/matchesFreeFree, 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, and neither does include=contacts here: it reads what the alert's own lookups already found.
POST, GET/alerts/{alertId}/previewFreeFree. Preview returns how many records a rule would deliver and what that would cost, not the records themselves.
POST/alerts/{alertId}/runFreeFree. A manual run delivers matching records at no credit cost. Finding contact info on those records is a separate enrichment.
POST/analytics/aggregateFreeFree. POST only (GET returns 404/405). Returns counts and group keys, never a project id, name, address, contact, or document.
GET/analytics/datasetsFreeFree. GET only. What the analytics plane can and cannot answer, self-described.
POST/analytics/rankingsFreeFree. POST only (GET returns 405). Same small-group suppression floor as /aggregate.
GET/documents/{id}FreeCounty, State, and National: 1 export record the first time this account receives the document, against the shared 100,000 a month. A later read of the same document is free. Standalone API Only and the free trial: 1 credit the first time.
GET/enrichments/{id}FreeFree to poll: meta.creditsUsed stays 0. contactBilling reports the cumulative reserved, charged, released, refunded, and qualifyingProjects counts; repeated polls do not charge again.
POST/exportsFreeFree 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, phone, or a personal LinkedIn profile for it.
GET/exportsFreeFree. Lists export jobs for your team (including jobs queued with POST /exports or format=csv on search).
GET/exports/{id}FreeFree. Poll job status until ready.
GET/exports/{id}/downloadFreeFree 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/healthFreeFree 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/listsFreeFree. Every list your membership resolves: your own and the ones shared with you.
POST/listsFreeFree. Creates a named membership list (the "new list" option on save).
GET/lists/{listId}FreeFree. 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}/projectsFreeFree. Adds project ids to a membership-backed list. Idempotent per id.
DELETE/lists/{listId}/projects/{projectId}FreeFree. Removes a project from a membership-backed list.
GET/lists/{listId}/resultsFreeCounty, State, and National: 1 export record per project that is new or changed, against the shared 100,000 a month. Unchanged records already delivered are free. Standalone API Only and the free trial: 1 credit per new or changed record. 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}FreeFree.
GET/locations/counties/{id}FreeFree.
GET/locations/statesFreeFree. Resolve the ids you filter with.
GET/locations/states/{id}FreeFree.
GET/locations/states/{id}/countiesFreeFree.
GET/locations/states/{stateId}/counties/{countyId}/citiesFreeFree.
POST/projects/ai-searchFreeNot 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/jobsFreeCounty, State, and National: confirmed new or changed matches count toward the shared 100,000 export records a month. Rejected candidates do not. Find Contact Info on those records is a separate job. Standalone API Only and the free trial: credits are reserved at 1 per requested record and settled against confirmed matches. API Only includes Find Contact Info after the record is purchased.
GET/projects/ai-search/jobs/{id}FreePolling is free. The records the job delivers were charged when the job settled, not when you read them.
DELETE/projects/ai-search/jobs/{id}FreeCancelling 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/countFreeFree, always. A count does not deliver a project record, so it does not use export records or Find Contact Info credits. On API Only and the trial it also prices the set.
GET/projects/searchFreeCounty, State, and National: 1 export record per project that is new to this account or changed since the last delivery, against the shared 100,000 a month. API, MCP, CSV, and the app share that counter. An unchanged record already delivered is free. format=csv queues the full filter match and returns HTTP 202. Find Contact Info is a separate allowance. Standalone API Only and the free trial: 1 credit per new or changed record; unchanged owned records are free. API Only includes Find Contact Info on records already purchased.
GET/projects/syncFreeCounty, State, and National: 1 export record per new or changed project, against the shared 100,000 a month. Unchanged records bill 0. Standalone API Only and the free trial: 1 credit per new or changed record.
GET/projects/{id}FreeCounty, State, and National: 1 export record the first time this account receives the project, against the shared 100,000 a month. A later read of the same unchanged project is free. Email, phone, and LinkedIn stay withheld until Find Contact Info unlocks them, which spends the contact allowance, not export records. Standalone API Only and the free trial: 1 credit the first time. API Only includes Find Contact Info after the record is purchased.
GET/reference/decision-bodiesFreeFree. Canonical values accepted by the decisionBodies filter.
GET/reference/owner-typesFreeFree. 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-typesFreeFree. Canonical values accepted by the requestTypes filter.
GET/reference/statusesFreeFree. Canonical status filter tokens plus display aliases (e.g. scheduled).
GET/taxonomyFreeFree. The complete Building Type tree.
GET/taxonomy/action-categoriesFreeFree.
GET/taxonomy/action-typesFreeFree.
GET/taxonomy/asset-classesFreeFree.
GET/taxonomy/project-typesFreeFree.
GET/taxonomy/subtypesFreeFree.

The free plane is not a teaser

Counting, the location tree, project types, alert configuration, and the entire analytics surface are free permanently, on paid and trial keys alike, and GET /projects/count answers even when your balance is zero. You can always see how many projects match before you page them or spend a Find Contact Info credit.

Allowances

County, State, and National each include 100,000 export records a month. The plan tier does not change that number. It changes the Find Contact Info allowance: 50 a month on a county, 200 on a state, 1,000 on National. Unused contact credits do not roll over. The export counter resets on the billing anniversary, not the calendar month. API Only includes 500 record credits per month and is not on the export cap. See plans and pricing for prices; this page is about what each counter buys.

Worked examples

A Utah county search returns 40 projects. Twelve were already delivered and have not changed. The page uses 28 export records and 0 Find Contact Info credits. Downloading that same CSV again, with nothing changed, still returns the file and uses 0 export records. GET /projects/count on the same filter uses 0 of either.

You then ask for contacts on 10 of those projects. Seven come back with an email, a phone, or a LinkedIn profile. That uses 7 Find Contact Info credits and 0 additional export records, because the projects were already delivered. The same request on 10 projects where nothing is found uses 0 contact credits.

A one-county plan and National share the same 100,000 export records. They do not share the contact allowance: the county plan has 50 Find Contact Info credits a month, the state plan 200, National 1,000. Past the export cap, the next new record is refused. Past the contact allowance, records still download; only the contact lookup is refused.

json
{
  "error": "export_limit_reached",
  "limit": 100000,
  "resetsAt": "2026-11-08T06:00:00Z",
  "contact": "https://boardwalkai.com/contact",
  "message": "You've used this month's 100,000 export records. They reset on November 8, 2026. For higher volume, contact us about Enterprise."
}

Reading your balance

Read the shared balance

bash
curl 'https://api.boardwalkai.com/api/v1/account/credits' \
  -H 'Authorization: Bearer bwk_live_YOUR_KEY'

Response ยท HTTP 200

json
{
  "data": {
    "plan": "single_state",
    "planDisplayName": "State",
    "creditsLimit": 500,
    "creditsUsed": 200,
    "creditsRemaining": 300,
    "periodStart": "2026-08-01",
    "periodEnd": "2026-08-31",
    "resetsAt": "2026-09-01T00:00:00+00:00",
    "rateLimit": 60,
    "rateLimitPer": "minute",
    "isTeamPool": true,
    "poolUserId": 8814
  },
  "meta": {
    "requestId": "req_01K1QF3M0000EXAMPLE0001"
  }
}

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.

Metered responses also carry X-Credits-Remaining, and meta.creditsUsed / meta.creditsRemaining on the body. Read one of those rather than keeping a local counter. The pool is shared, and someone else may be spending it.

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.