Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the Zomato API page →
Reputation & Reviews

Zomato API & Scraper

The Zomato API turns zomato.com, India's restaurant discovery and food-delivery marketplace, into clean JSON in five actions.

5 actionsLive JSON1,000 free credits$0.67–$1.50 / 1,000 creditsMCP-ready
Get a free keyOpen in playground

🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.

search takes a city slug such as ncr, mumbai or bangalore and returns restaurant rows with the numeric res_id, the name, the Zomato URL, the locality and full address, the cuisines, the cost for two as both the printed text and a rupee number, the image, and an is_promoted flag on every row. It can be narrowed to one cuisine, one locality, one curated collection, or to the restaurants that deliver. restaurant/detail returns one full record by id: street address, latitude and longitude, city and postcode, the business phone numbers the page prints, cuisines, opening hours day by day, cost for two, popular dishes, what people say the place is known for, facility highlights such as full bar or outdoor seating, and the photographed menu pages. restaurant/menu returns the dish catalogue — every menu, its categories and the dishes in them with name, description and veg or vegan tags. restaurant/reviews returns review text with the star rating, how old the review is, the like and comment counts, and the reviewer name and profile link as the public page prints them. locations/search turns a place name into the localities Zomato knows, with coordinates, which is how you find the locality value the search action takes. Zomato rates a restaurant twice, once for dining and once for delivery, and the two often disagree: a venue measured in this build scored 3.9 for dining across 6,851 reviews and 3.1 for delivery across 21. This API therefore returns rating_dining, rating_dining_count, rating_delivery and rating_delivery_count as four separate fields and deliberately publishes no single field called rating, because no honest single value exists. What the source does not publish, this API does not invent: dish prices are not shown to a signed-out reader, so price_inr comes back null on every dish with prices_published false rather than a guessed number. No Zomato account, one ReefAPI key and the standard { ok, data, meta, error } envelope.

Reference

The two ratings, and the four fields that keep them apart

Zomato scores the same restaurant twice — once by people who ate in, once by people who ordered delivery — and it shows them as two separate badges. The two numbers regularly disagree, and a restaurant can be excellent on one and poor on the other. This API never blends them. Every search row and every detail record carries all four fields below, and any of them can be null when the restaurant has no rating of that kind yet.

FieldWhat it isHow often it was filled
rating_diningThe dine-in star rating, 1 to 5.8 of 8 restaurants in the detail sample
rating_dining_countHow many dining reviews that score is based on.8 of 8
rating_deliveryThe delivery star rating, 1 to 5. Null when the restaurant does not deliver.4 of 8 — only half the sample delivered
rating_delivery_countHow many delivery reviews that score is based on.8 of 8
rating_count_approximateTrue when Zomato published only a rounded count such as 11.8K instead of an exact figure.Set per record; detail returns the exact count where the source publishes one

Checked against the structured data Zomato itself publishes on each restaurant page, on 12 restaurants drawn from four listing surfaces across three cities: name, dining rating, dining review count, cost for two and street address all matched on 12 of 12. An id taken from search resolved to the same record in detail on 12 of 12.

Live example

Real request and response JSON

Captured from the indexed primary action, search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/zomato/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "city": "ncr"
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "zomato",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 1995.6,
    "record_count": 9,
    "bytes": 151181,
    "cache_hit": false,
    "upstream_requests": 1,
    "stop_reason": "source_page_limit",
    "promoted_count": 9,
    "dropped_tiles": 1,
    "charged_credits": 2,
    "version": "1.0.0"
  },
  "data": {
    "restaurants": [
      {
        "res_id": 311057,
        "name": "[redacted-name]",
        "url": "https://www.zomato.com/ncr/my-bar-headquarters-connaught-place-new-delhi",
        "slug": "/ncr/my-bar-headquarters-connaught-place-new-delhi",
        "rating_dining": 3.9,
        "rating_dining_count": 6861,
        "rating_delivery": 3.1,
        "rating_delivery_count": 21,
        "rating_count_approximate": false,
        "price_for_two_text": "₹3,000 for two",
        "price_for_two_inr": 3000,
        "price_for_one_text": "₹1,200 for one",
        "locality": "Connaught Place, New Delhi",
        "address": "N-49, SF, CP, Chankya Puri, Connaught Place, New Delhi",
        "cuisines": [
          "North Indian",
          "Chinese",
          "Pizza"
        ],
        "distance": "1.1 km",
        "timing": "Opens at 11am",
        "image": "https://b.zmtcdn.com/data/pictures/7/311057/15ecea5e19d35b31311d398fcb1436f0_featured_v2.jpg",
        "is_promoted": true,
        "is_disabled": false
      },
      {
        "res_id": 20863533,
        "name": "Cé La Vie Kitchen & Bar",
        "url": "https://www.zomato.com/ncr/cé-la-vie-kitchen-bar-connaught-place-new-delhi",
        "slug": "/ncr/cé-la-vie-kitchen-bar-connaught-place-new-delhi",
        "rating_dining": 4.3,
        "rating_dining_count": 11800,
        "rating_delivery": null,
        "rating_delivery_count": 0,
        "rating_count_approximate": true,
        "price_for_two_text": "₹3,300 for two",
        "price_for_two_inr": 3300,
        "price_for_one_text": "₹1,350 for one",
        "locality": "Connaught Place, New Delhi",
        "address": "H-11, Ground Floor, Connaught Circle, Block H, Connaught Place, New Delhi",
        "cuisines": [
          "North Indian",
          "Mediterranean",
          "Continental"
        ],
        "distance": "1.4 km",
        "timing": "Opens at 12noon",
        "image": "https://b.zmtcdn.com/data/pictures/3/20863533/3ad7a12bd1f6fbf993708a3a8498369f_featured_v2.jpg",
        "is_promoted": true,
        "is_disabled": false
      },
      {
        "res_id": 307060,
        "name": "[redacted-name]",
        "url": "https://www.zomato.com/ncr/the-beer-cafe-2-connaught-place-new-delhi",
        "slug": "/ncr/the-beer-cafe-2-connaught-place-new-delhi",
        "rating_dining": 4.3,
        "rating_dining_count": 4517,
        "rating_delivery": 3.8,
        "rating_delivery_count": 151,
        "rating_count_approximate": false,
        "price_for_two_text": "₹1,800 for two",
        "price_for_two_inr": 1800,
        "price_for_one_text": "₹750 for one",
        "locality": "Connaught Place, New Delhi",
        "address": "D-2, Inner Circle, Radial Road 5, Connaught Place, New Delhi",
        "cuisines": [
          "Beverages"
        ],
        "distance": "1.4 km",
        "timing": "Opens at 11am",
        "image": "https://b.zmtcdn.com/data/pictures/0/307060/a6b42b0877b66a39e11afd5c9cfa1ce5_featured_v2.jpg",
        "is_promoted": true,
        "is_disabled": false
      }
    ],
    "count": 9,
    "promoted_count": 9,
    "organic_count": 0,
    "dropped_tiles": 1,
    "source_total_results": 25602,
    "city": "ncr",
    "mode": "dining",
    "listing_url": "https://www.zomato.com/ncr/restaurants",
    "heading": "Restaurants in Delhi NCR",
    "stop_reason": "source_page_limit"
  }
}
Actions

What the Zomato API does

ActionDescriptionConcrete use caseKey params
searchList a city's restaurants, optionally narrowed to one cuisine, locality or curated collection, or to the restaurants that deliver. Returns up to 9 rows — that is the source's own ceiling per listing and it does not page, so breadth comes from varying city/cuisine/locality/collection rather than from a page number. Every row carries `is_promoted`, because on a plain city listing all 9 rows are paid placements.Support teams call search to list a city's restaurants, optionally narrowed to one cuisine, locality or curated collection….city, cuisine, locality, collection, mode
restaurant/detailOne full restaurant record by id: address and coordinates, city and postcode, the business phone numbers the page prints, cuisines, opening hours per day, cost-for-two, popular dishes, facility highlights, and the dining and delivery ratings as separate named fields.Reputation platforms call restaurant/detail to get one full restaurant record by id.res_id
restaurant/menuThe restaurant's dish catalogue: every menu, its categories and the dishes in them with name, description and veg/vegan tags. 🔴 Dish PRICES are not returned, because Zomato does not publish them to a logged-out reader — the page sets its own `price_login_blocker` flag and the dish records carry no price key at all (verified from four different exits, including one inside India). `price_inr` is therefore null on every dish and `prices_published` is false, rather than a guessed number.Market researchers call restaurant/menu to get the restaurant's dish catalogue.res_id
restaurant/reviewsReview text for one restaurant, newest first, 5 per page. Returns at most 25 reviews: page 6 is where Zomato answers 'Please login', measured identically on three restaurants. Each review carries its text, star rating, age, like and comment counts, and the reviewer name and profile link exactly as the public page prints them.B2B review analysts call restaurant/reviews to get review text for one restaurant, newest first, 5 per page.res_id, max_pages
locations/searchTurn a place name into the localities Zomato knows, with coordinates — the lookup that tells you what to pass as `locality`.Support teams call locations/search to turn a place name into the localities Zomato knows, with coordinates.query
Code samples

Call search from your stack

curl -X POST https://api.reefapi.com/zomato/v1/search \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"city":"ncr"}'
MCP one-liner
Ask your MCP-connected assistant: call reefapi.zomato.search with {"city":"ncr"}.
Use cases

Who uses this API and why

  • Restaurant discovery apps list a city by cuisine or locality and read is_promoted on every row, so paid placements can be dropped before anything reaches a user.
  • Location intelligence and delivery-market teams pull address, locality, postcode, latitude and longitude per restaurant and compare cuisine mix across cities, which differ completely: the eight cities measured shared no restaurants at all.
  • Rating trackers store rating_dining and rating_delivery as two separate series, which is the only way to see a kitchen that is strong for dine-in and weak on delivery.
  • Menu and dish research reads the full dish catalogue with veg and vegan tags per item to answer what a city's restaurants actually cook, without needing prices.
  • Review monitoring reads up to 25 of the newest reviews per restaurant with text, star rating, review age and the reviewer as the page prints them.
FAQ

Questions developers ask before integrating

Why is there no field called rating?

Because Zomato publishes two ratings for the same restaurant and they disagree. One venue measured in this build scored 3.9 for dining from 6,851 reviews and 3.1 for delivery from 21. Any single blended number would be wrong for one of those two audiences, so this API returns rating_dining, rating_dining_count, rating_delivery and rating_delivery_count and lets you choose. rating_delivery is null when a restaurant does not deliver, which was the case for half the detail sample.

Can I get dish prices from the menu?

No, and the API says so rather than guessing. Zomato does not show dish prices to a signed-out reader: the dish records carry no price at all and the page itself sets a flag saying prices are held back until you sign in. Across 1,690 dishes read from 13 restaurants, not one carried a price. So restaurant/menu returns price_inr as null on every dish, sets prices_published to false and includes a price_note explaining it. What you do get is the complete catalogue: every menu, its categories, and each dish with its name, its description and its veg or vegan tags — 36 to 365 dishes per restaurant in the sample. The restaurant's own cost-for-two figure is separate and is returned in full, as both printed text and a rupee number.

How many restaurants does one search return, and can I page through a whole city?

One search returns up to 9 restaurants, and it does not page. That is the source's own ceiling, not a setting: eight different paging approaches were tested against the same listing and every one returned the identical nine restaurants. The count you see in source_total_results is how many restaurants match in that city — 25,603 in Delhi NCR — not how many you can retrieve. Coverage comes from breadth instead of depth: vary the city, the cuisine, the locality and the collection, and each combination returns its own nine. Each response tells you what happened in stop_reason.

How many reviews can I read per restaurant?

Up to 25, the newest first. Zomato serves five pages of five reviews to a signed-out reader and asks for a login after that, measured identically on three different restaurants. The response carries reviews_truncated so you know more exist, and source_number_of_pages, which is Zomato's own page count for a signed-in reader and will be much larger. Each review comes with its text, its star rating, whether it is a dining or a delivery review, its age, the like and comment counts, and the reviewer name and profile link exactly as the public page prints them.

Are the search results ordered, or are some of them ads?

Some of them are ads, and the API flags them. On a plain city listing every one of the nine rows was a paid placement in every city measured. Curated collections were the opposite — a collection listing returned nine rows with no paid placements at all — and delivery listings were mixed at six of nine. Every row carries is_promoted, and each response carries promoted_count and organic_count so you can filter before displaying. Promotional banner tiles that sit inside the grid have no restaurant behind them; they are removed and counted in dropped_tiles.

Which cities can I search, and do they really differ?

Pass the city slug Zomato uses in its own URLs: ncr for Delhi NCR, plus mumbai, bangalore, hyderabad, chennai, kolkata, pune, jaipur and the rest. The cities are genuinely separate inventories, not one list filtered: the eight cities measured returned 6,260 to 25,603 matching restaurants each, and all 28 pairwise comparisons of their results shared zero restaurants. If you are not sure what to pass for a neighbourhood, locations/search turns a place name into the localities Zomato knows, with coordinates.

What is the cost for two, exactly?

It is Zomato's own estimate of what two people spend, and it comes back both ways: price_for_two_text as the site prints it, and price_for_two_inr as a plain rupee number you can sort on. It is an estimate of a typical bill, not a menu price, and for a bar it can be calculated on drinks. The detail record also returns cost_notes, the full list of cost lines the page shows, because a second line is often a different thing entirely such as the price of a pint rather than a meal. It matched the figure Zomato publishes in its own page data on 12 of 12 restaurants checked.

Does every restaurant have a menu I can read?

Most do. In a 16 restaurant sample, 13 returned a dish catalogue and 3 did not; all eight taken from delivery listings had one. The three without a catalogue are dine-in only venues that never took online orders, and for those the API returns a clear not-found rather than an empty list. Those restaurants usually still have a photographed menu, and restaurant/detail lists those menu images under image_menus with a label and page count.

What is the Zomato API?

Zomato API is a ReefAPI endpoint group for india's restaurant guide: search a city by cuisine, locality or collection, with dining and delivery ratings kept as separate numbers, plus dish catalogues and review text. It returns live JSON through POST requests under /zomato/v1.

Is the Zomato API free to try?

Yes. ReefAPI starts with 1,000 free credits, no card required. Zomato calls use the same shared credit balance as every other ReefAPI engine.

Do I need a Zomato login or account?

No login to Zomato 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 Zomato data?

The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.

How many credits does the Zomato API use?

Zomato actions currently cost 1-3 credits per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.

Can I call Zomato from an AI assistant or MCP client?

Yes. Connect ReefAPI once through MCP and your assistant can call zomato actions with the same key, credit pool and JSON envelope used by normal REST requests.

docs / zomato

Zomato

India's restaurant guide: search a city by cuisine, locality or collection, with dining and delivery ratings kept as separate numbers, plus dish catalogues and review text.

base /zomato/v15 endpoints
post/zomato/v1/restaurant/detail2 credits

One full restaurant record by id: address and coordinates, city and postcode, the business phone numbers the page prints, cuisines, opening hours per day, cost-for-two, popular dishes, facility highlights, and the dining and delivery ratings as separate named fields.

ParameterAllowed / rangeDescription
res_idrequiredThe numeric Zomato restaurant id, as `search` returns it in `res_id`. A zomato.com URL containing the id is also accepted.
Try in playground →
post/zomato/v1/restaurant/menu3 credits

The restaurant's dish catalogue: every menu, its categories and the dishes in them with name, description and veg/vegan tags. 🔴 Dish PRICES are not returned, because Zomato does not publish them to a logged-out reader — the page sets its own `price_login_blocker` flag and the dish records carry no price key at all (verified from four different exits, including one inside India). `price_inr` is therefore null on every dish and `prices_published` is false, rather than a guessed number.

ParameterAllowed / rangeDescription
res_idrequiredThe numeric Zomato restaurant id, as `search` returns it in `res_id`. A zomato.com URL containing the id is also accepted.
Try in playground →
post/zomato/v1/restaurant/reviews3 credits

Review text for one restaurant, newest first, 5 per page. Returns at most 25 reviews: page 6 is where Zomato answers 'Please login', measured identically on three restaurants. Each review carries its text, star rating, age, like and comment counts, and the reviewer name and profile link exactly as the public page prints them.

ParameterAllowed / rangeDescription
res_idrequiredThe numeric Zomato restaurant id, as `search` returns it in `res_id`. A zomato.com URL containing the id is also accepted.
max_pages = 5optional1–5How many review pages to walk, 5 reviews each. Capped at 5 because page 6 is where Zomato returns 'Please login' — measured identically on three restaurants, so 25 reviews is the logged-out ceiling.
Try in playground →
post/zomato/v1/locations/search1 credit

Turn a place name into the localities Zomato knows, with coordinates — the lookup that tells you what to pass as `locality`.

ParameterAllowed / rangeDescription
queryrequiredA place name to resolve — a neighbourhood, a landmark or a city.
Try in playground →