Introduction
Welcome to the MAPPIN API — the unified partner API gateway for global travel data. Aggregate countries, cities, and hotels from 6+ travel providers through one intelligent mapping layer. Built for speed, designed for scale.
New here? Jump to the Quickstart to make your first API call in under 5 minutes.
Quickstart
Get up and running with MAPPIN in three quick steps.
1. Create an account
Head to the registration page and sign up as a partner. It takes under a minute — no credit card required.
2. Get your API key
After signing in, navigate to API Keys in your partner dashboard. Copy your key — you'll need it for every API request.
Keep it secret. Treat your API key like a password. Never commit it to a public repo or expose it in client-side code.
3. Make your first request
Try fetching the list of countries:
curl https://mappin.rpconnect.travel/api/countries/ \
-H "X-API-Key: your_api_key_here"
You should get back a JSON response with all supported countries. That's it — you're integrated. 🎉
Authentication
All API requests must include your API key in the X-API-Key header. Requests without a valid key will be rejected with 401 Unauthorized.
GET /api/hotels/ HTTP/1.1
Host: mappin.rpconnect.travel
X-API-Key: your_api_key_here
cURL
curl https://mappin.rpconnect.travel/api/hotels/ \
-H "X-API-Key: your_api_key_here"
Python
import requests
headers = {"X-API-Key": "your_api_key_here"}
response = requests.get(
"https://mappin.rpconnect.travel/api/hotels/",
headers=headers
)
print(response.json())
JavaScript
const response = await fetch(
"https://mappin.rpconnect.travel/api/hotels/",
{ headers: { "X-API-Key": "your_api_key_here" } }
);
const data = await response.json();
console.log(data);
How It Works
MAPPIN sits between your application and multiple travel data providers — including HotelBeds, Rezlive, Travellanda and Dida. Instead of integrating each provider separately, you talk to one unified API and we handle:
- Provider aggregation — one request fans out to every provider mapped to that record
- Data normalization — a consistent JSON schema no matter which provider the data came from
- Canonical master records — duplicate cities and hotels are merged into one stable ID you can store forever
- Confidence scores — every provider mapping carries a 0–1 score so you know how sure the match is
- Content merging — hotel details combine the best description, images and amenities across providers
- Fresh lists, cached details — list endpoints always read live; hotel details are cached for 15 minutes per partner
Provider slugs are lowercase — hotelbeds, rezlive, travellanda, dida. Use these exact values in ?provider= filters and provider-map calls. A wrong slug returns the full valid list.
Pagination
Every list endpoint returns the same envelope. Default page size is 50 — override with ?limit= (max 500) and walk pages with ?page=.
| Parameter | Type | Default | Notes |
|---|---|---|---|
page | integer | 1 | Page number, starting at 1 |
limit | integer | 50 | Results per page, max 500 |
{
"pagination": {
"total_results": 195,
"total_pages": 4,
"current_page": 1,
"page_size": 50,
"next": "https://mappin.rpconnect.travel/api/countries/?page=2",
"previous": null
},
"results": [ ... ]
}
Follow pagination.next — it's a ready-made URL for the next page. Stop when it's null.
Rate Limits & Quotas
MAPPIN enforces three types of limits to keep the platform fast for everyone:
| Limit Type | Description | Response When Exceeded |
|---|---|---|
| Daily Quota | Max requests per day (per plan) | 429 Daily quota exceeded |
| Monthly Quota | Max requests per calendar month | 429 Monthly quota exceeded |
| Burst Limit | Max concurrent requests per second | 429 Burst limit exceeded |
| IP Abuse Guard | >10 requests/sec from single IP → 5-min block | 429 IP blocked |
Pro tip: Check your current usage anytime from the Analytics tab in your partner dashboard.
Error Handling
MAPPIN uses standard HTTP status codes. Errors always return a JSON body with an error field.
{
"error": "Daily API quota exceeded"
}
| Status | Meaning | What to do |
|---|---|---|
200 | Success | Nothing — you're good |
400 | Bad request | Check your query parameters |
401 | Missing/invalid API key | Verify your X-API-Key header |
403 | Partner disabled | Contact support |
404 | Resource not found | Check the ID in your URL |
429 | Rate limit exceeded | Wait & retry, or upgrade plan |
500 | Server error | Retry with exponential backoff |
Real examples
Missing parameter (400):
{
"error": "Parameter 'city_id' or 'city' is required. Use 'city' to search for cities, 'city_id' to fetch hotels."
}
Unknown record (404):
{
"error": "Hotel not found"
}
One quirk: the country-detail 404 uniquely returns {"success": false, "error": "..."}. Every other endpoint returns a bare {"error": ...}. Handle both shapes.
Countries
Access the master list of countries, each with its provider mappings and live city count.
GET /api/countries/
List countries. Results are paginated (see Pagination) and sorted by name.
| Parameter | Type | Required | Description |
|---|---|---|---|
search | string | No | Match against name, ISO code, or numeric ID — ?search=india, ?search=IN, ?search=247 |
page | integer | No | Page number (default 1) |
limit | integer | No | Page size, max 500 (default 50) |
curl "https://mappin.rpconnect.travel/api/countries/?search=united&limit=2" \
-H "X-API-Key: your_api_key_here"
{
"pagination": {
"total_results": 2,
"total_pages": 1,
"current_page": 1,
"page_size": 2,
"next": null,
"previous": null
},
"results": [
{
"id": 1,
"name": "United Arab Emirates",
"code": "AE",
"status": "Active",
"city_count": 42,
"provider_count": 2,
"providers": [
{
"provider": "hotelbeds",
"provider_country_id": "AE",
"provider_country_name": "United Arab Emirates",
"provider_country_code": "AE",
"confidence": 1.0
},
{
"provider": "rezlive",
"provider_country_id": "AE",
"provider_country_name": "UAE",
"provider_country_code": "AE",
"confidence": 0.98
}
]
}
]
}
GET /api/countries/<identifier>/
Country detail. The identifier is flexible — use whichever you have:
- Numeric ID —
/api/countries/1/ - ISO code (case-insensitive) —
/api/countries/us/ - Full name —
/api/countries/Japan/(URL-encode spaces)
curl https://mappin.rpconnect.travel/api/countries/GB/ \
-H "X-API-Key: your_api_key_here"
{
"id": 247,
"name": "United Kingdom",
"code": "GB",
"status": "Active",
"city_count": 1284,
"total_providers": 3,
"providers": [
{
"provider": "hotelbeds",
"provider_country_id": "GB",
"provider_country_name": "United Kingdom",
"provider_country_code": "GB",
"confidence": 1.0
}
]
}
Unknown identifier returns 404 with {"success": false, "error": "Country with ID or code 'XX' not found."} — note the extra success flag, unique to this endpoint.
Cities
Search the master city list and fetch city details with provider mappings and live hotel counts.
GET /api/cities/
List cities. Results are paginated and sorted by name.
| Parameter | Type | Required | Description |
|---|---|---|---|
search | string | No | Match against city name — or numeric ID (?search=london, ?search=123) |
country | string | No | Filter by country code, name, or numeric ID (?country=GB, ?country=247) |
country_id | integer | No | Same as numeric ?country= — filter by country ID |
page | integer | No | Page number (default 1) |
limit | integer | No | Page size, max 500 (default 50) |
curl "https://mappin.rpconnect.travel/api/cities/?country=AE&limit=2" \
-H "X-API-Key: your_api_key_here"
{
"pagination": {
"total_results": 42,
"total_pages": 21,
"current_page": 1,
"page_size": 2,
"next": "https://mappin.rpconnect.travel/api/cities/?country=AE&limit=2&page=2",
"previous": null
},
"results": [
{
"id": 2041,
"name": "Dubai",
"country": { "id": 1, "name": "United Arab Emirates", "code": "AE" },
"status": "Active",
"hotel_count": 1284,
"provider_count": 3,
"providers": [
{
"provider": "hotelbeds",
"provider_city_id": "DXB",
"provider_city_name": "Dubai",
"provider_country_id": "AE",
"confidence": 1.0
}
]
}
]
}
GET /api/cities/<city_id>/
City detail by numeric master ID only (unlike countries, codes and names are not accepted here).
curl https://mappin.rpconnect.travel/api/cities/2041/ \
-H "X-API-Key: your_api_key_here"
{
"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
}
]
}
Unknown ID returns 404 with {"error": "City with ID '999' not found"}.
City Master
One dual-purpose endpoint that takes you from a city name to its hotels in two calls — no IDs to look up first.
The fastest name → hotels path: search ?city=Dubai to get a city_id, then fetch ?city_id=2041 for its hotels. The search response even includes this hint.
GET /api/city/?city=<name>
Search cities by name. Tries an exact match first, then falls back to partial matching.
| Parameter | Type | Required | Description |
|---|---|---|---|
city | string | Yes* | City name (?city=London). *Required unless city_id is given |
country | string | No | Narrow by country code (?city=Paris&country=FR). If it matches nothing, it's ignored and unfiltered results return |
page / limit | integer | No | Standard pagination |
curl "https://mappin.rpconnect.travel/api/city/?city=Dubai" \
-H "X-API-Key: your_api_key_here"
{
"pagination": {
"total_results": 1,
"total_pages": 1,
"current_page": 1,
"page_size": 50,
"next": null,
"previous": null
},
"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="
}
GET /api/city/?city_id=<id>
List active hotels in a city, each with its provider mappings — plus a metadata block echoing the city.
| Parameter | Type | Required | Description |
|---|---|---|---|
city_id | integer | Yes* | Master city ID. *Required unless city is given |
provider | string | No | Only hotels mapped to this provider slug (?provider=hotelbeds) |
page / limit | integer | No | Standard pagination |
curl "https://mappin.rpconnect.travel/api/city/?city_id=2041&limit=1" \
-H "X-API-Key: your_api_key_here"
{
"pagination": {
"total_results": 1284,
"total_pages": 1284,
"current_page": 1,
"page_size": 1,
"next": "https://mappin.rpconnect.travel/api/city/?city_id=2041&limit=1&page=2",
"previous": null
},
"results": [
{
"master_id": 12847,
"name": "Burj Al Arab",
"coordinates": { "lat": 25.1412, "lng": 55.1853 },
"mappings": [
{
"provider": "hotelbeds",
"provider_code": "12847",
"provider_hotel_id": "12847",
"provider_hotel_name": "Burj Al Arab Jumeirah",
"confidence": 0.99
}
]
}
],
"metadata": {
"city_id": 2041,
"city_name": "Dubai",
"country_name": "United Arab Emirates",
"country_code": "AE",
"selected_provider": null
}
}
Calling with neither parameter returns 400; an unknown name or ID returns 404.
Hotels
The core of MAPPIN — search the master hotel list, then drill into rich merged details per property.
GET /api/hotels/
List hotels. Results are paginated and sorted by name.
| Parameter | Type | Required | Description |
|---|---|---|---|
search | string | No | Match against hotel name — or numeric master ID (?search=hilton, ?search=12847) |
city_id | integer | No | Master city ID. Must be numeric — anything else is ignored |
country / country_code / country_id | string | No | Three aliases, same filter: code, name, or numeric ID (?country=GB, ?country_id=247) |
provider | string | No | Only hotels mapped to this provider slug |
page / limit | integer | No | Standard pagination |
curl "https://mappin.rpconnect.travel/api/hotels/?city_id=2041&limit=1" \
-H "X-API-Key: your_api_key_here"
{
"pagination": {
"total_results": 1284,
"total_pages": 1284,
"current_page": 1,
"page_size": 1,
"next": "https://mappin.rpconnect.travel/api/hotels/?city_id=2041&limit=1&page=2",
"previous": null
},
"results": [
{
"id": 12847,
"name": "Burj Al Arab",
"city": { "id": 2041, "name": "Dubai" },
"country": { "id": 1, "name": "United Arab Emirates", "code": "AE" },
"coordinates": { "lat": 25.1412, "lng": 55.1853 },
"status": "Active",
"provider_count": 3,
"providers": [
{
"provider": "hotelbeds",
"provider_code": "12847",
"provider_hotel_id": "12847",
"provider_hotel_name": "Burj Al Arab Jumeirah",
"confidence": 0.99
}
]
}
]
}
GET /api/hotels/<hotel_id>/
Full detail for one hotel by numeric master ID — merged description, address, rating, images and amenities, plus every provider mapping. Arrays below are truncated for brevity.
curl https://mappin.rpconnect.travel/api/hotels/12847/ \
-H "X-API-Key: your_api_key_here"
{
"id": 12847,
"master_id": 12847,
"name": "Burj Al Arab",
"status": "Active",
"city": { "id": 2041, "name": "Dubai" },
"country": { "id": 1, "name": "United Arab Emirates", "code": "AE" },
"coordinates": { "lat": 25.1412, "lng": 55.1853 },
"total_providers": 3,
"providers": [
{
"provider": "hotelbeds",
"provider_code": "12847",
"provider_hotel_id": "12847",
"provider_hotel_name": "Burj Al Arab Jumeirah",
"confidence": 0.99
}
],
"description": "Iconic sail-shaped luxury hotel on its own island off the Dubai coast...",
"address": "Jumeirah St, Umm Suqeim 3, Dubai",
"phone": "+97143017777",
"star_rating": 5,
"images": [
"https://photos.hotelbeds.com/giata/00/001234/001234a_hb_a_001.jpg"
],
"amenities": ["Free WiFi", "Outdoor pool", "Spa", "Airport shuttle"],
"source_provider": "hotelbeds",
"providers_available": ["hotelbeds", "rezlive", "travellanda"],
"providers_used": ["hotelbeds", "rezlive"]
}
How content is picked: the richest provider record wins (description length, images ×2, amenities ×1.5, plus rating and address) and becomes source_provider; missing fields are then filled in from the others (providers_used). provider_code is the supplier-side code — pass it back to that provider's own booking APIs.
Cached 15 minutes per partner. Brand-new mappings can take up to 15 minutes to appear in this endpoint; list endpoints always read live.
Unknown ID returns 404 with {"error": "Hotel not found"}.
Provider Mapping
Reverse lookup: hand over any supplier's hotel ID and get back the canonical master record — plus every other provider's ID for the same hotel, so you can translate IDs across suppliers (e.g. hotelbeds → dida) without extra calls. Hotels only.
GET /api/provider-map/
Single lookup via query params.
| Parameter | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | Lowercase provider slug (hotelbeds, rezlive, …) |
hotel_id | string | Yes | That provider's hotel ID or code |
curl "https://mappin.rpconnect.travel/api/provider-map/?provider=hotelbeds&hotel_id=12847" \
-H "X-API-Key: your_api_key_here"
{
"mapped": true,
"query": { "provider": "hotelbeds", "provider_hotel_id": "12847" },
"master": {
"master_id": 12847,
"name": "Burj Al Arab",
"city": { "id": 2041, "name": "Dubai" },
"country": { "id": 1, "name": "United Arab Emirates", "code": "AE" },
"coordinates": { "lat": 25.1412, "lng": 55.1853 },
"status": "Active"
},
"match": {
"provider": "hotelbeds",
"provider_code": "12847",
"provider_hotel_id": "12847",
"provider_hotel_name": "Burj Al Arab Jumeirah",
"confidence": 0.99,
"lookup": "exact"
},
"siblings": [
{
"provider": "dida",
"provider_code": "DUB12847",
"provider_hotel_id": "DUB12847",
"provider_hotel_name": "Burj Al Arab",
"confidence": 0.95
}
],
"total_providers": 2,
"hint": "Full details: GET /api/hotels/12847/"
}
POST /api/provider-map/
Same lookup as JSON — single or batch. Batch accepts up to 100 IDs and uses exact matching only (no code fallbacks, for speed).
curl -X POST https://mappin.rpconnect.travel/api/provider-map/ \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"provider": "hotelbeds", "hotel_ids": ["12847", "99999"]}'
{
"provider": "hotelbeds",
"total": 2,
"found": 1,
"not_found": 1,
"results": [
{
"mapped": true,
"query": { "provider": "hotelbeds", "provider_hotel_id": "12847" },
"master": { "master_id": 12847, "name": "Burj Al Arab" },
"match": { "provider": "hotelbeds", "lookup": "exact" },
"siblings": [ ... ],
"total_providers": 2
},
{
"mapped": false,
"query": { "provider": "hotelbeds", "provider_hotel_id": "99999" }
}
]
}
Smart matching: single lookups try an exact match first, then provider-specific code fallbacks (hotelbeds code → id, dida id ↔ hotel_id). The lookup field tells you which one hit.
No match still returns HTTP 200 — check the mapped flag, not the status code. Real errors: unknown provider (400 + the valid_providers list), empty hotel_ids (400), over 100 IDs (400).
API Playground
Test any endpoint interactively without writing a single line of code. Log in to your dashboard and click API Playground in the sidebar.
Open PlaygroundGet Help
Stuck? We're here to help.
- 📧 Support: assist@rpconnect.travel
Our team typically responds within 2 hours during business hours (IST).