Why City Mapping Breaks Hotel Search (and How to Fix It)
Hotel mapping gets all the attention, but most broken searches start one level up: the city. Here is why supplier city codes never agree, what it costs you, and how a master city ID fixes it.
Ask a travel-tech team what breaks hotel search and they will talk about hotel mapping - duplicate properties, mismatched names, wrong coordinates. Fair enough. But a surprising share of "no results" and "why is this hotel in the wrong place" tickets start one level higher, before a single hotel is looked at: the city.
If your product takes a destination from the user and asks five suppliers for hotels there, you depend on all five agreeing on what that destination is. They do not. This article explains why city mapping fails, what it costs you, what a master city record needs to contain, and how to fix the problem once instead of per supplier.
The symptom: valid city, broken results
Three patterns show up again and again in support queues:
- Empty results for a real city. The user picks "Jumeirah", one supplier files every Jumeirah hotel under "Dubai", and your query for Jumeirah to that supplier returns nothing. The hotels exist; you asked under the wrong code.
- Hotels from the wrong place. "Paris" quietly matches Paris, Texas for one supplier, or "Santa Cruz" returns a mix of Tenerife, Bolivia and California. Travellers notice before you do.
- Duplicate destinations in autocomplete. Your destination box offers "Bangalore", "Bengaluru" and "Bangalore City" as three choices, each backed by a different supplier, each with a different subset of hotels.
None of these is a hotel-matching problem. They are all city mapping failures - a disagreement about what the destination is, before any hotel is compared.
Why city mapping is hard: suppliers disagree on cities
Every bed bank, wholesaler and channel manager keeps its own destination table, built for its own contracting needs rather than for your search box. The same place arrives in very different shapes:
| Supplier style | What "Dubai" looks like | What breaks |
|---|---|---|
| Destination codes | DXB covering the whole emirate |
Jumeirah, Deira, Marina all collapse into one code - fine for breadth, useless for neighbourhood search |
| Numeric city IDs | 100234 for Dubai, 100987 for Jumeirah Beach |
Two IDs for what travellers consider one place |
| Free-text city names | Dubai, DUBAI, Dubai - Jumeirah, Dubai (Deira) |
Spelling and formatting variants multiply with every import |
| Regional buckets | "Dubai & Northern Emirates" | Sharjah and Ajman hotels appear in Dubai results |
Add the usual data-quality problems on top: transliteration (Munchen / Munich / Muenchen), renamed cities (Bombay / Mumbai, Madras / Chennai), diacritics stripped by one supplier and kept by another, and suburbs that one country treats as independent cities and another as districts. There is no global registry every supplier uses, so each one has made its own decisions - and none of them documented why.
What bad city mapping actually costs
The damage from broken city mapping is quieter than duplicate hotels, which is exactly why it persists:
- Lost inventory. Hotels you have contracted and paid to load never appear because they sit under a city code your search never asks for. In our own data, a single large city can have its inventory split across three or four supplier-side destinations.
- Broken price comparison. If supplier A's "Dubai" and supplier B's "Dubai" are different polygons, the same hotel can appear in one result set and not the other, so the "cheapest rate" you show is cheapest among the suppliers that happened to match the city.
- Cache and analytics fragmentation. Search caches keyed on supplier city codes cannot be shared. Conversion reports count "Bengaluru" and "Bangalore" as different destinations.
- Engineering time. Every new supplier means a fresh round of city mapping, usually done in a spreadsheet, usually never maintained.
What a master city record needs
Good city mapping starts with a good target. The fix is the same idea as hotel mapping, applied one level up: a supplier-independent master city ID that every supplier code maps to. A usable master city record carries:
| Field | Why it matters |
|---|---|
id (stable master ID) |
The only key your product stores, caches and reports on |
| Canonical name + country | What you display; country prevents Paris/Paris collisions |
| Coordinates (centre) and ideally a radius or bounding box | Lets you sanity-check hotel coordinates against the city they claim |
| Alias list | Bangalore / Bengaluru, Munchen / Munich - for search and autocomplete |
| Status (active / merged / retired) | Cities get merged and corrected; clients need to follow |
| Supplier code map with confidence | hotelbeds: DXB, dida: 100234, rezlive: "Dubai" - the actual mapping, per supplier |
| Hotel count and provider count | Tells you at a glance whether the city is well covered |
With this in place, "give me hotels in Dubai" becomes one lookup of the master city, then one fan-out using each supplier's own code - no guessing, no string matching at request time.
How Mappin handles city mapping
Mappin maintains 146,000+ active master cities across 258 countries, each linked to the matching destination codes of Hotelbeds, Dida, RezLive, Restel and Travellanda. Two calls take you from a user's text to supplier-mapped hotels.
1. Resolve the name to a master city. Exact match first, then partial matching; the optional country parameter removes Paris/Paris ambiguity.
curl "https://mappin.rpconnect.travel/api/city/?city=Dubai&country=AE" \
-H "X-API-Key: YOUR_API_KEY"
{
"pagination": {
"total_results": 1,
"total_pages": 1,
"current_page": 1,
"page_size": 50
},
"results": [
{
"city_id": 2041,
"city_name": "Dubai",
"country_name": "United Arab Emirates",
"country_code": "AE"
}
],
"hint": "Use city_id from results to fetch hotels: /api/city/?city_id=<id>"
}
2. Inspect the master city - including every supplier's own code for it, so you can see exactly how each supplier will be queried:
curl https://mappin.rpconnect.travel/api/cities/2041/ \
-H "X-API-Key: YOUR_API_KEY"
{
"id": 2041,
"name": "Dubai",
"country": { "id": 1, "name": "United Arab Emirates", "code": "AE" },
"status": "Active",
"hotel_count": 1284,
"total_providers": 3,
"providers": [
{
"provider": "hotelbeds",
"provider_city_id": "DXB",
"provider_city_name": "Dubai",
"provider_country_id": "AE",
"confidence": 1.0
}
]
}
3. Fetch the hotels with ?city_id=2041 - every active master hotel in the city, each carrying its supplier mappings, optionally filtered to one supplier with &provider=hotelbeds. The full walkthrough is in How to Integrate a Hotel Mapping API in One Afternoon.
Because the city is resolved once, centrally, a correction (a merged duplicate city, a fixed supplier code) reaches every partner on the next request rather than waiting for each team to update a spreadsheet.
A checklist for your own search
Whether you build or buy city mapping, these six checks catch most of the damage:
- Key everything on a master city ID, never on a supplier code or a name string.
- Store aliases and search them - users type Bangalore, suppliers say Bengaluru.
- Always pass a country when resolving a name; ambiguous city names are more common than you think.
- Validate hotel coordinates against the city centre. A "Dubai" hotel 300 km from Dubai is a city-mapping error, not a hotel-mapping one.
- Track supplier coverage per city (hotel count per supplier). A city with 1,400 hotels from one supplier and 0 from another is a mapping gap, not a contracting gap.
- Watch merges and status changes. Cities get deduplicated too - follow the change feed so your cached IDs stay valid, the same way you would for hotel deduplication.
Getting started
City mapping is unglamorous, which is why it is usually the last thing fixed and the first thing to break when a new supplier is added. Solving it with one master city ID removes a whole class of "no results" tickets before you ever touch hotel matching.
You can explore the city endpoints with a free Mappin key - 5 calls per endpoint, no card required. Create an account, then start with /api/city/?city= for the destination you support worst today. Full reference in the API documentation.
Frequently asked questions
What is city mapping in travel technology?
City mapping is the process of linking every supplier's own city or destination code (for example Hotelbeds destination 'DXB', a Dida numeric city ID, a RezLive city name) to one master city record, so a search for 'Dubai' returns every supplier's hotels in Dubai in a single call.
Why do hotel searches return empty results for a valid city?
Usually because the city the user picked is not mapped to the supplier you are querying: the supplier files those hotels under a district, a region or a differently spelled city. The hotels exist, but under a code you never asked for.
How is city mapping different from hotel mapping?
Hotel mapping links supplier hotel IDs to one master hotel. City mapping links supplier city or destination codes to one master city. You need both: a perfectly mapped hotel is still unreachable if it sits under an unmapped city.
How many cities does Mappin maintain?
Mappin maintains 146,000+ active master cities across 258 countries, each linked to the matching city or destination codes of Hotelbeds, Dida, RezLive, Restel and Travellanda, accessible through the /api/cities/ and /api/city/ endpoints.
Try Mappin on your own hotel data
Create a free account, grab an API key and query 1M+ mapped hotels in the Playground - no credit card needed.