Hotel Rates โ Direct OTA
Return the exact per-room-type price a real guest sees on an OTA's own site โ for Agoda, Booking.com and MakeMyTrip โ normalized into a single schema so you can compare them field-for-field. Like the other scrapers, this is an async job: submit, receive a job_id, poll for the result.
Base URL: https://gumo.co.in ยท Auth: X-API-Key: gsk_โฆ (same key as Google Hotels; the key needs the matching ota:<name> scope) ยท See the Overview.
Submit a job
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
ota | string | Optional | agoda | agoda, booking, makemytrip. Aliases: booking.com โ booking, mmt / makemytrip.com โ makemytrip. |
hotel_name | string | Required | โ | โค 300 chars. Resolved to the OTA's own property id. |
city | string | Required | โ | โค 200 chars. |
check_in | date | Required | โ | YYYY-MM-DD; not past, โค 1 year. |
check_out | date | Required | โ | After check_in; โค 30 nights. |
adults | int | Optional | 2 | 1โ10. Total party size across all rooms, not per room. |
rooms | int | Optional | 1 | 1โ8. Must be โค adults (at least one adult per room). |
currency | string | Optional | INR | 3-letter ISO. Support varies by OTA โ see per-OTA notes. Unsupported codes are rejected with a 400. |
children field returns a 400 telling you to remove it (use the Google Hotels scraper for child-inclusive pricing).curl -X POST https://gumo.co.in/api/v1/scraper/ota-price/ \
-H "X-API-Key: gsk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"ota": "agoda",
"hotel_name": "The Taj Mahal Palace, Mumbai",
"city": "Mumbai",
"check_in": "2026-09-15",
"check_out": "2026-09-17",
"adults": 2,
"rooms": 1,
"currency": "INR"
}'
{
"job_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "pending",
"ota": "agoda",
"poll_url": "/api/v1/scraper/ota-price/a1b2c3d4-e5f6-7890-abcd-ef1234567890/"
}
Poll for results
Poll the poll_url every ~2 seconds until status is completed or failed. Statuses: pending โ processing โ completed | failed. Google Hotels job IDs 404 here (and OTA job IDs 404 on the Google poll endpoint) โ each scraper polls its own jobs.
Response schema
The poll response is a job envelope: id, status, ota, hotel_name, city, check_in, check_out, adults, rooms, currency, result, error_message, created_at, started_at, completed_at, duration_seconds, bandwidth_kb. On completion, result holds the pricing object, which nests HotelRoomPricing โ room_types[] โ offers[], identical across all three OTAs.
{
"id": "a1b2c3d4-...", "status": "completed", "error_message": "",
"result": {
"ota": "agoda",
"hotel_name": "The Taj Mahal Palace, Mumbai",
"hotel_id": "16082488",
"currency": "INR",
"check_in": "2026-09-15", "check_out": "2026-09-17",
"adults": 2, "rooms": 1,
"nights": 2, "adults_per_room": 2, "price_scope": "per_room",
"occupancy_honored": true,
"cheapest_fitting_price": 22500.0, "cheapest_fitting_basis": "per_night_before_taxes",
"source": "http", "scraped_at": "2026-09-01T12:00:00+00:00",
"sold_out": false, "error": null, "truncated": false,
"room_types": [
{
"name": "Luxury Room Palace Wing", "sold_out": false,
"room_size": "45 mยฒ", "bed": "1 king bed", "view": "City view",
"amenities": ["Free WiFi", "Parking"], "images": ["https://..."],
"tags": ["free-cancellation", "king-bed"], "room_id": "991243155",
"room_size_sqm": 45.0, "max_guests": 3,
"offers": [
{
"price": 22500.0, "currency": "INR", "price_text": "โน 22,500",
"price_basis": "per_night_before_taxes", "price_before_discount": null,
"board": "Breakfast included", "free_cancellation": true,
"cancellation_text": "Cancel for free before Sep 13, 2026",
"refundable": true, "occupancy": 2,
"occupancy_source": "priced", "fits_occupancy": true,
"badges": ["Lowest price available!"], "rate_token": "8b:0;c:2D1N_100P;..."
}
]
}
]
}
}
Object fields
| Object | Fields |
|---|---|
HotelRoomPricing | ota, hotel_name, hotel_id, currency, check_in, check_out, room_types[], adults, rooms, nights, adults_per_room, price_scope ("per_room"), occupancy_honored, cheapest_fitting_price, cheapest_fitting_basis, source ("http"|"browser"), scraped_at, sold_out, error, truncated |
RoomType | name, offers[], sold_out, room_size, room_size_sqm, max_guests, bed, view, description, amenities[], images[], tags[], room_id |
RoomOffer | price, currency, price_text, price_basis, price_before_discount, board, free_cancellation, cancellation_text, refundable, occupancy, occupancy_source ("priced"|"capacity"), fits_occupancy, badges[], rate_token, raw_label |
price_basis, not raw price. price_basis is a per-offer field with values per_night_before_taxes, per_night, total_stay_before_taxes, total_stay or unknown. MakeMyTrip is always per_night_before_taxes; Agoda is usually per_night_before_taxes (derived from Agoda's own price label); Booking.com returns total_stay or total_stay_before_taxes. Always read price_basis before comparing across OTAs โ or use the pre-computed cheapest_fitting_price + cheapest_fitting_basis.Result outcomes
Submitting can 4xx (validation 400, auth 401, missing scope 403, throttling 429). Once a job is accepted, polling always returns HTTP 200 โ you distinguish scrape outcomes by fields, never by status code:
| Outcome | How to detect |
|---|---|
| Priced | status: "completed", result.error: null, result.room_types populated. |
| Sold out | status: "completed", result.sold_out: true, result.room_types: [], result.error: null โ resolved but no availability. |
| Failure | status: "failed" with a human-readable error_message; result.error carries the same string (e.g. "unresolved (no match for name+city)", "proxy quota (407): ...") with result.room_types: []. |
A scrape failure is never a 4xx/5xx on the poll โ it is a failed job with an explanation.
Agoda
Set "ota": "agoda". Resolved and fetched over pure HTTP. Requires the ota:agoda key scope.
- Currencies:
INR, USD, GBP, EUR, AED. - Price basis: usually
per_night_before_taxes, derived per offer from Agoda's own price label โ always read the field. - Full room grid with room size, bed, view, amenities and per-offer cancellation terms.
Booking.com
Set "ota": "booking" (alias booking.com). Requires the ota:booking key scope.
- Currencies:
INR, USD, GBP, EUR, AED. - Price basis:
total_stayortotal_stay_before_taxes(depending on whether Booking shows a taxes-and-charges line) โ the total for the whole stay, not per-night. Normalize before comparing with Agoda/MMT.
ota:booking scope you get 403 {"detail": "This API key does not have the 'ota:booking' scope."}; if the scraper is switched off platform-wide you get 400 {"error": "ota 'booking' is not currently enabled"}. Contact us to enable it.MakeMyTrip (MMT)
Set "ota": "makemytrip" (aliases mmt, makemytrip.com). Requires the ota:makemytrip key scope.
- Currency:
INRonly โ other codes are rejected rather than mislabeled. - Price basis:
per_night_before_taxes. - Distinguishes genuine no-availability (returns
sold_out: true) from property errors.
Back to: Overview ยท Google Hotels ยท Google Flights