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.
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'
JSON: add json=1. JSONP: add
jsonp=1&callback=yourFn. CSV: use geoit=CSV instead of geoit=XML.
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.
| Parameter | Req. | Description & values |
|---|---|---|
| locate | yes | The 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. |
| geoit | yes | Output port/type: XML or CSV. |
| auth | premium | Your token (≤30 bytes) for unthrottled service; tracks your lookup count. |
| json | — | JSON output. Value: 1. |
| jsonp / callback | — | JSONP output (jsonp=1) with your callback string. |
| standard | — | Return the standardized, properly-formatted address. Value: 1. |
| strict | — | Strict parsing of free-form input. Value: 1. |
| strictmode | — | Don't guess on ambiguous input (e.g. city with no state) — return a suggestion list instead. 0 or 1. |
| topmatches | — | For partial input, return up to this many best suggestions (positive integer). |
| showpostal | — | For an address/intersection, also return the postal code. Value: 1. |
| showcountry | — | Return the country code (US or CA). Value: 1. |
| showaddrs | premium | For a postal/ZIP, return all associated addresses. 1. Costs 1 credit per address — pair with limit (e.g. limit=100) and optionally street=. try › |
| bounds | — | Bias to a bounding box: SWlat,SWlng,NElng — for scantext or locate. |
| country | — | Bias by country: country=usa or country=canada. |
| region | — | Limit to a region: 2-letter state/province (e.g. region=NY), or region=canada / region=usa. |
| decimal | — | Limit decimal places in coordinates (smaller = less precise). |
| utm | — | Also return UTM coordinates. Value: 1. |
| id | — | Your transaction id (≤15 bytes), echoed back in the response. |
| postal | dep. | (Deprecated) A Canadian postal code or US ZIP5 / ZIP+4, format ANANAN. |
| getpolygon | — | Return the postal-code boundary polygon. 1. try › |
| boundary | premium | Look up a neighborhood boundary (CSV only): boundary=Name,City,lat,lng&geoit=csv. |
Pass free-form text and get back every location found, ordered by confidence score. Great for mining addresses out of documents, emails or articles.
| Parameter | Req. | Description & values |
|---|---|---|
| scantext | yes | Free-form text containing one or more locations. Output lists found locations in confidence order. |
| geoit | yes | XML or CSV. |
| bounds / country / region | — | Bias 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” ›
Find the coordinates where two streets cross. Send via GET or POST.
| Parameter | Req. | Description & values |
|---|---|---|
| street1 | yes | First street name (≤220 bytes). |
| street2 | yes | Second street name (≤220 bytes). |
| city | yes | City name (≤220 bytes). |
| prov | yes | 2-letter province (AB,BC,MB,NB,NL,NS,NT,NU,ON,PE,QC,SK,YT) or US state. |
| cross | yes | Intersection mode flag. Value: 1. |
| geoit | yes | Value: XML. |
| locate | — | Instead of street1/street2: we'll parse an address or intersection from this. |
| showpostal / decimal / id | — | As in forward geocoding. |
A failed request may return a <suggestion> with corrected street names, city and province.
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'
| Parameter | Req. | Description & values |
|---|---|---|
| latt, longt | yes | The point to reverse-geocode (decimals). |
| reverse | yes | Interface flag. Value: 1. |
| geoit | yes | Value: XML. |
| allna | — | Search both USA & Canada — required for US reverse geocoding; near borders may return two results. 1. |
| corner | — | Also return the nearest street intersection. 1. |
| moreinfo | — | Add county and metro-area info. 1. |
| range | — | Limit the search radius (number). |
| exact | — | Attempt an exact (rooftop) match. 1. |
| nopostal | — | Ignore the postal code — street-level match only. 1. |
| strict | — | Perform a strict match. 1. |
| decimal / id | — | As in forward geocoding. |
?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.Add pois=1 to a reverse lookup to also return nearby points of interest.
| Parameter | Req. | Description & values |
|---|---|---|
| pois | yes | Enable place search. Value: 1. |
| type | — | Place category, e.g. restaurant. Full lists for Canada / USA. |
| keyword | — | Search keyword, e.g. keyword=Subway. If sent, type is ignored. |
| radius | — | Search 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.
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.
Responses (XML or JSON) may include the following. Empty latt/longt means no match.
| Field | Meaning |
|---|---|
| latt, longt | Latitude / longitude (decimals). |
| confidence | Accuracy 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, postal | Standardized address components (with standard=1). |
| more | The 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. |
| TimeZone | Time zone code. |
| AreaCode | Telephone area code. |
| LSD | Alberta Township System (ATS / DLS) legal subdivision, where applicable. |
| remaining_credits | Credits left (min −100 buffer; below that, lookups stop). |
| id | Your transaction id, if supplied. |
| inlatt, inlongt, distance, NearRoad, NearRoadDistance, neighborhood | Reverse-geocoding extras: input point, result distance, nearest road and the neighborhood the point falls in. |
| Code | Meaning |
|---|---|
| 001 | IP address not allowed to use this auth token (token IP-restricted). |
| 002 | Auth token out of credits (more than 100 over balance). |
| 003 | Auth token not found. |
| 004 | Specify a valid Canadian province or US state 2-letter code. |
| 005 | Postal code not in the proper format. |
| 007 | Supply a valid query. |
| 008 | No results — check spelling. May include <suggestion> tags. |
| 009 | Latitude/longitude out of valid range (reverse geocoding). |
| 010 | Intersection needs two streets + city + province. |
| 101 | Ambiguous input — several cities match; response lists <possiblecity> options. |
topmatches, the most likely matches are returned for malformed input, e.g.
?locate=200+mutcalf,+ottawa+on&geoit=xml&topmatches=5.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.
Our agent skills (MIT-licensed) teach Claude Code, Codex, Gemini CLI and other coding agents the Geocoder.ca API. With them installed, an agent knows the endpoints, parameters, output fields, error codes and rate limits on this page. It also has ready-made examples in Python, Node.js, PHP, Perl and the command line. Ask it to geocode a column of addresses or validate postal codes, and it writes working code on the first try.
geocoder-ca-apiForward & reverse geocoding, address validation and standardization, postal-code / ZIP+4 lookup,
intersections, geoparsing (scantext), nearby places and Canadian census geography.
geocoder-ca-autocompleteAdds our dependency-free JavaScript drop-in for as-you-type Canadian address entry to your web forms (see autocomplete).
Claude Code
/plugin marketplace add geocode-xyz/geolytica-skills /plugin install geolytica@geolytica-skills
Gemini CLI
gemini extensions install https://github.com/geocode-xyz/geolytica-skills
Codex and other agents: add to your AGENTS.md or agent instructions
Fetch and follow instructions from https://geocoder.ca/SKILL.md https://raw.githubusercontent.com/geocode-xyz/geolytica-skills/refs/heads/main/skills/geocoder-ca-autocomplete/SKILL.md
GEOCODER_CA_AUTH:
export GEOCODER_CA_AUTH=YOUR_AUTH_TOKEN. Without a token the skills use the throttled free tier,
which is fine for testing. Agents that discover APIs through
https://geocoder.ca/.well-known/api-catalog find the skill without installing anything.
Full instructions: install.md.Create an account, grab your auth token, and you're geocoding in minutes.
Create an API account Browse examples