<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Catherine Li</title>
    <description>The latest articles on DEV Community by Catherine Li (@catherine_li).</description>
    <link>https://dev.to/catherine_li</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3991525%2F8d5c18a6-4e7a-4c90-bde2-a7314730bd22.jpg</url>
      <title>DEV Community: Catherine Li</title>
      <link>https://dev.to/catherine_li</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/catherine_li"/>
    <language>en</language>
    <item>
      <title>Scrape and Summarize App Reviews from the Apple App Store</title>
      <dc:creator>Catherine Li</dc:creator>
      <pubDate>Fri, 26 Jun 2026 07:02:59 +0000</pubDate>
      <link>https://dev.to/serpapi/scrape-and-summarize-app-reviews-from-the-apple-app-store-5bla</link>
      <guid>https://dev.to/serpapi/scrape-and-summarize-app-reviews-from-the-apple-app-store-5bla</guid>
      <description>&lt;p&gt;AI coding tools have made building a mobile app more accessible than ever, but getting it into the App Store is only half the battle. The real challenge is finding product-market fit before you invest weeks of work and vibe-coding into the wrong idea.&lt;/p&gt;

&lt;p&gt;That usually means hours of manual research: digging through App Store listings, scrolling review after review, trying to spot patterns in what users love, hate, and desperately wish existed. What gaps are worth pursuing? What language are real users actually using to describe their pain points?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe7puuseq7gcqyben7khn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe7puuseq7gcqyben7khn.png" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, I want to show you a way to fetch all the reviews for a mobile app in the Apple App Store with only a few lines of JavaScript code and a couple of API calls to &lt;a href="https://serpapi.com/" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt;. Since it’s JSON data that you can use anywhere, we’ll even pass along the reviews to OpenAI's large language model so we can get a summary of the reviews.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;When building AI-powered applications that rely on recent web data as a review aggregator, you need a reliable data scraping solution. &lt;a href="https://serpapi.com/" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt; leads the market in terms of both reliability and accuracy.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://serpapi.com/blog/scraping-apple-app-store-search-with-python/" rel="noopener noreferrer"&gt;Scraping Apple App Store Search with Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Before we get started, make sure you’ve created a free account on &lt;a href="https://serpapi.com/" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt; so you can get access to 250 free search credits. You may also need to sign up and create a developer account to receive an API key from &lt;a href="https://developers.openai.com/" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frz7k6i3muqppsy8i401l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frz7k6i3muqppsy8i401l.png" width="799" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this demo, we're also going to use OpenAI's latest large language model – gpt5.4 – to summarize our reviews.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up your project
&lt;/h2&gt;

&lt;p&gt;First, set up a basic Node.js project. You can do so by running &lt;code&gt;npm init -y&lt;/code&gt; in your terminal at the root of your project folder. At the root of the project, create an &lt;code&gt;index.js&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install required packages
&lt;/h3&gt;

&lt;p&gt;For this demo, it's highly recommended you install and import into &lt;code&gt;index.js&lt;/code&gt; the following packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dotenv&lt;/code&gt;: &lt;a href="https://www.npmjs.com/package/dotenv" rel="noopener noreferrer"&gt;Node package&lt;/a&gt; that loads environment variables from your &lt;code&gt;.env&lt;/code&gt; file directly into &lt;code&gt;process.env&lt;/code&gt; so you can access your API keys &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;serpapi&lt;/code&gt;: &lt;a href="https://serpapi.com/" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt;'s open-source &lt;a href="https://github.com/serpapi/serpapi-javascript" rel="noopener noreferrer"&gt;JavaScript SDK&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;openai&lt;/code&gt;: &lt;a href="https://developers.openai.com/api/docs" rel="noopener noreferrer"&gt;OpenAI's SDK&lt;/a&gt;to interface with their AI model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As per the OpenAI &lt;a href="https://developers.openai.com/api/docs" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; online, you'll also need to create an instance of the OpenAI client to make the API calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;OpenAI&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;openai&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getJson&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serpapi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;//OpenAI API setup&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openAiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OPEN_AI_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;openAiKey&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;//SerpApi setup&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serpApiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SERP_API_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Making the API call to SerpApi's Apple App Store API
&lt;/h3&gt;

&lt;p&gt;Now, let’s make a call to &lt;a href="https://serpapi.com/" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt; to get the app information, including its ID. We can just use fetch, but since we’ve imported the SDK, we'll use the &lt;code&gt;getJson&lt;/code&gt; from the &lt;a href="https://github.com/serpapi/serpapi-javascript" rel="noopener noreferrer"&gt;SerpApi library&lt;/a&gt;. And just like fetch, &lt;code&gt;getJson&lt;/code&gt; is an asynchronous function that returns a JavaScript Promise. The API has three required parameters: &lt;strong&gt;API key&lt;/strong&gt; , the &lt;strong&gt;search term&lt;/strong&gt; which is the app you want to fetch data for, and the &lt;strong&gt;engine&lt;/strong&gt; which in this case is &lt;code&gt;apple_app_store&lt;/code&gt; since app data is what we want to scrape today.&amp;nbsp;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getJson&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;serpApiKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apple_app_store&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;term&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;instagram&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://serpapi.com/blog/easily-scrape-apple-app-store-and-filter-results-by-categories-for-better-insights/" rel="noopener noreferrer"&gt;Easily scrape Apple App Store and filter results by categories for better insights&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Testing your API calls
&lt;/h2&gt;

&lt;p&gt;If you &lt;code&gt;console.log&lt;/code&gt; app, you should see JSON that resembles this in your terminal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqadmyl798beg3gbads4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqadmyl798beg3gbads4s.png" width="799" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 For the sake of simplicity, we are not implementing validation, error handling or other guardrails that would be highly recommended should you launch this in production&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inside the &lt;code&gt;organic_results&lt;/code&gt; array is where you'll find the search results for the query "instagram". As expected, the first item in this array pertains to the Instagram app owned by Meta. We simply need to pass in the &lt;code&gt;id&lt;/code&gt; value into the second API call, which will be to SerpApi's &lt;a href="https://serpapi.com/apple-reviews" rel="noopener noreferrer"&gt;Apple App Store Reviews API&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;organic_results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;appReviews&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getJson&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;serpApiKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apple_reviews&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;appId&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you &lt;code&gt;console.log(appId)&lt;/code&gt; and scroll down to the &lt;code&gt;reviews&lt;/code&gt; array, you'll see the text of the reviews within the array objects' &lt;code&gt;text&lt;/code&gt; property. Now, we just need to parse out the text reviews and send them to OpenAI to get the summary.&lt;/p&gt;

&lt;h3&gt;
  
  
  Making the API call to OpenAI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-5.4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Given the list of comma-separated reviews for a mobile app, give me a summary of the main criticisms: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;textReviews&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to get response from OpenAI:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above example is a basic API call to OpenAI's &lt;a href="https://developers.openai.com/api/reference/resources/responses" rel="noopener noreferrer"&gt;Responses API&lt;/a&gt; to generate text from a prompt, similar to the way you'd generate text from OpenAI's ChatGPT.&lt;/p&gt;

&lt;p&gt;If everything went according to plan, you should be able to see the summary in your terminal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyicl29h4suivsq6lc893.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyicl29h4suivsq6lc893.png" width="800" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;When running this in your local terminal, don't be alarmed if you don't see any response for a few seconds. As you may know, large language models tend to take some time to generate text. While I'm not doing so in this demo, there's a way to &lt;a href="https://developers.openai.com/api/reference/resources/responses/streaming-events" rel="noopener noreferrer"&gt;stream&lt;/a&gt; the response, which will allow the text to appear chunks at a time so your users are not left waiting until the entire response is complete. Make sure to give streaming a shot if you're building an AI-powered app that relies on timely responses. I hope you've found this post helpful! If you have any questions at all, leave me a comment below or contact us at &lt;a href="mailto:contact@serpapi.com"&gt;contact@serpapi.com&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://serpapi.com/blog/tag/apple-app-store-reviews-scraper-api/" rel="noopener noreferrer"&gt;Apple App Store Reviews Scraper API - SerpApi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Get Google Organic Search Results Instantly with Google Light Fast API</title>
      <dc:creator>Catherine Li</dc:creator>
      <pubDate>Thu, 25 Jun 2026 07:00:52 +0000</pubDate>
      <link>https://dev.to/serpapi/get-google-organic-search-results-instantly-with-google-light-fast-api-46h</link>
      <guid>https://dev.to/serpapi/get-google-organic-search-results-instantly-with-google-light-fast-api-46h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The API documented here has been discontinued because Google now limits the underlying endpoint to only 3 organic results. We recommend using the&amp;nbsp;&lt;/em&gt;&lt;a href="https://serpapi.com/google-light-api" rel="noopener noreferrer"&gt;&lt;em&gt;Google Light API&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&amp;nbsp;as an alternative.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’re a marketer who wants to monitor keyword rankings for your business, or a developer wanting to pull the latest headlines for your news application, you know how much of a pain this can be. Most online tools are costly, bloated and can’t be customized to your problem. Today, we’ll use &lt;a href="https://serpapi.com/google-light-fast-api" rel="noopener noreferrer"&gt;SerpApi’s Google Light Fast API&lt;/a&gt; to easily and quickly scrape Google search results. We’re going to retrieve the data programmatically, &lt;strong&gt;exactly&lt;/strong&gt;  &lt;strong&gt;as it appears&lt;/strong&gt; on Google’s own search results page.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;In this tutorial, we’ll write a simple server-side script that checks how a URL ranks for specific keywords on Google. With &lt;a href="https://serpapi.com/" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt;, you don’t have to worry about the usual web scraping headaches, like updating your code for layout changes, dealing with IP blocks, or fighting CAPTCHAs. Instead, you can focus on building your app. Before we start, make sure you’ve signed up for a free account on &lt;a href="https://serpapi.com/users/sign_up" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites and Project Setup
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Important: This application is for demonstration purposes only. If you want to use it in production, you may wish to add more robust error handling and security features.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This tutorial assumes you have a basic understanding of JavaScript, Node, and npm. If not, no worries. We also have a no-code solution that can be found &lt;a href="https://nocodeserpapi.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Alternatively, you can always come back to this post once you gain familiarity with basic JavaScript and Node. Feel free to jump directly to integrating with SerpApi if you already have a basic Node skeleton project set up.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;To set up a brand new project, create a new folder, navigate to that folder in your terminal and run the following commands:&amp;nbsp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We need to install a few dependencies: &lt;code&gt;dotenv&lt;/code&gt; to access environment variables, and &lt;code&gt;serpapi&lt;/code&gt; for the public JavaScript library.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i serpapi dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, create an &lt;code&gt;index.js&lt;/code&gt; file in your root directory. We also need to store and access the API key that comes with the free SerpApi account. There are several different ways to do this, but for this tutorial let’s create an &lt;code&gt;.env&lt;/code&gt; file and store the key there.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;API_KEY=your_key_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Important: Make sure to keep your API key private and never commit it into version control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Of course, we’ll need to import the libraries we’ve installed at the top of our file before using them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getJson&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;serpapi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we’ll be using ES6 modules in this tutorial, don’t forget to include &lt;code&gt;“type”: "module"&lt;/code&gt; in your &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"type": "module"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Scraping with JavaScript
&lt;/h2&gt;

&lt;p&gt;Let’s imagine you own Starbucks, and you want to check your ranking for a list of popular coffee-related keywords. We’ll need to put those keywords we want to target into an array. We’ll also define the domain we want to be looking for as “starbucks.com”.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;coffee&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iced coffee&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;oat latte&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;best coffee&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;americano&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;latte&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;matcha&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pumpkin spice latte&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;oat milk latte&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;www.starbucks.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All we need to do is call &lt;code&gt;getJson&lt;/code&gt; from the &lt;code&gt;serpapi&lt;/code&gt; library. Note that &lt;a href="https://serpapi.com/integrations/javascript" rel="noopener noreferrer"&gt;getJson is an asynchronous function&lt;/a&gt; with callback and &lt;code&gt;async/await&lt;/code&gt; support. Before calling an array of keywords, let’s try out the API with the first keyword in our array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getJson&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//required&lt;/span&gt;
  &lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google_light_fast&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="c1"&gt;//required&lt;/span&gt;
  &lt;span class="na"&gt;google_domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="c1"&gt;//required&lt;/span&gt;
  &lt;span class="na"&gt;hl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;gl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only required parameters for the Google Light Fast API are &lt;code&gt;api_key&lt;/code&gt;, &lt;code&gt;engine&lt;/code&gt;, and &lt;code&gt;q&lt;/code&gt;. For a full list of supported parameters, take a look at our &lt;a href="https://serpapi.com/google-light-fast-api" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;. Also, if you’d like to experiment more with this API, don’t forget to check out our &lt;a href="https://serpapi.com/playground?engine=google_light_fast" rel="noopener noreferrer"&gt;public playground&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Now let's run this!&lt;/p&gt;

&lt;p&gt;In your terminal, navigate to the root of this project and run:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If everything went well, you should have received a response in your console within a second. The JSON response should resemble something like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "search_metadata": {
    "id": "68d437484c437fdcf83f1897",
    "status": "Success",
    "json_endpoint": "https://serpapi.com/searches/967ec5090d430149/68d437484c437fdcf83f1897.json",
    "created_at": "2025-09-24 18:24:08 UTC",
    "processed_at": "2025-09-24 18:24:08 UTC",
    "google_light_fast_url": "https://www.google.com/search?q=Coffee&amp;amp;hl=en&amp;amp;gl=us&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8",
    "raw_html_file": "https://serpapi.com/searches/967ec5090d430149/68d437484c437fdcf83f1897.html",
    "total_time_taken": 0.97
  },
  "search_parameters": {
    "engine": "google_light_fast",
    "q": "Coffee",
    "google_domain": "google.com",
    "hl": "en",
    "gl": "us"
  },
  "search_information": {
    "organic_results_state": "Results for exact spelling"
  },
  "organic_results": [
    {
      "position": 1,
      "title": "Coffee - Wikipedia",
      "link": "https://en.wikipedia.org/wiki/Coffee",
      "displayed_link": "https://en.wikipedia.org › wiki › Coffee",
      "favicon": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn%3AANd9GcSVMU85vzsP5RTNub9IaAsl7rV0Nyf_xTINCBJZ1nlvBnxTDgf0HU9xmmPaba08IkD_mWLlL8LDthkMoG4tsyqVPp6VYs98tC-e5-E",
      "snippet": "Coffee is a beverage brewed from roasted, ground coffee beans. Darkly colored, bitter, and slightly acidic, coffee has a stimulating effect on humans"
    },
    {
      "position": 2,
      "title": "Starbucks Coffee Company",
      "link": "https://www.starbucks.com/",
      "displayed_link": "https://www.starbucks.com",
      "favicon": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn%3AANd9GcRdvxQfPWiafCxH9HD0XtJerZ5FY7ctOVpxK4U9EldMD3SkXwh5oKlsGSS8A_GBPbNYj4_pdsmKya0-XXSG6XkkpircValazFMJsz9o",
      "snippet": "More than just great coffee. Explore the menu, sign up for Starbucks® Rewards, manage your gift card and more."
    },
    {
      "position": 3,
      "title": "Wonderstate Coffee: Sustainable Coffee Roasters | Specialty ...",
      "link": "https://wonderstate.com/?srsltid=AfmBOopAdGD571-IHoJTulurDRLUKETcgkzQfHKQNZPsH8Qq8eDsXRbw",
      "displayed_link": "https://wonderstate.com",
      "favicon": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn%3AANd9GcRkkAe_Nr9r_KGO8rsBxg32ryD4lN3GUn5mZd4nByuqHpZ5QJQ1gyWDmiLC58xylF0G8jT5n_xxHic0KO6aCNAIe3UrOAZVr79s_w",
      "snippet": "Award-winning, organic coffee roasters in Wisconsin. 100% solar powered. Paying farmers more with a minimum price guarantee that's double the Fair Trade ..."
    },
    {
      "position": 4,
      "title": "r/Coffee - Reddit",
      "link": "https://www.reddit.com/r/Coffee/",
      "displayed_link": "https://www.reddit.com › Coffee",
      "favicon": "https://encrypted-tbn2.gstatic.com/favicon-tbn?q=tbn%3AANd9GcRt_ioW2I2eFmqJJLAWQSl7Fa22pXg9CBflQgcrSYXdMzIwWTa8eHdeZ7OKCeCySe9gqu2bcJ6_Fb4ZlTRQWnx9d5z3ide5sGU7",
      "snippet": "Welcome to the daily · /r/Coffee. question thread! There are no stupid questions here, ask a question and get an answer! We all have to start somewhere and ..."
    },
    {
      "position": 5,
      "title": "Blue Bottle Coffee | Fresh Roasted Specialty Coffee",
      "link": "https://bluebottlecoffee.com/?srsltid=AfmBOopxMGf5ASuuIzlP2zEnsmxVUaUpcVIL_Omb2XXZHLoMZIkDNYdf",
      "displayed_link": "https://bluebottlecoffee.com",
      "favicon": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn%3AANd9GcQrS-d7qjN2SDnT3GkjE7o8RH7JrmSdLttp1UvAcoXpDs02e0_3g--k76_K93BYNdQb3qy6wIyxKfH1OSN6lW7q5kLmD77Q9DCuSs4Hnw7y",
      "snippet": "Blue Bottle Coffee is a specialty coffee roaster with cafes in LA, SF, NYC, &amp;amp; Japan. Shop our freshly roasted specialty coffee online &amp;amp; in-store."
    },
    {
      "position": 6,
      "title": "All Coffee - Verve Coffee Roasters",
      "link": "https://www.vervecoffee.com/collections/all-coffee?srsltid=AfmBOoqWVxbvNcxCo2cb5WPdO_8jZV2YDfbdabwn9OkQnbOQL3sw6hTo",
      "displayed_link": "https://www.vervecoffee.com › collections › all-...",
      "favicon": "https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn%3AANd9GcQzMum2G8lsDS0YSPwMugOHqS0y9zN2MOXtp-QvDxJCqt9YeGdiZxUqkXmm0ta4_uG17l8u-HeDmVGkS0r2UksQOBS8Dt_9VLkqua0UNnk",
      "snippet": "Verve Coffee Roasters - Sermon - So easy to wake up to - Sweet, deep, &amp;amp; soulful - Medium Roast blend - Notes: Blueberry Pie, Cocoa, Candied Pecan"
    },
    {
      "position": 7,
      "title": "Buy Coffee, Tea, Powders Online | The Coffee Bean &amp;amp; Tea ...",
      "link": "https://www.coffeebean.com/",
      "displayed_link": "https://www.coffeebean.com",
      "favicon": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn%3AANd9GcRc9wUBGZNChw_o9jALpdvp8DpUvmKJZBHoi6SjSbIAMxC3dKUta8lOmLQ93yAlgjciko0OlyYYnqxxYe3-er5G0jEMEGv8zpbOXPaZkA",
      "snippet": "Buy exceptional coffee, tea, powders, equipment and drinkware at The Coffee Bean &amp;amp; Tea Leaf® online store to enjoy our globally sourced products at home."
    },
    {
      "position": 8,
      "title": "Coffee - The Nutrition Source",
      "link": "https://nutritionsource.hsph.harvard.edu/food-features/coffee/",
      "displayed_link": "https://nutritionsource.hsph.harvard.edu › coffee",
      "favicon": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn%3AANd9GcRobWpRagBKXMoDcfSN3X_img5d8Nq67TuwrAktRwrYtmdaP9mlboWwArcZiFjXnk8ebAjJTKbCjn9UliNZx9AZUMSxGoDrNKyi90c1AaIjO-4Dt8GOYJLeO1yy",
      "snippet": "A plain “black” cup of coffee is a very low calorie drink—8 ounces only contains 2 calories! However, adding sugar, cream, and milk can quickly bump up the ..."
    },
    {
      "position": 9,
      "title": "Black Rifle Coffee | Home | Veteran Founded",
      "link": "https://www.blackriflecoffee.com/?srsltid=AfmBOooqbrXMU1TgC5NfJI3S2N6OArBNRVxOQ0vn2ULhC_pDPuDCIOKh",
      "displayed_link": "https://www.blackriflecoffee.com",
      "favicon": "https://encrypted-tbn1.gstatic.com/favicon-tbn?q=tbn%3AANd9GcSQ0KPBZYN-E6_-TG395r9g5fduhEk-a1UgURz6gvCdO6_GfUaDSIJLD0ry6J8cxdeATqVju60LM3tsH6fiMPNFxVRiJvWfYd3CX3leJEHkU9Q5vw",
      "snippet": "Veteran-founded Black Rifle Coffee Company delivers premium small-batch coffee, gear, and unapologetic American values. Join the mission, fuel your day."
    },
    {
      "position": 10,
      "title": "Caribou Coffee® | Life Is Short. Stay Awake For It®",
      "link": "https://www.cariboucoffee.com/?srsltid=AfmBOopdVML0bJqbgvRe1RZV9qnofeFKw9oep5TWl_izz84n7_GMualB",
      "displayed_link": "https://www.cariboucoffee.com",
      "favicon": "https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn%3AANd9GcRjjXlKFqUKDV8Z3T69L4YTdEL4lvE5SRtpTzdLjSAMvTDNEyJIgfeF7qemE3qaNhLBzA_lmcQ7ZUIoL-QapePqpBCttfqTcmJGU7iENd48sw",
      "snippet": "Caribou Coffee® is more than a premium coffeehouse featuring high-quality, handcrafted beverages and food. Explore our menu, sign up for Caribou Coffee® ..."
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;organic_results&lt;/code&gt; array stores the list of unpaid listings on Google’s results page and excludes paid ads, which are marked as “Sponsored”. The values in this array corresponds to the links you see on Google's search results page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpd9ty838lbxztqokd59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqpd9ty838lbxztqokd59.png" width="800" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore, the values in &lt;code&gt;organic_results&lt;/code&gt; is what we will look at to find out in which position starbucks.com ranks for each of the keywords. As you can see, the Starbucks domain is the second search result on the page for the keyword “coffee”.&lt;/p&gt;

&lt;p&gt;By default, the API will return the first ten search results which reflects what is displayed on the first page of Google's search results. For keyword rankings, oftentimes we'll need to pull search results beyond the first page. Due to &lt;a href="https://serpapi.com/blog/google-experiments-with-restricting-results-per-page/" rel="noopener noreferrer"&gt;recent changes&lt;/a&gt; in the number of results served by Google in a single search, many web scraping services on the market are unable to retrieve more than 10 results at a time. This is the case currently with our &lt;a href="https://serpapi.com/google-light-api" rel="noopener noreferrer"&gt;Google Light Search API&lt;/a&gt;, so you'd need to make 10 separate API calls if you wanted 100 results. However, with the new &lt;a href="https://serpapi.com/google-light-fast-api" rel="noopener noreferrer"&gt;Light Fast API&lt;/a&gt;, all you need to do is assign the &lt;code&gt;num&lt;/code&gt; parameter to &lt;code&gt;100&lt;/code&gt; in our request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getJson&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//required&lt;/span&gt;
    &lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google_light_fast&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//required&lt;/span&gt;
    &lt;span class="na"&gt;google_domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="c1"&gt;//required &lt;/span&gt;
    &lt;span class="na"&gt;gl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As of now, SerpApi's &lt;a href="https://serpapi.com/google-light-fast-api" rel="noopener noreferrer"&gt;Light Fast API&lt;/a&gt; is the only web scraping API on the market that lets you retrieve 100 results at a time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://serpapi.com/blog/solution-to-scrape-100-search-results-on-google-google-fast-light-api/" rel="noopener noreferrer"&gt;Solution to scrape 100 Search Results on Google - Google Fast Light API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting the Keyword Ranking
&lt;/h2&gt;

&lt;p&gt;We’ll write a helper function to find the ranking for starbucks.com within the organic search results. This function returns the first index of the search result whose displayed_link contains starbucks.com, and it will be called for each of our specified keywords.&amp;nbsp;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getRanking&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;organic_results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;displayed_link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;N/A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we have an array of keywords we want to check for and not just one, what we need to do now is call this API in a loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;keywords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyword&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;getJson&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google_light_fast&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;google_domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;keyword&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="c1"&gt;//required &lt;/span&gt;
        &lt;span class="na"&gt;gl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;us&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;responses&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once all the API calls for the keywords are complete, we can then check for the ranking of starbucks.com for each of the results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keywords.forEach&lt;span class="o"&gt;((&lt;/span&gt;keyword, i&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;The ranking &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;keyword&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; is: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;getRanking&lt;/span&gt;&lt;span class="p"&gt;(json[i])&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all went well, you should see something like this:&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr48ke1nvakyvvie5s3v6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr48ke1nvakyvvie5s3v6.png" width="780" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means that, with the given parameters, a link to starbucks.com appears as the second search result on Google if the term “coffee” is used to search. Of course, your exact results may be different since search results change frequently.&amp;nbsp;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://serpapi.com/blog/tracking-google-search-rankings-and-exporting-to-a-csv-file-with-node-js/" rel="noopener noreferrer"&gt;Track Google Search Rankings and Export to a .CSV file with Node.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the final version of this script, feel free to clone this &lt;a href="https://github.com/serpapi/tutorials/tree/master/keywordRanking" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;. If you wanted to build on top of this, you could also add a feature to export the data into a csv. SerpApi makes it effortless to integrate up-to-date, relevant Google search results into your application. This month, we’ve boosted free plans from &lt;strong&gt;100 to 250 credits&lt;/strong&gt;. Make sure to give it a try by signing up for a free account and experimenting in our&lt;a href="https://serpapi.com/playground" rel="noopener noreferrer"&gt;public playground&lt;/a&gt;. If you have any questions, don't hesitate to contact us at &lt;a href="mailto:contact@serpapi.com"&gt;SerpApi Contact&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
