Reverse geocoding for the United States

Turn coordinates into trusted street addresses.

RevAddr is a reverse geocoding API: send a latitude and longitude, get a structured US address (house number, street, city, state, ZIP, and county). Built for accuracy first, so your users see the right place, not a rough guess on a road.

  • Continental US coverage
  • Structured address fields
  • Simple REST API
example response
{
  "formatted_address": "1600 Pennsylvania Ave NW,
    Washington, DC 20500",
  "house_number": "1600",
  "street": "Pennsylvania Ave NW",
  "city": "Washington",
  "state": "DC",
  "postcode": "20500",
  "county": "District of Columbia",
  "confidence": 0.97
}

Why teams choose RevAddr

Clear value for products that need “where is this pin?” without overpaying or overcomplicating.

Accuracy you can stand behind

We prefer real address points when they are near the coordinate. When we must interpolate along a street, we respect side-of-street and house-number parity so results stay grounded in how US addressing actually works.

Fields your product needs

Every response includes a ready-to-display formatted address plus house number, street, city, state, postal code, and county, with match quality and distance so you can set confidence rules in your app.

Continental US focus

Purpose-built for the lower 48 and DC, not a global grab-bag. Ideal for US logistics, field service, fintech, insurance, marketplaces, and analytics.

Fast, predictable API

Simple HTTPS requests. No map SDK required for geocoding. Batch endpoint when you need many points in one call.

$

Straightforward pricing

Competitive per-thousand rates with a one-time free credit when you create an account, then prepaid top-ups as you need them. Volume rates apply to each large top-up on its own (not retroactively to earlier purchases). No surprise platform lock-in for a basic reverse call.

🔑

Keys and usage you control

Authenticate with an API key. Track usage per key so billing, quotas, and apps stay organized as you move from prototype to production.

Built for real products

If your system already has a latitude and longitude (GPS, a map click, a device ping, a photo geotag), RevAddr turns that point into a street address your users, ops teams, and reports can actually use.

Last-mile delivery & dispatch

A courier drops a pin or your vehicle GPS reports a stop. Reverse geocode it so the driver, customer, and support ticket all see the same street address, not a raw coordinate.

Fleet & telematics

Convert trip breadcrumbs, idle events, and geofence breaches into city, street, and county labels for dashboards, exception reviews, and customer-facing ETAs.

Field service & work orders

Technicians open a job from a map or mobile GPS fix. Fill the work order with a structured address so routing, parts, and history stay consistent across the back office.

IoT, sensors & cameras

Devices often know where they are, not what to call that place. Attach house number, street, city, ZIP, and county to alerts so operators can act without decoding lat/lon by hand.

Insurance, fraud & claims

Enrich FNOL locations, loss sites, and app-reported incidents with address and county for underwriting rules, SIU review, and territorial analysis.

Lending & fintech

Map a customer-selected pin or device location to a postal address and county for KYC support, branch-of-service rules, or risk models that need place context, not only coordinates.

Marketplaces & listings

Sellers or hosts place a pin on a map. Store a formatted address (and optional city/county) for search cards, buyer trust, and ops, while keeping the precise pin for navigation.

Public safety & emergency apps

When a user shares their location, show a readable street address in the SOS flow and admin console so responders are not stuck with decimal degrees under pressure.

Photo, media & asset metadata

Geotagged images, inspections, and site surveys gain a human-readable address for catalogs, compliance archives, and client deliverables.

Analytics & BI

Batch reverse geocode historical events so analysts can slice by city, ZIP, or county without maintaining a full GIS stack in every warehouse job.

CRM & customer support

When a user reports “I’m here” from the app map, resolve an address for the ticket so agents can verify service area, schedule visits, and avoid back-and-forth.

Real estate & site selection

Turn scouted pins and drive-by GPS tracks into street addresses for field notes, comps research, and internal site databases.

Common pattern: capture coordinates in the product, call RevAddr once (or in batch for backfills), store the structured fields next to the original lat/lon. Keep the point for maps; use the address for people and reports.

Try reverse geocoding live

Click the map or enter coordinates. Results come from the RevAddr API.

Click anywhere in the continental United States to reverse geocode that point. Map imagery is for context only; addresses come from the RevAddr API.

Advanced connection settings

The map demo does not use a shared API key. Leave the key empty for the public demo, or paste your key from create account.

Quick points:

Simple API

Authenticate with an API key. Integrate in minutes from any language that can call HTTPS.

Single lookup

GET /v1/reverse?lat={lat}&lon={lon}

Or POST /v1/reverse with JSON {"lat": ..., "lon": ...}.

Optional search radius. Response includes structured fields plus match quality and distance.

Batch

POST /v1/reverse/batch

Send multiple coordinates in one request (up to 100 points) for bulk jobs and imports.

Account & status

GET /v1/usage: usage for your key.

GET /health: service health.

Header: x-api-key: your_key

Example request

curl -s "https://api.revaddr.com/v1/reverse?lat=38.8977&lon=-77.0365" \
  -H "x-api-key: YOUR_API_KEY"
const res = await fetch(
  "https://api.revaddr.com/v1/reverse?lat=38.8977&lon=-77.0365",
  { headers: { "x-api-key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.result.formatted_address);
import requests

r = requests.get(
    "https://api.revaddr.com/v1/reverse",
    params={"lat": 38.8977, "lon": -77.0365},
    headers={"x-api-key": "YOUR_API_KEY"},
    timeout=10,
)
r.raise_for_status()
print(r.json()["result"]["formatted_address"])
package main

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

func main() {
	q := url.Values{}
	q.Set("lat", "38.8977")
	q.Set("lon", "-77.0365")

	req, err := http.NewRequest(
		http.MethodGet,
		"https://api.revaddr.com/v1/reverse?"+q.Encode(),
		nil,
	)
	if err != nil {
		panic(err)
	}
	req.Header.Set("x-api-key", "YOUR_API_KEY")

	client := &http.Client{Timeout: 10 * time.Second}
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()

	body, err := io.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}
	if res.StatusCode != http.StatusOK {
		panic(fmt.Sprintf("HTTP %d: %s", res.StatusCode, body))
	}

	var payload struct {
		Result struct {
			FormattedAddress string `json:"formatted_address"`
		} `json:"result"`
	}
	if err := json.Unmarshal(body, &payload); err != nil {
		panic(err)
	}
	fmt.Println(payload.Result.FormattedAddress)
}
const url = new URL("https://api.revaddr.com/v1/reverse");
url.searchParams.set("lat", "38.8977");
url.searchParams.set("lon", "-77.0365");

const res = await fetch(url, {
  headers: { "x-api-key": "YOUR_API_KEY" },
});
const data = await res.json();
console.log(data.result.formatted_address);
using System.Net.Http.Headers;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", "YOUR_API_KEY");

var url =
  "https://api.revaddr.com/v1/reverse?lat=38.8977&lon=-77.0365";
var json = await client.GetStringAsync(url);
Console.WriteLine(json);

// Parse with System.Text.Json as needed for result.formatted_address
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
    .uri(URI.create(
        "https://api.revaddr.com/v1/reverse?lat=38.8977&lon=-77.0365"))
    .header("x-api-key", "YOUR_API_KEY")
    .GET()
    .build();

var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
// Requires libcurl (https://curl.se/libcurl/)
#include <curl/curl.h>
#include <string>
#include <iostream>

static size_t write_cb(char* ptr, size_t size, size_t nmemb, void* userdata) {
  auto* out = static_cast<std::string*>(userdata);
  out->append(ptr, size * nmemb);
  return size * nmemb;
}

int main() {
  CURL* curl = curl_easy_init();
  std::string body;
  struct curl_slist* headers = nullptr;
  headers = curl_slist_append(headers, "x-api-key: YOUR_API_KEY");

  curl_easy_setopt(curl, CURLOPT_URL,
    "https://api.revaddr.com/v1/reverse?lat=38.8977&lon=-77.0365");
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body);

  CURLcode rc = curl_easy_perform(curl);
  if (rc == CURLE_OK) std::cout << body << std::endl;

  curl_slist_free_all(headers);
  curl_easy_cleanup(curl);
  return rc == CURLE_OK ? 0 : 1;
}
/* Requires libcurl (https://curl.se/libcurl/) */
#include <curl/curl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct mem { char *data; size_t len; };

static size_t write_cb(char *ptr, size_t size, size_t nmemb, void *userdata) {
  size_t total = size * nmemb;
  struct mem *m = (struct mem *)userdata;
  char *p = realloc(m->data, m->len + total + 1);
  if (!p) return 0;
  m->data = p;
  memcpy(m->data + m->len, ptr, total);
  m->len += total;
  m->data[m->len] = '\0';
  return total;
}

int main(void) {
  CURL *curl = curl_easy_init();
  struct mem chunk = {0};
  struct curl_slist *headers = NULL;
  headers = curl_slist_append(headers, "x-api-key: YOUR_API_KEY");

  curl_easy_setopt(curl, CURLOPT_URL,
    "https://api.revaddr.com/v1/reverse?lat=38.8977&lon=-77.0365");
  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk);

  if (curl_easy_perform(curl) == CURLE_OK)
    printf("%s\n", chunk.data ? chunk.data : "");

  free(chunk.data);
  curl_slist_free_all(headers);
  curl_easy_cleanup(curl);
  return 0;
}

Response fields

Successful reverse calls return JSON shaped like {"result": { ... }} (batch returns {"results": [ ... ]}). The demo shows that raw payload. Field meanings:

Field Meaning
formatted_address Single-line display string built from the structured parts (or a locality label when only area data is available).
house_number Street number when known. Null when the match is street-only, area-only, or none.
street Street or road name (for example Singleton Rd).
city City or place name when present in the data.
state Two-letter USPS state code (for example CA).
postcode ZIP or ZIP+4 when available.
county County name (Census enrich), for example Riverside County.
match_type How the result was resolved:
  • address_point: real mapped address point (OpenAddresses or similar)
  • interpolated: house number estimated along a TIGER street range
  • street_only: nearest street segment, no reliable house number
  • area: locality only (city / county / state / ZIP); no street address nearby
  • none: nothing usable near the coordinate
confidence Score from 0 to 1. Higher means closer, stronger match. Falls as distance grows or match type is weaker (interpolated, area).
distance_meters Straight-line distance from your query lat/lon to the matched feature (meters). Always check this for delivery or enforcement use cases.
lat / lon The coordinates you queried (echoed back), not the feature’s rooftop coordinates.

Billing: each reverse is 1 unit, including area and none results.

Full interactive schema: OpenAPI reference.

Pricing that scales with you

List price $0.50 per 1,000 reverse geocodes. New accounts receive a one-time $2 free credit (4,000 units) after email verification. Add prepaid units anytime. Volume discounts apply to each single top-up by how much you pay in that purchase — not cumulative spend across many smaller buys.

Free start

$2 one-time credit

Try the full reverse-geocoding API before you pay. After you verify your email, we add a one-time free balance — not a monthly free tier, and not a limited demo mode.

  • $2.00 free credit4,000 reverse geocodes at list ($0.50 / 1,000)
  • Same structured responses as paid (street, city, ZIP, county, confidence)
  • One API key per account; view usage and rotate the key anytime
  • Continental US coverage; each reverse uses 1 unit (batch of 100 = 100 units)
  • Abuse limits: one free account per network (IP), unique email per account
  • Need dev + staging + prod? Email support@revaddr.com to raise your IP allowance (still one unique email each)

How it works: create account → verify email → free units unlock with your API key. When free credit runs out, top up on the account page (list or volume rates).

Create an account

Volume

from $0.40 / 1,000

Rate is set by the size of one prepaid top-up (one card charge). Larger single payments get a lower rate on only the units from that payment — not lifetime spend, and not by adding smaller top-ups together.

You pay
(one top-up)
Rate
per 1,000 units
Units you get
(examples)
Under $500 $0.50 $100 → 200,000
$500 – $1,999 $0.48 $500 → ~1.04M
$2,000 – $3,999 $0.46 $2,000 → ~4.35M
$4,000 – $5,999 $0.44 $4,000 → ~9.1M
$6,000 – $7,999 $0.42 $6,000 → ~14.3M
$8,000 or more $0.40 $8,000 → 20M
$10,000 → 25M

Example: one $8,000 top-up is billed at $0.40 / 1,00020 million units. Eight separate $1,000 top-ups stay at the $500–$1,999 rate ($0.48 / 1,000 each) and do not unlock $0.40.

Sign in to add credit

All prices in USD. Fair-use and rate limits apply. Free credit is one-time at signup (not monthly). Each top-up is priced on its own using the table above (payment amount → rate → units credited for that purchase only). Earlier units keep the rate you already paid; a later large top-up does not reprice them. Purchased credits are non-refundable except where required by law. Speed and uptime are not guaranteed. See Terms of Service.

Get started

Create an account with email verification. New accounts include $2.00 free credit (4,000 reverse geocodes at list price) after you verify. By signing up you accept our Terms and Privacy Policy.

Next steps

  1. Try the demo Confirm results on locations that matter to your product.
  2. Create an account Get an API key and free credit on the create account page. Free signups are limited to one account per network (IP), each account has one API key, and each account needs a unique email. For extra accounts (dev/staging/prod), contact support@revaddr.com so we can raise the free-account allowance for your IP (distinct emails still required).
  3. Integrate Send x-api-key on every request. Each reverse is 1 unit; a batch of 100 points is 100 units.
Create an account

FAQ

What is reverse geocoding?

It converts a map coordinate (latitude, longitude) into a street address. Forward geocoding goes the other way: address to coordinate.

Where does RevAddr cover?

The continental United States (lower 48 + DC). Coverage quality follows available public address and street-range data and is continually improved.

Why is county included?

Many products need county for reporting, tax, or service regions. RevAddr returns county as a first-class field whenever it can be determined.

How accurate is a result?

Each response includes match type, confidence, and distance from your coordinate to the matched feature. Use those fields to accept, flag, or re-prompt users when needed.