Documentation

Reverse Geocoding

If you need to find out what address, city, or region are at a set of coordinates, then you need Reverse Geocoding.
For the opposite, see Forward Geocoding.


Storing and Limits

Temporary Geocoding Only

Server side storage and/or caching of responses is currently not permitted due to licensing.
All requests should be in response to end user actions.

Service Limits

Free Plan accounts are limited to a total of 60 requests per minute. Limit hits can be tracked in Per Key analytics, and will show as a 1-min rate limit of "search". Blocked requests will return a 429 response code, and a "reject-reason" header of "Account Maximum Reached".


Request

Make the HTTPS Get or Post request using the url and parameters below.
We recommend GET whenever possible for browser and CDN caching.

Get URL

https://api.slpy.com/v1/search?level={Location Level}&lat={latitude}&lon={longitude}&key={your_api_key}

Post URL

https://api.slpy.com/v1/search?key={your_api_key}
Parameter Description
key
String
Required
The API Key created on your Account page after you login to Slpy.
lat
Number
Required
The latitude of the location being requested.
lon
Number
Required
The longitude of the location being requested.
level
Integer
optional
Desired location type by Level number between 1-10.
Default: 10
  • 9 - 10 : Bias towards nearest building address. Will prefer an exact address on nearby street.
  • 7 - 8 : Bias towards nearest Street. Will prefer closest street with no or estimated street number.
  • 6 : Prefer Nearest Neighborhood or Suburb. Will fallback to Level 4 city.
  • 5 : Postcode
  • 4 : Prefer Nearest Major City or Town. May include Level 6 neighborhood if available.
  • 3 : District or County
  • 2 : Region or State
  • 1 : Country
polygon
String
optional
Desired polygon format of geojson, kml, svg, or text. Returns a polygon and boundingbox of the result, or point if none available. Results for large detailed features can result in slower performance.
Default: No polygon returned.
  • geojson : {"type":"Point","coordinates":[-0.0,0.0]}
  • kml : <Point><coordinates>-0.0,0.0</coordinates></Point>
  • svg : 'cx="-0.0" cy="-0.0"'
  • text : POINT(-0.3375468 51.6000736)
language
String
optional
The preferred two character language code for the returned result. See Supported Languages for a list of codes available. Default is "en" for English.
country
String
optional
The two character iso_alpha2 country code.
Default: deternmines country from coordinates.

Example

Request usage

Get URL

https://api.slpy.com/v1/search?level=10&lat=47.6205&lon=-122.3493&language=en&key=abc123

Post URL

https://api.slpy.com/v1/level?key=abc123
Post Data Object Value
level 10
lat 47.6205
lon -122.3493
polygon geojson
language en

Response

The response is returned as a JSON formatted object, which contains information on the location as well as how confident it was in the result and how accurate the geocoordinates are.

Example Response

{
	"level": 10,
	"accuracy": "building",
	"lat": 47.620495,
	"lon": -122.349297,
	"status": "OK",
	"properties": {
		"name": "Space Needle",
		"street": "400 Broad St",
		"neighborhood": "Uptown",
		"sub_city": "Example Town",
		"city": "Seattle",
		"postcode": "98109",
		"district": "King County",
		"district_short": "KN",
		"region": "Washington",
		"region_short": "WA",
		"country_code": "US",
		"country": "United States of America",
		"address": "400 Broad St, Seattle, WA 98109"
	},
	"distance": "0.008",
	"polygon": {"type":"Polygon","coordinates":"[[[-122.3487246,47.6216724],[-122.3487006,47.6216358],...]]"},
	"boundingbox":	[ "47.621006", "47.6219872", "-122.3487246", "-122.3477557" ],
	"license": "\u00a9 Slpy \u00a9 OpenStreetMap contributors. Caching\/storage not permitted. Attribution-Terms at https:\/\/slpy.com"
}

Level

A location level scale from 0-10, with 10 being an exact street address match, and 1 being a country match.

Important: Geocoding will always try to return the next best level, rather than no result. For example, a request for a street that can't be found may return the city, region, or country. This behaviour allows you to decide what level range is acceptable for your use case, instead of simply success or failure.

Parameter Description
10 Exact match on street address, often with roof level accuracy
9 Matched street address with approximate accuracy
8 A street address calculated from surrounding street numbers on the same road
7 Road level accuracy or unvalidated street location
6 Suburb or neighborhood center
5 Postalcode center
4 City or Town centroid
3 District or County center
2 Region or State center
1 Country center
0 None or no results

Details

Parameter Description
accuracy A string denoting extra information on the level of location found.
lat The latitude of the returned point
lon The longitude of the returned poin
status
  • OK : A result was successfully returned.
  • No Results : No Level of result could be found.
  • {Error} : A short error text on incorrect parameters or account issues.
distance Distance between the requested coordinates and the returned result in KM.
polygon optional - When a polygon format is requested, this will contain a Polygon or Point in that format.
boundingbox optional - When a polygon format is requested AND a polygon is returned, this will conatin a maximum/minimum latitude and longitude array.
license Required attribution, copyrights, and legal disclaimer. "© Slpy, © OpenStreetMap contributors" should be displayed on the map or somewhere near the results displayed information as required by our partners and data sources.

Properties

An object containing additional Properties of the returned response.

Parameter Description
name optional - POI name if available
street optional - Road number, or location name, with street name in country native format.
neighborhood optional - From Suburb or Neighborhood down to Retail or Residential level area.
sub_city optional - When location has Town, Village, Hamlet, or Borough level, AND is also part of a larger City area.
city optional - Independent City or Town area.
postcode optional - Postal code or Zipcode.
district optional - District or county level.
district_short optional - Abbreviation of District or county level.
region optional - State or region level.
region_short optional - Abbreviation of State or region level.
country_code optional - two character iso_alpha2 country code.
country optional - Long name of country.
address optional - Full postal address formatted in the country's native format. Will try to return mailing address if street or name are available, or a well formatted reference area if not.

Code Examples

Simple GET requests to the Structured search in different programming languages.


function fetchData(params) {
  const apiUrl = 'https://api.slpy.com/v1/search';

  fetch(`${apiUrl}?${params}`)
	.then(response => {
	  if (response.ok) {
		return response.json();
	  } else {
		throw new Error(`Error: ${response.status}`);
	  }
	})
	.then(data => {
	  console.log(data);
	})
	.catch(error => {
	  console.error(error);
	});
}

const params = new URLSearchParams({
	lat: 'example_lat',
	lon: 'example_lon',
	level: '10',
	polygon: 'geojson',
	country: 'example_country',
	key: 'your_api_key'
  });

fetchData(params);

import requests

api_url = 'https://api.slpy.com/v1/search'
params = {
	'lat': 'example_lat',
	'lon': 'example_lon',
	'level': '10',
	'polygon': 'geojson',
	'country': 'example_country',
	'key': 'your_api_key'
}

response = requests.get(api_url, params=params)

if response.status_code == 200:
	print(response.json())
else:
	print('Error:', response.status_code)

require 'net/http'
require 'uri'
require 'json'

api_url = 'https://api.slpy.com/v1/search'
params = {
  'lat' => 'example_lat',
  'lon' => 'example_lon',
  'level' => '10',
  'polygon' => 'geojson',
  'country' => 'example_country',
  'key' => 'your_api_key'
}

uri = URI.parse(api_url)
uri.query = URI.encode_www_form(params)

response = Net::HTTP.get_response(uri)

if response.code == '200'
  data = JSON.parse(response.body)
  puts data
else
  puts "Error: #{response.code}"
end

<?php
$apiUrl = 'https://api.slpy.com/v1/search';
$params = array(
  'lat' => 'example_lat',
  'lon' => 'example_lon',
  'level' => '10',
  'polygon' => 'geojson',
  'country' => 'example_country',
  'key' => 'your_api_key'
);

$query = http_build_query($params);
$url = $apiUrl . '?' . $query;

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);

if (curl_errno($ch)) {
  echo 'Error:' . curl_error($ch);
} else {
  $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

  if ($statusCode == 200) {
	$data = json_decode($response);
	print_r($data);
  } else {
	echo 'Error: ' . $statusCode;
  }
}

curl_close($ch);
?>

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class ApiExample {
  public static void main(String[] args) {
	String apiUrl = "https://api.slpy.com/v1/search";
	String params = "lat=example_lat&lon=example_lon&level=10&polygon=geojson&country=example_country&key=your_api_key";
	String url = apiUrl + "?" + params;

	try {
	  URL obj = new URL(url);
	  HttpURLConnection con = (HttpURLConnection) obj.openConnection();
	  con.setRequestMethod("GET");

	  int responseCode = con.getResponseCode();
	  if (responseCode == HttpURLConnection.HTTP_OK) {
		BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
		String inputLine;
		StringBuffer response = new StringBuffer();

		while ((inputLine = in.readLine()) != null) {
		  response.append(inputLine);
		}
		in.close();

		System.out.println(response.toString());
	  } else {
		System.out.println("Error: " + responseCode);
	  }
	} catch (IOException e) {
	  e.printStackTrace();
	}
  }
}

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

func main() {
	apiUrl := "https://api.slpy.com/v1/search"
	params := url.Values{}
	params.Set("lat", "example_lat")
	params.Set("lon", "example_lon")
	params.Set("level", "10")
	params.Set("polygon", "geojson")
	params.Set("country", "example_country")
	params.Set("key", "your_api_key")

	resp, err := http.Get(fmt.Sprintf("%s?%s", apiUrl, params.Encode()))

	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}

	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {
		bodyBytes, err := ioutil.ReadAll(resp.Body)
		if err {
			fmt.Printf("Error reading response body: %v\n", err)
			return
		}

		var data interface{}
		json.Unmarshal(bodyBytes, &data)
		fmt.Println(data)
	} else {
		fmt.Printf("Error: %d\n", resp.StatusCode)
	}
}

  
import React from 'react';

function fetchData(params) {
  const apiUrl = 'https://api.slpy.com/v1/search';
  
  fetch(`${apiUrl}?${params}`)
	.then(response => {
	  if (response.ok) {
		return response.json();
	  } else {
		throw new Error(`Error: ${response.status}`);
	  }
	})
	.then(data => {
	  console.log(data);
	})
	.catch(error => {
	  console.error(error);
	});
}

function App() {
  const params = new URLSearchParams({
	lat: 'example_lat',
	lon: 'example_lon',
	level: '10',
	polygon: 'geojson',
	country: 'example_country',
	key: 'your_api_key'
  });
  
  React.useEffect(() => {
	fetchData(params);
  }, []);

  return (
	<div>
	  Check your console for the API response.
	  </div>
  );
}

export default App;

}
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `Check your console for the API response.`
})
export class AppComponent implements OnInit {
  ngOnInit() {
	this.fetchData();
  }

  fetchData() {
	const apiUrl = 'https://api.slpy.com/v1/search';
	const params = new URLSearchParams({
		lat: 'example_lat',
		lon: 'example_lon',
		level: '10',
		polygon: 'geojson',
		country: 'example_country',
		key: 'your_api_key'
	});

	fetch(`${apiUrl}?${params}`)
	  .then(response => {
		if (response.ok) {
		  return response.json();
		} else {
		  throw new Error(`Error: ${response.status}`);
		}
	  })
	  .then(data => {
		console.log(data);
	  })
	  .catch(error => {
		console.error(error);
	  });
  }
}
<template>
<div>Check your console for the API response.</div>
</template>

<script>
export default {
  created() {
	this.fetchData();
  },
  methods: {
	fetchData() {
	  const apiUrl = 'https://api.slpy.com/v1/search';
	  const params = new URLSearchParams({
		lat: 'example_lat',
		lon: 'example_lon',
		level: '10',
		polygon: 'geojson',
		country: 'example_country',
		key: 'your_api_key'
	  });

	  fetch(`${apiUrl}?${params}`)
		.then(response => {
		  if (response.ok) {
			return response.json();
		  } else {
			throw new Error(`Error: ${response.status}`);
		  }
		})
		.then(data => {
		  console.log(data);
		})
		.catch(error => {
		  console.error(error);
		});
	}
  }
}
</script>
<script>
  function fetchData(params) {
	const apiUrl = 'https://api.slpy.com/v1/search';

	fetch(`${apiUrl}?${params}`)
	  .then(response => {
		if (response.ok) {
		  return response.json();
		} else {
		  throw new Error(`Error: ${response.status}`);
		}
	  })
	  .then(data => {
		console.log(data);
	  })
	  .catch(error => {
		console.error(error);
	  });
  }

  const params = new URLSearchParams({
	lat: 'example_lat',
	lon: 'example_lon',
	level: '10',
	polygon: 'geojson',
	country: 'example_country',
	key: 'your_api_key'
  });

  fetchData(params);
</script>

<main>
  Check your console for the API response.
</main>
const fetchData = (params: URLSearchParams) => {
  const apiUrl = 'https://api.slpy.com/v1/search';

  fetch(`${apiUrl}?${params}`)
	.then(response => {
	  if (response.ok) {
		return response.json();
	  } else {
		throw new Error(`Error: ${response.status}`);
	  }
	})
	.then(data => {
	  console.log(data);
	})
	.catch(error => {
	  console.error(error);
	});
}

const params = new URLSearchParams({
	lat: 'example_lat',
	lon: 'example_lon',
	level: '10',
	polygon: 'geojson',
	country: 'example_country',
	key: 'your_api_key'
});

fetchData(params);
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

void fetchData() async {
  const apiUrl = 'https://api.slpy.com/v1/search';
  final params = {
	lat: 'example_lat',
	lon: 'example_lon',
	level: '10',
	polygon: 'geojson',
	country: 'example_country',
	key: 'your_api_key',
  };

  final uri = Uri.parse(apiUrl).replace(queryParameters: params);

  try {
	final response = await http.get(uri);
	if (response.statusCode == 200) {
	  final data = json.decode(response.body);
	  print(data);
	} else {
	  throw Exception('Error: ${response.statusCode}');
	}
  } catch (error) {
	print(error);
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
	fetchData();

	return MaterialApp(
	  home: Scaffold(
		appBar: AppBar(
		  title: Text('API Fetch Example'),
		),
		body: Center(
		  child: Text('Check your console for the API response.'),
		),
	  ),
	);
  }
}

Demo Examples

Real world examples and common use cases.

Map Demo

  • Click on place names, streets, and buildings to return the nearest result based on the assumed location level.

Troubleshooting

No Response

Your Api Key may not be configured correctly. Open Developer Tools, and look in the Network tab for "search?" files not loading with status 200. Click the file and check "Response Headers" for "Reject-Reason:".
Example: "Reject-Reason:Bad Referrer: cdpn.io" not matching "codepen.io" in key's whitelist.

Error Codes

Next Steps

Enhance your search with Maps or Autocomplete

Forward Geocoding

  • Get the location of an address
  • Search for points of interest
  • Add a search bar to your map

Autocomplete

  • Enhance your input
  • Rapid search cities or regions
  • Guide your search

Maps

  • Display your location
  • Provide context to an address
  • Add popups for more information