Public Toilet API
Query live toilet locations by coordinate. Data sourced from OpenStreetMap via Overpass API, UK government open data, Australia's National Public Toilet Map, and our curated worldwide seed dataset. Free for non-commercial use.
All responses are JSON. The API requires no authentication for the open tier. HTTPS only. Rate limited by IP address to prevent abuse.
Base URL
https://toiletnearest.comAll endpoints are relative to this base URL. All requests must use HTTPS. HTTP requests are redirected to HTTPS automatically.
Endpoint reference
/api/toiletsFetch toilets near a coordinate| Parameter | Type | Required | Description |
|---|---|---|---|
| lat | number | Yes | Latitude in decimal degrees (e.g. 51.505) |
| lng | number | Yes | Longitude in decimal degrees (e.g. -0.09) |
| radius | number | No | Search radius in metres (default 2000, max 50000) |
Example requests
curl "https://toiletnearest.com/api/toilets?lat=51.505&lng=-0.09&radius=2000"
const res = await fetch(`https://toiletnearest.com/api/toilets?lat=${lat}&lng=${lng}&radius=2000`);
const data = await res.json();
console.log(data.elements); // Array of toilet locationsimport requests
res = requests.get(
"https://toiletnearest.com/api/toilets",
params={"lat": 51.505, "lng": -0.09, "radius": 2000}
)
data = res.json()
print(f"Found {len(data['elements'])} toilets")Example response
{
"elements": [
{
"type": "node",
"id": 123456789,
"lat": 51.5007,
"lon": -0.1246,
"tags": {
"amenity": "toilets",
"name": "Westminster Bridge WC",
"fee": "no",
"wheelchair": "yes",
"opening_hours": "24/7",
"changing_table": "yes",
"addr:city": "London",
"addr:country": "GB"
}
}
],
"_osm_count": 48,
"_seed_count": 0
}Response fields
| Field | Type | Description |
|---|---|---|
| elements | Array | List of toilet objects. Each object contains id, lat, lon, and a tags object. |
| elements[].id | Number | OpenStreetMap node ID. Unique identifier for the facility. |
| elements[].lat / lon | Number | Geographic coordinates of the toilet in decimal degrees. |
| elements[].tags.amenity | String | Always 'toilets' for toilet nodes. |
| elements[].tags.name | String | Name of the facility if recorded in OSM. May be empty. |
| elements[].tags.fee | String | 'yes' if there is a charge, 'no' if free. May be absent. |
| elements[].tags.wheelchair | String | 'yes', 'limited', or 'no'. May be absent. |
| elements[].tags.opening_hours | String | OSM opening_hours format string. '24/7' for always open. |
| elements[].tags.changing_table | String | 'yes' if baby changing facilities are present. |
| _osm_count | Number | Count of results from OpenStreetMap Overpass queries. |
| _seed_count | Number | Count of results from our curated seed dataset (fallback). |
Data sources and freshness
API responses draw from a three-layer data pipeline. Understanding which layer served a response helps you assess its accuracy and freshness.
The primary data source. For most coordinates, we query the OpenStreetMap Overpass API in real time and return fresh node, way, and relation data tagged as amenity=toilets. Response time varies by region, typically 300ms–2s.
For the UK, Australia, Germany, Singapore and several others, we maintain locally cached government datasets that are refreshed daily. These provide higher completeness and verified opening hours compared to OSM alone.
When OSM and government data return sparse or empty results (common in developing countries), we fall back to our manually curated seed dataset of 300+ high-confidence locations. _seed_count in the response tells you how many results came from this layer.
Rate limits and access tiers
| Tier | Requests / minute | Radius limit | Auth required | Cost |
|---|---|---|---|---|
| Open (no key) | 10 | 2,000 m | None | Free |
| Developer | 100 | 10,000 m | API key header | Free (approval) |
| Commercial | 1,000+ | 50,000 m | API key header | Contact us |
Rate limit responses return HTTP 429 with a Retry-After header indicating when you may resume. Persistent circumvention of rate limits will result in your IP being blocked. If you are experiencing rate limit issues on the open tier for a legitimate non-commercial project, get in touch and we will work something out.
Attribution requirements
Toilet location data sourced from OpenStreetMap is made available under the Open Database Licence (ODbL). If you integrate its data into a public-facing product, you must display the following attribution:
Need higher limits or commercial access?
Commercial usage, white-label integrations, bulk data exports, or bespoke country datasets - get in touch and we'll find the right arrangement. We work with councils, mapping agencies, travel apps, and accessibility platforms.