API reference

Everything your organization sees on the web — listings, a property's risk register, your watchlist, the underwriting calculator — by API key, for your own scripts or agents.

Authentication

Create a key under Settings → API keys (included on the Standard plan). Send it as a bearer token on every request:

Authorization: Bearer tsi_live_...

A missing, invalid, or revoked key returns 401. Every endpoint below is read-only — there's no way to modify your account data through the API yet.

GET/api/v1/tax-sales

List active tax-sale properties, with the same filters /tax-sales uses: municipality, class (repeatable), status (repeatable), min, max, q, includeClosed, sort.

curl "https://taxsaleintelligence.com/api/v1/tax-sales?municipality=Chatham-Kent&max=20000" \
  -H "Authorization: Bearer tsi_live_..."
GET/api/v1/properties/{id}

A property's full overview and risk register — the same data the property page renders.

curl "https://taxsaleintelligence.com/api/v1/properties/<property-id>" \
  -H "Authorization: Bearer tsi_live_..."
GET/api/v1/watchlist

Your organization's own watchlist.

curl "https://taxsaleintelligence.com/api/v1/watchlist" \
  -H "Authorization: Bearer tsi_live_..."
POST/api/v1/underwriting/calculate

Run the Maximum Rational Bid calculator against your own numbers — no stored state, pure computation.

curl -X POST "https://taxsaleintelligence.com/api/v1/underwriting/calculate" \
  -H "Authorization: Bearer tsi_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "acquisition": {"tenderBid": 15000, "legalFees": 1500, "landTransferTax": 200, "hst": 0, "titleSearch": 300, "titleInsurance": 400, "environmentalReview": 0, "survey": 0},
    "project": {"developmentFees": 0, "utilityConnections": 0, "demolition": 0, "repairs": 20000, "renovations": 0, "carryingCosts": 1200, "propertyTaxes": 800, "insurance": 600, "financing": 0, "contingency": 2000},
    "selling": {"realtorCommission": 3000, "sellingLegalFees": 500},
    "expectedResaleValue": 65000
  }'