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

Quick Start

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!

Authentication

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

GET /Auth/Token

Send your profileName and profilePassword as request headers. The API returns a JWT access token and its expiration time.

Request Headers
HeaderTypeRequiredDescription
profileNamestringRequiredYour access profile identifier. Case-sensitive.
profilePasswordstringRequiredYour access profile password. Case-sensitive.
Request
curl -s "https://api.sthan.io/Auth/Token" \
  -H "profileName: YOUR_PROFILE_NAME" \
  -H "profilePassword: YOUR_PROFILE_PASSWORD"
200 Response
{
  "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
FieldTypeDescription
Result.access_tokenstringJWT Bearer token, nested under the Result field of the response envelope. Include in Authorization header for all API calls.
Result.expirationdatetimeToken expiration timestamp (server local time, America/Los_Angeles), nested under Result. Request a new token before this time.

Try it: get your token

Enter your access profile credentials to get a real JWT token. Your credentials are sent to the API via a server-side proxy and are not stored.

Step 2: Use the Token

Include the access_token as a Bearer token in the Authorization header of every subsequent API request.

All Subsequent Requests
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.

Envelope Format
{
  "Id": "unique-request-id",
  "Result": { /* endpoint-specific data shown in examples below */ },
  "ClientSessionId": "your-session-id",
  "StatusCode": 200,
  "IsError": false,
  "Errors": []
}

Rate Limits

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).

ProductFreeBasicStarterBusiness
Address Verification3,000 / mo
100 / day
10 / min
10,000 / mo
500 / min
50,000 / mo
2,500 / min
150,000 / mo
7,500 / min
Address Parser3,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 Autocomplete10,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 Geolocation50,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.

429 Response
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."
  ]
}
GET

Address Autocomplete

/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
NameTypeRequiredDescription
textstringRequiredPartial address to search. URL-encoded. Min 3 chars for best results.
Response Codes
200 Success 400 Bad Request 401 Unauthorized 429 Rate Limited
Request
curl -s "https://api.sthan.io/AutoComplete/USA/Address/123%20main%20st" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
[
  "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"
]

Try it live

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 →
GET

Address Parser

/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
NameTypeRequiredDescription
addressstringRequiredFull or partial US address to parse. URL-encoded.
Request
curl -s "https://api.sthan.io/v2/address-parser/usa/speculative/1600%20pennsylvania%20ave%20nw%20washington%20dc%2020500" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
{
  "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
FieldTypeDescription
fullAddressstringStandardized full address with ZIP+4
addressNumberstringHouse/building number
streetNamestringStandardized street name
unitTypestring?APT, STE, UNIT, etc.
countystringCounty name
confidencefloatMatch confidence score (0.0 – 1.0)

Try it live

GET

Address Verification

/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
NameTypeRequiredDescription
addressstringRequiredUS address to verify. URL-encoded.
Request
curl -s "https://api.sthan.io/v2/address-verification/usa/speculative/6000%20j%20st%20sacramento%20ca%2095819" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
{
  "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
FieldTypeDescription
deliverableStatusenumConfirmed = 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.
dpvConfirmationstringPostal 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
carrierRoutestringPostal carrier route code (e.g., C001 = city route 1)
deliveryPointstring2-digit delivery point code appended to ZIP+4
recordTypestringS = street, H = highrise, F = firm, R = rural route, P = PO box
zip4string4-digit ZIP extension for precise delivery routing
unitTypestringConfirmed 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.
unitNumberstringConfirmed secondary-unit number, for example 142. Empty when the address has no secondary unit.

Try it live

GET

City Autocomplete

/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
NameTypeRequiredDescription
displayTypeintRequired0 = City, StateCode (e.g., Sacramento, CA)
1 = City, State (e.g., Sacramento, California)
textstringRequiredPartial city name to search. URL-encoded.
Request
curl -s "https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/sacram" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
[
  "Sacramento, CA",
  "Sacramento, KY",
  "Sacramento, NM",
  "Sacramento, PA"
]

Try it live

GET

ZIP Code Autocomplete

/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
NameTypeRequiredDescription
displayTypeintRequired0 = ZipCode, City, StateCode
1 = ZipCode, City, State
2 = ZipCode-Zip4, City, StateCode
3 = ZipCode-Zip4, City, State
textstringRequiredPartial ZIP code or city name. URL-encoded.
Request
curl -s "https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/9582" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
[
  "95820, Sacramento, CA",
  "95821, Sacramento, CA",
  "95822, Sacramento, CA",
  "95825, Sacramento, CA"
]

Try it live

GET

Forward Geocoding

/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
NameTypeRequiredDescription
addressstringRequiredFull US address to geocode. URL-encoded.
Request
curl -s "https://api.sthan.io/Geocoding/USA/Forward/1600%20Pennsylvania%20Ave%20NW%20Washington%20DC%2020500" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
{
  "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
FieldTypeDescription
inputAddressstringThe address as you sent it.
formattedAddressstringThe matched address in postal form, with ZIP+4 when known.
locationobjectlatitude and longitude of the answer.
confidencenumber0 to 1. How sure the match is.
accuracy.typestringrooftop = 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.
componentsobjectstreetNumber, street, unit, city, county, countyFips (5-digit county code), state, zip, zip4, country. Empty parts are left out.
source / sourceNamestringHow 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.
addressIdstringStable id of the address point. Only on address_point answers.
timezoneobjectTime 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).
interpolationobjectOnly on estimated answers: requestedHouseNumber and the lowerHouseNumber / upperHouseNumber the spot was estimated from.

Try it live

GET

Reverse Geocoding

/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
NameTypeRequiredDescription
latdoubleRequiredLatitude coordinate (-90 to 90)
londoubleRequiredLongitude coordinate (-180 to 180)
limitintegerOptionalQuery 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
Request
curl -s "https://api.sthan.io/Geocoding/USA/Reverse/38.897676/-77.036530" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
{
  "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
FieldTypeDescription
locationobjectThe coordinates you sent.
distancenumberMeters from your point to the address.
formattedAddressstringThe matched address in postal form, with ZIP+4 when known.
confidencenumber0 to 1. How sure the match is.
accuracy.typestringrooftop = 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.
componentsobjectstreetNumber, street, unit, city, county, countyFips (5-digit county code), state, zip, zip4, country. Empty parts are left out.
source / sourceNamestringHow 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.
addressIdstringStable id of the address point. Only on address_point answers.
timezoneobjectTime 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).
nearbyarrayOnly 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).

Try it live

GET

IP Geolocation

/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
NameTypeRequiredDescription
ipstringRequiredIPv4 or IPv6 address (e.g., 8.8.8.8)
Request
curl -s "https://api.sthan.io/IpGeolocation/8.8.8.8" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
{
  "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
}

Try it live

GET

City Autocomplete (India)

/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
NameTypeRequiredDescription
displayTypeintRequired0 = City, State
1 = City, District, State
textstringRequiredPartial city name. URL-encoded.
Request
curl -s "https://api.sthan.io/AutoComplete/Ind/City/DisplayType/0/mumbai" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
[
  "Mumbai, Maharashtra",
  "Mumbai Suburban, Maharashtra",
  "Navi Mumbai, Maharashtra",
  "Mumbai City, Maharashtra"
]

Try it live

GET

Locality Autocomplete (India)

/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
NameTypeRequiredDescription
displayTypeintRequired0 = Locality, City, State
1 = Locality, City, District, State
textstringRequiredPartial locality name. URL-encoded.
Request
curl -s "https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/0/koramangala" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
[
  "Koramangala, Bengaluru, Karnataka",
  "Koramangala 1st Block, Bengaluru, Karnataka",
  "Koramangala 2nd Block, Bengaluru, Karnataka",
  "Koramangala 3rd Block, Bengaluru, Karnataka",
  "Koramangala 4th Block, Bengaluru, Karnataka"
]

Try it live

GET

PIN Code Autocomplete (India)

/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
NameTypeRequiredDescription
displayTypeintRequired0 = PinCode, City, State
1 = PinCode, City, District, State
textstringRequiredPartial PIN code or city name. URL-encoded.
Request
curl -s "https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/0/400001" \
  -H "Authorization: Bearer YOUR_TOKEN"
200 Response
[
  "400001, Mumbai, Maharashtra",
  "400002, Mumbai, Maharashtra",
  "400003, Mumbai, Maharashtra",
  "400004, Mumbai, Maharashtra",
  "400005, Mumbai, Maharashtra"
]

Try it live

Error Handling

All endpoints return consistent error responses. Check the IsError field and StatusCode for error detection.

HTTP Status Codes
CodeMeaningCommon Cause
200SuccessRequest processed successfully
400Bad RequestInvalid parameters or empty address
401UnauthorizedMissing or invalid auth token
403ForbiddenToken lacks permission for this endpoint
429Rate LimitedToo many requests. Slow down or upgrade plan.
500Server ErrorInternal error. Contact support if persistent.
Error Response Example
{
  "StatusCode": 400,
  "IsError": true,
  "Errors": [
    "Arguments cannot be null or empty"
  ]
}