Stop scraping 68 municipal permit portals

One REST API for Canadian building permits, licences, zoning and inspections. Ten datasets, one schema, joined on one address.

curl "https://api.builddata.ca/permit?municipality=toronto&limit=5" \
  -H "X-RapidAPI-Key: YOUR_KEY"
  • 17M records
  • 10 datasets
  • 68 cities, 9 provinces
  • Refreshed daily

Free tier: 25 requests a day, no card. Pro: 1,000 a day for $49 USD a month.

Every city publishes differently

Toronto ships one format, Calgary another, Montreal another again. Column names differ, permit types differ, addresses are written every way a clerk can write them, and a portal changes shape without telling anyone. Doing this yourself is not one scraper, it is 68 of them, plus the address matching, plus the mornings they break.

That is the part we run. You get one schema and one key.

One address, every dataset

Records are joined on a normalised address, so a single lookup returns the permits, the licences, the zoning and the inspections for that property. This is the part you cannot get by scraping harder: the cities publish these separately and never key them to each other.

Built for product teams putting Canadian property data in their own app, and for analysts who would rather query than maintain scrapers.

Same filters, whichever dataset

Every endpoint takes the same filters and returns the same envelope, so the code you write for permits already works for licences. Swap /permit for /licence, /zoning, /inspection or any of the ten.

What you can query

Building permits68 cities
Major projects58 cities
Zoning47 cities
Planning applications31 cities
Business licences28 cities
New business openings19 cities
Property assessments18 cities
Contractor profiles17 cities
Development permits12 cities
Building inspections3 cities

Coverage, city by city

What the free tier covers

Almost all of it. Every dataset, every filter, geocoding, contractor profiles and property profiles are on the free tier. Two endpoints need Pro: /permit/estimate, which prices a permit from a model, and /permit/feed, which returns only what arrived since your last call.

Bulk export and a Snowflake share carry the same schema, for loading a whole dataset rather than paging through it. Ask about bulk access.