Geocoder.ca

The Geocoder.ca API

One HTTPS endpoint — https://geocoder.ca/ — for forward & reverse geocoding, intersections, geoparsing, autocomplete and places. GET or POST, over SSL. XML by default; JSON, JSONP, GeoJSON and CSV on request.

Quick start

Shortcut form: https://geocoder.ca/some_location?desired_output. Sign up for an auth token to use the XML/JSON/CSV data port unthrottled.

curl -G 'https://geocoder.ca/' \\
  --data-urlencode 'locate=330 metcalfe ottawa on' \\
  --data 'geoit=XML' --data 'json=1' \\
  --data 'standard=1' \\
  --data 'auth=YOUR_AUTH_TOKEN'
1 successful lookup = 1 credit (regardless of response size). Credits never expire — $1 buys 200. Non-profit or need the free XML port? Use it here.

JSON: add json=1. JSONP: add jsonp=1&callback=yourFn. CSV: use geoit=CSV instead of geoit=XML.

Forward geocoding

Send these to https://geocoder.ca/ via GET or POST. Put as much location detail as possible in locate — it parses addresses, intersections, postal/ZIP codes and IP addresses.

ParameterReq.Description & values
locateyesThe location: street address, intersection, zip/postal, IP, or any combination. e.g. 330 metcalfe ottawa or metcalfe & wellington ottawa. Deprecated component params (addresst, stno, city…) still work for backwards compatibility.
geoityesOutput port/type: XML or CSV.
authpremiumYour token (≤30 bytes) for unthrottled service; tracks your lookup count.
jsonJSON output. Value: 1.
jsonp / callbackJSONP output (jsonp=1) with your callback string.
standardReturn the standardized, properly-formatted address. Value: 1.
strictStrict parsing of free-form input. Value: 1.
strictmodeDon't guess on ambiguous input (e.g. city with no state) — return a suggestion list instead. 0 or 1.
topmatchesFor partial input, return up to this many best suggestions (positive integer).
showpostalFor an address/intersection, also return the postal code. Value: 1.
showcountryReturn the country code (US or CA). Value: 1.
showaddrspremiumFor a postal/ZIP, return all associated addresses. 1. Costs 1 credit per address — pair with limit (e.g. limit=100) and optionally street=. try ›
boundsBias to a bounding box: SWlat,SWlng,NElng — for scantext or locate.
countryBias by country: country=usa or country=canada.
regionLimit to a region: 2-letter state/province (e.g. region=NY), or region=canada / region=usa.
decimalLimit decimal places in coordinates (smaller = less precise).
utmAlso return UTM coordinates. Value: 1.
idYour transaction id (≤15 bytes), echoed back in the response.
postaldep.(Deprecated) A Canadian postal code or US ZIP5 / ZIP+4, format ANANAN.
getpolygonReturn the postal-code boundary polygon. 1. try ›
boundarypremiumLook up a neighborhood boundary (CSV only): boundary=Name,City,lat,lng&geoit=csv.

Geoparsing — extract locations from text scantext

Pass free-form text and get back every location found, ordered by confidence score. Great for mining addresses out of documents, emails or articles.

ParameterReq.Description & values
scantextyesFree-form text containing one or more locations. Output lists found locations in confidence order.
geoityesXML or CSV.
bounds / country / regionBias the parse to a box, country, or 2-letter region (same as forward).

try: “This and That and the Other street in Porters Lake Nova Scotia” ›

Premium functions

Available to premium API subscribers. Several bill per returned data item — note the cost column.

FunctionCostDescription & example
autocompletesubAutocomplete Canadian postal addresses: autocomplete=1&locate=1435 prince&geoit=xml. xml › demo ›
showaddrs1/addrAll addresses for a postal/ZIP. Use limit and street to control volume.
batchpostal1/codeMultiple postal codes, pipe-separated: batchpostal=K2C1N5&geoit=xml.
postalinpolygon1/codeAll postal codes inside a polygon: postalinpolygon=lat,lng,lng|…&geoit=xml. Large polygons = many codes.
censusdatafromdauid1/itemCensus data for a Canadian dauid returned by a lookup: censusdatafromdauid=59350105&geoit=xml.
getpolygonPostal-code boundary polygon (see Forward).

Intersection geocoding

Find the coordinates where two streets cross. Send via GET or POST.

ParameterReq.Description & values
street1yesFirst street name (≤220 bytes).
street2yesSecond street name (≤220 bytes).
cityyesCity name (≤220 bytes).
provyes2-letter province (AB,BC,MB,NB,NL,NS,NT,NU,ON,PE,QC,SK,YT) or US state.
crossyesIntersection mode flag. Value: 1.
geoityesValue: XML.
locateInstead of street1/street2: we'll parse an address or intersection from this.
showpostal / decimal / idAs in forward geocoding.

A failed request may return a <suggestion> with corrected street names, city and province.

Reverse geocoding

Supply a latitude/longitude pair; get the nearest civic address, postal/ZIP, nearest intersection, nearest major intersection, and the closest road — plus optional POIs.

curl -G 'https://geocoder.ca/' \\
  --data 'latt=45.4215' --data 'longt=-75.6972' \\
  --data 'reverse=1' --data 'geoit=XML' \\
  --data 'allna=1' --data 'auth=YOUR_AUTH_TOKEN'
ParameterReq.Description & values
latt, longtyesThe point to reverse-geocode (decimals).
reverseyesInterface flag. Value: 1.
geoityesValue: XML.
allnaSearch both USA & Canada — required for US reverse geocoding; near borders may return two results. 1.
cornerAlso return the nearest street intersection. 1.
moreinfoAdd county and metro-area info. 1.
rangeLimit the search radius (number).
exactAttempt an exact (rooftop) match. 1.
nopostalIgnore the postal code — street-level match only. 1.
strictPerform a strict match. 1.
decimal / idAs in forward geocoding.
Reverse from a postal/ZIP too: ?postal=75704-2933&geoit=xml&standard=1&moreinfo=1 — accepts ZIP5, ZIP+4 or a Canadian postal code. US results come wrapped in <usa> tags; optional <intersection> and <major_intersection> blocks carry nearest corners.

Reverse place search — nearest POIs pois

Add pois=1 to a reverse lookup to also return nearby points of interest.

ParameterReq.Description & values
poisyesEnable place search. Value: 1.
typePlace category, e.g. restaurant. Full lists for Canada / USA.
keywordSearch keyword, e.g. keyword=Subway. If sent, type is ignored.
radiusSearch radius in metres. Omit to auto-size (denser areas → smaller radius, up to ~1.5 km).

restaurants within 200 m › keyword “elgin” › all nearby (JSON) ›

Each poi returns: name, distance_km, main/second category, address, city, neighborhood, phone, location_id / area_id / small_area_id, lat/long, prov, postal, formatted_address, source_url, crawl_time and opening_hours.

Partial street-name matching

Match partial street names across Canada and the USA.

https://geocoder.ca/?cityname=Ottawa&provname=on&streetname=metcalfe&matchonly=1&geoit=xml

Required: cityname, provname, streetname, matchonly=1, geoit=xml. Or constrain with a box via bounds=SWlat,SWlng,NElng instead of city/prov.

Output fields

Responses (XML or JSON) may include the following. Empty latt/longt means no match.

FieldMeaning
latt, longtLatitude / longitude (decimals).
confidenceAccuracy estimate 0–1 (1 = best). Results below 0.5 aren't returned (a suggestion may be) — except IP geocoding, where city-level approximations are allowed.
stnumber, staddress, city, prov, postalStandardized address components (with standard=1).
moreThe part of the input not used for the location — useful for extracting PO boxes, apt/unit numbers, etc.
Dissemination_Area (adauid, dauid)Canadian census dissemination-area IDs. Feed dauid to censusdatafromdauid.
TimeZoneTime zone code.
AreaCodeTelephone area code.
LSDAlberta Township System (ATS / DLS) legal subdivision, where applicable.
remaining_creditsCredits left (min −100 buffer; below that, lookups stop).
idYour transaction id, if supplied.
inlatt, inlongt, distance, NearRoad, NearRoadDistance, neighborhoodReverse-geocoding extras: input point, result distance, nearest road and the neighborhood the point falls in.

Error codes

CodeMeaning
001IP address not allowed to use this auth token (token IP-restricted).
002Auth token out of credits (more than 100 over balance).
003Auth token not found.
004Specify a valid Canadian province or US state 2-letter code.
005Postal code not in the proper format.
007Supply a valid query.
008No results — check spelling. May include <suggestion> tags.
009Latitude/longitude out of valid range (reverse geocoding).
010Intersection needs two streets + city + province.
101Ambiguous input — several cities match; response lists <possiblecity> options.
With topmatches, the most likely matches are returned for malformed input, e.g. ?locate=200+mutcalf,+ottawa+on&geoit=xml&topmatches=5.

Code samples

Forward geocoding in a few popular languages. Every example hits the same endpoint — https://geocoder.ca/?locate=<address>&json=1&auth=<token> — and reads latt / longt from the JSON response. Swap locate for stno/addresst/city/prov components, or add &geoit=XML / &geoit=CSV for other formats.

# Forward geocode, JSON out
curl "https://geocoder.ca/?locate=101+Wellington+St,+Ottawa,+ON&json=1&auth=YOUR_AUTH_TOKEN"

# Reverse geocode (POST)
curl -X POST "https://geocoder.ca/" \
  -d latt=45.4215 -d longt=-75.6972 \
  -d geoit=XML -d reverse=1 -d auth=YOUR_AUTH_TOKEN
import requests

r = requests.get("https://geocoder.ca/", params={
    "locate": "101 Wellington St, Ottawa, ON",
    "json":   1,
    "auth":   "YOUR_AUTH_TOKEN",
})
data = r.json()
print(data["latt"], data["longt"])
// Node 18+ or browsers (fetch is built in)
const params = new URLSearchParams({
  locate: "101 Wellington St, Ottawa, ON",
  json:   "1",
  auth:   "YOUR_AUTH_TOKEN",
});
const res  = await fetch(`https://geocoder.ca/?${params}`);
const data = await res.json();
console.log(data.latt, data.longt);
<?php
$params = http_build_query([
    "locate" => "101 Wellington St, Ottawa, ON",
    "json"   => 1,
    "auth"   => "YOUR_AUTH_TOKEN",
]);
$data = json_decode(
    file_get_contents("https://geocoder.ca/?" . $params),
    true
);
echo $data["latt"] . ", " . $data["longt"];
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "net/url"
)

func main() {
    q := url.Values{}
    q.Set("locate", "101 Wellington St, Ottawa, ON")
    q.Set("json", "1")
    q.Set("auth", "YOUR_AUTH_TOKEN")

    res, _ := http.Get("https://geocoder.ca/?" + q.Encode())
    defer res.Body.Close()

    var d struct{ Latt, Longt string }
    json.NewDecoder(res.Body).Decode(&d)
    fmt.Println(d.Latt, d.Longt)
}
require "net/http"
require "json"

uri = URI("https://geocoder.ca/")
uri.query = URI.encode_www_form(
  locate: "101 Wellington St, Ottawa, ON",
  json:   1,
  auth:   "YOUR_AUTH_TOKEN",
)
data = JSON.parse(Net::HTTP.get(uri))
puts "#{data['latt']}, #{data['longt']}"
use strict; use warnings;
use HTTP::Tiny;
use JSON::PP;
use URI::Escape;

my $addr = uri_escape("101 Wellington St, Ottawa, ON");
my $url  = "https://geocoder.ca/?locate=$addr&json=1&auth=YOUR_AUTH_TOKEN";

my $res = HTTP::Tiny->new->get($url);
my $d   = decode_json($res->{content});
print "$d->{latt}, $d->{longt}\n";

Reverse geocoding uses the same endpoint with a POST sending latt, longt, reverse=1 (add allna=1 for nearest address + corner), plus geoit and auth. More: live examples · AWS cloud guide · community libraries.

Ready to test it?

Create an account, grab your auth token, and you're geocoding in minutes.

Create an API account Browse examples