Agoda hotel records and guest reviews, thousands deep
The Agoda API returns hotel and destination data as clean JSON.
4 active endpoints. Every call is 1 credit.
- POST/agoda/v1/destinations
- POST/agoda/v1/city_browse
- POST/agoda/v1/detail
- POST/agoda/v1/reviews
What Agoda endpoints does ReefAPI ship?
4 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Agoda API
3 of 4 endpoints, ready to run
A city's popular hotels as a starting list — around a hundred properties with their Agoda links, plus the theme and travel-guide links that sit beside them.
{ "ok": true, "meta": { "api": "agoda", "endpoint": "city_browse", "mode": "live", "latency_ms": 622, "record_count": 100, "cache_hit": false }, "data": { "hotels": [ { "name": "The Berkeley Hotel Pratunam", "url": "https://www.agoda.com/the-berkeley-hotel-pratunam/hotel/bangkok-th.html" }, { "name": "Solitaire Bangkok Sukhumvit 11 by Kingston Hotels", "url": "https://www.agoda.com/solitaire-bangkok-sukhumvit-11/hotel/bangkok-th.html" }, { "name": "Bangkok Marriott Hotel The Surawongse", "url": "https://www.agoda.com/bangkok-marriott-hotel-the-surawongse/hotel/bangkok-th.html" } ], "theme_links": [ { "name": "Best Apartments in Bangkok", "url": "https://www.agoda.com/theme/apartments/city/bangkok-th.html" }, { "name": "Best Hostels in Bangkok", "url": "https://www.agoda.com/theme/hostels/city/bangkok-th.html" }, { "name": "Best Guest Houses in Bangkok, Thailand", "url": "https://www.agoda.com/theme/guest-house/city/bangkok-th.html" } ], "travel_guides": [ { "name": "Discover 10 Quirky Bangkok Things to Do That Will Make You Smile", "url": "https://www.agoda.com/travel-guides/thailand/bangkok/discover-10-quirky-bangkok-things-to-do-that-will-make-you-smile/" }, { "name": "Capture Chatuchak: Your Guide to Weekend Market Photos", "url": "https://www.agoda.com/travel-guides/thailand/bangkok/capture-chatuchak-your-guide-to-weekend-market-photos/" }, { "name": "Swim with the Fishes: Bangkok Ocean World Tickets Guide", "url": "https://www.agoda.com/travel-guides/thailand/bangkok/swim-with-the-fishes-bangkok-ocean-world-tickets-guide/" } ], "place_of_interest": "Things to Do in Bangkok" } }
How the Agoda API works
Agoda is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 185 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
Place to city id, city to hotel, hotel to its record and its reviews
Agoda's whole id space is one integer per hotel and one per city, and three calls get you from a place name to the reviews. Measured against Bangkok while writing this.
{"query": "Bangkok"}Seven matches — the city, two districts, two airport areas — each with a city_id, a country_id and the source's own property count. Bangkok is 9395 and holds 12,048 properties. Deduplicate before you show a picker: the city row came back twice, identical in every field, and the area rows repeat the whole city's property count rather than their own.
{"city_id": 9395}A hundred popular hotels with their Agoda URLs, in one second. Name and link only on this action, which is what makes it fast.
{"url": "<a URL from the browse list>"}The full record, and the numeric hotel_id you need next. Bangkok Marriott The Surawongse resolved to 3014254.
{"hotel_id": 3014254, "page": 1}Fifty reviews in half a second, with meta reporting 3,593 total across 52 pages. Page 2 returned seventy more with zero overlap; keep going until a page comes back empty.
A hotel's complete public record and as many of its reviews as you want to pay for, keyed on an id you can store and re-fetch forever.
curl -X POST https://api.reefapi.com/agoda/v1/city_browse \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"city_id":9395}'{
"ok": true,
"data": { … },
"meta": {
"api": "agoda",
"endpoint": "city_browse",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}Agoda ids, scales and formats, and the one thing this engine does not return
The most common wrong assumption here is that a hotel API quotes prices. This one does not: no action accepts a check-in date, a night count, an occupancy or a currency, and no price, tax or total appeared in any response. What it does return is the static property record and the review corpus. Measured 2026-08-27 on hotel 294217, The Okura Prestige Bangkok with 11,382 reviews, and hotel 461790, The Berkeley Hotel Pratunam.
| Thing | Format | Measured value |
|---|---|---|
| hotel_id | Integer, taken directly or extracted from an Agoda /hotel/ URL passed as url | 294217 resolved to The Okura Prestige Bangkok; the Berkeley URL resolved to 461790 |
| city_id | Integer from the destinations action, required by city_browse | Bangkok 9395, Paris France 15470, Paris Texas 20936, Paris Tennessee 20935 |
| object_type_id | Integer type tag on each destinations suggestion | 5 = city, 6 = airport, 14 = area, 15 = point of interest |
| star_rating | Float on a 0 to 5 scale, the official property class | 5.0 for both hotels tested |
| Review rating and summary.overall_score | Float on a 0 to 10 scale with one decimal, not out of 5 | Individual reviews returned 10.0 and 9.6, and 2.0 and 3.2 when sorted rating_low; the hotel's overall_score was 9.2 |
| total_reviews vs total_comments | Two different counts in the same summary block | 11,382 reviews against 4,899 comments for hotel 294217 |
| nearby_places.distance | Kilometres from the property, as a float | Siam Paragon is 1.47 from the Okura and 0.87 from the Berkeley, with identical landmark coordinates in both |
| Review date formats | Two formats inside one record | date "July 23, 2026", owner_reply_date "2026/07/28 07:49:47", and a separate stay_month "July 2026" |
| Reviews per page | Up to 70, and meta.total_pages is derived from total_reviews divided by 70 | Page 2 returned 70 rows, page 1 sorted newest returned only 50, total_pages 163 |
| Nightly price, tax, total | Not returned by any action | No price field appeared in destinations, city_browse, detail or reviews |
policies is passed through in Agoda's own camelCase (childPolicies, extrabedPolicies, policyNotes, extraBedAge) while the rest of the response is snake_case. faq[].category is a raw key such as property_faq_location_landmark rather than a label.
How deep the reviews go, what the record holds, and the two things it does not
Measured on 2026-08-28 against two Bangkok hotels with 96,537 and 3,593 reviews. Three of these lines go against us.
Against us, and the first thing to know. Not one of the four actions accepts a check-in date or an occupancy, and not one field in any response carries a nightly rate. This reads Agoda's hotel RECORD and its review history, not its booking board. If you need a price for a date, that is the Booking or Airbnb engine next door; if you need the property's facts and what guests said, this is the deeper of the two.
Fifty rows on page one, seventy on page two, zero ids in common between them, and meta reporting 52 pages and 3,593 reviews for that hotel. Pages past the declared end return an empty list under ok:true rather than repeating the tail — asking for page 52, 53 and 60 each returned nothing. So the end announces itself honestly, and a loop that stops on an empty page terminates.
Against us. Across nine review calls, three returned zero records with an explicit error naming its own contradiction — 'hotel has 96537 reviews but the page returned 0'. Every one of those cleared on a plain retry seconds later with no change of parameters. Treat that error as retryable, because it is; the engine is telling you it does not believe its own empty result either.
On fifty rows the fields that matter were filled on all fifty: the ten-point score and its label, a title, the review body, the review date, the stay month, the reviewer's country and country code, the traveller type, the room type and the length of stay. Three fields are structurally empty rather than sometimes missing, and knowing which is the difference between a working parser and a silent one: positive_text and negative_text were empty on all one hundred rows across two hotels — the source stores one body of text and the whole review is in the text field — and helpful_votes was zero on all fifty. photo_count was non-zero on three rows of fifty, and the owner's reply was present on forty-nine of fifty at one hotel and twenty-six of fifty at the other. The summary beside the rows splits total reviews from total written comments — 96,537 against 44,638 on the larger hotel — and the second number is the one you want if you are counting text.
One call returned a 23,000-character description, seventy-eight facilities across eleven named groups, the child and extra-bed policy blocks, twenty ranked nearby places each with a name, a distance in kilometres and coordinates, and an eight-question FAQ. None of it depends on a date, so it can be cached for a long time and refreshed on your own schedule rather than the source's.
Against us. The property's own latitude and longitude are not in the address block — only the nearby landmarks carry coordinates, so geocode from those or from the search side. And the FAQ ships with the source's own unfilled template markers still in it: all eight entries on the property we opened contained [hotel_name] somewhere, reading 'Is there a laundry service at [hotel_name]?'. Substitute the name field yourself before showing an FAQ answer to a human.
city_browse returned a hundred hotels for Bangkok in one second, each with a name and an Agoda URL, plus the property-type theme links, the travel guides and the points of interest that sit around them. There is no rating and no price on those rows by design — it is a discovery list you feed into detail, which is why it is the fastest action here.
The destinations action resolves free text into cities, areas, airports and landmarks, and every suggestion carries a hotel_count taken from the source: 12,048 for the city of Bangkok, 6,243 for the Sukhumvit area, 1,547 for the central district. That is a coverage answer you can check before you spend a call.
Public hotel records and public guest reviews, in whatever locale you ask for. A review carries the reviewer's country and traveller type. Not a price, not availability, not a booking, and nothing that needs an Agoda partner or affiliate account — the identity you send is a ReefAPI key and nothing else.
What people build with Agoda
The jobs this data is most often used for.
endpoints
credit per call
Travel apps call destinations then city_browse to show hotels for a place.
Price monitors use detail to track a property's rates.
Reputation tools use reviews to track guest sentiment.
What Agoda data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 185 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/agoda/v1/city_browse \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"city_id":9395}'import requests
r = requests.post(
"https://api.reefapi.com/agoda/v1/city_browse",
headers={"x-api-key": REEF_KEY},
json={
"city_id": 9395
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up Agoda.
Get a free key →Can I get a nightly rate, taxes or a total for specific dates?▾
No. None of the four actions accepts a check-in date, a check-out date, a night count, an occupancy or a currency, and no price, tax or total field came back from destinations, city_browse, detail or reviews. This engine returns the property record and the review corpus, so the question of whether a rate includes tax does not arise. Use it for hotel attributes, locations and guest sentiment, not for shopping rates.
Are review ratings out of 5 or out of 10?▾
Out of 10, with one decimal place, and so is the hotel's overall score. Hotel 294217 returned individual ratings of 10.0 and 9.6 on the newest page, 2.0 and 3.2 when sorted rating_low, and summary.overall_score 9.2. Do not halve them into stars, because star_rating on the detail action is a separate field that genuinely is out of 5. Mixing the two scales is the most common error against this data.
Why are positive_text and negative_text always empty?▾
Because the reviews we measured all came from Agoda's own form, which stores one body of text rather than a pros and cons split. All 70 rows on page 2 of hotel 294217 returned provider "Agoda", an empty positive_text, an empty negative_text and the full comment in text. Read text, and treat the split fields as optional extras that appear only when the source review had them.
Why does the property FAQ say [hotel_name] instead of the hotel name?▾
Agoda templates those entries and does not always fill the token in. All 11 FAQ entries for hotel 461790 contained [hotel_name] somewhere, and the substitution is inconsistent inside a single entry: the question read "What dining options are offered at [hotel_name]?" while its answer began "The Berkeley Hotel Pratunam has a variety of restaurant and dining options". Substitute hotel.name yourself before displaying anything from faq[].
How do I go from a city name to hotel ids?▾
Three steps, and the middle one is thinner than it looks. destinations resolves "Bangkok" to city_id 9395; city_browse on that id returns exactly 100 popular hotels plus 36 theme links and the city's travel guides; but each hotel row is only a name and an Agoda URL, with no hotel_id. Pass that URL to the detail action as url and it extracts the id for you, which is how the Berkeley URL resolved to 461790.
Why is the first destinations result duplicated?▾
The city match is emitted twice. "Bangkok" returned seven suggestions whose first two rows were identical (object_id 9395, type city, hotel_count 12048), and "Paris" did the same with object_id 15470. Deduplicate on object_id plus object_type_id before you show a picker. Note too that hotel_count on an area row repeats the whole city's number: both Bangkok area rows carried 12048, the same value as the city itself.
Which Paris am I searching?▾
Check city_id and country_id, because the query is ambiguous and Agoda returns all of them. "Paris" returned city_id 15470 with country_id 153 and 14,318 hotels for the French one, city_id 20936 with country_id 181 and 379 hotels for Paris, Texas, and city_id 20935 for Paris, Tennessee. Airports come back in the same list, with Charles de Gaulle as object_id 639999 and Orly as 80243, both pointing at city_id 15470.
What does rating_text "Review score" mean?▾
It is a placeholder Agoda serves when it has no adjective for a low score. Sorting hotel 294217 by rating_low, the 70 returned rows carried only three distinct rating_text values: "Good", "Very good" and "Review score". The numeric rating on those rows is still correct, so bucket the number yourself rather than trusting the label. traveler_type is more dependable, returning Solo traveler, Couple, Group, Business traveler, Family with young children and Family with teens.
What is the Agoda API?▾
Agoda API is a ReefAPI endpoint group for agoda It returns live JSON through POST requests under /agoda/v1.
Is the Agoda API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. Agoda calls use the same shared credit balance as every other ReefAPI engine.
Do I need an Agoda login or account?▾
No login to Agoda is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Agoda data?▾
The page example is captured from a live destinations call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Agoda API use?▾
Agoda actions currently cost 1 credit per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Agoda from an AI assistant or MCP client?▾
Yes. Connect ReefAPI once through MCP and your assistant can call agoda actions with the same key, credit pool and JSON envelope used by normal REST requests.
8 Travel & Lodging APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Agoda, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 184 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-28.