Feed that address into almost any geocoding API built for the Western world and watch it struggle. There’s no street number to anchor on, no clean locality field, and the most useful piece of information — the community centre across the road — is treated as noise to be discarded.
That single line captures the whole problem. Indian addresses aren’t badly written. They’re differently structured. And the fix isn’t a smarter geocoder — it’s a cleaning layer that sits in front of one.
Here’s how I approached it while building the backend for AddressFix, an India-first address cleaning and geocoding API — and, more usefully, the parts you can apply to any system that has to make sense of a messy Indian address.

Why Indian addresses break geocoders
Most geocoding stacks assume an address is a structured object: house number, street name, city, postal code, in a predictable order. That assumption is baked into how they parse, how they score matches, and what they choose to ignore. It holds in a lot of the world. It falls apart in India for a handful of concrete reasons.
Locations are anchored to landmarks, not streets. “Opposite community centre,” “behind the metro station,” “near the water tank” — the meaningful spatial signal lives in the landmark, not in a numbered street. Western normalizers are built to strip this kind of text as filler, because in their world it is filler. In India, throwing it away throws away the address.
Locality naming is inconsistent. Colony, sector, nagar, gali, block, phase, extension — these appear in any combination, with spelling drift and transliteration from Hindi adding more variants. “Gali No. 3”, “Gali Number 3”, and “Gali 3” are the same thing, written three ways. The same place gets written differently by different people, and a naive string match treats each variant as distinct.
PIN codes are unreliable. They’re frequently missing, occasionally wrong, and sometimes copy-pasted from a nearby area that happens to be more familiar to the person typing. A large Delhi PIN can cover multiple localities, so even a correct PIN often isn’t precise enough to resolve a doorstep. You can’t treat the PIN as ground truth — only as one signal among several.
There’s no canonical component order. City, locality, and landmark show up in whatever sequence the writer thought of them. “Delhi, Uttam Nagar” and “Uttam Nagar, Delhi” are equally common. A parser that keys on position gets confused fast, and worse, silently mis-assigns fields.
Everything arrives as free text. One blob, no fields. Whatever structure exists has to be recovered, not read. This is the crux: you’re not validating a form, you’re doing information extraction on natural language.
The architecture: a cleaning layer, then geocode — not just geocode
The core design decision was to run a normalization pass before the geocoding call, rather than throwing raw user input straight at the API and hoping.
I want to be honest about why this layer earns its place, because it’s a fair question. A geocoder’s own search already parses a good deal of messy input — so a thin wrapper around it wouldn’t add much. The cleaning pass justifies itself by doing the things a raw geocode call doesn’t: expanding Indian address abbreviations, stripping the noise that real users type, and pulling the landmark out and keeping it instead of letting it get swallowed. That’s the piece that’s actually mine, and it’s the piece worth writing about.
The flow, at a high level:
raw free text
→ clean & normalize (pure rules/regex)
→ extract pincode + landmark
→ geocode the cleaned address
→ score confidence (layered)
→ structured record out
The order matters. Cleaning before geocoding means the API receives its best-case input, not its worst. And extracting the pincode before the call means that when a result comes back, you already have something to check it against — which is what makes real confidence scoring possible.
What the cleaning pass actually does — with examples
This layer is pure rules and regex. No machine learning, no LLM — deterministic, fast, free, and trivially testable. That’s a deliberate choice, not a limitation: for the bulk of real addresses, well-chosen rules beat a model on speed, cost, and predictability, and you can unit-test every one of them. Here’s what runs, in order, on our running example.
1. Expand abbreviations. A dictionary of common Indian address shorthand, applied whole-word and longest-key-first so the greedy matches win:
opp community centre, gali no 3, uttam nagar, delhi
→ opposite community centre, lane no 3, uttam nagar, delhi
opp → opposite, gali → lane, nr → near, rd → road, h.no → house number, sec → sector, and so on. Cheap, and it removes a lot of variance before any harder logic runs.
2. Strip noise. Real users type things that aren’t part of the address: “call before delivery”, “cash on delivery / COD”, stray phone numbers. Those get removed by pattern, along with the orphaned action-words they leave behind, so the geocoder isn’t handed instructions as if they were location text.
3. Extract the pincode — by type, not position. A six-digit-PIN regex ([1-9]\d{5}) searches the whole string, so the PIN is found wherever it sits. If it’s absent, that absence is recorded — which matters later for scoring.
4. Extract the landmark — by cue phrase. Cue words (near, opposite, behind, next to, beside, in front of, adjacent to…) trigger capture of the phrase that follows, up to the next comma. So “opposite community centre” is identified as a landmark by what it is, not where it appears — and then it’s kept, not discarded. In an Indian context the landmark is frequently the strongest locator available, sometimes stronger than the PIN. A pipeline that strips it is optimizing for the wrong continent.
5. Standardize. Title-casing and comma normalization so whatever consumes the record gets something uniform:
Opposite Community Centre, Lane No 3, Uttam Nagar, Delhi
A note on honesty, since it’s the whole point of the exercise: this layer expands abbreviations and extracts pincode and landmark. It does not do spell-correction, and it does not parse out separate city/state/locality fields — the geocoder handles resolving those. Keeping the cleaning layer narrow and deterministic is what keeps it reliable.
Geocoding and the eLoc
Once the address is cleaned, it goes to the geocoding API, which returns coordinates, a match level, a confidence score, and — with Mappls — the eLoc, a six-character code that resolves to a precise doorstep location.
One clarification worth making, because it trips people up: the eLoc is the six-character code. It’s not a separate “pin” product layered on top. Access uses an OAuth token flow — client credentials exchanged for a short-lived access token, sent as a bearer token on the geocode call — rather than a raw key dropped into the URL. Practically, that means your backend should cache the token and only refresh it near expiry, rather than requesting a new one per call. (I cache the token and reuse a single client across a bulk batch so one exchange covers hundreds of lookups.)
Mappls vs Google — and why I built for both
The obvious question: why not just use Google? It’s the default geocoder for most developers, and its global coverage is excellent. Rather than argue it in the abstract, I built the backend provider-agnostic — it runs against Mappls or Google Address Validation behind the same interface, switchable by config, with each vendor’s granularity mapped onto one common 0–1 score so the rest of the system doesn’t care which is active. That turned the comparison into something I could actually test rather than assert.
The honest trade-offs:
| Consideration | Mappls (MapmyIndia) | Google Address Validation |
|---|---|---|
| India hyperlocal depth | Built India-first; deep on colonies, galis, small localities | Broad global coverage; strong in metros, thinner on tier-2/3 lanes |
| Doorstep code | Native eLoc (~3m, six chars) | Plus Code — capable, but less embedded in Indian addressing habits |
| Landmark & vernacular input | Tuned for Indian landmark-based, transliterated text | Improving, but optimized for structured global input |
| Pricing context | Priced for the Indian market (INR) | USD-denominated; can climb at volume |
| Global coverage | India-focused | Best-in-class worldwide |
| Ecosystem | Smaller developer community | Huge community, abundant tutorials |
The summary: if you’re geocoding worldwide, Google is the safer default. If your problem is specifically Indian last-mile precision — resolving a landmark-anchored address in a tier-2 colony to an actual doorstep — Mappls’ India-first design and the eLoc are built for that job. Because AddressFix is India-only, Mappls is the primary provider; the Google backend exists as a real, switchable alternative rather than a hypothetical.
(A full quantitative head-to-head — accuracy, latency, cost at volume — is really its own post. This is the short version of why the setup made sense here.)
Confidence scoring: the trust layer
A cleaned address and a returned coordinate aren’t the same as a correct result. A geocoder will almost always return something; the question is whether to believe it. So every result carries a High / Medium / Low rating, computed in ordered layers rather than pulled from a single number:
- Base tier — the vendor’s confidence score. The geocoder’s own 0–1 confidence sets the starting tier: high scores start High, low scores start Low, the middle starts Medium.
- Match-level bump. A precise match level (e.g. resolving to a house number) with a strong score can lift a Medium result up to High — a good match type is evidence in its own right.
- PIN-agreement hard downgrade. If the input carried a PIN and it disagrees with the geocoded location, the result is forced to Low, overriding everything above. Disagreement is the loudest possible red flag, so it wins.
The result is auditable: each record also stores which layer decided the tier and which rules fired, so a surprising rating can be explained rather than shrugged at. And the practical payoff — Low-confidence results are the ones you route to a human before trusting. That distinction is what separates a tool people rely on at checkout from one they quietly stop trusting after the first bad delivery.
Input to output, end to end
Putting it together, here’s opposite community centre, gali no 3, uttam nagar, delhi traced through the pipeline:
INPUT
opposite community centre, gali no 3, uttam nagar, delhi
CLEANED
Opposite Community Centre, Lane No 3, Uttam Nagar, Delhi
EXTRACTED
landmark : Opposite Community Centre
pincode : (missing — flagged)
GEOCODED
lat/lng : <coordinates>
eLoc : <6-char code>
SCORED
confidence : Medium (vendor match resolved, but no PIN to cross-check)
landmark : Opposite Community Centre
The Medium here is the honest outcome, not a failure: the address resolved, but with no PIN to cross-check it against, the system correctly signals “probably right, worth a glance” rather than overclaiming certainty.
Where this goes — and what to take away
The immediate payoff is at the point of capture: validating an address at checkout, or giving a delivery rider a precise doorstep code instead of a landmark and a phone call. For tier-2 and tier-3 sellers, where messy addresses are the norm rather than the exception, that’s the difference between a delivery that lands and one that bounces.
There’s an honest open question I’m still working through: measuring how much lift the cleaning layer actually adds over raw geocoding. Because I log every cleaned result, I’ve got the raw material to test it — but quantifying that properly against a real set of messy addresses is the next step, and I’d rather prove it than assert it.
If you’re building anything that has to take an Indian address and turn it into a reliable location, here’s the pattern, distilled:
- Don’t ask the geocoder to do the cleaning. Clean first, so the API gets its best-case input.
- Keep the landmark. In India it’s often your strongest signal, not noise.
- Extract by type, not position — search for the pincode and landmark anywhere in the string.
- Treat the PIN as a signal, never as truth — and let a PIN mismatch downgrade your confidence.
- Rules and regex go a long way. Deterministic, fast, free, testable — reach for heavier machinery only when they genuinely fall short.
- Score confidence in layers and route the low-confidence ones to a human. A wrong answer delivered confidently is worse than an honest “check this one.”
- Pick the geocoder that matches where your addresses live — India-first problem, India-first tool.
Clean first, keep the landmark, score the confidence in layers, then geocode. Everything else is detail.

Comments