Skip to main content
Job postings describe places inconsistently — Store 04494 - Lynchburg, VA, münchen, US or Canada, 2 Locations. GET /api/locations/geocode resolves these to canonical labels and coordinates.
Geocode results are highly cacheable — the same input always resolves to the same output. Cache locally and you will rarely pay for a repeat lookup.

How resolution works

Each input runs through a fixed sequence. Classification can short-circuit early; otherwise the pipeline extracts structured parts, geocodes each one, validates the result, and caches it.
1

Classify (remote / placeholder)

The trimmed input is checked against two regex sets before anything else runs.Remote sentinels return immediately as remote_keyword, with country: "Remote" and no coordinates: remote, anywhere, global, worldwide, work from home, wfh, telecommute, distributed — optionally followed by /, |, or , plus one of traveling, travel, anywhere, remote, virtual, or a trailing parenthetical.Placeholders return an error with succeeded: false and no geocoding attempted:
  • Counts — 2 Locations, 15 locations
  • Quantifiers — multiple/various/several/many/all locations
  • Single words — hq, headquarters, head office, office, location, flexible, hybrid, onsite, on-site, various, n/a, tbd, tba
2

Normalize

Real inputs are normalized into a stable cache key — abbreviations expanded, diacritics folded, casing standardized. Inputs differing only in case, punctuation, or common abbreviations share a cache entry.
3

Cache lookup

On hit, the previously resolved locations return immediately with method: "cache".Only successful resolutions are cached. Failed lookups are not written, so the same input can succeed later as data quality improves.
4

LLM extraction

On cache miss, the raw input goes to a language model that handles translation, abbreviation expansion, multi-location splitting ("US or Canada" → two parts), and noise removal ("Store 04494 - Lynchburg, VA"Lynchburg / Virginia / United States). It returns zero or more {city, region, country} parts.No usable parts means no_match.
5

Geocode each part

Each part goes to a structured geocoder returning canonical city / region / country / country-code labels plus coordinates. The geocoder’s labels are authoritative — the saved location uses its casing and spelling, not the model’s. Parts the geocoder cannot resolve are dropped.
6

Validation

Each geocoded result is validated against the original input by comparing token overlap with the canonical labels. This catches mis-geocodes (Springfield, IL resolving to Springfield, MA) and confabulations (inventing a country the input never mentioned).The match score (0.0–1.0) is returned as fuzzy_confidence. Results below the threshold are rejected. If every result is rejected, the response is no_match.
7

Cache the result

Accepted results are saved under the normalized key, so the next identical request is served instantly. The response returns with method: "llm".

The method field

Every response carries method, telling you which branch produced the result.
Most repeated lookups hit the cache and return in single-digit milliseconds. Cache misses go through the full pipeline and typically complete in a few hundred milliseconds. The endpoint has a 15-second budget; on timeout it returns 200 with succeeded: false and method: "timeout".

Supported input formats

Because extraction is model-driven there is no fixed format grammar. The table below shows formats observed working well in practice; it is not exhaustive.

Compound locations

Compound expressions split on or, and, &, ;, and |. Splitting happens during extraction, which returns one part per location. Each part is geocoded independently, and the resulting array comes back in locations on a single response.

Ambiguous codes

Some two-letter codes match both a US state abbreviation and an ISO country code. Disambiguation uses surrounding city or context tokens. Heuristics the resolver tends to apply:
  1. A standalone two-letter code usually resolves to the more common US state reading — CA alone → California.
  2. A code paired with a city is disambiguated by city context — Los Angeles, CA → California; Toronto, CA → Canada; Amsterdam, NL → Netherlands; Tel Aviv, IL → Israel.
  3. Three-letter codes are unambiguous ISO alpha-3 — DEU → Germany; GBR → United Kingdom.
Validation compares canonical labels back against the original input, so if the resolver settles on Canada for an input containing California, it is typically rejected.
For best results with ambiguous codes, include a city name or use the full state/country name — prefer California or Canada over a bare CA.

Tips

Be specific

Include both city and state/country when possible. San Francisco, CA beats a bare CA.

Spell out ambiguous codes

Use California or Canada instead of CA; Germany instead of DE.

Use standard separators

or, and, &, ;, or | between locations. US or Canada works; US, Canada may be read as one location.

Ignore case and diacritics

münchen, MÜNCHEN, and Munchen all resolve to Munich, Germany.

Aliases are handled

NYC, SF, LA, DC and transliterations like Bombay or Peking resolve automatically.

Noise is stripped

Store 04494 - Lynchburg, VA and Greater San Francisco Area normalize to the underlying city.

Unresolvable input

A location that cannot be resolved is not an error. The endpoint returns 200 with succeeded: false, so check that field rather than the status code.
A missing or whitespace-only location parameter is a genuine 400. See Errors for the envelope.