Getting started overview
Nominatim is an open-source geocoding engine built on OpenStreetMap data. Unlike many commercial APIs, Nominatim is primarily designed for self-hosting, which provides full control over data, usage, and performance, but requires significant setup and maintenance. Alternatively, developers can use public Nominatim instances, which often have strict usage policies and rate limits, or opt for commercial services that utilize Nominatim or similar OpenStreetMap data under a managed model.
This guide outlines the general process for interacting with a Nominatim instance, focusing on the core steps to make a geocoding request. It will cover understanding the prerequisites for self-hosting, how to formulate your first API call, and common troubleshooting steps. For comprehensive details on installing and configuring a full Nominatim server, refer to the official Nominatim documentation.
Quick Reference Steps
| Step | What to Do | Where |
|---|---|---|
| 1. Choose Instance | Decide between self-hosting, using a public server, or a commercial provider. | Nominatim documentation on setup |
| 2. Obtain Credentials (if applicable) | For public servers or commercial services, acquire an API key or token. Self-hosted instances typically do not require keys for internal use. | Provider-specific documentation |
| 3. Understand Endpoints | Review the geocoding (/search) and reverse geocoding (/reverse) endpoints. |
Nominatim API reference |
| 4. Formulate Request | Construct a URL query with necessary parameters (e.g., q for address, lat/lon for coordinates). |
This guide's "Your first request" section |
| 5. Execute Request | Use a tool like curl or a programming language's HTTP client to send the request. |
Command line or preferred development environment |
| 6. Process Response | Parse the JSON response and extract relevant geocoding data. | Your application logic |
Create an account and get keys
For the core Nominatim software, there is no centralized account creation or API key system, as it is designed for self-hosting. When you run your own Nominatim instance, you manage access directly, typically through network configuration or application-level authentication within your own services.
However, if you opt to use a public Nominatim instance, such as the one provided by OpenStreetMap Foundation (OSMF) for demonstration purposes, or a commercial service built on Nominatim, you will likely encounter usage policies and potentially require an API key or token. For example, the OpenStreetMap Nominatim Usage Policy outlines restrictions on heavy usage and mandates a valid User-Agent header for all requests to public servers.
To get keys (if required):
- Public Instances: Some public instances might require registration or a specific identifier in your requests (e.g., a unique
User-Agentstring). Always consult the specific instance's documentation or usage policy. The OSMF instance generally does not issue API keys but relies on respectful use and a clearUser-Agent. - Commercial Providers: If you choose a commercial geocoding service that uses Nominatim data (e.g., OpenCage Geocoding API, which leverages OpenStreetMap data), you will typically sign up on their platform to obtain an API key. This key authenticates your requests and tracks your usage against their service tiers.
- Self-Hosted: No API key is needed. Access is controlled by your server's network configuration and any application-level security you implement.
For this guide, we will assume interaction with a Nominatim instance that either does not require an API key (like a self-hosted instance) or accepts requests with appropriate headers (like the OSMF public server under its usage policy).
Your first request
Nominatim supports both geocoding (address to coordinates) and reverse geocoding (coordinates to address). We will demonstrate a basic geocoding request.
The primary endpoint for geocoding is /search. You can query by a free-form address string or by structured parameters.
Example: Geocoding an Address
To geocode an address, you typically pass the address string using the q parameter. You should also specify the desired output format, commonly JSON.
Endpoint: /search
Method: GET
Parameters:
q: The address or place to search for.format: The desired output format (e.g.,json,xml).addressdetails: (Optional) Set to1to include a breakdown of the address into components.limit: (Optional) Maximum number of results to return.user-agent: (Required for public servers) A unique string identifying your application.
Using curl (Command Line)
Let's find the coordinates for "Eiffel Tower, Paris". For public Nominatim instances, ensure you include a descriptive User-Agent header as per the OpenStreetMap Foundation's usage policy.
curl -X GET \
-H "User-Agent: apispine-nominatim-getting-started/1.0 ([email protected])" \
"https://nominatim.openstreetmap.org/search?q=Eiffel+Tower%2C+Paris&format=json&limit=1"
Expected (abbreviated) JSON response:
[
{
"place_id": 28096277,
"licence": "Data © OpenStreetMap contributors, ODbL. ...",
"osm_type": "way",
"osm_id": 5013364,
"lat": "48.8582602",
"lon": "2.2944990",
"display_name": "Eiffel Tower, 7th Arrondissement, Paris, Île-de-France, Metropolitan France, 75007, France",
"class": "tourism",
"type": "attraction",
"importance": 0.8126744837269152,
"icon": "https://nominatim.openstreetmap.org/ui/mapicons/tourism_attraction.svg",
"boundingbox": [
"48.8569584",
"48.8595738",
"2.2930263",
"2.2959717"
]
}
]
The response is an array of JSON objects, where each object represents a potential match. Key fields include lat (latitude) and lon (longitude), display_name (the full address string), and importance (a score indicating relevance).
Using Python (with requests library)
import requests
url = "https://nominatim.openstreetmap.org/search"
params = {
"q": "Eiffel Tower, Paris",
"format": "json",
"limit": 1
}
headers = {
"User-Agent": "apispine-nominatim-getting-started/1.0 ([email protected])" # Required for public servers
}
try:
response = requests.get(url, params=params, headers=headers)
response.raise_for_status() # Raise an exception for HTTP errors (4xx or 5xx)
data = response.json()
if data:
first_result = data[0]
print(f"Display Name: {first_result.get('display_name')}")
print(f"Latitude: {first_result.get('lat')}")
print(f"Longitude: {first_result.get('lon')}")
else:
print("No results found.")
except requests.exceptions.RequestException as e:
print(f"An error occurred: {e}")
Common next steps
After successfully making your first request, consider these common next steps:
- Implement Reverse Geocoding: Explore the
/reverseendpoint to convert coordinates back into human-readable addresses. This is useful for displaying location names based on GPS data or map clicks. Refer to the Nominatim reverse geocoding API documentation. - Batch Geocoding: For processing multiple addresses, consider strategies for batching requests. While Nominatim doesn't have an explicit batch endpoint, you can send multiple individual requests. Be mindful of rate limits on public servers, or consider optimizing your self-hosted instance for higher throughput.
- Error Handling: Implement robust error handling in your application. Check HTTP status codes and parse error messages from the Nominatim response. Common errors include rate limits (HTTP 429), bad requests (HTTP 400), or server errors (HTTP 500).
- Configure
User-Agent: If using a public server, ensure yourUser-Agentheader is descriptive and includes contact information, as specified by the OpenStreetMap Foundation's Usage Policy. - Explore Advanced Parameters: Nominatim offers numerous parameters to refine searches, such as
countrycodes,viewbox(bounding box for search), anddedupe. Consult the Nominatim Search API documentation for a full list. - Self-Hosting Considerations: If your project requires high volume, specific data customization, or strict privacy, begin planning for a self-hosted Nominatim instance. This involves setting up a Linux server, installing PostgreSQL with PostGIS, downloading OpenStreetMap data, and importing it into Nominatim. Detailed instructions are available in the Nominatim installation guide.
Troubleshooting the first call
If your initial Nominatim request fails or returns unexpected results, consider the following troubleshooting steps:
- Check URL Encoding: Ensure all query parameters, especially the search query (
q), are correctly URL-encoded. Spaces should be replaced with+or%20, and special characters handled appropriately. Most HTTP client libraries handle this automatically, but manual construction requires care. - Verify Endpoint URL: Double-check that the base URL for the Nominatim instance is correct. If using a public server, ensure it is active and accessible.
- Review
User-AgentHeader: For public Nominatim instances (likenominatim.openstreetmap.org), a valid and descriptiveUser-Agentheader is crucial. Requests without one may be blocked or throttled. Ensure it follows the format specified in the OSMF Nominatim Usage Policy. - Examine HTTP Status Codes:
200 OK: Request was successful. If no results, the query might be too vague or incorrect.400 Bad Request: Often indicates missing or malformed parameters. Check your query string for errors.403 Forbidden: May indicate that your request is being blocked, possibly due to missing or incorrect authentication (if applicable) or a policy violation.429 Too Many Requests: You have exceeded the rate limits of the public server. Wait and retry, or consider optimizing your usage.5xx Server Error: An issue on the Nominatim server side. For self-hosted instances, check server logs. For public instances, it might be a temporary outage.
- Simplify Your Query: Start with a very simple and well-known address (e.g., "Paris") to isolate if the issue is with the query complexity or the overall setup.
- Consult Nominatim Logs (Self-Hosted): If you are running your own Nominatim instance, check the Nominatim and web server (e.g., Apache, Nginx) logs for specific error messages.
- Check Network Connectivity: Ensure your machine can reach the Nominatim server. Use
pingortracerouteto diagnose network issues. - Read Documentation: The official Nominatim API documentation provides detailed explanations of parameters, expected responses, and potential error conditions.