Skip to documentation
Developer documentation
Get API key
REST API v1

Agriculture

Read parcel-level agriculture intelligence and render agriculture map layers.

On this page

Agriculture Parcel Reports

Soil, capability, crop rotation, and land-use data for any quarter section in AB, SK, and MB. LSD inputs resolve up to their quarter section.

Example request

cURL
curl --get "https://developer.townshipcanada.com/ag/report" \
  -H "X-API-Key: $TOWNSHIP_API_KEY" \
  --data-urlencode "legal_location=NW-11-5-6-W2"
Parameters
Name Type Required Description
legal_locationstringRequiredQuarter section or LSD (LSDs resolve up to their quarter section) NW-11-5-6-W2
includestringOptionalComma-separated sections to return (omit for the full report). Only the requested sections are queried. geometry attaches the parcel polygon soil,drought,geometryproductivity , cropping , soil , land_use , drought , wetlands , hydrology , parcel_context , provincial_detail , geometry
Example Response
response.json
{
  "legal_location": "NW-11-5-6-W2",
  "resolved_legal_location": "NW-11-5-6-W2",
  "grain": "quarter_section",
  "province": "SK",
  "parcel": { "area_ha": 64.75, "centroid": { "lat": 50.36, "lng": -104.65 }, "geometry": null },
  "productivity": {
    "lsrs": { "score": 62, "class": "3", "limiter": "M - Moisture" },
    "cli": { "score": 60, "class": "3", "limiter": "M" }
  },
  "cropping": {
    "dominant": { "code": "146", "name": "Spring Wheat", "category": "Cereal" },
    "rotation": "Wheat-Canola",
    "diversity_index": 0.6412,
    "years_covered": 10
  },
  "soil": {
    "classification": { "order": "Chernozemic", "great_group": "Dark Brown Chernozem", "subgroup_code": "Orthic Dark Brown Chernozem" },
    "drainage_class": "Well drained",
    "slope_class": "2-5%"
  },
  "land_use": {
    "dominant": { "code": "51", "label": "Annual cropland", "ipcc_class": "Cropland" },
    "breakdown": [{ "code": "51", "label": "Annual cropland", "ipcc_class": "Cropland", "pct": 88.2 }]
  },
  "drought": { "class": "D1", "severity_label": "Moderate Drought", "as_of": "2026-07" },
  "wetlands": null,
  "hydrology": {
    "watercourse": { "name": "Wascana Creek", "distance_m": 240, "is_on_parcel": false },
    "water_body": { "name": null, "distance_m": null, "is_on_parcel": false, "on_parcel_pct": null },
    "search_radius_m": 500
  },
  "parcel_context": { "municipality": { "name": "Sherwood No. 159", "type": "Rural Municipality" } },
  "provincial_detail": { "crown_land": [], "soils": [], "pastures": [] },
  "units": { "area": "ha", "distance": "m" },
  "meta": {
    "unavailable": [{ "section": "wetlands", "reason": "not_published_in_province" }],
    "sources": { "...": "..." }
  }
}

Vector Tiles

The Agriculture bundle's 18 map layers as vector tiles: soils, capability, crop rotation, Crown land, pastures, and the ALR. Served from the maps CDN, authenticated with an api_key query parameter.

Tile URL Pattern

https://maps.townshipcanada.com/ag/{archive}/{z}/{x}/{y}.mvt?api_key=... https://maps.townshipcanada.com/ag/{archive}.json?api_key=... (TileJSON)
Available Archives

The source layer is the layer name inside the tile - MapLibre needs it in source-layer, and it does not always match the archive name. Anything outside this list returns 403.

Archive Source Layer Zoom Layer
ag_summary_qsag_summaryz9-22Ag Summary (quarter section)
ag_summary_secag_summary_secz6-9Ag Summary (section rollup)
ag_summary_twpag_summary_twpz0-6Ag Summary (township rollup)
aafc_crop_summarycropsz9-22Crops (quarter section)
aafc_crop_summary_seccrops_secz6-9Crops (section rollup)
aafc_crop_summary_twpcrops_twpz0-6Crops (township rollup)
soilssoilsz6-22Soil Landscapes of Canada
lsrs_productivitylsrsz9-22Productivity / LSRS (quarter section)
lsrs_productivity_seclsrs_secz6-9Productivity / LSRS (section rollup)
lsrs_productivity_twplsrs_twpz0-6Productivity / LSRS (township rollup)
bc_ag_capabilitybc_ag_capabilityz6-22BC Agricultural Capability
sk_ag_crown_landsk_ag_crown_landz6-22SK Agricultural Crown Land
sk_ag_crown_land_labelssk_ag_crown_landz10+SK Agricultural Crown Land (labels)
sk_pasturessk_pasturesz4-22SK Pastures
sk_pastures_labelssk_pasturesz8+SK Pastures (labels)
bc_alrbc_alrz4-22BC Agricultural Land Reserve
bc_alr_labelsbc_alrz10+BC Agricultural Land Reserve (labels)
bc_fwa_wetlandsbc_fwa_wetlandsz6-22BC Freshwater Atlas Wetlands
Zoom-Banded Rollup Families

ag_summary, aafc_crop_summary, and lsrs_productivity each ship as three archives covering different zoom bands - quarter-section geometry is far too dense to draw at province scale. Add all three as separate sources and let the zoom ranges hand off; a client that adds only the detail archive sees an empty map below z9.

Zoom Archive Granularity
z0-6_twpTownship (6 x 6 miles)
z6-9_secSection (1 x 1 mile)
z9+base archive (_qs / _lsd / no suffix)Quarter section / LSD

The _labels archives are the same footprint rendered as a label layer - add them as their own source alongside the geometry archive when you want text.

MapLibre Usage
const KEY = "YOUR_API_KEY";
const base = "https://maps.townshipcanada.com/ag";

// Ag Summary is a zoom-banded family: add all three sources.
// A client that adds only the detail archive sees an empty map below z9.
map.addSource("ag-summary-twp", {
  type: "vector",
  tiles: [`${base}/ag_summary_twp/{z}/{x}/{y}.mvt?api_key=${KEY}`],
  minzoom: 0,
  maxzoom: 6
});
map.addSource("ag-summary-sec", {
  type: "vector",
  tiles: [`${base}/ag_summary_sec/{z}/{x}/{y}.mvt?api_key=${KEY}`],
  minzoom: 6,
  maxzoom: 9
});
map.addSource("ag-summary-qs", {
  type: "vector",
  tiles: [`${base}/ag_summary_qs/{z}/{x}/{y}.mvt?api_key=${KEY}`],
  minzoom: 9,
  maxzoom: 14
});

map.addLayer({
  id: "ag-summary-qs-fill",
  type: "fill",
  source: "ag-summary-qs",
  "source-layer": "ag_summary", // note: not the archive name
  minzoom: 9,
  paint: { "fill-color": "#41ab5d", "fill-opacity": 0.6 }
});

// TileJSON works too, and carries the bounds and zoom range
map.addSource("soils", {
  type: "vector",
  url: `${base}/soils.json?api_key=${KEY}`
});