Reputation & Reviews

How do you scrape Yelp businesses via API without getting blocked?

Call ReefAPI's yelp search action with a term and a location and read businesses with an encrypted id, rating, review count, categories and neighbourhoods back as JSON, then business/reviews for the reviews plus the ones Yelp filtered out. That second set is the reason to use Yelp data at all.

Yelp engineLive JSON5 steps1,000 free credits

This guide demonstrates the real Yelp API engine with a captured response from . The example is only published because the engine passed the SEO snapshot gate.

Use case

Local-business intelligence, reputation monitoring, lead generation and market research.

Step by step

Call the live endpoint

  1. 1

    Search by term and location

    Both are required. price (as a list of levels), min_rating and attributes narrow it, and the response echoes the offset and limit it used.

  2. 2

    Key on enc_biz_id

    It is the encrypted business id and it is stable. The slug is not - Yelp appends disambiguating suffixes when businesses collide.

  3. 3

    Pull reviews with the not-recommended set

    not_recommended_reviews and not_recommended_count are what Yelp leaves out of the star rating. For reputation work that is the half that matters.

  4. 4

    Check the histogram against claimed_review_count

    Ours summed to exactly 64. A mismatch means a truncated fetch, and it costs nothing to assert.

  5. 5

    Weight by reviewer, not just by star

    is_elite, friend_count and review_count come on every reviewer. A five-star review from a one-review account and one from a Yelp Elite are not the same evidence.

Code

Copy the request

These snippets use the captured request params for yelp/v1/search.

curl -X POST https://api.reefapi.com/yelp/v1/search \
  -H "x-api-key: $REEF_KEY" \
  -H "content-type: application/json" \
  -d '{"term":"Pizza","location":"San Francisco, CA","limit":10}'
MCP one-liner
Ask your MCP-connected assistant: call reefapi.yelp.search with {"term":"Pizza","location":"San Francisco, CA","limit":10}.
Real response

Captured output from ReefAPI

Captured on UTC. The response below is the committed snapshot, including the API envelope and metadata.

Captured request
{
  "method": "POST",
  "url": "https://api.reefapi.com/yelp/v1/search",
  "headers": {
    "x-api-key": "$REEF_KEY",
    "content-type": "application/json"
  },
  "body": {
    "term": "Pizza",
    "location": "San Francisco, CA",
    "limit": 10
  }
}
Captured response
{
  "ok": true,
  "meta": {
    "api": "yelp",
    "endpoint": "search",
    "mode": "live",
    "latency_ms": 2854.3,
    "record_count": 10,
    "bytes": 0,
    "cache_hit": false,
    "limit": 10,
    "offset": 0,
    "sort_by": "recommended"
  },
  "data": {
    "results": [
      {
        "enc_biz_id": "mSMZJj2pFvttWLpcDmgrEA",
        "name": "Tony's Pizza Napoletana",
        "slug": "tonys-pizza-napoletana-san-francisco",
        "url": "https://www.yelp.com/biz/tonys-pizza-napoletana-san-francisco",
        "rating": 4.2,
        "review_count": 9007,
        "price": "$$",
        "price_level": 2,
        "categories": [
          "Pizza",
          "Italian",
          "Cocktail Bars"
        ],
        "address": "1570 Stockton St",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/ptCPOJoqVokZW7GmQ5F4NQ/1000s.jpg"
      },
      {
        "enc_biz_id": "074WalqFJbISNhaOsuuhxg",
        "name": "Golden Boy Pizza",
        "slug": "golden-boy-pizza-san-francisco-5",
        "url": "https://www.yelp.com/biz/golden-boy-pizza-san-francisco-5",
        "rating": 4.3,
        "review_count": 298,
        "price": "$",
        "price_level": 1,
        "categories": [
          "Pizza"
        ],
        "address": "1447 Taraval St",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/AIHgzb-LDw8YdWdlUidPpw/1000s.jpg"
      },
      {
        "enc_biz_id": "rq8j3j3yZCkySv7fFQfqRg",
        "name": "Rose Pizzeria",
        "slug": "rose-pizzeria-san-francisco",
        "url": "https://www.yelp.com/biz/rose-pizzeria-san-francisco",
        "rating": 4,
        "review_count": 109,
        "price": "$$",
        "price_level": 2,
        "categories": [
          "Pizza"
        ],
        "address": "1 Clement St",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/-7vNhhcePR5ixi3WHJSdhw/1000s.jpg"
      },
      {
        "enc_biz_id": "75UY4SkdvuhJ-nZTKdVaMw",
        "name": "Outta Sight Pizza",
        "slug": "outta-sight-pizza-san-francisco",
        "url": "https://www.yelp.com/biz/outta-sight-pizza-san-francisco",
        "rating": 4.6,
        "review_count": 501,
        "price": "$",
        "price_level": 1,
        "categories": [
          "Pizza"
        ],
        "address": "422 Larkin St",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/TeU1odn80ePjzta_igJ6VQ/1000s.jpg"
      },
      {
        "enc_biz_id": "snTlXOecPHN_BN3Jkd6PZw",
        "name": "Outta Sight Pizza",
        "slug": "outta-sight-pizza-san-francisco-2",
        "url": "https://www.yelp.com/biz/outta-sight-pizza-san-francisco-2",
        "rating": 4.4,
        "review_count": 223,
        "price": "$",
        "price_level": 1,
        "categories": [
          "Pizza"
        ],
        "address": "643 Clay St",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/onn2cei0qv5oJrpm7vsWVQ/1000s.jpg"
      },
      {
        "enc_biz_id": "PTFxtXS47ZVRCdZIrEWvGw",
        "name": "Golden Boy Pizza",
        "slug": "golden-boy-pizza-san-francisco",
        "url": "https://www.yelp.com/biz/golden-boy-pizza-san-francisco",
        "rating": 4.3,
        "review_count": 4870,
        "price": "$",
        "price_level": 1,
        "categories": [
          "Pizza",
          "Italian"
        ],
        "address": "542 Green St",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/LzMZYAathPmoqKgXfx2iOg/1000s.jpg"
      },
      {
        "enc_biz_id": "bX9oEDq6qvQuuf6sxbfwVw",
        "name": "Pizzetta Napoletana",
        "slug": "pizzetta-napoletana-san-francisco",
        "url": "https://www.yelp.com/biz/pizzetta-napoletana-san-francisco",
        "rating": 4.3,
        "review_count": 325,
        "price": "$$",
        "price_level": 2,
        "categories": [
          "Pizza"
        ],
        "address": "775 Frederick St",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/wCoiYXOMnuUI2LB1naoLWQ/1000s.jpg"
      },
      {
        "enc_biz_id": "xDwEMq8kgT0eQepn90Jkvg",
        "name": "Arizmendi Bakery",
        "slug": "arizmendi-bakery-san-francisco",
        "url": "https://www.yelp.com/biz/arizmendi-bakery-san-francisco",
        "rating": 4.5,
        "review_count": 2428,
        "price": "$",
        "price_level": 1,
        "categories": [
          "Bakeries",
          "Pizza"
        ],
        "address": "1331 9th Ave",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/KWuT-JyKAOFl4E-ZVVMYnQ/1000s.jpg"
      },
      {
        "enc_biz_id": "IxDRIBkKtP-f24sr5zHAhQ",
        "name": "Pink Onion",
        "slug": "pink-onion-san-francisco",
        "url": "https://www.yelp.com/biz/pink-onion-san-francisco",
        "rating": 4.5,
        "review_count": 1436,
        "price": "$$",
        "price_level": 2,
        "categories": [
          "Pizza",
          "Italian",
          "Gastropubs"
        ],
        "address": "64 14th St",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/8GtQUJi_GHlrng88Mv9TOQ/1000s.jpg"
      },
      {
        "enc_biz_id": "o43B4DnnQbvkdDK6AVafQg",
        "name": "Piccolo Forno",
        "slug": "piccolo-forno-san-francisco",
        "url": "https://www.yelp.com/biz/piccolo-forno-san-francisco",
        "rating": 4.6,
        "review_count": 1209,
        "price": "$$",
        "price_level": 2,
        "categories": [
          "Pizza",
          "Italian"
        ],
        "address": "725 Columbus Ave",
        "city": "San Francisco",
        "state": null,
        "neighborhoods": [],
        "image": "https://s3-media0.fl.yelpcdn.com/bphoto/Ehg7g3gZb7gsSQ-5Ycab5Q/1000s.jpg"
      }
    ],
    "term": "Pizza",
    "location": "San Francisco, CA"
  }
}
Manual way

Why this is hard manually

Yelp's public rating is not computed over every review it holds. Reviews the recommendation software distrusts are moved to a separate 'not currently recommended' page, excluded from the star average, and effectively invisible unless you go looking. Any reputation analysis that reads only the visible reviews is reading a curated set, and for a business fighting a review-filtering problem the hidden set is the entire story.

The second thing that catches people is identity. Yelp's business key is an encrypted string ('JvSfQXeBKYQQpHMxF6sSww'), not a numeric id and not the URL slug. The slug changes when a business moves or Yelp disambiguates it - note the '-2' on 'bollywood-pizza-san-francisco-2' - so a pipeline keyed on the slug will lose history the first time that happens.

The third is that the search card is thinner than it looks. Across our ten 'Pizza in San Francisco' results, price and price_level were populated on seven, image on four, and rating on nine. Nothing failed; Yelp simply does not put every field on every card.

ReefAPI way

Why ReefAPI solves it

business/reviews returns two arrays and two counts, which is what makes the filtered-review question answerable. reviews holds the visible ones, not_recommended_reviews holds the ones Yelp excluded, not_recommended_count reports how many exist, and every review carries is_not_recommended so the two sets stay distinguishable after you merge them. Our test business had 0 not-recommended reviews - a clean profile - and knowing that is itself a finding.

The rating histogram is an integrity check you get for free. It came back as {5: 51, 4: 9, 3: 0, 2: 1, 1: 3}, summing to exactly 64, which matched claimed_review_count. scraped_review_count was 20 and completeness_pct 31.2 - the ratio between what you asked for and what exists. If the histogram ever stops summing to the claimed count, something truncated mid-fetch.

Reviewer credibility comes pre-attached, which is unusual. Each reviewer carries friend_count, review_count, photo_count, is_elite and elite_year. Yelp Elite status is awarded by Yelp and is the closest thing to a verified-reviewer signal on any consumer review site - weighting sentiment by it produces a very different picture from a flat average.

reactions is a map and useful_count is not its total. One review returned reactions {HELPFUL: 1, THANKS: 0, LOVE_THIS: 2, OH_NO: 0} with useful_count 1 - only the HELPFUL bucket feeds the visible 'useful' figure. Sum the map if you want total engagement; read useful_count if you want the number Yelp displays.

One limitation to know before you design around it: the amenities array on business/details returns twenty attribute names with value null on all twenty. It tells you which attributes Yelp tracks for that category - BusinessAcceptsCreditCards, WheelchairAccessible, OutdoorSeating, DogsAllowed - not whether the business has them, and the same concepts appear twice under two naming conventions. It is a taxonomy, not an answer set, and we would rather say so than let you ship a filter built on it.

Nine actions share the engine, and several cover ground no general place API does: menus and popular_dishes return the actual food and what people order, review_highlights returns Yelp's extracted phrases, business/photos returns images with captions, and business/url-to-id turns a Yelp URL you already have into the encrypted id without a search. Search answered in about 4.2 seconds, details in 3.4, reviews in 8.5.

FAQ

Questions developers ask

Do I need a Yelp Fusion API key?

No. You send a ReefAPI key. There is no Yelp developer account, no Fusion key and no daily call allowance to manage.

What are not-recommended reviews?

Reviews Yelp's software distrusts. They are excluded from the public star rating and kept on a separate page. business/reviews returns them in not_recommended_reviews with a not_recommended_count, and every review carries is_not_recommended. Our test business had none, which is a clean signal in itself.

Why is price null on some search results?

Because Yelp does not put it on every card. Across our ten results price and price_level were populated on seven and image on four. Call business/details for the ones you care about.

Should I key on the slug or the id?

The id. enc_biz_id ('JvSfQXeBKYQQpHMxF6sSww') is stable; slugs get disambiguating suffixes like '-2' when businesses collide or move. business/url-to-id converts a URL you already have.

The amenities all have null values. Is that a bug?

It is a limitation and we are being explicit about it: the array names the twenty attributes Yelp tracks for that category and does not report whether the business has them. Do not build an amenity filter on it.

Why does reactions show more than useful_count?

Because only the HELPFUL bucket feeds Yelp's visible 'useful' number. One of our reviews had LOVE_THIS 2 and HELPFUL 1, and useful_count read 1. Sum the map for total engagement.

How do I judge whether a five-star review means anything?

Read the reviewer block. is_elite, elite_year, friend_count, review_count and photo_count all come attached. Yelp Elite is awarded by Yelp and is the strongest reviewer-credibility signal available on any consumer review platform.