API Documentation
Access Toronto zoning data programmatically. Look up any address and get back effective standards, development potential, GIS layers, and more. The same data that powers the web app.
Base URL
https://toronto-zoning-production.up.railway.appAll endpoints accept and return JSON. Every endpoint requires a signed-in account — create one free and send your session token as a Bearer credential. Calls without one return 401 sign_in_required.
Quick Start
Look up zoning data for any Toronto address with a single API call:
curl -X POST https://toronto-zoning-production.up.railway.app/lookup \
-H "Content-Type: application/json" \
-d '{"address": "226 Viewmount Ave"}'/lookup
The primary endpoint. Returns a complete zoning profile for a Toronto address including effective standards, development potential, GIS layers, and constraints.
Request Body
addressrequired | string | Toronto street address (e.g. "226 Viewmount Ave") |
include_parcel | boolean | Include property boundary geometry. Default: true |
include_nearby | boolean | Include nearby development activity. Default: false |
include_policy | boolean | Include policy conformity analysis. Default: false |
lot_area_sqm | number | Override lot area (useful for assembly scenarios) |
lot_frontage_m | number | Override lot frontage |
lot_depth_m | number | Override lot depth |
proposed_use | string | Proposed use to analyze (e.g. "restaurant", "dwelling unit") |
Response
{
"address": "226 Viewmount Ave",
"coordinates": { "latitude": 43.65633, "longitude": -79.43123 },
"effective_standards": {
"zone_code": "RD",
"zone_string": "RD (f12.0; a325) (x123)",
"height": { "effective_m": 10, "effective_storeys": 3, "effective_source": "base_zone" },
"fsi": { "effective_total": 0.6, "effective_source": "base_zone" },
"lot_coverage": { "effective_pct": 35, "effective_source": "base_zone" },
"setbacks": { "effective_front_m": 6.0, "effective_rear_m": 7.5, "effective_side_m": 1.2 },
"exception": { "exception_number": 123 },
"heritage_impact": { "has_heritage": false },
"natural_hazards": { "has_hazards": false }
},
"development_potential": {
"lot": { "area_sqm": 325, "frontage_m": 12.0, "depth_m": 27.1 },
"max_gfa": { "sqm": 195, "limiting_factor": "lot_coverage" },
"height": { "max_m": 10, "max_storeys": 3 },
"setbacks": { "buildable_area_sqm": 195 },
"confidence": { "overall_score": 85, "overall_confidence": "high", "grade": "A" }
},
"layers": {
"zoning_area": [ ... ],
"heritage_register": [ ... ],
"major_transit_station_area": [ ... ]
},
"policy_conformity": { ... },
"zoning_statistics_table": { ... }
}/suggest
Address autocomplete. Returns matching Toronto addresses for typeahead search.
Request Body
textrequired | string | Partial address text (minimum 3 characters) |
max_suggestions | number | Maximum results to return. Default: 8 |
curl -X POST https://toronto-zoning-production.up.railway.app/suggest \
-H "Content-Type: application/json" \
-d '{"text": "226 view"}'
// Response
{
"suggestions": [
"226 Viewmount Ave",
"226 View North Rd",
...
]
}/lookup/batch
Look up multiple addresses in a single request (up to 50).
Request Body
addressesrequired | string[] | Array of Toronto addresses (max 50) |
include_parcel | boolean | Include property boundaries. Default: true |
include_nearby | boolean | Include nearby activity. Default: false |
max_concurrency | number | Max parallel lookups. Default: 10 |
curl -X POST https://toronto-zoning-production.up.railway.app/lookup/batch \
-H "Content-Type: application/json" \
-d '{
"addresses": [
"226 Viewmount Ave",
"100 Queen St W",
"1 Yonge St"
]
}'
// Response
{
"results": [ ... ],
"total": 3,
"success_count": 3,
"error_count": 0,
"total_ms": 2340
}/analyze-use
Check if a specific use is permitted in a zone. Returns conditions, parking requirements, and by-law references.
Request Body
userequired | string | The use to analyze (e.g. "restaurant", "dwelling unit", "retail store") |
reportrequired | object | Full zoning report object (from /lookup response) |
// First, get a zoning report
const report = await fetch("https://toronto-zoning-production.up.railway.app/lookup", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ address: "100 Queen St W" })
}).then(r => r.json());
// Then check use eligibility
const analysis = await fetch("https://toronto-zoning-production.up.railway.app/analyze-use", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
use: "restaurant",
report: report
})
}).then(r => r.json());/analyze-use/list
List all available uses that can be analyzed for a given zone family.
curl -X POST https://toronto-zoning-production.up.railway.app/analyze-use/list \
-H "Content-Type: application/json" \
-d '{"zone_family": "CR"}'
// Response
{
"uses": ["amusement arcade", "art gallery", "artist studio", "bar", ...]
}/reference
Fetch by-law text, exception details, SASP policies, or zone information.
Request Body
typerequired | string | "bylaw-section", "exception", "sasp", "op-designation", or "zone-info" |
idrequired | string | Section ID, exception number, or policy reference |
zone_code | string | Zone code for context (optional) |
curl -X POST https://toronto-zoning-production.up.railway.app/reference \
-H "Content-Type: application/json" \
-d '{"type": "exception", "id": "123"}'
// Response
{
"found": true,
"title": "Exception 123",
"text": "Despite regulation 10.20.40.10(1), the maximum ...",
"data": { ... }
}/map/metadata
List all available GIS layers with styling information. Useful for building map UIs.
curl https://toronto-zoning-production.up.railway.app/map/metadata
// Response
{
"layers": [
{
"key": "zoning_area",
"label": "Zoning Areas",
"color": "#3b82f6",
"weight": 2,
"fillOpacity": 0.15,
"group": "Zoning"
},
...
]
}/map/layers/{layer_key}
Get GeoJSON features for a specific GIS layer within a radius of a coordinate.
Query Parameters
lonrequired | number | Longitude |
latrequired | number | Latitude |
radius | number | Radius in degrees. Default: 0.005 |
curl "https://toronto-zoning-production.up.railway.app/map/layers/zoning_area?lon=-79.431&lat=43.656&radius=0.005"
// Response: GeoJSON FeatureCollection
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": { "type": "Polygon", "coordinates": [...] },
"properties": {
"ZONE_CODE": "RD",
"ZONE_LABEL": "Residential Detached",
...
}
}
]
}/nearby-activity
Nearby development activity: building permits, Committee of Adjustment applications, and rezoning applications.
Query Parameters
lonrequired | number | Longitude |
latrequired | number | Latitude |
radius | number | Radius in metres. Default: 500 |
limit | number | Max events to return. Default: 50 |
event_type | string | Filter by type: "permit", "coa", "rezoning" |
curl "https://toronto-zoning-production.up.railway.app/nearby-activity?lon=-79.431&lat=43.656&radius=500"
// Response
{
"center": { "lon": -79.431, "lat": 43.656 },
"radius_m": 500,
"total": 12,
"by_type": { "permit": 8, "coa": 3, "rezoning": 1 },
"events": [ ... ]
}/dev-charges/calculate
Estimate development charges for a proposed project based on unit counts and building type.
Request Body
units_bachelor | number | Number of bachelor units |
units_2plus | number | Number of 2+ bedroom units |
units_lowrise | number | Number of low-rise units |
units_single_semi | number | Number of single/semi units |
non_residential_gfa_sqm | number | Non-residential GFA in m² |
is_purpose_built_rental | boolean | Is this purpose-built rental? (affects exemptions) |
curl -X POST https://toronto-zoning-production.up.railway.app/dev-charges/calculate \
-H "Content-Type: application/json" \
-d '{
"units_2plus": 6,
"is_purpose_built_rental": false
}'
// Response
{
"city_dc": { "items": [...], "subtotal": 142800 },
"education_dc": { "items": [...], "subtotal": 18600 },
"go_transit_dc": { ... },
"exemptions_applied": [],
"total_estimated": 168420
}Usage Notes
- The API is free during the beta period. Rate limits may be introduced in the future.
- Responses are cached for up to 1 hour. Identical requests will return cached results.
- Data is sourced from the City of Toronto Open Data Portal. This is not legal advice.
- Batch requests are limited to 50 addresses per call.