Geocoding, IP and timezone lookups over one plain HTTP API
Turn addresses into coordinates and back, find out where an IPv4 or IPv6 address sits, get the timezone or elevation of any point, and resolve postal codes. Send a GET request, read the JSON. Nothing to install.
2,500 free requests a day from any address, with no key and no account. Need more? Sign up with your name and email, add prepaid credit at €0.0001 per request, or take an Unlimited key for €50 a month (€500 a year, two months free). Cards and crypto accepted.
$ curl -H "X-API-Key: YOUR_KEY" "https://api.mygeocode.com/v1/reverse?lat=48.8584&lon=2.2945"{ "status": "ok", "lat": 48.8584, "lon": 2.2945, "result": { "formatted": "5 Avenue Anatole France, 75007 Paris, France", "lat": 48.858821, "lon": 2.294596, "distance_m": 47, "type": "address", "precision": "house", "confidence": 0.85, "place_id": "uaOpXczzaHCkNCaNUcKLUz6vyUB3_IjkyQ", "components": { "house_number": "5", "road": "Avenue Anatole France", "suburb": "7e arrondissement", "city": "Paris", "postcode": "75007", "country": "France", "country_code": "fr" }, "bounds": { "north": 48.859321, "south": 48.858318, "east": 2.295098, "west": 2.294096 }, "codes": { "plus_code": "8FW4V75V+GR", "geohash": "u09tunqz7bqg", "mgrs": "31UDQ4825912001", "maidenhead": "JN18du56", "dms": { "lat": "48° 51' 31.8\" N", "lon": "2° 17' 40.5\" E" }, "mapcode": "FRA 4H.QX", "mapcode_international": "VHPM8.QYF6" } } }
Eight lookups, one base URL
Every endpoint lives under https://api.mygeocode.com/v1/, takes query parameters, and returns JSON with the same envelope. Learn one and you know them all.
Forward Geocoding API
GET /v1/forwardSend an address, a place name or a rough description and get coordinates, a cleaned up address and each of its parts.
Details and examplesReverse Geocoding API
GET /v1/reverseSend a latitude and longitude and get the nearest address, with the city, region, postcode and country broken out.
Details and examplesAddress Autocomplete API
GET /v1/autocompleteSuggest addresses while someone types. Every suggestion comes with coordinates, so you rarely need a second call.
Details and examplesIPv4 Lookup API
GET /v1/ipv4Country, region, city, coordinates, timezone and network owner for any IPv4 address, or for the caller if you leave it out.
Details and examplesIPv6 Lookup API
GET /v1/ipv6The same details for IPv6 addresses, including the announced prefix the address belongs to.
Details and examplesTimezone Lookup API
GET /v1/timezoneIANA timezone name, UTC offset, DST status and local time for any coordinate, now or at a timestamp you choose.
Details and examplesElevation Lookup API
GET /v1/elevationHeight above sea level in metres for one point, or up to 100 points in a single call.
Details and examplesPostal Code Lookup API
GET /v1/postcodeTurn a postal code into a place name, region and coordinates. Works for ZIP codes, postcodes and their equivalents in most countries.
Details and examplesEvery result says how precise it is
A geocoder that returns a city centre when you asked for a house number is worse than one that says it could not find the house. Each result we return carries a precision field, so your code can decide what to do with a coarse match instead of guessing.
Coverage is not the same everywhere, and we would rather show you than make a blanket claim. The coverage page lists the best level we reach in each of 252 countries and territories.
| Level | What the point represents |
|---|---|
house | The house asked for: on the building or parcel where the address data has it, or placed along its street from the street's number range. |
street | The street, when the house itself could not be answered. |
postcode | The centre of the postal code area. |
city, region, country | The centre of the town, region or country, whichever is the most specific match we could make. |
Already using someone else's API? Change the hostname.
We run drop-in hosts that accept the same paths and parameters as Google Maps, Bing Maps, HERE, Mapbox, Geocode.Farm, Nominatim and eleven others, and answer in their response format with our data. Your parsing code does not change. Put your My Geocode key where the old key went.
$ curl "https://maps.googleapis.com/maps/api/geocode/json?address=10+Downing+St+London&key=GOOGLE_KEY"$ curl "https://gapi.mygeocode.com/maps/api/geocode/json?address=10+Downing+St+London&key=MYGEOCODE_KEY"The same idea works for JavaScript libraries. Load the Google Maps JavaScript API from gapi.mygeocode.com and google.maps.Map, Geocoder and Places Autocomplete keep working, with the map drawn on free OpenStreetMap tiles and nothing charged for loading the library. There are loaders for the Bing Maps V8 control, HERE Maps for JavaScript and MapQuest.js, and settings for MapLibre, Mapbox GL and Leaflet geocoder plugins.
- Google Maps
- Bing Maps
- HERE
- Mapbox
- Geocode.Farm
- Nominatim
- OpenCage
- LocationIQ
- Geoapify
- TomTom
- MapQuest
- Geocodio
- PositionStack
- ip-api
- ipinfo
- ipstack
- Open-Elevation
If it can send an HTTP request, it can use this
No SDK is needed. These examples geocode an address and print its coordinates.
$ curl -H "X-API-Key: YOUR_KEY" "https://api.mygeocode.com/v1/forward?q=221B+Baker+Street,+London"const url = new URL("https://api.mygeocode.com/v1/forward");
url.searchParams.set("q", "221B Baker Street, London");
const res = await fetch(url, { headers: { "X-API-Key": process.env.MYGEOCODE_KEY } });
const data = await res.json();
const [first] = data.results;
console.log(first.lat, first.lon, first.precision);import os
import requests
r = requests.get(
"https://api.mygeocode.com/v1/forward",
params={"q": "221B Baker Street, London"},
headers={"X-API-Key": os.environ["MYGEOCODE_KEY"]},
timeout=10,
)
r.raise_for_status()
first = r.json()["results"][0]
print(first["lat"], first["lon"], first["precision"])<?php
$url = "https://api.mygeocode.com/v1/forward?" . http_build_query([
"q" => "221B Baker Street, London",
]);
$context = stream_context_create(["http" => ["header" => "X-API-Key: " . getenv("MYGEOCODE_KEY")]]);
$data = json_decode(file_get_contents($url, false, $context), true);
$first = $data["results"][0];
echo $first["lat"], ", ", $first["lon"], " (", $first["precision"], ")\n";package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{"q": {"221B Baker Street, London"}}
req, _ := http.NewRequest("GET", "https://api.mygeocode.com/v1/forward?"+q.Encode(), nil)
req.Header.Set("X-API-Key", os.Getenv("MYGEOCODE_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var data struct {
Results []struct {
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
Precision string `json:"precision"`
} `json:"results"`
}
json.NewDecoder(resp.Body).Decode(&data)
fmt.Println(data.Results[0].Lat, data.Results[0].Lon, data.Results[0].Precision)
}import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class Geocode {
public static void main(String[] args) throws Exception {
String q = URLEncoder.encode("221B Baker Street, London", StandardCharsets.UTF_8);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.mygeocode.com/v1/forward?q=" + q))
.header("X-API-Key", System.getenv("MYGEOCODE_KEY"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}using System.Net.Http;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", Environment.GetEnvironmentVariable("MYGEOCODE_KEY"));
var q = Uri.EscapeDataString("221B Baker Street, London");
var json = await client.GetStringAsync($"https://api.mygeocode.com/v1/forward?q={q}");
using var doc = JsonDocument.Parse(json);
var first = doc.RootElement.GetProperty("results")[0];
Console.WriteLine($"{first.GetProperty("lat")}, {first.GetProperty("lon")} ({first.GetProperty("precision")})");require "net/http"
require "json"
uri = URI("https://api.mygeocode.com/v1/forward")
uri.query = URI.encode_www_form(q: "221B Baker Street, London")
req = Net::HTTP::Get.new(uri)
req["X-API-Key"] = ENV["MYGEOCODE_KEY"]
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
first = JSON.parse(res.body)["results"][0]
puts "#{first["lat"]}, #{first["lon"]} (#{first["precision"]})"An email address is the whole signup
Any address gets 2,500 free requests a day with no key at all, across all endpoints and drop-in hosts, measured from 00:00 UTC. A key takes a minute when you want one: sign up with your name, an email address and a password, confirm the address from the email we send, and your first key is waiting in the dashboard. No company, no card. An account gets 2,500 free requests a day, shared by all of its keys. Requests made without a key from the same network share that allowance too, so an account adds credit, packages and a usage history, not a second free 2,500.
Keys are tied to the machines that use them. A pay-as-you-go key serves two IP addresses in any rolling 24 hours, an Unlimited key three. Each address holds its slot for 24 hours from its first request and then frees it. A request from a further address is refused and not counted, which is what stops a leaked key from being useful to anyone else. Need more addresses? Create more keys or add packages.
-
Sign up, get a key
Email and password. The key stays in the dashboard, so you can copy it again at any time. 2,500 requests a day, free, from up to two IP addresses.
-
Add credit when you need more
Top up €10, €25, €50 or €100 by card or crypto. Requests above your account's free allowance take €0.0001 each from the balance. Credit never expires and nothing is charged automatically.
-
Or take an Unlimited key
€50 a month, or €500 a year with two months free, buys a key with no per-request charges, usable from three IP addresses per rolling 24 hours. Order as many packages as you have applications.
Free to start, simple to pay for
Every endpoint costs the same. Every drop-in host counts the same. No tiers, no per-seat charges, no contract. Prices in euros, paid by card or crypto.
Free key
2,500 requests a day per account, shared by all your keys. Sign up with your name and email; no card. Same data and the same endpoints as paid usage.
Credit
€0.0001 per request above your account's free 2,500 each day, taken from a balance you top up whenever you like. No monthly fee, no expiry. 10,000 requests in a day use €0.75 of credit.
Unlimited key
€50 a month, or €500 a year (two months free). A key with no per-request charges across every endpoint and every drop-in host, from up to three IP addresses per rolling 24 hours.
Client libraries
Client libraries for JavaScript and TypeScript, Python, PHP, Go, Java, C#, Ruby and Rust will stay small: typed responses, sensible timeouts and retries on 429 and 503. Each one goes on the SDK page with its install command when it is released.
Do I need a key to try it?
No. Any address gets 2,500 requests a day with no key and no account. The demo page sends requests straight from the browser without one. A free key takes a minute when you want credit, an Unlimited package or a usage history.
What happens at request 2,501?
If your account has credit, the request goes through and uses €0.0001 of it. If it does not, you get HTTP 402 until 00:00 UTC or until you top up. On an Unlimited key nothing changes.
Why is a key limited to two or three IP addresses?
Keys are meant for servers, and the limit means a key that leaks into a public repository cannot be used from a hundred machines. Each address holds its slot for 24 hours from its first request, then the slot frees. A pay-as-you-go key has two slots, an Unlimited key three. For more machines, create more keys or add packages.
Can I store the results?
Yes. Cache them, save them in your database, show them on a map from another provider. The terms only ask that you do not resell the raw data as a geocoding service of your own.
Send your first request now
The demo sends live requests from your browser with your key and opens the JSON response. A free key takes your name, an email address and a minute; when you outgrow 2,500 a day, top up credit or add an Unlimited key.