Looking for the overview — what this API returns, what it costs, and a call you can run without a key? See the Rappi API page →
E-commerce & Marketplaces

Rappi API & Scraper

The Rappi API turns the public pages of Rappi, Latin America's largest delivery and quick-commerce marketplace, into clean JSON in five actions: restaurant/search, restaurant/detail, store/search, store/detail and cities.

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.

It covers nine storefronts through one country parameter - Colombia, Mexico, Brazil, Argentina, Chile, Peru, Uruguay, Ecuador and Costa Rica - and they are genuinely separate catalogues: on 2026-09-23 all nine answered with their own city, their own restaurants and their own currency, and no two countries shared a meaningful set of store ids. Location is the second axis and it is real, not decorative: restaurant/search takes a city slug, and on 2026-09-23 six Colombian cities returned six disjoint sets of restaurants - Bogota 6,252 restaurants, Medellin 4,739, Barranquilla 4,593, Cali 3,638, Pereira 1,415 and Cartagena 1,276 - with zero shared store ids across all 15 city pairs. Every search row carries the Rappi store id, name, canonical URL, the catalogue rating and its review count, delivery cost, estimated delivery time in minutes, free-shipping flag, promotion text, brand id and open/closed status. restaurant/detail returns the full store record - address, coordinates, rating with the complete 1-to-5 review histogram, schedule, cuisines, offers and currency - plus the COMPLETE menu, grouped into its sections, with every item's price, pre-discount price where one exists, description, availability and image. Menus are not samples: across the 10 Bogota restaurants measured on 2026-09-23 the API returned 742 menu items, from 10 for a small kitchen up to 158 for a cafe. All 742 prices matched the page's own published schema.org menu, and a second, fully independent read found every price in the text the page prints. store/search lists grocery, pharmacy and retail stores by store type, and store/detail returns a store's record plus its product aisles with prices, going deeper through a pages parameter - 60 products at pages=1, 196 at pages=2 and 376 at pages=3 for the store measured. cities returns the city slugs each country actually serves, read from Rappi's own published index: 188 cities across the nine countries on 2026-09-23. No Rappi account needed - one ReefAPI key and the standard { ok, data, meta, error } envelope.

Reference

A Rappi store has two different ratings, and they do not mean the same thing

The single thing to get right before you build anything on Rappi restaurant data. The rating printed on a catalogue listing and the rating on the restaurant's own page are different measurements over different review sets, so the API returns them under different names and never merges them. Measured on 2026-09-23 across 10 Bogota restaurants.

FieldWhere it comes fromHome Burgers, Chapinero
list_rating / list_review_countthe city catalogue listing4.6 from 1,337 reviews
rating / review_countthe restaurant's own record3.4 from 317 reviews
rating_histogramthe restaurant's own record1★ 96, 2★ 16, 3★ 21, 4★ 20, 5★ 164
The two agreed10 restaurants compared0 of 10

The histogram always adds up to review_count, so you can recompute the score yourself. If you need one number for a listing UI use list_rating; if you are judging a restaurant use rating, which is the figure the restaurant's own page shows and the figure its published review summary agrees with.

Live example

Real request and response JSON

Captured from the indexed primary action, restaurant/search, on .

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/rappi/v1/restaurant/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "country": "co",
    "city": "bogota",
    "limit": 10
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "rappi",
    "endpoint": "restaurant/search",
    "mode": "live",
    "latency_ms": 1255.2,
    "record_count": 10,
    "bytes": 649159,
    "cache_hit": false,
    "charged_credits": 3,
    "version": "1.0.0"
  },
  "data": {
    "country": "co",
    "city": {
      "slug": "bogota",
      "name": "Bogotá",
      "lat": 4.676777,
      "lng": -74.056748
    },
    "cuisine": null,
    "restaurants": [
      {
        "country": "co",
        "store_id": 900044812,
        "name": "[redacted-name]",
        "url": "https://www.rappi.com.co/restaurantes/900044812-home-burgers",
        "brand_id": 13,
        "status": "OPEN",
        "is_open": true,
        "next_available_time": null,
        "eta_text": "19 min",
        "eta_minutes": 19,
        "list_rating": 4.6,
        "list_review_count": 1337,
        "delivery_cost": 4500,
        "has_free_shipping": false,
        "promotion_text": "Envío Gratis: Aplican TyC",
        "is_new": false,
        "is_prime_exclusive": false,
        "cuisines": [
          "Hamburguesa",
          "Comida Rápida"
        ],
        "cuisine_ids": [
          372,
          332
        ],
        "logo": "https://images.rappi.com/restaurants_logo/900000899-1111-1572986352241.png",
        "image": "https://images.rappi.com/restaurants_background/homeburgers1-1658872922809.jpg"
      },
      {
        "country": "co",
        "store_id": 13,
        "name": "Kanka Perú",
        "url": "https://www.rappi.com.co/restaurantes/13-kanka-peru",
        "brand_id": 294,
        "status": "OPEN",
        "is_open": true,
        "next_available_time": null,
        "eta_text": "14 min",
        "eta_minutes": 14,
        "list_rating": 4.8,
        "list_review_count": 695,
        "delivery_cost": 4500,
        "has_free_shipping": false,
        "promotion_text": "Envío Gratis: Aplican TyC",
        "is_new": false,
        "is_prime_exclusive": false,
        "cuisines": [
          "Peruana",
          "Internacional"
        ],
        "cuisine_ids": [
          343,
          338
        ],
        "logo": "https://images.rappi.com/restaurants_logo/13-1549390267.png",
        "image": "https://images.rappi.com/restaurants_background/kankaperu-1660672084544.jpg"
      },
      {
        "country": "co",
        "store_id": 121,
        "name": "Empanaditas de Pipian - Empanadas",
        "url": "https://www.rappi.com.co/restaurantes/121-empanaditas-de-pipian-empanadas",
        "brand_id": 667,
        "status": "OPEN",
        "is_open": true,
        "next_available_time": null,
        "eta_text": "24 min",
        "eta_minutes": 24,
        "list_rating": 4.9,
        "list_review_count": 111,
        "delivery_cost": 4500,
        "has_free_shipping": false,
        "promotion_text": "Envío Gratis: Aplican TyC",
        "is_new": false,
        "is_prime_exclusive": false,
        "cuisines": [
          "Empanadas",
          "Típica"
        ],
        "cuisine_ids": [
          363,
          336
        ],
        "logo": "https://images.rappi.com/restaurants_logo/121-1111.png",
        "image": "https://images.rappi.com/restaurants_background/empanaditasdepipian-1661364004384.jpg"
      }
    ],
    "returned": 10,
    "matched": 30,
    "unfiltered": 30,
    "total_in_city": 6377,
    "cuisine_taxonomy": [
      {
        "id": 372,
        "name": "Hamburguesa",
        "slug": "hamburguesa"
      },
      {
        "id": 395,
        "name": "Sushi",
        "slug": "sushi"
      },
      {
        "id": 469,
        "name": "[redacted-name]",
        "slug": "experiencias-foodies"
      }
    ],
    "source_url": "https://www.rappi.com.co/bogota/restaurantes",
    "match_mode": "catalogue"
  }
}
Actions

What the Rappi API does

ActionDescriptionConcrete use caseKey params
restaurant/searchRestaurants deliverable in one city, with that city's own restaurant count and its cuisine taxonomy. Pass `cuisine` to get the site's own complete list for that cuisine.Pricing teams call restaurant/search to get restaurants deliverable in one city, with that city's own restaurant count and its cuisine ta….country, city, cuisine, sort, limit, ...
restaurant/detailOne restaurant's full record and its COMPLETE menu with prices, sections, discounts, rating histogram, schedule and offers.Marketplace operators call restaurant/detail to get one restaurant's full record and its COMPLETE menu with prices, sections, discounts, rating h….country, store_id, url
store/searchGrocery, pharmacy and retail STORES of one store type. This listing is country-wide: Rappi redirects the city form to the country URL (measured), so it is not city-scoped and says so.Catalog enrichment teams call store/search to get grocery, pharmacy and retail STORES of one store type.country, store_type, query, limit, offset
store/detailOne grocery/retail store's record, its aisle directory with each aisle's product count, and its products with prices. `pages` walks deeper into the aisles.Retail analysts call store/detail to get one grocery/retail store's record, its aisle directory with each aisle's product count, and i….country, store_id, pages
citiesThe city slugs one country's storefront actually serves, read from Rappi's own published sitemap. These are the values `city` accepts.Pricing teams call cities to get the city slugs one country's storefront actually serves, read from Rappi's own published sitemap.country
Code samples

Call restaurant/search from your stack

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

Who uses this API and why

  • Track menu prices across a restaurant chain's branches in one city, or the same brand across Bogota, Medellin, Cali and six more countries, using country plus store_id as a stable key.
  • Build a competitive menu-pricing dashboard for a restaurant group: pull the complete menu with sections, prices and discounts, then re-read it on a schedule to see what a rival repriced.
  • Feed a market-entry study with real supply density: the per-city restaurant counts Rappi itself publishes, plus the full cuisine breakdown for each city, across 188 cities in 9 countries.
  • Monitor delivery economics by city - delivery cost, estimated delivery time and free-shipping share across a city's catalogue - to see where a marketplace subsidises delivery.
  • Populate a grocery price comparison for Latin America by reading store product aisles for a specific delivery address, so the prices you store are the ones a shopper at that address is actually quoted.
FAQ

Questions developers ask before integrating

Which countries does it cover, and are they really different catalogues?

Nine: Colombia, Mexico, Brazil, Argentina, Chile, Peru, Uruguay, Ecuador and Costa Rica. They are separate storefronts with separate catalogues and currencies, and the API treats them that way. On 2026-09-23 all nine answered with their own default city - Bogota, Ciudad de Mexico, Grande Sao Paulo, Buenos Aires, Santiago de Chile, Lima, Montevideo, Quito and San Jose - and their own restaurants. One consequence matters for your database: Rappi store ids are namespaced per country, not globally unique, so a low id such as 98 exists in more than one country as a different business. Key your records on country plus store_id, which is exactly how every record the API returns is labelled.

Does the city parameter actually change the results?

Yes, and it is the main reason to use this API rather than a single national scrape. On 2026-09-23 six Colombian cities returned six completely disjoint sets: across all 15 pairs of those cities, zero store ids were shared. The per-city restaurant counts Rappi itself publishes were Bogota 6,252, Medellin 4,739, Barranquilla 4,593, Cali 3,638, Pereira 1,415 and Cartagena 1,276. Each response also carries the city's own name and coordinates. Use the cities action to get the list a country actually serves - 34 for Colombia, 53 for Mexico, 53 for Brazil, 16 for Chile, 10 each for Peru and Ecuador, 9 for Argentina, 2 for Uruguay and 1 for Costa Rica - and a city outside that list returns NOT_FOUND rather than quietly answering with a different city's restaurants.

Do I get the whole menu, or a sample?

The whole menu, grouped into the sections the restaurant uses. Across the 10 Bogota restaurants measured on 2026-09-23 the API returned 742 items in total, ranging from 10 items for a small kitchen to 158 for a cafe, with 6 sections and 49 items for Home Burgers. Every item carries its price, its description, whether it is currently available, whether it has options or toppings to choose, and its image. Where an item is discounted you also get original_price and the discount percent; on that sample 5 of 742 items were discounted, so expect original_price to be null most of the time rather than assuming a promotion is missing.

How do I know the prices are right?

Every restaurant page publishes its own machine-readable menu, and the API checks its parsed prices against it on every call and reports the result in price_cross_check. On 2026-09-23, across 742 menu items from 10 restaurants, every item matched. As a second and fully independent check, 6 of those restaurants were re-read from scratch and all 377 prices the API returned were found in the text the page itself prints. Prices are whole units of the local currency, exactly as the source publishes them - a 146000 in Colombia is 146,000 COP, printed on the page as $ 146.000 - so nothing is divided by 100. The currency is returned per restaurant from the source's own declaration rather than assumed from the country.

Can I filter by cuisine, and does the filter really narrow the results?

Yes. Pass cuisine and you get Rappi's own complete list for that cuisine in that city, not a page of it. Measured in Bogota on 2026-09-23 against an unfiltered city page of 30 rows: hamburguesa returned 58 restaurants, sushi 41, pizza 36, mexicana 32 and postres 131 - and every single returned row carried that cuisine's own id, 131 of 131 for postres and 32 of 32 for mexicana. The full cuisine vocabulary for a city comes back with any unfiltered search as cuisine_taxonomy, 32 cuisines in Bogota. One honest limitation: a cuisine-filtered page does not republish that vocabulary, so on those responses the rows carry cuisine_ids but not cuisine names, and the API tells you which case you are in with cuisine_names_available rather than inventing names.

What about groceries and supermarkets, not just restaurants?

store/search lists stores by store type and store/detail returns a store's record plus its product aisles with prices. In Colombia on 2026-09-23 the market type listed 68 stores and rappimall-parent 1,574. A store's products come back grouped into aisles with each item's price, pre-discount price, sale type and category - for example a convenience store returned 60 priced items across 4 aisles. Two honest limits: the grocery store listing is country-wide rather than city-scoped, and the API reports that as city_scoped false instead of pretending otherwise; and a store type Rappi does not publish returns NOT_FOUND rather than silently answering with the default type.

How many grocery products do I get, and can I get more?

store/detail takes a pages parameter and it genuinely goes deeper. Measured on one Bogota convenience store on 2026-09-23: pages=1 returned 4 aisles and 60 products, pages=2 returned 13 aisles and 196 products, and pages=3 returned 25 aisles and 376 products. The default is 2. Every response also carries aisle_directory, the store's own list of aisles with the number of products Rappi says each one holds - for that store, Bebidas 424, Novedades 505 and Carnes 85 - so you can see what remains beyond the pages you asked for. This is the store's shelf catalogue as Rappi renders it, not a guaranteed complete inventory dump, and the directory is what tells you the difference.

Can I price a grocery store for a specific delivery address?

No, and rather than offer a parameter that does nothing we left it out. We tested it properly: querying one store repeatedly with the same coordinates produced results that differed from each other as much as two different cities did, and coordinates in Madrid, Spain returned a Bogota store's identical shelves. The shelf content rotates between variants on its own and the address does not steer it, so there is no lat/lng parameter on store/detail. The store's own record still carries its real address and coordinates.

What does Rappi not publish, and what will be null?

Individual customer review text - only the aggregate score and the 1-to-5 histogram are published, so there is no reviews list to return. Also absent: per-item stock counts, restaurant phone numbers, and courier tracking. On the 10-restaurant sample all stores carried name, rating, review count, address, coordinates, currency, delivery cost, cuisines, schedule, brand name, logo and image; the review histogram was present on 7 of 10, estimated delivery time on 7 of 10 and offers on 7 of 10. Anything the source does not publish comes back null rather than guessed.

What is the Rappi API?

Rappi API is a ReefAPI endpoint group for latin america's delivery marketplace: restaurants, menus with prices, and grocery stores across 9 countries. It returns live JSON through POST requests under /rappi/v1.

Is the Rappi API free to try?

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

Do I need a Rappi login or account?

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

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

How many credits does the Rappi API use?

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

docs / rappi

Rappi

Latin America's delivery marketplace: restaurants, menus with prices, and grocery stores across 9 countries.

base /rappi/v15 endpoints
post/rappi/v1/restaurant/search3 credits

Restaurants deliverable in one city, with that city's own restaurant count and its cuisine taxonomy. Pass `cuisine` to get the site's own complete list for that cuisine.

ParameterAllowed / rangeDescription
country = corequiredco · mx · br · ar · cl · pe · uy · ec · crRappi storefront. Each country is a separate catalogue and currency.
cityoptionalCity slug, e.g. `bogota`, `medellin`, `sao-paulo`. Omit for the country's default city. Use the `cities` action for the live list.
cuisineoptionalCuisine slug from `cuisine_taxonomy`, e.g. `hamburguesa`, `sushi`, `pizza`. Returns the site's complete list for that cuisine.
sortoptionalrating · eta · delivery_cost · name · reviewsOrder the returned rows.
limit = 30optional1–200Rows to return (1-200).
offset = 0optional0–Rows to skip.
min_ratingoptional0–5Keep rows whose catalogue rating is at least this.
free_delivery_only = falseoptionalKeep only rows Rappi flags as free shipping.
open_now = falseoptionalKeep only rows whose status is OPEN.
max_delivery_costoptional0–Keep rows whose delivery cost is at most this, in the local currency.
Try in playground →
post/rappi/v1/restaurant/detail3 credits

One restaurant's full record and its COMPLETE menu with prices, sections, discounts, rating histogram, schedule and offers.

ParameterAllowed / rangeDescription
country = corequiredco · mx · br · ar · cl · pe · uy · ec · crRappi storefront.
store_idoptionalRappi restaurant id, as returned by restaurant/search. Ids are namespaced per country.
urloptionalA rappi.com restaurant URL instead of store_id.
Try in playground →
post/rappi/v1/store/search3 credits

Grocery, pharmacy and retail STORES of one store type. This listing is country-wide: Rappi redirects the city form to the country URL (measured), so it is not city-scoped and says so.

ParameterAllowed / rangeDescription
country = corequiredco · mx · br · ar · cl · pe · uy · ec · crRappi storefront.
store_type = marketoptionalParent store type slug, e.g. `market`, `rappimall-parent`, `super-farma`, `express`, `turbox`.
queryoptionalKeep only stores whose name contains this (accent-insensitive).
limit = 50optional1–200Rows to return (1-200).
offset = 0optional0–Rows to skip.
Try in playground →
post/rappi/v1/store/detail3 credits

One grocery/retail store's record, its aisle directory with each aisle's product count, and its products with prices. `pages` walks deeper into the aisles.

ParameterAllowed / rangeDescription
country = corequiredco · mx · br · ar · cl · pe · uy · ec · crRappi storefront.
store_idrequiredRappi store id from store/search.
pages = 2optional1–4How many aisle pages to read (1-4). Each page adds more aisles and their products; 1 returns the store's front shelves only.
Try in playground →
post/rappi/v1/citiesfree

The city slugs one country's storefront actually serves, read from Rappi's own published sitemap. These are the values `city` accepts.

ParameterAllowed / rangeDescription
country = corequiredco · mx · br · ar · cl · pe · uy · ec · crRappi storefront.
Try in playground →