# sthan.io — Complete API Reference for AI Systems > For a summary, see https://api.sthan.io/llms.txt This file provides complete request/response examples for every sthan.io API endpoint, with exact field names and interpretation guidance. All responses use the standard envelope: { Id, Result, ClientSessionId, StatusCode, IsError, Errors }. The actual data is always in the "Result" field. --- ## Authentication Two methods are supported. API keys are recommended for CLI, MCP servers, and AI agent integrations. ### Option 1: API Key (recommended) All requests require this header: Authorization: Bearer sthan_test_your_api_key_here API keys use the format: sthan_{environment}_{random_alphanumeric} - sthan_test_* for test environment - sthan_live_* for production environment Get your API key from your dashboard at https://sthan.io/dashboard. ### Option 2: JWT Token (legacy) Step 1 — Obtain token: GET https://api.sthan.io/Auth/Token Headers: profileName: {your-profile-name} profilePassword: {your-profile-password} Response (200): { "Id": "a1b2c3d4-...", "Result": { "access_token": "eyJhbGciOiJIUzI1NiIs...", "expiration": "2026-03-16T15:30:00-08:00" }, "ClientSessionId": null, "StatusCode": 200, "IsError": false, "Errors": [] } Token is valid immediately upon issuance. Lifetime is capped at 60 minutes. Step 2 — All subsequent requests require: Authorization: Bearer {access_token} ### Getting Credentials Sign up at https://sthan.io. API keys can be created from your dashboard. For legacy JWT auth, go to https://sthan.io/apikeys to view your profileName and profilePassword. --- ## Address Verification (USA) Verify a US address for deliverability. Returns standardized postal components, DPV confirmation, carrier route, and postal verification status. ### Request GET https://api.sthan.io/AddressVerification/Usa/Single/123 Main St, New York, NY 10001 Headers: Authorization: Bearer {token} ### Response (200) { "Id": "a1b2c3d4-...", "Result": { "InputAddress": "123 Main St, New York, NY 10001", "FullAddressHash": 1234567890, "FullAddress": "123 MAIN ST, NEW YORK, NY 10001-1234", "AddressLine1": "123 MAIN ST", "AddressLine2": "", "City": "NEW YORK", "StateCode": "NY", "County": "NEW YORK", "ZipCode": "10001", "Zip4": "1234", "CarrierRoute": "C001", "DeliveryPoint": "23", "CheckDigit": "5", "Cmar": "N", "Elot": "0001", "ElotIndicator": "A", "RecordType": "H", "DpvConfirmation": "Y", "DefaultFlag": "N", "DefaultInd": "", "AlgorithmUsed": "100", "IsPostalVerified": true, "IsError": false, "ErrorMessages": [] }, "StatusCode": 200, "IsError": false, "Errors": [] } ### Field Definitions DpvConfirmation (Delivery Point Validation): Y = Confirmed — address is a valid delivery point N = Not confirmed — address was not found in postal data S = Secondary info missing — the street address is valid but an apartment/suite/unit number is needed D = Primary confirmed, secondary missing — street is valid, but the specific unit could not be confirmed RecordType: H = Highrise (apartment building) S = Street (individual house) F = Firm (business) G = General delivery P = PO Box R = Rural route IsPostalVerified: true = Address was matched against authoritative postal data false = Address could not be verified against postal data AlgorithmUsed (numeric codes): 100 = Fuzzy exact match 101-105 = Fuzzy with corrections (street, city, zip, multiple) 201-203 = Census-based match 301 = Legacy algorithm 400 = No candidates found 404 = No match 410-416 = Rejected (specific reason: house number, street name, state, etc.) 500 = Error 304xxx = Cache hit (304 prefix + original algorithm code) ### How to Interpret Results A verified, deliverable address has: DpvConfirmation=Y, IsPostalVerified=true. If DpvConfirmation=S, ask the user for an apartment or unit number. If DpvConfirmation=N and IsPostalVerified=false, the address likely does not exist. --- ## Address Parser (USA) Parse a freeform address string into structured components. Handles messy input — abbreviations, missing punctuation, transposed components. ### Request GET https://api.sthan.io/AddressParser/USA/Single/apt 2b 500 broadway new york ny 10012 Headers: Authorization: Bearer {token} ### Response (200) { "Id": "a1b2c3d4-...", "Result": { "InputAddress": "apt 2b 500 broadway new york ny 10012", "FullAddressHash": 9876543210, "FullAddress": "500 BROADWAY APT 2B, NEW YORK, NY 10012", "AddressLine1": "500 BROADWAY", "AddressLine2": "APT 2B", "AddressNumber": "500", "StreetPreMod": "", "StreetPreDir": "", "StreetPreType": "", "StreetPreSep": "", "StreetName": "BROADWAY", "StreetPostType": "", "StreetPostDir": "", "StreetPostMod": "", "UnitType": "APT", "UnitNumber": "2B", "City": "NEW YORK", "StateCode": "NY", "State": "New York", "ZipCode": "10012", "Zip4": "", "County": "NEW YORK", "IsPostalVerified": true, "AlgorithmUsed": "100", "Confidence": 0.97, "IsError": false, "ErrorMessages": [] }, "StatusCode": 200, "IsError": false, "Errors": [] } ### Field Definitions Confidence (0.0 to 1.0): 0.95 - 1.0 = Exact match — high confidence in all parsed components 0.85 - 0.94 = High confidence — minor normalization applied 0.70 - 0.84 = Medium confidence — some components may have been inferred or corrected Below 0.70 = Low confidence — significant uncertainty in parsed components Street Component Fields: StreetPreDir = Directional prefix (N, S, E, W, NE, NW, SE, SW) StreetPreType = Street type prefix (rare, e.g., "Avenue" in "Avenue of the Americas") StreetName = Core street name StreetPostType = Street type suffix (ST, AVE, BLVD, DR, LN, CT, etc.) StreetPostDir = Directional suffix UnitType = Unit designator (APT, STE, UNIT, FL, RM, etc.) UnitNumber = Unit identifier ### How to Interpret Results If Confidence >= 0.85 and IsPostalVerified=true, the parsed result is reliable. If Confidence < 0.70, present the result to the user for confirmation. If IsError=true, the address could not be parsed at all. --- ## Address Autocomplete (USA) Get address suggestions from partial input. Designed for type-ahead search. Sub-100ms response time. ### Request GET https://api.sthan.io/AutoComplete/USA/Address/123 Main Headers: Authorization: Bearer {token} ### Response (200) { "Id": "a1b2c3d4-...", "Result": [ "123 MAIN ST, NEW YORK, NY 10001", "123 MAIN AVE, LOS ANGELES, CA 90012", "123 MAIN BLVD, CHICAGO, IL 60601", "123 MAIN ST, SAN FRANCISCO, CA 94105", "123 MAIN DR, HOUSTON, TX 77001" ], "StatusCode": 200, "IsError": false, "Errors": [] } ### Notes - Result is an array of complete address strings (not objects). - Results are ranked by relevance. - Minimum input: typically 3+ characters for useful results. --- ## City Autocomplete (USA) ### Request GET https://api.sthan.io/AutoComplete/USA/City/DisplayType/0/New Y Headers: Authorization: Bearer {token} ### Response (200) { "Id": "a1b2c3d4-...", "Result": [ "New York, NY", "New York Mills, NY", "New Yorktown, IN" ], "StatusCode": 200, "IsError": false, "Errors": [] } ### DisplayType Options 0 = City, StateCode (e.g., "New York, NY") 1 = City, State (e.g., "New York, New York") --- ## ZipCode Autocomplete (USA) ### Request GET https://api.sthan.io/AutoComplete/USA/ZipCode/DisplayType/0/100 Headers: Authorization: Bearer {token} ### Response (200) { "Id": "a1b2c3d4-...", "Result": [ "10001, NY", "10002, NY", "10003, NY", "10004, NY", "10005, NY" ], "StatusCode": 200, "IsError": false, "Errors": [] } ### DisplayType Options 0 = ZipCode, StateCode (e.g., "10001, NY") 1 = ZipCode, State (e.g., "10001, New York") 2 = ZipCode-Zip4, StateCode (e.g., "10001-1234, NY") 3 = ZipCode-Zip4, State (e.g., "10001-1234, New York") --- ## Forward Geocoding (USA) Convert a US address to geographic coordinates (latitude/longitude). Returns match confidence, accuracy type, and address components. ### Request GET https://api.sthan.io/Geocoding/USA/Forward/1600 Pennsylvania Ave, Washington DC Headers: Authorization: Bearer {token} ### Response (200) { "Id": "a1b2c3d4-...", "Result": { "inputAddress": "1600 Pennsylvania Ave, Washington DC", "formattedAddress": "1600 PENNSYLVANIA AVE NW, WASHINGTON, DC 20500", "location": { "latitude": 38.8977, "longitude": -77.0365 }, "confidence": 0.98, "accuracy": { "type": "rooftop" }, "components": { "streetNumber": "1600", "street": "PENNSYLVANIA AVE NW", "city": "WASHINGTON", "county": "DISTRICT OF COLUMBIA", "state": "DC", "zip": "20500", "country": "US" }, "source": "10" }, "StatusCode": 200, "IsError": false, "Errors": [] } Note: Forward geocoding uses camelCase JSON property names (via JsonPropertyName attributes), unlike other endpoints which use PascalCase. ### Response with Interpolation When an exact rooftop match is not found, the API interpolates the position along the street range: { "Id": "a1b2c3d4-...", "Result": { "inputAddress": "12345 Some St, Anytown, CA 90001", "formattedAddress": "12345 SOME ST, ANYTOWN, CA 90001", "location": { "latitude": 34.0522, "longitude": -118.2437 }, "confidence": 0.72, "accuracy": { "type": "interpolated" }, "components": { "streetNumber": "12345", "street": "SOME ST", "city": "ANYTOWN", "state": "CA", "zip": "90001", "country": "US" }, "interpolation": { "requestedHouseNumber": 12345, "lowerHouseNumber": 12300, "upperHouseNumber": 12400, "estimatedAccuracyMeters": 15.3 }, "source": "40" }, "StatusCode": 200, "IsError": false, "Errors": [] } ### Field Definitions accuracy.type: "rooftop" = Exact building-level coordinates "interpolated" = Estimated position along a street range "centroid" = Center of a geographic area (ZIP code, city) "approximate" = Low-precision estimate confidence (0.0 to 1.0): 0.90 - 1.0 = Rooftop-level accuracy — coordinates pinpoint the building 0.50 - 0.89 = Approximate — suitable for mapping but not precise navigation Below 0.50 = Low confidence — coordinates may be significantly off source codes: 10 = Primary database (highest quality) 11 = Fast-match (optimized lookup) 20 = Census data 30 = External source 40 = Interpolated from street range 41 = Nearest known address 42 = Area centroid interpolation (only present when accuracy.type = "interpolated"): requestedHouseNumber = The house number from the input lowerHouseNumber = Lower bound of the address range used upperHouseNumber = Upper bound of the address range used estimatedAccuracyMeters = Estimated distance from true position --- ## Reverse Geocoding (USA) Convert latitude/longitude coordinates to the nearest US street address. Returns distance from input coordinates to the found address. ### Request GET https://api.sthan.io/Geocoding/USA/Reverse/38.8977/-77.0365 Headers: Authorization: Bearer {token} ### Response (200) { "Id": "a1b2c3d4-...", "Result": { "location": { "latitude": 38.8977, "longitude": -77.0365 }, "formattedAddress": "1600 PENNSYLVANIA AVE NW, WASHINGTON, DC 20500", "distance": 0.0, "confidence": 0.99, "accuracy": { "type": "rooftop" }, "components": { "streetNumber": "1600", "street": "PENNSYLVANIA AVE NW", "city": "WASHINGTON", "county": "DISTRICT OF COLUMBIA", "state": "DC", "zip": "20500", "country": "US" }, "source": "10" }, "StatusCode": 200, "IsError": false, "Errors": [] } Note: Reverse geocoding also uses camelCase JSON property names. ### Field Definitions distance: Distance in meters from the input coordinates to the found address location. 0.0 = Exact match at the coordinates. Values under 50 = Very close, likely the correct address. Values over 500 = The nearest address is far — coordinates may be in an area without addresses. confidence: Same scale as forward geocoding (0.0 to 1.0). Derived from distance — closer = higher confidence. ### Input Validation latitude must be between -90 and 90 longitude must be between -180 and 180 If invalid, the API returns HTTP 400 with an error message. --- ## IP Geolocation (Global) Look up the geographic location of an IPv4 or IPv6 address. ### Request GET https://api.sthan.io/IpGeolocation/8.8.8.8 Headers: Authorization: Bearer {token} ### Response (200) { "Id": "a1b2c3d4-...", "Result": { "IpAddress": "8.8.8.8", "Country": "United States", "CountryCode": "US", "Region": "California", "City": "Mountain View", "Latitude": 37.386, "Longitude": -122.0838, "Continent": "North America", "Timezone": "America/Los_Angeles", "PostalCode": "94035" }, "StatusCode": 200, "IsError": false, "Errors": [] } Note: IP Geolocation uses PascalCase field names. ### Notes - Supports both IPv4 (e.g., 8.8.8.8) and IPv6 (e.g., 2001:4860:4860::8888). - Private/reserved IPs (127.0.0.1, 10.x.x.x, 192.168.x.x) will not return location data. - Accuracy varies: country-level is typically 99%+, city-level is typically 80-90%. --- ## India Autocomplete Endpoints ### City Autocomplete (India) GET https://api.sthan.io/AutoComplete/Ind/City/DisplayType/{displayType}/{text} ### Locality Autocomplete (India) GET https://api.sthan.io/AutoComplete/Ind/Locality/DisplayType/{displayType}/{text} ### PinCode Autocomplete (India) GET https://api.sthan.io/AutoComplete/Ind/PinCode/DisplayType/{displayType}/{text} All return arrays of strings, same format as USA autocomplete. DisplayType options are 0-3 depending on the endpoint. --- ## Error Responses ### Authentication Failed (401) { "Id": "a1b2c3d4-...", "Result": null, "ClientSessionId": null, "StatusCode": 401, "IsError": true, "Errors": ["Unauthorized"] } Cause: Missing, expired, or invalid JWT token. Obtain a new token from GET /Auth/Token. ### Bad Request (400) { "Id": "a1b2c3d4-...", "Result": null, "StatusCode": 400, "IsError": true, "Errors": ["Address input is required."] } Cause: Missing or empty required parameter. ### Not Found (404) { "Id": "a1b2c3d4-...", "Result": null, "StatusCode": 404, "IsError": true, "Errors": ["Address not found."] } Cause: The address could not be matched in the database. The address may not exist, or the input may be too ambiguous. ### Rate Limited (429) { "Id": "a1b2c3d4-...", "Result": null, "StatusCode": 429, "IsError": true, "Errors": ["Rate limit exceeded. Try again in 60 seconds."] } Cause: Too many requests. Wait and retry. Check current limits at https://sthan.io/pricing/united-states. ### Server Error (500) { "Id": "a1b2c3d4-...", "Result": null, "StatusCode": 500, "IsError": true, "Errors": ["An internal error occurred."] } Cause: Unexpected server error. Retry once. If persistent, contact support@sthan.io. --- ## JSON Casing Note Different endpoints use different JSON casing: - Geocoding (Forward & Reverse): camelCase (e.g., inputAddress, formattedAddress, location.latitude) - Address Verification: PascalCase (e.g., InputAddress, AddressLine1, DpvConfirmation) - Address Parser: PascalCase (e.g., InputAddress, AddressLine1, Confidence) - IP Geolocation: PascalCase (e.g., IpAddress, Country, Latitude) - Autocomplete: Array of strings (no object fields) The response envelope itself (Id, Result, StatusCode, IsError, Errors) is always PascalCase. --- ## Endpoint Quick Reference | Endpoint | Method | Route | Returns | |----------|--------|-------|---------| | Auth Token | GET | /Auth/Token | JWT access_token | | Address Verification | GET | /AddressVerification/Usa/Single/{address} | VerifiedAddressModel | | Address Parser | GET | /AddressParser/USA/Single/{address} | ParsedAddressModel | | Address Autocomplete | GET | /AutoComplete/USA/Address/{text} | string[] | | City Autocomplete | GET | /AutoComplete/USA/City/DisplayType/{dt}/{text} | string[] | | ZipCode Autocomplete | GET | /AutoComplete/USA/ZipCode/DisplayType/{dt}/{text} | string[] | | Forward Geocoding | GET | /Geocoding/USA/Forward/{address} | GeocodingResult | | Reverse Geocoding | GET | /Geocoding/USA/Reverse/{lat}/{lon} | ReverseGeocodingResult | | IP Geolocation | GET | /IpGeolocation/{ip} | GeoLocation | | India City Autocomplete | GET | /AutoComplete/Ind/City/DisplayType/{dt}/{text} | string[] | | India Locality Autocomplete | GET | /AutoComplete/Ind/Locality/DisplayType/{dt}/{text} | string[] | | India PinCode Autocomplete | GET | /AutoComplete/Ind/PinCode/DisplayType/{dt}/{text} | string[] |