sthan.io API Documentation
developer-friendly US address APIs for autocomplete, parsing, verification, geocoding, and IP geolocation. Get started in under 5 minutes.
All systems operational
Free tier, no credit card
API key or JWT auth
REST API
Last updated: March 7, 2026
Make your first API call in under 5 minutes.
1
Create a Free Account
Sign up free at sthan.io . Your account comes with the free plans, no credit card required. The free tier covers 3,000 requests a month (up to 100 a day) for verification, parsing and geocoding, 10,000 for autocomplete (up to 5,000 a day), 50,000 for IP geolocation (up to 5,000 a day), and 10,000 for India autocomplete (up to 1,000 a day).
2
Get an API Key
Create an API key in your dashboard (it looks like sthan_live_...) and send it as Authorization: Bearer YOUR_API_KEY on every request. A JWT from /Auth/Token still works if you prefer the original flow.
3
Make Your First Call
Copy any example below and replace YOUR_TOKEN with your API key from step 2. That's it!
Two methods are supported. API key (recommended): create one in the dashboard and send Authorization: Bearer sthan_live_... on every request; keys do not expire and work with the CLI, the MCP server and AI agents. JWT token (original flow): obtain a token from /Auth/Token with your profile credentials and send it as a Bearer token; tokens last 60 minutes. The steps below show the JWT flow.
Step 1: Get Your Token
Send your profileName and profilePassword as request headers. The API returns a JWT access token and its expiration time.
Request Headers
Header Type Required Description
profileName string Required Your access profile identifier. Case-sensitive.
profilePassword string Required Your access profile password. Case-sensitive.
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/Auth/Token" \
-H "profileName: YOUR_PROFILE_NAME" \
-H "profilePassword: YOUR_PROFILE_PASSWORD"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/Auth/Token" , {
headers: { profileName: "YOUR_PROFILE_NAME" , profilePassword: "YOUR_PROFILE_PASSWORD" }
});
const { Result } = await response.json();
console.log(Result.access_token);
import requests
response = requests.get(
"https://api.sthan.io/Auth/Token" ,
headers={"profileName" : "YOUR_PROFILE_NAME" , "profilePassword" : "YOUR_PROFILE_PASSWORD" },
timeout=10,
)
response.raise_for_status()
print (response.json()["Result" ]["access_token" ])
using System.Text.Json;
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://api.sthan.io/Auth/Token" );
request.Headers.Add("profileName" , "YOUR_PROFILE_NAME" );
request.Headers.Add("profilePassword" , "YOUR_PROFILE_PASSWORD" );
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
using var doc = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
Console.WriteLine(doc.RootElement.GetProperty("Result" ).GetProperty("access_token" ).GetString());
// Java 11+ (java Example.java). The token is at Result.access_token.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/Auth/Token" ))
.header("profileName" , "YOUR_PROFILE_NAME" )
.header("profilePassword" , "YOUR_PROFILE_PASSWORD" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/Auth/Token" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["profileName: YOUR_PROFILE_NAME" , "profilePassword: YOUR_PROFILE_PASSWORD" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
echo $data["Result" ]["access_token" ], PHP_EOL;
require "net/http"
require "json"
uri = URI("https://api.sthan.io/Auth/Token" )
req = Net::HTTP::Get.new(uri)
req["profileName" ] = "YOUR_PROFILE_NAME"
req["profilePassword" ] = "YOUR_PROFILE_PASSWORD"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)["Result" ]["access_token" ]
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/Auth/Token" , nil )
req.Header.Set("profileName" , "YOUR_PROFILE_NAME" )
req.Header.Set("profilePassword" , "YOUR_PROFILE_PASSWORD" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
var auth struct {
Result struct {
AccessToken string `json:"access_token"`
}
}
json.NewDecoder(resp.Body).Decode(&auth)
fmt.Println(auth.Result.AccessToken)
}
// Cargo.toml: reqwest = { version = "0.12", features = ["json"] }, serde_json = "1",
// tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let auth: serde_json::Value = reqwest::Client::new()
.get("https://api.sthan.io/Auth/Token" )
.header("profileName" , "YOUR_PROFILE_NAME" )
.header("profilePassword" , "YOUR_PROFILE_PASSWORD" )
.send()
.await ?
.json()
.await ?;
println!("{}" , auth["Result" ]["access_token" ].as_str().unwrap_or_default());
Ok (())
}
// The token is at Result.access_token
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/Auth/Token" ))
.header("profileName" , "YOUR_PROFILE_NAME" )
.header("profilePassword" , "YOUR_PROFILE_PASSWORD" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response =
Req.get!("https://api.sthan.io/Auth/Token" ,
headers: [{"profileName" , "YOUR_PROFILE_NAME" }, {"profilePassword" , "YOUR_PROFILE_PASSWORD" }]
)
IO.puts(response.body["Result" ]["access_token" ])
{
"Id" : "a1b2c3d4-0000-0000-0000-000000000000" ,
"Result" : {
"access_token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5..." ,
"expiration" : "2026-02-19T03:45:00.0000000"
},
"ClientSessionId" : null ,
"StatusCode" : 200 ,
"IsError" : false ,
"Errors" : []
}
Response Fields
Field Type Description
Result.access_token string JWT Bearer token, nested under the Result field of the response envelope. Include in Authorization header for all API calls.
Result.expiration datetime Token expiration timestamp (server local time, America/Los_Angeles), nested under Result. Request a new token before this time.
Step 2: Use the Token
Include the access_token as a Bearer token in the Authorization header of every subsequent API request.
Authorization : Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy5...
Content-Type : application/json
Response Envelope
All API responses are wrapped in a standard envelope. The examples in this documentation show only the Result field contents for clarity.
{
"Id" : "unique-request-id" ,
"Result" : { /* endpoint-specific data shown in examples below */ },
"ClientSessionId" : "your-session-id" ,
"StatusCode" : 200 ,
"IsError" : false ,
"Errors" : []
}
API requests are rate-limited per subscription plan. When you exceed your limit, the API returns 429 Too Many Requests. The Retry-After header gives the number of seconds until you can retry, and the Errors list says which limit was reached, when it resets and how many requests are left this month. Every response also carries X-RateLimit-ByEndpoint-Per{Minute|Hour|Day|Month} and -Remaining headers (-1 means no limit for that window).
Product Free Basic Starter Business
Address Verification 3,000 / mo 100 / day 10 / min 10,000 / mo 500 / min 50,000 / mo 2,500 / min 150,000 / mo 7,500 / min
Address Parser 3,000 / mo 100 / day 10 / min 10,000 / mo 500 / min 50,000 / mo 2,500 / min 150,000 / mo 7,500 / min
Geocoding (forward + reverse) 3,000 / mo 100 / day 10 / min 10,000 / mo 500 / min 50,000 / mo 2,500 / min 150,000 / mo 7,500 / min
Address Autocomplete 10,000 / mo 5,000 / day 2,500 / hour 600 / min 100,000 / mo 5,000 / min 1,000,000 / mo 50,000 / min 5,000,000 / mo 250,000 / min
IP Geolocation 50,000 / mo 5,000 / day 2,000 / min 100,000 / mo 4,000 / min 1,000,000 / mo 40,000 / min 5,000,000 / mo 200,000 / min
Larger Basic, Starter and Business volumes (up to 3,000,000 a month for address products, 100,000,000 for autocomplete) are on the pricing page . Enterprise volumes and higher per-minute rates are quoted on request.
HTTP/1.1 429 Too Many Requests
Retry-After : 48
X-RateLimit-ByEndpoint-PerMinute : 10
X-RateLimit-ByEndpoint-PerMinute-Remaining : 0
X-RateLimit-ByEndpoint-PerMonth : 3000
X-RateLimit-ByEndpoint-PerMonth-Remaining : 2995
{
"Id": "d3d91e37-5ec3-4dd8-b945-dc35b1a3d2ea",
"Result": {},
"ClientSessionId": null,
"StatusCode": 429,
"IsError": true,
"Errors": [
"Too Many Requests",
"Limit of 10 requests per minute reached for Geocoding. Try again in 48 seconds. 2,995 of 3,000 requests left this month."
]
}
/AutoComplete/USA/Address/{text}
Returns real-time address suggestions as the user types. Handles abbreviations, apartment/suite numbers, and partial input. Ideal for checkout forms and address fields.
Parameters
Name Type Required Description
text string Required Partial address to search. URL-encoded. Min 3 chars for best results.
Response Codes
200 Success
400 Bad Request
401 Unauthorized
429 Rate Limited
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
[
"123 Main St APT 1, Andover, MA 01810-3816" ,
"123 Main St APT 1, Delhi, NY 13753-1257" ,
"123 Main St STE 1, Caldwell, ID 83605-5476" ,
"123 Main St STE 1, Corinth, NY 12822-1010" ,
"123 Main St STE 1, Delhi, NY 13753-1258"
]
Need more than just the full address string? Explore related APIs:
Address Parser From $8/mo
Break addresses into components: street, city, state, ZIP, county.
View docs →
Address Verification From $12/mo
Verify deliverability with DPV confirmation, carrier routes, ZIP+4.
View docs →
Forward Geocoding From $5/mo
Convert addresses to latitude/longitude. High-accuracy coordinate resolution.
View docs →
/v2/address-parser/usa/speculative/{address}
Parses a raw address string into structured components (street number, street name, unit, city, state, ZIP, county). Returns postal-standardized results with confidence scores.
Parameters
Name Type Required Description
address string Required Full or partial US address to parse. URL-encoded.
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
{
"inputAddress" : "1600 pennsylvania ave nw washington dc 20500" ,
"fullAddress" : "1600 Pennsylvania Ave NW, Washington, DC 20500-0005" ,
"addressLine1" : "1600 Pennsylvania Ave NW" ,
"addressLine2" : "Washington, DC 20500-0005" ,
"addressNumber" : "1600" ,
"streetName" : "Pennsylvania" ,
"streetPostType" : "Ave" ,
"streetPostDir" : "NW" ,
"city" : "Washington" ,
"stateCode" : "DC" ,
"state" : "District Of Columbia" ,
"zipCode" : "20500" ,
"zip4" : "0005" ,
"county" : "District Of Columbia" ,
"matchMode" : "Speculative" ,
"matchTier" : "Exact" ,
"confidence" : 1 ,
"matchCode" : {
"houseNumber" : "Matched" ,
"street" : "Matched" ,
"city" : "Matched" ,
"state" : "Matched" ,
"zipCode" : "Matched"
},
"isError" : false ,
"errorMessages" : []
}
Response Fields
Field Type Description
fullAddress string Standardized full address with ZIP+4
addressNumber string House/building number
streetName string Standardized street name
unitType string? APT, STE, UNIT, etc.
county string County name
confidence float Match confidence score (0.0 – 1.0)
/v2/address-verification/usa/speculative/{address}
Verifies a US address and returns deliverability information including DPV confirmation, carrier route, ZIP+4, delivery point, and record type.
Parameters
Name Type Required Description
address string Required US address to verify. URL-encoded.
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
{
"inputAddress" : "6000 j st sacramento ca 95819" ,
"fullAddress" : "6000 J St, Sacramento, CA 95819-2605" ,
"addressLine1" : "6000 J St" ,
"addressLine2" : "Sacramento, CA 95819-2605" ,
"unitType" : "" ,
"unitNumber" : "" ,
"city" : "Sacramento" ,
"stateCode" : "CA" ,
"zipCode" : "95819" ,
"zip4" : "2605" ,
"county" : "Sacramento" ,
"dpvConfirmation" : "Y" ,
"carrierRoute" : "C007" ,
"deliveryPoint" : "00" ,
"recordType" : "S" ,
"deliverableStatus" : "Confirmed" ,
"matchMode" : "Speculative" ,
"matchTier" : "Exact" ,
"confidence" : 1 ,
"matchCode" : {
"houseNumber" : "Matched" ,
"street" : "Matched" ,
"city" : "Matched" ,
"state" : "Matched" ,
"zipCode" : "Matched"
},
"isError" : false ,
"errorMessages" : []
}
Response Fields
Field Type Description
deliverableStatus enum Confirmed = safe to ship, ConfirmedPrimaryOnly = primary OK but secondary unit missing or invalid, NotDeliverable = postal authority rejected, Unknown = no postal confirmation on file. Single field for client routing logic; derived from dpvConfirmation.
dpvConfirmation string Postal DPV code: Y = confirmed, including the unit when one was given; D = building confirmed, but the address needs a unit (apartment or suite) and none was given; S = building confirmed, but the unit given could not be confirmed; N = not confirmed; empty = no postal check on file
carrierRoute string Postal carrier route code (e.g., C001 = city route 1)
deliveryPoint string 2-digit delivery point code appended to ZIP+4
recordType string S = street, H = highrise, F = firm, R = rural route, P = PO box
zip4 string 4-digit ZIP extension for precise delivery routing
unitType string Confirmed secondary-unit designator split out of the standardized address, for example APT, STE, UNIT. Empty when the address has no secondary unit. Only a postal-confirmed unit appears here.
unitNumber string Confirmed secondary-unit number, for example 142. Empty when the address has no secondary unit.
/AutoComplete/USA/City/DisplayType/{displayType}/{text}
Returns real-time US city name suggestions as the user types. Supports multiple display formats combining city name with state code or full state name.
Parameters
Name Type Required Description
displayType int Required 0 = City, StateCode (e.g., Sacramento, CA)1 = City, State (e.g., Sacramento, California)
text string Required Partial city name to search. URL-encoded.
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
[
"Sacramento, CA" ,
"Sacramento, KY" ,
"Sacramento, NM" ,
"Sacramento, PA"
]
/AutoComplete/USA/ZipCode/DisplayType/{displayType}/{text}
Returns real-time ZIP code suggestions for US addresses. Supports 4 display formats with varying levels of detail. Covers all ~42,000 active US ZIP codes.
Parameters
Name Type Required Description
displayType int Required 0 = ZipCode, City, StateCode1 = ZipCode, City, State2 = ZipCode-Zip4, City, StateCode3 = ZipCode-Zip4, City, State
text string Required Partial ZIP code or city name. URL-encoded.
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
[
"95820, Sacramento, CA" ,
"95821, Sacramento, CA" ,
"95822, Sacramento, CA" ,
"95825, Sacramento, CA"
]
/Geocoding/USA/Forward/{address}
Converts a US street address into geographic coordinates (latitude and longitude). Returns the matched address with county, ZIP+4 and time zone, how exact the spot is, and a confidence score.
Parameters
Name Type Required Description
address string Required Full US address to geocode. URL-encoded.
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
{
"inputAddress" : "1600 Pennsylvania Ave NW, Washington DC 20500" ,
"formattedAddress" : "1600 Pennsylvania Ave NW, Washington, DC 20500" ,
"location" : {
"latitude" : 38.89767510742324 ,
"longitude" : -77.03654697024702
},
"confidence" : 0.9 ,
"accuracy" : {
"type" : "rooftop"
},
"components" : {
"streetNumber" : "1600" ,
"street" : "Pennsylvania Ave NW" ,
"city" : "Washington" ,
"county" : "District of Columbia" ,
"countyFips" : "11001" ,
"state" : "DC" ,
"zip" : "20500" ,
"zip4" : "0005" ,
"country" : "US"
},
"source" : "12" ,
"sourceName" : "address_point" ,
"addressId" : "-5080390856974210536" ,
"timezone" : {
"id" : "America/New_York" ,
"utcOffset" : "-04:00" ,
"offsetSeconds" : -14400 ,
"isDst" : true ,
"currentLocalTime" : "2026-10-16T12:14:59-04:00"
}
}
Response Fields
Field Type Description
inputAddress string The address as you sent it.
formattedAddress string The matched address in postal form, with ZIP+4 when known.
location object latitude and longitude of the answer.
confidence number 0 to 1. How sure the match is.
accuracy.type string rooftop = on the building, parcel = centre of the lot, address_point = an official address point whose spot on the lot is not known, interpolated = estimated between nearby house numbers on the same street, centroid = centre of the ZIP code, approximate = area match.
components object streetNumber, street, unit, city, county, countyFips (5-digit county code), state, zip, zip4, country. Empty parts are left out.
source / sourceName string How the answer was found, as a code and a word: 12 address_point, 11 exact_match, 10 primary, 20 standardized, 30 extended_coverage, 40 interpolated, 41 nearest, 42 zip_centroid.
addressId string Stable id of the address point. Only on address_point answers.
timezone object Time zone of the address: id (IANA name, e.g. America/Chicago), utcOffset and offsetSeconds (current offset from UTC, daylight saving included), isDst, and currentLocalTime (local time at the moment of the request).
interpolation object Only on estimated answers: requestedHouseNumber and the lowerHouseNumber / upperHouseNumber the spot was estimated from.
/Geocoding/USA/Reverse/{lat}/{lon}
Converts geographic coordinates (latitude/longitude) into a street address. Returns the nearest address with its distance, county, ZIP+4 and time zone, and on request other addresses nearby.
Parameters
Name Type Required Description
lat double Required Latitude coordinate (-90 to 90)
lon double Required Longitude coordinate (-180 to 180)
limit integer Optional Query string, 1 to 10 (default 1). Above 1, up to limit - 1 other addresses near the point are returned in nearby, one per building, nearest first. Example: ?limit=5
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
{
"location" : {
"latitude" : 38.897676 ,
"longitude" : -77.03653
},
"formattedAddress" : "1600 Pennsylvania Ave NW, Washington, DC 20500" ,
"distance" : 1.5 ,
"confidence" : 0.95 ,
"accuracy" : {
"type" : "rooftop"
},
"components" : {
"streetNumber" : "1600" ,
"street" : "Pennsylvania Ave NW" ,
"city" : "Washington" ,
"county" : "District of Columbia" ,
"countyFips" : "11001" ,
"state" : "DC" ,
"zip" : "20500" ,
"zip4" : "0005" ,
"country" : "US"
},
"source" : "12" ,
"sourceName" : "address_point" ,
"addressId" : "-5080390856974210536" ,
"timezone" : {
"id" : "America/New_York" ,
"utcOffset" : "-04:00" ,
"offsetSeconds" : -14400 ,
"isDst" : true ,
"currentLocalTime" : "2026-10-16T12:14:40-04:00"
}
}
Response Fields
Field Type Description
location object The coordinates you sent.
distance number Meters from your point to the address.
formattedAddress string The matched address in postal form, with ZIP+4 when known.
confidence number 0 to 1. How sure the match is.
accuracy.type string rooftop = on the building, parcel = centre of the lot, address_point = an official address point whose spot on the lot is not known, interpolated = estimated between nearby house numbers on the same street, centroid = centre of the ZIP code, approximate = area match.
components object streetNumber, street, unit, city, county, countyFips (5-digit county code), state, zip, zip4, country. Empty parts are left out.
source / sourceName string How the answer was found, as a code and a word: 12 address_point, 11 exact_match, 10 primary, 20 standardized, 30 extended_coverage, 40 interpolated, 41 nearest, 42 zip_centroid.
addressId string Stable id of the address point. Only on address_point answers.
timezone object Time zone of the address: id (IANA name, e.g. America/Chicago), utcOffset and offsetSeconds (current offset from UTC, daylight saving included), isDst, and currentLocalTime (local time at the moment of the request).
nearby array Only when limit is above 1: other addresses near the point, one per building, nearest first. Each has the same fields as the main answer, and its own location.
Data credits for forward and reverse geocoding: address and building data include © OpenStreetMap contributors (ODbL) and FEMA USA Structures (CC BY 4.0); time zone boundaries come from timezone-boundary-builder (ODbL).
/IpGeolocation/{ip}
Look up any IPv4 or IPv6 address. Returns country, region, city, coordinates, postal code, timezone with current local time, flag, currency, calling code, network (ASN, ISP, organisation), mobile/proxy/hosting flags, reverse DNS and a confidence score. confidence is 0 to 1 and is absent when the address is new to us (ask again in a few seconds) or when the sources did not agree on a city; precision says whether the answer goes down to a city, a region or only a country.
Parameters
Name Type Required Description
ip string Required IPv4 or IPv6 address (e.g., 8.8.8.8)
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/IpGeolocation/8.8.8.8" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/IpGeolocation/8.8.8.8" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/IpGeolocation/8.8.8.8" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/IpGeolocation/8.8.8.8" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/IpGeolocation/8.8.8.8" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/IpGeolocation/8.8.8.8" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/IpGeolocation/8.8.8.8" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/IpGeolocation/8.8.8.8" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/IpGeolocation/8.8.8.8" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/IpGeolocation/8.8.8.8" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/IpGeolocation/8.8.8.8" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
{
"ipAddress" : "8.8.8.8" ,
"country" : "United States" ,
"countryCode" : "US" ,
"region" : "California" ,
"regionCode" : "CA" ,
"city" : "Mountain View" ,
"postalCode" : "94043" ,
"latitude" : 37.422 ,
"longitude" : -122.085 ,
"continent" : "North America" ,
"continentCode" : "NA" ,
"timezone" : "America/Los_Angeles" ,
"timezoneDetail" : { "id" : "America/Los_Angeles" , "utcOffset" : "-07:00" , "offsetSeconds" : -25200 , "isDst" : true , "currentLocalTime" : "2026-10-01T13:13:59-07:00" },
"type" : "IPv4" ,
"precision" : "city" ,
"countryNativeName" : "United States" ,
"isEu" : false ,
"callingCode" : "+1" ,
"capital" : "Washington, D.C." ,
"borders" : ["CA" , "MX" ],
"currency" : { "code" : "USD" , "name" : "United States dollar" , "symbol" : "$" },
"languages" : ["English" ],
"tld" : ".us" ,
"flag" : { "emoji" : "πΊπΈ" , "svg" : "https://sthan.io/flags/us.svg" },
"asn" : 15169 ,
"asName" : "GOOGLE" ,
"isp" : "Google LLC" ,
"organization" : "Google Public DNS" ,
"isMobile" : false ,
"isProxy" : true ,
"isHosting" : true ,
"reverseDns" : "dns.google" ,
"confidence" : 0.78
}
/AutoComplete/Ind/City/DisplayType/{displayType}/{text}
Returns real-time city name suggestions for India. Covers all 700+ districts across 28 states and 8 UTs.
Parameters
Name Type Required Description
displayType int Required 0 = City, State1 = City, District, State
text string Required Partial city name. URL-encoded.
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
[
"Mumbai, Maharashtra" ,
"Mumbai Suburban, Maharashtra" ,
"Navi Mumbai, Maharashtra" ,
"Mumbai City, Maharashtra"
]
/AutoComplete/Ind/Locality/DisplayType/{displayType}/{text}
Returns real-time locality (area/neighborhood) suggestions for Indian addresses. Localities are sub-city areas commonly used in Indian addressing.
Parameters
Name Type Required Description
displayType int Required 0 = Locality, City, State1 = Locality, City, District, State
text string Required Partial locality name. URL-encoded.
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
[
"Koramangala, Bengaluru, Karnataka" ,
"Koramangala 1st Block, Bengaluru, Karnataka" ,
"Koramangala 2nd Block, Bengaluru, Karnataka" ,
"Koramangala 3rd Block, Bengaluru, Karnataka" ,
"Koramangala 4th Block, Bengaluru, Karnataka"
]
/AutoComplete/Ind/PinCode/DisplayType/{displayType}/{text}
Returns real-time PIN code suggestions for India. India uses a 6-digit PIN code system covering over 150,000 post offices.
Parameters
Name Type Required Description
displayType int Required 0 = PinCode, City, State1 = PinCode, City, District, State
text string Required Partial PIN code or city name. URL-encoded.
cURL
JavaScript
Python
C#
Java
PHP
Ruby
Go
Rust
Kotlin
Elixir
curl -s "https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" \
-H "Authorization: Bearer YOUR_TOKEN"
// Node.js 18+ (save as example.mjs)
const response = await fetch ("https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" , {
headers: { Authorization: "Bearer YOUR_TOKEN" }
});
console.log(await response.json());
import requests
response = requests.get(
"https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" ,
headers={"Authorization" : "Bearer YOUR_TOKEN" },
timeout=10,
)
print (response.json())
using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer" , "YOUR_TOKEN" );
var json = await client.GetStringAsync("https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" );
Console.WriteLine(json);
// Java 11+ (java Example.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String [] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build();
HttpResponse<String > response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
<?php
$ch = curl_init("https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" );
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer YOUR_TOKEN" ],
CURLOPT_RETURNTRANSFER => true ,
]);
$data = json_decode(curl_exec($ch), true );
print_r($data);
require "net/http"
require "json"
uri = URI("https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" )
req = Net::HTTP::Get.new(uri)
req["Authorization" ] = "Bearer YOUR_TOKEN"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET" , "https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" , nil )
req.Header.Set("Authorization" , "Bearer YOUR_TOKEN" )
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic (err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
// Cargo.toml: reqwest = "0.12", tokio = { version = "1", features = ["full"] }
#[tokio::main]
async fn main() -> Result <(), reqwest::Error> {
let body = reqwest::Client::new()
.get("https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" )
.bearer_auth("YOUR_TOKEN" )
.send()
.await ?
.text()
.await ?;
println!("{body}" );
Ok (())
}
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
fun main() {
val request = HttpRequest.newBuilder(URI.create("https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" ))
.header("Authorization" , "Bearer YOUR_TOKEN" )
.build()
val response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString())
println(response.body())
}
# elixir example.exs (in a Mix project, add {:req, "~> 0.5"} to deps instead)
Mix.install([{:req, "~> 0.5" }])
response = Req.get!("https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" , auth: {:bearer, "YOUR_TOKEN" })
IO.inspect(response.body)
[
"400001, Mumbai, Maharashtra" ,
"400002, Mumbai, Maharashtra" ,
"400003, Mumbai, Maharashtra" ,
"400004, Mumbai, Maharashtra" ,
"400005, Mumbai, Maharashtra"
]
All endpoints return consistent error responses. Check the IsError field and StatusCode for error detection.
HTTP Status Codes
Code Meaning Common Cause
200 Success Request processed successfully
400 Bad Request Invalid parameters or empty address
401 Unauthorized Missing or invalid auth token
403 Forbidden Token lacks permission for this endpoint
429 Rate Limited Too many requests. Slow down or upgrade plan.
500 Server Error Internal error. Contact support if persistent.
{
"StatusCode" : 400 ,
"IsError" : true ,
"Errors" : [
"Arguments cannot be null or empty"
]
}