SFOLN

Catalogue / Data utilities

Geocoding API – Address to Coordinates

sfoln/geocode-address · Developer tools, Automation, Travel On request

Geocode addresses to coordinates and reverse-geocode coordinates to addresses worldwide: formatted address, latitude/longitude, confidence, address parts, timezone, currency and calling code. US street addresses add Census tract, county and congressional district. $0.80 per 1,000 lookups.

About

What it does

Geocoding API – Address to Coordinates converts addresses to coordinates and coordinates to addresses, worldwide, in bulk. Each result is one clean record with the formatted address, latitude/longitude, a confidence score, structured components (country, state, city, postcode, road, house number) and useful extras: timezone and UTC offset, currency, calling code, flag, driving side and an OpenStreetMap link. US street addresses are matched by the US Census Bureau geocoder and also get their Census geographies (tract, block, county FIPS, congressional and state legislative districts, ZIP code area, metro area) at no extra cost. Mix both directions in one list: anything that looks like lat,lng is reverse-geocoded. Built for CRM and lead enrichment, logistics, analytics, store locators and AI agents.

Price

Price per delivered record

EventPricePer 1,000Charged for
Geocoded address
address-geocoded
$0.0008$0.80 / 1,000Charged once per address or coordinate pair looked up: a US Census match, an OpenCage result, or an OpenCage lookup with no match (OpenCage counts those too).

Apify free plan: up to 10 items per run. Paid plans have no per-run cap; set maxTotalChargeUsd to cap spend.

Run

Call it from code, an agent or the Console

This API is private on Apify for now. Email us and we will publish it for you, usually within two working days. The calls below work once it is public. contact@sfoln.com

curl · synchronous run, rows in the response
curl -X POST "https://api.apify.com/v2/actors/sfoln~geocode-address/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries":["Brandenburger Tor, Berlin","40.7484,-73.9857"]}'
mcp.json · hosted Apify MCP server
{
  "mcpServers": {
    "apify": {
      "type": "http",
      "url": "https://mcp.apify.com?tools=sfoln/geocode-address"
    }
  }
}
asynchronous run · for large batches
POST https://api.apify.com/v2/actors/sfoln~geocode-address/runs?maxTotalChargeUsd=1
GET  https://api.apify.com/v2/actor-runs/{runId}            # until status is SUCCEEDED
GET  https://api.apify.com/v2/datasets/{defaultDatasetId}/items?format=json

Authenticate with an Apify API token. MCP clients can instead sign in with OAuth when prompted. Example prompt for an agent: Geocode "Brandenburger Tor, Berlin" and "350 Fifth Avenue, New York" and give me their coordinates and time zones.

Input

Input fields

List addresses (forward geocoding) or "lat,lng" pairs (reverse geocoding), one per line.

FieldTypeDefaultMeaning
queries *arrayrequiredAddresses or coordinates
Addresses or place names (forward), or "latitude,longitude" pairs such as "52.5163,13.3777" (reverse; latitude first), one per line. Max 500 characters per line. Accounts on the Apify free plan can process up to 10 addresses per run.
countryCodestring—Country hint
Restrict forward results to these countries: ISO 3166-1 alpha-2 code(s), comma separated, e.g. "us" or "de,at,ch". Strongly recommended for short or ambiguous addresses. With "us" every street address goes to the US Census geocoder first.
languagestring—Language
Language for the formatted address and components, e.g. "en", "de", or "native" for the local language. Default: English where available.
useCensusForUsbooleantrueUse the US Census geocoder for US addresses
US street addresses are geocoded by the free US Census Bureau geocoder first (adds censusGeographies: tract, county, congressional district …); addresses it cannot match fall back to OpenCage. Off = OpenCage for every input.
maxItemsinteger1000Max items
Safety cap on how many addresses are processed in this run. Range 1–100000.
concurrencyinteger2Concurrency
Parallel requests (1–5). The geocoder limits requests per second, so more workers mostly add rate-limit errors. Range 1–5.
includeRawbooleanfalseInclude raw upstream response
Attach the unmodified upstream response to each record (OpenCage's answer, or { census } for US Census matches; larger output).
Example input
{
  "queries": [
    "Brandenburger Tor, Berlin",
    "40.7484,-73.9857"
  ]
}

Output

One record per input item

Records land in the run's dataset; a synchronous call returns them directly. Each has a status (ok is charged; everything else is free) and a charged flag. The run's OUTPUT record totals items and charges.

FieldTypeMeaning
inputstring | objectInput
The input item this record corresponds to.
statusstringStatus
ok | not_found | error | skipped_invalid | skipped_budget | skipped_free_plan
chargedbooleanCharged
Whether the record's main event was charged.
chargedEventstring | nullCharged event
Event charged by the runner for this record, if any.
sourcestringSource
Which geocoder answered: census (US Census Bureau geocoder, US street addresses) or opencage (everything else).
fetchedAtstringFetched at
ISO timestamp.
warningsarray | nullWarnings
Non-fatal problems (pages not reachable, truncation, budget limits).
errorobject | nullError
{ code, message, provider?, status? } when status is not ok.
querystring | nullQuery
The address or "lat,lng" pair as provided.
modestring | nullMode
forward (address → coordinates) or reverse (coordinates → address).
formattedstring | nullFormatted address
Full formatted address of the best match.
latitudenumber | nullLatitude
WGS84 latitude.
longitudenumber | nullLongitude
WGS84 longitude.
confidenceinteger | nullConfidence
OpenCage confidence 0–10 (10 = within ~250 m bounding box, 1 = > 25 km, 0 = unknown); US Census matches are street-address points (10).
typestring | nullResult type
Kind of match: building, road, city, postcode, county, state, country ... (Census matches: building).
componentsobject | nullComponents
{ country, countryCode, state, city, postcode, road, houseNumber } (city falls back to town / village / municipality).
timezonestring | nullTimezone
IANA timezone, e.g. Europe/Berlin.
utcOffsetstring | nullUTC offset
Current UTC offset, e.g. +0200.
currencystring | nullCurrency
ISO 4217 currency code of the location.
callingCodeinteger | nullCalling code
International dialling code.
flagstring | nullFlag
Country flag emoji.
driveOnstring | nullDrives on
left | right.
speedUnitstring | nullSpeed unit
kmh | mph.
mapUrlstring | nullMap URL
OpenStreetMap link to the location.
attributionstring | nullAttribution
Data source of the result (OpenCage / OpenStreetMap contributors, or the US Census Bureau geocoder).
matchTypestring | nullMatch type
Census matches: exact (agrees with every part of the input) or non_exact (the Census corrected part of the address, e.g. the ZIP code); null for OpenCage.
censusGeographiesobject | nullCensus geographies
US Census matches: state, county, tract, blockGroup, block, congressionalDistrict, stateLegislativeDistrictUpper/Lower, place, countySubdivision, zcta, cbsa, csa, metropolitanDivision, schoolDistrict, urbanArea, puma, region, division. Null for OpenCage results.
candidatesarray | nullCandidates
Census ambiguous_address records (OpenCage not configured): the matching addresses { formatted, latitude, longitude }.
foundboolean | nullFound
false on not_found records.
rawobject | nullRaw
Unmodified upstream response (includeRaw): OpenCage's answer, or { census } for US Census matches.
Example record
{
  "input": "1600 Pennsylvania Ave NW, Washington, DC 20500",
  "query": "1600 Pennsylvania Ave NW, Washington, DC 20500",
  "mode": "forward",
  "formatted": "1600 PENNSYLVANIA AVE NW, WASHINGTON, DC, 20500",
  "latitude": 38.898702605245,
  "longitude": -77.035189204737,
  "confidence": 10,
  "type": "building",
  "timezone": "America/New_York",
  "utcOffset": "-0400",
  "currency": "USD",
  "callingCode": 1,
  "flag": "🇺🇸",
  "driveOn": "right",
  "speedUnit": "mph",
  "mapUrl": "https://www.openstreetmap.org/?mlat=38.898702605245&mlon=-77.035189204737#map=17/38.898702605245/-77.035189204737",
  "components": {
    "country": "United States",
    "countryCode": "US",
    "state": "District of Columbia",
    "city": "WASHINGTON",
    "postcode": "20500",
    "road": "PENNSYLVANIA AVE NW",
    "houseNumber": "1600"
  },
  "source": "census",
  "attribution": "U.S. Census Bureau Geocoder (public domain)",
  "matchType": "exact",
  "censusGeographies": {
    "state": {
      "fips": "11",
      "code": "DC",
      "name": "District of Columbia"
    },
    "county": {
      "fips": "11001",
      "name": "District of Columbia"
    },
    "tract": {
      "geoid": "11001980000",
      "code": "980000",
      "name": "Census Tract 9800"
    },
    "block": {
      "geoid": "110019800001034",
      "code": "1034",
      "name": "Block 1034"
    },
    "congressionalDistrict": {
      "geoid": "1198",
      "code": "98",
      "name": "Delegate District (at Large)",
      "congress": 120
    },
    "zcta": "20006",
    "cbsa": {
      "geoid": "47900",
      "code": "47900",
      "name": "Washington-Arlington-Alexandria, DC-VA-MD-WV Metro Area",
      "type": "metropolitan"
    }
  },
  "status": "ok",
  "charged": true,
  "chargedEvent": "address-geocoded",
  "fetchedAt": "2026-10-14T10:00:00.000Z"
}

FAQ

Questions

Which geocoder answers my address?
US street addresses go to the US Census Bureau geocoder first (free, and it adds the Census tract, county and congressional district); every other address, coordinates and the US addresses the Census cannot match go to OpenCage (OpenStreetMap data). Each record says which one in its source field.
Why is a US address in upper case?
Census results use the standardized USPS form of the address ("1600 PENNSYLVANIA AVE NW"). Turn off useCensusForUs to get OpenCage's formatting for every input.

Machine-readable

This page for agents