Quickstart
Prerequisites
- An API key (get one here)
- A tool to make HTTP requests (curl, or your language runtime)
- Python: Python 3.6+ (the examples use f-strings and
requestslibrary type annotations compatible with 3.6+) - JavaScript: Node.js 18+ (the examples use top-level
awaitand ES modules) - PHP: PHP 7.4+ with the
curlextension enabled (the examples usecurl_init()). Most distributions include it; if not, installphp-curlvia your package manager.
Make Your First Request
Replace gm_YOUR_API_KEY below with the real API key you copied from your Dashboard.
For cURL, pass it directly in the header. For Python, JavaScript, and PHP, set the GEOCODEME_API_KEY environment variable first:
# macOS / Linux
export GEOCODEME_API_KEY="gm_YOUR_API_KEY"
# Windows PowerShell
$env:GEOCODEME_API_KEY = "gm_YOUR_API_KEY"
:: Windows Command Prompt
set GEOCODEME_API_KEY=gm_YOUR_API_KEY
- cURL
- Python
- JavaScript
- PHP
curl -H "X-Api-Key: gm_YOUR_API_KEY" \
"https://api.geocodeme.net/v1/geocode?q=Paris%2C%20France&limit=1"
To also check the HTTP status code, use -f (fail on HTTP errors):
curl -sf -H "X-Api-Key: gm_YOUR_API_KEY" \
"https://api.geocodeme.net/v1/geocode?q=Paris%2C%20France&limit=1" || echo "Error: request failed" >&2
First, install the requests library:
pip install requests
Then run:
import os
import sys
import requests
api_key = os.environ.get("GEOCODEME_API_KEY")
if not api_key:
sys.exit("Set the GEOCODEME_API_KEY environment variable")
base_url = "https://api.geocodeme.net/v1"
def check_api_error(response: requests.Response) -> None:
"""Check for API errors and exit with a clear message."""
if not response.ok:
try:
error = response.json()
sys.exit(f"{error['error']['code']}: {error['error']['message']}")
except (ValueError, KeyError):
sys.exit(f"HTTP {response.status_code}: {response.text}")
response = requests.get(
f"{base_url}/geocode",
params={"q": "Paris, France", "limit": 1},
headers={"X-Api-Key": api_key},
)
check_api_error(response)
data = response.json()
if not data["results"]:
print("No results found for the given query")
sys.exit(1)
print(data["results"][0]["display_name"])
# Display attribution as required by the OSM license (ODbL)
print(data["attribution"])
// Node.js only — not for browsers. Requires Node.js 18+ with top-level await (use .mjs extension or set "type": "module" in package.json).
const apiKey = process.env.GEOCODEME_API_KEY;
if (!apiKey) {
console.error("Set the GEOCODEME_API_KEY environment variable");
process.exit(1);
}
const baseUrl = "https://api.geocodeme.net/v1";
async function handleError(response) {
const text = await response.text();
let parsed;
try {
parsed = JSON.parse(text);
} catch {
console.error(`HTTP ${response.status}: ${text}`);
process.exit(1);
}
const code = parsed.error?.code ?? response.status;
const message = parsed.error?.message ?? text;
console.error(`${code}: ${message}`);
process.exit(1);
}
const response = await fetch(
`${baseUrl}/geocode?q=Paris%2C%20France&limit=1`,
{ headers: { "X-Api-Key": apiKey } }
);
if (!response.ok) await handleError(response);
const data = await response.json();
if (data.results.length === 0) {
console.error("No results found for the given query");
process.exit(1);
}
console.log(data.results[0].display_name);
// Display attribution as required by the OSM license (ODbL)
console.log(data.attribution);
Uses the geocodeme_get() helper from the PHP examples page:
<?php
// Paste the geocodeme_get() helper from the PHP examples page, then:
$data = geocodeme_get('/geocode', ['q' => 'Paris, France', 'limit' => 1]);
if (empty($data->results)) {
throw new RuntimeException('No results found for the given query');
}
echo $data->results[0]->display_name . PHP_EOL;
// Display attribution as required by the OSM license (ODbL)
echo $data->attribution . PHP_EOL;
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | Yes | Address or place name to search for (URL-encoded) |
limit | integer | No | Maximum number of results to return (default: 10, max: 50) |
For the full list of parameters, see the API Reference.
Expected Response
The attribution field in every response must be displayed in your application when using geocodeme.net data, as required by the OpenStreetMap license (ODbL). Include it in your UI footer or about page, for example:
<footer>Geocoding by geocodeme.net — © OpenStreetMap contributors</footer>
{
"results": [
{
"name": "Paris",
"display_name": "Paris, Île-de-France, France",
"lat": 48.8566101,
"lon": 2.3514992,
"type": "city",
"importance": 0.9288,
"address": {
"city": "Paris",
"state": "Île-de-France",
"country": "France",
"country_code": "fr"
}
}
],
"attribution": "© OpenStreetMap contributors",
"meta": {
"took_ms": 12,
"cache_hit": false
}
}
| Field | Description |
|---|---|
results | Array of location objects matching the query |
results[].name | Proper name of the place (OSM name tag); null for an unnamed object such as a plain street. Display it as the title, display_name underneath. See The name field |
results[].display_name | Human-readable location string (always present) |
results[].lat, lon | Coordinates as numbers (always present) |
results[].address | Structured address object; optional, may be absent for some results. Fields like |
results[].type, importance | Place type (e.g. city, house) and relevance score (0 to 1), optional |
attribution | Required OSM attribution string; must be displayed in any public-facing application |
meta.took_ms | Server processing time in milliseconds |
meta.cache_hit | Whether the response was served from Redis cache |
The address, type, and importance fields are optional and may be absent depending on the result. Always check for their presence before accessing them in your code.
Reverse Geocode
Convert coordinates to an address using the /v1/reverse endpoint.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
lat | number | Yes | Latitude of the location (-90 to 90) |
lon | number | Yes | Longitude of the location (-180 to 180) |
zoom | integer | No | Level of detail for the address (3 to 18, default: 18). Higher values return more specific addresses |
addressdetails | integer | No | Include a breakdown of the address into elements (0 or 1, default: 1) |
For the full list of parameters, see the Reverse Geocoding API Reference.
- cURL
- Python
- JavaScript
- PHP
curl -s -f -H "X-Api-Key: gm_YOUR_API_KEY" \
"https://api.geocodeme.net/v1/reverse?lat=48.8566&lon=2.3522" || echo "Error: request failed" >&2
import os
import sys
import requests
api_key = os.environ.get("GEOCODEME_API_KEY")
if not api_key:
sys.exit("Set the GEOCODEME_API_KEY environment variable")
base_url = "https://api.geocodeme.net/v1"
response = requests.get(
f"{base_url}/reverse",
params={"lat": 48.8566, "lon": 2.3522},
headers={"X-Api-Key": api_key},
)
if not response.ok:
try:
error = response.json()
sys.exit(f"{error['error']['code']}: {error['error']['message']}")
except (ValueError, KeyError):
sys.exit(f"HTTP {response.status_code}: {response.text}")
data = response.json()
if data["result"] is None:
print("No results found for the given coordinates")
sys.exit(1)
print(data["result"]["display_name"])
// Node.js only — not for browsers. Requires Node.js 18+ with top-level await.
const apiKey = process.env.GEOCODEME_API_KEY;
if (!apiKey) {
console.error("Set the GEOCODEME_API_KEY environment variable");
process.exit(1);
}
const baseUrl = "https://api.geocodeme.net/v1";
const reverseResponse = await fetch(
`${baseUrl}/reverse?lat=48.8566&lon=2.3522`,
{ headers: { "X-Api-Key": apiKey } }
);
if (!reverseResponse.ok) {
const text = await reverseResponse.text();
let parsed;
try {
parsed = JSON.parse(text);
} catch {
console.error(`HTTP ${reverseResponse.status}: ${text}`);
process.exit(1);
}
console.error(`${parsed.error?.code ?? reverseResponse.status}: ${parsed.error?.message ?? text}`);
process.exit(1);
}
const reverseData = await reverseResponse.json();
if (reverseData.result === null) {
console.error("No results found for the given coordinates");
process.exit(1);
}
console.log(reverseData.result.display_name);
Uses the geocodeme_get() helper from the PHP examples page:
<?php
// Paste the geocodeme_get() helper from the PHP examples page, then:
$data = geocodeme_get('/reverse', ['lat' => 48.8566, 'lon' => 2.3522]);
if (empty($data->result)) {
throw new RuntimeException('No results found for the given coordinates');
}
echo $data->result->display_name . PHP_EOL;
Expected Response
{
"result": {
"display_name": "3 Rue de Rivoli, Paris, Île-de-France, France",
"lat": 48.8565,
"lon": 2.3524,
"address": {
"house_number": "3",
"road": "Rue de Rivoli",
"city": "Paris",
"state": "Île-de-France",
"country": "France",
"country_code": "fr"
}
},
"attribution": "© OpenStreetMap contributors",
"meta": {
"took_ms": 8,
"cache_hit": false
}
}
Unlike /v1/geocode which returns results (an array), /v1/reverse returns result: a single object, or null when no address is found. Address fields like house_number and road are optional; always check for their presence before accessing them.
Common Errors
The API returns errors in a standard format:
{
"error": {
"code": "INVALID_API_KEY",
"message": "API key missing or invalid",
"field": null
}
}
| HTTP Status | Error Code | Cause | Fix |
|---|---|---|---|
| 400 | MISSING_PARAMETER | Required query parameter not provided (e.g., missing q) | Add the missing parameter to your request |
| 400 | INVALID_PARAMETER | Parameter value out of range (e.g., lat=999) | Check parameter constraints in the API Reference |
| 401 | INVALID_API_KEY | X-Api-Key header missing or key revoked | Verify your key in the Dashboard; regenerate if needed |
| 429 | RATE_LIMIT_EXCEEDED | Too many requests for your plan tier; see plan tiers | Implement exponential backoff; check X-RateLimit-Remaining header |
| 500 | INTERNAL_ERROR | Unexpected server error | Retry after a short delay; contact support if persistent |
Rate Limits
| Plan | Requests/second | Credit quota |
|---|---|---|
| Free | 1 | 3,000 / day |
| Startup | 10 | 150,000 / month |
| Growth | 15 | 500,000 / month |
| Pro | 25 | 1,500,000 / month |
See current pricing for plan details.
Every API response includes rate limit headers. Inspect them with:
curl -I -H "X-Api-Key: gm_YOUR_API_KEY" \
"https://api.geocodeme.net/v1/geocode?q=Paris"
X-RateLimit-Remaining: number of requests remaining in the current per-second windowX-RateLimit-Reset: Unix timestamp when the rate limit window resetsX-RateLimit-Monthly-Remaining: number of requests remaining in your monthly quota
See Rate Limiting for the full list of headers and how to handle 429 responses.
Next Steps
- Authentication: API key security best practices and rate limits per plan
- API Reference: full endpoint documentation with all parameters
- Examples: more code samples for common geocoding tasks