Skip to main content

Budgets, quotes and the 402

Price any request for free before you run it, and know exactly what a request you cannot afford returns.

Boardwalk never overshoots your balance and never partially delivers a paid request. That guarantee is only useful if you can see it coming, so the same quote arithmetic is available for free before the request and is attached to the refusal after it.

The free quote

Price a broad query — before spending anything

bash
curl 'https://api.boardwalkai.com/api/v1/projects/count?states=UT&assetClasses=Apartment%20Building&dateRange=all' \
  -H 'Authorization: Bearer bwk_live_YOUR_KEY'

Response · HTTP 200

json
{
  "data": {
    "matchCount": 5000,
    "matchCountIsExact": true,
    "matchCountBasis": "enumerated",
    "countedAs": "distinct_projects",
    "scanCeiling": 10000,
    "billable": {
      "records": 5000,
      "credits": 5000,
      "creditRate": 1,
      "isUpperBound": true,
      "nonBillable": {
        "alreadyDeliveredUnchanged": 0,
        "ledgerApplied": true
      }
    },
    "affordability": {
      "affordable": false,
      "blockReason": "insufficient_credits",
      "shortfallCredits": 4500,
      "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": "Paid plans are never partially delivered. A request that costs more than the balance is refused with 402 and a quote; narrow the filters or top up."
    }
  },
  "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"
      ],
      "dateRange": "all"
    },
    "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"
        ]
      }
    ]
  },
  "links": {
    "self": "https://api.boardwalkai.com/api/v1/projects/count?states=UT&assetClasses=Apartment%20Building&dateRange=all",
    "search": "https://api.boardwalkai.com/api/v1/projects/search?states=UT&assetClasses=Apartment%20Building&dateRange=all",
    "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.

Credit costFree — 0 creditsFree, always, including when your balance is zero. This is the endpoint that tells you what a query would cost before you buy it.

Reading a quote

FieldWhat it tells you
matchCountHow many distinct projects match. Post-collapse, so it counts developments, not filings.
matchCountIsExactfalse when the scan ceiling was reached and the true total is higher.
billable.recordsHow many of those you would actually be charged for. Lower than matchCount when you already hold some unchanged.
billable.creditsThe cost. records × creditRate.
billable.isUpperBoundAlways true, and it is a promise: the real charge can only be lower.
affordability.affordableWhether the balance covers it.
affordability.shortfallCreditsHow many more you would need.
affordability.maxAffordableRecordsHow many records the balance can pay for right now.
truncation.policyrefuse on a paid plan, trial on a trial key. This is what would happen if you called the metered endpoint anyway.
orderingThe sort that would be applied, so "the first 500" is a defined set rather than an arbitrary one.

The refusal

What a request you cannot afford looks like

bash
curl 'https://api.boardwalkai.com/api/v1/projects/search?states=UT&assetClasses=Apartment%20Building&dateRange=all&limit=100' \
  -H 'Authorization: Bearer bwk_live_YOUR_KEY'

Response · HTTP 402

json
{
  "error": {
    "code": "insufficient_credits",
    "message": "This request would deliver 5,000 records and cost 5,000 credits. You have 500.",
    "param": null,
    "details": {
      "quote": {
        "matchCount": 5000,
        "matchCountIsExact": true,
        "creditRate": 1,
        "creditsRequired": 5000,
        "creditsRemaining": 500,
        "affordableRecordCount": 500,
        "countUrl": "https://api.boardwalkai.com/api/v1/projects/count?states=UT&assetClasses=Apartment%20Building&dateRange=all"
      }
    },
    "docsUrl": "https://boardwalkai.com/docs/api/errors#insufficient_credits",
    "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.

error.details.quote is the same arithmetic as the count endpoint — one object, built once, so the number you narrow against and the number a refusal names cannot disagree. countUrl is a free URL that prices this exact filter set, which is what lets an agent recover without a human.

Why not just deliver what I can afford?

Because a short page is indistinguishable from the end of the results. A customer who receives 500 of 5,000 records with no signal concludes our coverage is thin, builds on a partial dataset, and finds out months later. Refusing is louder and cheaper for everyone. Trial keys are the exception, and they say so explicitly in meta.trialTruncation.

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.