<?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: SerpApi.Org</title>
    <description>The latest articles on DEV Community by SerpApi.Org (@serpapiorg).</description>
    <link>https://dev.to/serpapiorg</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%2F2109705%2F47d319df-6491-498e-b9b7-b6072856803e.png</url>
      <title>DEV Community: SerpApi.Org</title>
      <link>https://dev.to/serpapiorg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/serpapiorg"/>
    <language>en</language>
    <item>
      <title>How to fix google search api daily limit exceeded error</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Wed, 12 Aug 2026 01:58:24 +0000</pubDate>
      <link>https://dev.to/serpapiorg/how-to-fix-google-search-api-daily-limit-exceeded-error-n00</link>
      <guid>https://dev.to/serpapiorg/how-to-fix-google-search-api-daily-limit-exceeded-error-n00</guid>
      <description>&lt;p&gt;As a backend developer, few things are as frustrating as having a production data pipeline suddenly halt because of API quota limits. During a recent audit of our internal SEO tool stack, we faced sudden downtime. I quickly learned that resolving these blocks isn't just about throwing money at Google Cloud Platform (GCP); it requires a systematic approach to debugging rate limits, optimizing queries, and implementing fallback layers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Diagnose the Error Payload
&lt;/h3&gt;

&lt;p&gt;First, identify whether you are hitting a temporary rate limit or a hard daily cap. Developers often misdiagnose 429 rate limits as daily exhaustion, leading to unnecessary upgrade cycles.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;rateLimitExceeded&lt;/code&gt; (HTTP 429):&lt;/strong&gt; A short-term safety mechanism (e.g., exceeding 100 requests per 100 seconds). This resolves automatically after a 15-minute cool-down window.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;dailyLimitExceeded&lt;/code&gt; (HTTP 403):&lt;/strong&gt; You’ve exhausted your project's daily allocation. The default free tier is strictly limited (usually 100 queries/day for standard Custom Search API). This quota resets exactly at &lt;strong&gt;midnight Pacific Standard Time (PST)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Implement Code-Level Optimizations
&lt;/h3&gt;

&lt;p&gt;Before requesting higher quotas, optimize your request structure to maximize the value of every single call.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Implement Redis Caching
&lt;/h4&gt;

&lt;p&gt;In my applications, I cache identical search queries for 12 to 24 hours. Serving cached JSON payloads to users instead of hitting live endpoints can cut API request volume by up to 70%.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Avoid Double-Dimension Filtering
&lt;/h4&gt;

&lt;p&gt;Grouping or filtering by both page and query string simultaneously is highly resource-intensive. Instead, fetch page-level metrics first, and then target high-priority URLs for query-level details.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Exponential Backoff with Jitter
&lt;/h4&gt;

&lt;p&gt;To handle temporary &lt;code&gt;429 Too Many Requests&lt;/code&gt; errors, configure your HTTP client to pause and retry using exponential backoff with randomized delay jitter. This prevents a "thundering herd" problem where multiple worker threads retry concurrently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_backoff_delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;base_delay&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="c1"&gt;# Calculate exponential delay with randomized jitter
&lt;/span&gt;    &lt;span class="n"&gt;jitter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uniform&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="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_delay&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;attempt&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;jitter&lt;/span&gt;

&lt;span class="c1"&gt;# Usage inside a retry loop
# time.sleep(get_backoff_delay(attempt_number))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Scale via GCP Console
&lt;/h3&gt;

&lt;p&gt;If optimizations aren't enough, navigate to &lt;strong&gt;IAM &amp;amp; Admin &amp;gt; Quotas&lt;/strong&gt; in your Google Cloud Console.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Enable Billing:&lt;/strong&gt; Simply linking a valid credit card can instantly lift standard sandbox constraints, shifting you from developer limits to enterprise-ready quotas.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Request an Increase:&lt;/strong&gt; Submit a manual quota increase request. &lt;strong&gt;Pro tip:&lt;/strong&gt; Explicitly mention in your request justification that you have already implemented client-side caching and backoff logic. This shows Google's review team that your system is highly optimized, speeding up the approval process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Outsource the Complexity to SerpApi
&lt;/h3&gt;

&lt;p&gt;When your data pipeline scales past 50,000 queries daily, managing proxies, IP rotations, and GCP enterprise pricing plans becomes a complex infrastructure burden. &lt;/p&gt;

&lt;p&gt;In my high-scale projects, I transition to &lt;a href="https://serpapi.com" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt;. It handles all proxy management, CAPTCHA bypasses, and Google/Bing search scraping on its end. This allows developers to fetch clean, structured JSON feeds using a single API key, bypassing strict native Google Search API limits entirely.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/how-to-fix-google-search-api-daily-limit-exceeded-error" rel="noopener noreferrer"&gt;How to fix google search api daily limit exceeded error&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to get a free Bing search API key without getting billed</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Tue, 11 Aug 2026 12:47:16 +0000</pubDate>
      <link>https://dev.to/serpapiorg/how-to-get-a-free-bing-search-api-key-without-getting-billed-n06</link>
      <guid>https://dev.to/serpapiorg/how-to-get-a-free-bing-search-api-key-without-getting-billed-n06</guid>
      <description>&lt;p&gt;After a decade of integrating search functionality into various projects, I have seen too many developers fall into the trap of accidental cloud overspending. A single misclick in the Azure portal can transform a simple hobby project into an unexpected monthly invoice. If you are looking to tap into Microsoft’s search infrastructure without risking your wallet, there is a reliable way to do it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The F0 Tier Explained
&lt;/h3&gt;

&lt;p&gt;Microsoft offers an entry-level tier for their search services that allows up to 1,000 requests per month at zero cost. This is the "gold standard" for students, hobbyists, and developers building initial prototypes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Catch:&lt;/strong&gt; You must provide a credit card during registration to verify your identity.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Safety Net:&lt;/strong&gt; By explicitly selecting the &lt;strong&gt;F0 (Free)&lt;/strong&gt; pricing tier during the resource creation process, you create a hard sandbox. If you exceed your quota, the API will simply return error codes (403 or 429) rather than charging your card.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Strategic Setup to Prevent Costs
&lt;/h3&gt;

&lt;p&gt;To ensure your development environment remains strictly non-billable, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Register a Personal Account:&lt;/strong&gt; Avoid using corporate or university-managed emails, as strict SSO policies can block resource creation. Use a standard personal Microsoft account.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Select the Right Resource:&lt;/strong&gt; In the Azure marketplace, search specifically for "Bing Search." &lt;strong&gt;Do not&lt;/strong&gt; choose the "Azure AI Services" multi-service resource, as it often bundles features that might incur costs outside the free tier.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Deploy Locally:&lt;/strong&gt; Within the resource creation flow, ensure the "Pricing tier" dropdown is set to &lt;strong&gt;F0&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Set a Budget Guardrail:&lt;/strong&gt; Navigate to the &lt;strong&gt;Cost Management + Billing&lt;/strong&gt; section in your dashboard. Set a monthly budget alert for $0.01. Even if you don’t plan to spend a dime, this acts as an automated notification system if an auxiliary service accidentally spins up.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Defensive Development Practices
&lt;/h3&gt;

&lt;p&gt;Never commit your API keys to version control. I have seen countless developers expose their credentials via public GitHub repositories, leading to automated bots exhausting their monthly quota in minutes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Environment Variables:&lt;/strong&gt; Store your key locally in a &lt;code&gt;.env&lt;/code&gt; file or as a system environment variable.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Request Throttling:&lt;/strong&gt; The F0 tier is limited to 3 transactions per second (TPS). I recommend adding a &lt;code&gt;time.sleep(0.5)&lt;/code&gt; or similar delay between your calls during testing to avoid hitting this limit.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Credential Rotation:&lt;/strong&gt; If you suspect your key has been compromised, do not delete the entire resource. Simply regenerate the secondary key in the "Keys and Endpoint" panel and update your code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scaling Beyond the Limit
&lt;/h3&gt;

&lt;p&gt;If your application grows and you need to move beyond 1,000 requests per month, you will find that Azure's paid tiers can become complex and expensive. At that stage, I often recommend switching to specialized providers like &lt;strong&gt;SerpApi&lt;/strong&gt;. They offer a more developer-centric experience, predictable pricing, and none of the administrative overhead associated with managing cloud enterprise portals.&lt;/p&gt;

&lt;p&gt;By maintaining strict control over your resource selection and keeping your credentials outside your codebase, you can experiment with powerful search data while keeping your development costs at absolute zero.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/how-to-get-a-free-bing-search-api-key-without-getting-billed" rel="noopener noreferrer"&gt;How to get a free Bing search API key without getting billed&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Serpapi vs ValueSERP vs Scale SERP: 2026 comparison</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Tue, 11 Aug 2026 03:57:16 +0000</pubDate>
      <link>https://dev.to/serpapiorg/serpapi-vs-valueserp-vs-scale-serp-2026-comparison-4a0j</link>
      <guid>https://dev.to/serpapiorg/serpapi-vs-valueserp-vs-scale-serp-2026-comparison-4a0j</guid>
      <description>&lt;p&gt;As a developer who has spent the last decade building data pipelines, I’ve seen many teams fall into the same trap: defaulting to the most popular API and watching their monthly costs explode once they scale beyond 100,000 queries. Choosing the right extraction partner isn't just about parsing JSON; it’s about balancing latency, rate-limiting, and, most importantly, your bottom line.&lt;/p&gt;

&lt;p&gt;In this breakdown, I’m comparing three major players—SerpApi, ValueSERP, and Scale SERP—to help you optimize your stack for 2026.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Trade-off: Complexity vs. Cost
&lt;/h3&gt;

&lt;p&gt;The core differentiator is simple: &lt;strong&gt;Do you need premium, deeply nested parsing, or raw, high-volume data at a fraction of the cost?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;SerpApi&lt;/strong&gt; is an end-to-end powerhouse. It handles complex JavaScript rendering and provides highly detailed schemas for over 80 APIs. However, this comes at a premium, with costs climbing as high as $9.17 per 1,000 queries on high-volume tiers.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;ValueSERP and Scale SERP&lt;/strong&gt; follow a "less is more" philosophy. They provide clean, flat JSON payloads that are significantly easier to ingest directly into a database, and their pricing models are built for scale—often dropping below $0.30 per 1,000 requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance &amp;amp; Latency Benchmarks
&lt;/h3&gt;

&lt;p&gt;If your app is user-facing, latency is non-negotiable. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;SerpApi&lt;/th&gt;
&lt;th&gt;ValueSERP&lt;/th&gt;
&lt;th&gt;Scale SERP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Start Price (per 1k)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$25&lt;/td&gt;
&lt;td&gt;&amp;lt;$1.50&lt;/td&gt;
&lt;td&gt;&amp;lt;$1.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Price at 1M Queries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$9,170&lt;/td&gt;
&lt;td&gt;~$300&lt;/td&gt;
&lt;td&gt;~$350&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Proxy Management&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Implicit&lt;/td&gt;
&lt;td&gt;Implicit&lt;/td&gt;
&lt;td&gt;Explicit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Avg. Latency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.1s – 1.5s&lt;/td&gt;
&lt;td&gt;2.2s – 3.2s&lt;/td&gt;
&lt;td&gt;1.8s – 2.5s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;SerpApi’s "Google Light" mode is a lifesaver for speed, keeping queries under 1.5s by skipping heavy JS rendering. If you’re building a real-time monitoring dashboard, that 500ms difference in response time matters. Conversely, ValueSERP is my go-to for asynchronous background jobs where throughput and concurrency limits are more important than sub-second response times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handling CAPTCHAs and Proxy Rotation
&lt;/h3&gt;

&lt;p&gt;Stop building your own proxy pools. All three services handle proxy rotation on the backend, which is essential to keeping success rates above 99%. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Scale SERP&lt;/strong&gt; offers excellent, explicit proxy rotation that makes it a breeze to bypass blocks. &lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;SerpApi&lt;/strong&gt; is reliable but, in my experience, the rate limits become a major bottleneck if you aren't on an expensive enterprise tier.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  My Recommendation for 2026
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Use SerpApi if:&lt;/strong&gt; You need highly complex data (Map Packs, Shopping, deeply nested snippets) and your query volume is low enough that the premium price is justified by the engineering time saved on parsing.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Use ValueSERP or Scale SERP if:&lt;/strong&gt; You are scraping at scale (over 500k queries/month) and need a lean, flat JSON output that won't destroy your budget. &lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Pro Tip:&lt;/strong&gt; If your use case is AI retrieval or rank tracking, don't ignore &lt;strong&gt;Bing&lt;/strong&gt;. Providers like SerpApi.org offer structured Bing search data at a fraction of the cost of Google, often saving teams up to 80% on their total extraction overhead.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before migrating, audit your current schema requirements. If you're currently paying for "deeply parsed" features that your frontend isn't even using, switching to a flatter, more affordable JSON output will save your team thousands in annual overhead.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/serpapi-vs-valueserp-vs-scale-serp-2026-comparison" rel="noopener noreferrer"&gt;Serpapi vs ValueSERP vs Scale SERP: 2026 comparison&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Cheapest Bing SERP API options for startups in 2026</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Mon, 10 Aug 2026 11:05:20 +0000</pubDate>
      <link>https://dev.to/serpapiorg/cheapest-bing-serp-api-options-for-startups-in-2026-15ck</link>
      <guid>https://dev.to/serpapiorg/cheapest-bing-serp-api-options-for-startups-in-2026-15ck</guid>
      <description>&lt;p&gt;When building data-heavy applications, most developers default to the official Microsoft Azure search gateway. In my experience auditing API spend for early-stage SaaS, this is a costly mistake. Relying on native endpoints often drains startup capital 100x faster than necessary. If you are developing AI agents, RAG pipelines, or market intelligence tools, switching to specialized third-party aggregators is the most effective way to protect your margins.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Financial Reality
&lt;/h3&gt;

&lt;p&gt;The official Azure S1 tier charges $25 per 1,000 queries. If your LLM integration requires 100,000 monthly calls, you are looking at a $2,500 monthly bill—a massive burn for a bootstrapped project.&lt;/p&gt;

&lt;p&gt;By contrast, specialized scraping APIs offer the same data for a fraction of the cost, often starting as low as $0.03 to $0.50 per 1,000 queries. These services provide pre-parsed JSON, saving your engineering team the headache of maintaining fragile Python wrappers or custom DOM selectors that break whenever Bing updates its UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Factors for Budget Optimization
&lt;/h3&gt;

&lt;p&gt;Before integrating, consider these technical trade-offs to keep your burn rate low:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Asynchronous Processing:&lt;/strong&gt; Don't let your backend threads hang on search requests. Use webhook-based providers that handle the proxy rotation and retries for you. This prevents local rate-limiting and improves overall system resilience.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Avoid JavaScript Rendering:&lt;/strong&gt; Many developers enable JS rendering by default. Only turn this on if the specific search result requires dynamic element loading. Disabling it can reduce your credit consumption by up to 10x per request.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Geo-Targeting:&lt;/strong&gt; Avoid hyper-specific coordinate parameters if a country-level code suffices. Routing through residential proxy networks for every single request creates unnecessary credit multipliers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Comparison Table for Strategic Selection
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Entry Cost (Per 1k)&lt;/th&gt;
&lt;th&gt;Parsing Capability&lt;/th&gt;
&lt;th&gt;Ideal Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SerpApi&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Full (Web, Shopping, Images)&lt;/td&gt;
&lt;td&gt;Production-grade structured data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Brave API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Snippets only&lt;/td&gt;
&lt;td&gt;AI RAG grounding (text-centric)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bright Data&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pay-as-you-go&lt;/td&gt;
&lt;td&gt;Highly customizable&lt;/td&gt;
&lt;td&gt;High-volume async scraping&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Prototyping for Free
&lt;/h3&gt;

&lt;p&gt;If you are at the pre-seed stage, you should leverage the free tiers offered by major scraping providers. Most platforms (like SerpApi) provide up to 5,000 free credits monthly. This is more than enough to validate your product-market fit and test your RAG response schemas without spending a cent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Structured JSON Wins
&lt;/h3&gt;

&lt;p&gt;Writing your own scrapers with tools like BeautifulSoup is a technical debt trap. When you use a third-party API, you receive a standardized JSON response. This allows your backend to treat search results as simple dictionary lookups, keeping your microservices lightweight and container-ready. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; If your current architecture is failing due to latency or cost, try decoupling your ingestion. Use a task queue to ping a provider’s API, then ingest the resulting structured JSON into your vector database. This keeps your main application loop fast and eliminates the memory overhead associated with headless browsers.&lt;/p&gt;

&lt;p&gt;Choosing the right API isn't just about the per-query cost; it's about reducing maintenance engineering hours. By offloading the complexity of proxy management and DOM parsing to a specialized provider, you can focus your limited resources on what actually drives value: your product features.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/cheapest-bing-serp-api-options-for-startups-in-2026" rel="noopener noreferrer"&gt;Cheapest Bing SERP API options for startups in 2026&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Bing local SERP API ZIP code targeting: a developer guide</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Mon, 10 Aug 2026 04:15:37 +0000</pubDate>
      <link>https://dev.to/serpapiorg/bing-local-serp-api-zip-code-targeting-a-developer-guide-521k</link>
      <guid>https://dev.to/serpapiorg/bing-local-serp-api-zip-code-targeting-a-developer-guide-521k</guid>
      <description>&lt;p&gt;During my years building rank-tracking pipelines, I've seen many developers make the same mistake: appending a raw ZIP code directly to a Bing search query (e.g., &lt;code&gt;q="plumber 90210"&lt;/code&gt;). While intuitive, this approach is highly unreliable. Bing’s internal geo-parsing engine frequently struggles with raw postal strings, often falling back to broad municipal centroids. In suburban or rural areas, this fallback introduces a localization error of up to 15 miles, completely corrupting your hyper-local SEO data.&lt;/p&gt;

&lt;p&gt;To get precise local map pack data, you must bypass Bing's geo-fallback entirely. The most efficient design pattern is to translate ZIP codes into GPS coordinates &lt;em&gt;before&lt;/em&gt; hitting the search engine.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architectural Solution: Offline Geocoding
&lt;/h3&gt;

&lt;p&gt;Instead of calling live geocoding APIs for every search query—which adds cost and network overhead—I recommend maintaining a lightweight, offline lookup database. You can easily store ZIP codes and their corresponding latitude/longitude centroids in a local SQLite database or an in-memory Redis cache. &lt;/p&gt;

&lt;p&gt;Your ingestion pipeline should run as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receive the target ZIP code.&lt;/li&gt;
&lt;li&gt;Query your local database to retrieve the coordinate pair (lookup times are typically &amp;lt;2ms).&lt;/li&gt;
&lt;li&gt;Send those explicit coordinates to the search API.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Executing Structured Queries
&lt;/h3&gt;

&lt;p&gt;To run this at scale without managing massive proxy pools, CAPTCHA bypasses, or headless browser clusters, I use SerpApi as a managed gateway. By passing precise latitude and longitude values into the &lt;code&gt;location&lt;/code&gt; parameter and specifying the &lt;code&gt;bing&lt;/code&gt; engine, you force the system to return the exact map pack for that specific neighborhood.&lt;/p&gt;

&lt;p&gt;Here is a clean Python implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Retrieve cached coordinates for target ZIP (e.g., 90210)
&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;34.0901&lt;/span&gt;
&lt;span class="n"&gt;longitude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;118.4065&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Build the API payload with isolated parameters
&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;engine&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;plumber&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lat:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;latitude&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;,lon:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;longitude&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api_key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_SERPAPI_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Execute the search
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://serpapi.com/search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;search_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parsing the Local Payload Safely
&lt;/h3&gt;

&lt;p&gt;Bing’s localized results are nested within the &lt;code&gt;local_results&lt;/code&gt; array. Because search engine schemas can shift and some business listings lack phone numbers, websites, or reviews, hardcoded parsing will break your data collection pipelines. &lt;/p&gt;

&lt;p&gt;I always use a defensive, null-safe parsing function to flatten the payload for storage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_map_rankings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_payload&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;raw_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api_payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;local_results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="n"&gt;structured_listings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;raw_results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;structured_listings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rating&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rating&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reviews&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reviews&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;address&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;address&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;N/A&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;position&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;position&lt;/span&gt;&lt;span class="sh"&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;return&lt;/span&gt; &lt;span class="n"&gt;structured_listings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Optimizing Your Multi-Engine Strategy
&lt;/h3&gt;

&lt;p&gt;If you are tracking rankings across both Google and Bing, avoid using the exact same spatial grid for both engines. &lt;/p&gt;

&lt;p&gt;Google’s local search algorithms are hyper-sensitive to micro-locations, meaning rankings can fluctuate block-by-block. Bing, on the other hand, operates on much broader, static geographic zones. To optimize your API budget, run a split-frequency polling model: query Google on a dense, coordinate-heavy grid, and monitor Bing on a broader, cost-efficient ZIP-to-coordinate schedule.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/bing-local-serp-api-zip-code-targeting-a-developer-guide" rel="noopener noreferrer"&gt;Bing local SERP API ZIP code targeting: a developer guide&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Custom Shopify search API integration blueprint</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Sun, 09 Aug 2026 14:58:22 +0000</pubDate>
      <link>https://dev.to/serpapiorg/custom-shopify-search-api-integration-blueprint-2jjm</link>
      <guid>https://dev.to/serpapiorg/custom-shopify-search-api-integration-blueprint-2jjm</guid>
      <description>&lt;p&gt;I have built several Shopify storefronts scaling past 10,000 SKUs, and I can tell you firsthand: relying on native Liquid templates for complex search and multi-level filtering is a recipe for performance degradation. Liquid executes on-the-fly inside Shopify’s rendering sandbox, meaning dynamic facet calculations across heavily nested variants easily trigger timeouts or spike response times past 1.2 seconds.&lt;/p&gt;

&lt;p&gt;To achieve consistent sub-100ms search latency, we must decouple query execution from Shopify’s core. Here is the system design I use to run an external search index alongside Shopify without hitting API limitations.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Mitigating Leaky Bucket Rate Limits via Redis Queues
&lt;/h3&gt;

&lt;p&gt;Shopify's GraphQL Admin API strictly limits calls using a leaky bucket algorithm. To prevent high-frequency catalog syncs from exhausting your API limit, you must decouple webhook ingestion from search index writes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ingestion:&lt;/strong&gt; Create a lightweight endpoint to capture incoming product updates, validate the webhook signature, and immediately return a &lt;code&gt;200 OK&lt;/code&gt; response.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Buffering:&lt;/strong&gt; Push the raw webhook payloads to a Redis queue (such as BullMQ).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throttling:&lt;/strong&gt; Run a worker pool that consumes the queue at a controlled rate, ensuring total Admin API call costs remain under Shopify's 40 point/second replenishment threshold.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Circuit Breaker:&lt;/strong&gt; If your middleware encounters consecutive 429 (Too Many Requests) or 503 errors, open the circuit breaker, halt consumption, and alert your team.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Document Flattening for the Search Index
&lt;/h3&gt;

&lt;p&gt;Shopify represents products with deeply nested variants and metafield arrays. Directly indexing this nested structure makes search filtering slow and complex. &lt;/p&gt;

&lt;p&gt;Instead, serialize catalog data so every individual variant behaves as a root document in your external index (e.g., Elasticsearch, Algolia). This allows instant matching on exact variant inventories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"variant_456789"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"product_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"product_123456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Classic Denim Jacket - Medium / Blue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"parent_title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Classic Denim Jacket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sku"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CDJ-MED-BLU"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"price"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;89.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"in_stock"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inventory_quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Blue"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Medium"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"metafields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"fabric_weight"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"14oz"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Securing Middleware and Token Rotation
&lt;/h3&gt;

&lt;p&gt;The latest Shopify security standards require programmatic offline token rotation. To prevent middleware lockouts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolate decryption secrets in a secure environment key vault (like AWS Secrets Manager).&lt;/li&gt;
&lt;li&gt;When your middleware runs a synchronization cycle, check the active token’s timestamp. If it is within two hours of expiration, programmatically POST a renewal request to Shopify’s OAuth endpoint to obtain a new 24-hour token. &lt;/li&gt;
&lt;li&gt;Never expose these offline token exchange secrets to the client-side code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Hybrid Frontend Rendering with the Section Rendering API
&lt;/h3&gt;

&lt;p&gt;One of the biggest pain points of custom search is maintaining storefront layout consistency. Rebuilding product card markup in client-side JavaScript creates continuous maintenance bottlenecks when merchants update their themes. &lt;/p&gt;

&lt;p&gt;Instead, query your external index first to retrieve matching product IDs, then pass those IDs to Shopify's &lt;strong&gt;Section Rendering API&lt;/strong&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="c1"&gt;// Example query fetching pre-rendered HTML cards for matching search IDs&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchIds&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="s1"&gt;123456&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="s1"&gt;789012&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`/sections/main-search?q=id:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;searchIds&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="s1"&gt;,id:&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;search-results-grid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;main-search&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;This returns pre-rendered, theme-compatible HTML cards, preserving your store's native stylesheets, lazy-loading logic, and event tracking.&lt;/p&gt;

&lt;p&gt;Keep your frontend state management lightweight using Alpine.js or Preact. Implement a 300ms debounce on input events to prevent query spamming, and push state changes to the address bar with &lt;code&gt;history.pushState&lt;/code&gt; so users can bookmark filtered search results. &lt;/p&gt;

&lt;p&gt;If you are scaling these data pipelines further or want to align your internal search metrics with live search engine intelligence, utilizing programmatic tools like &lt;a href="https://serpapi.com/" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt; can help you extract structured search trends and automate indexing tasks across external channels.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/custom-shopify-search-api-integration-blueprint" rel="noopener noreferrer"&gt;Custom Shopify search API integration blueprint&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to get Google search autocomplete suggestions via API</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Sun, 09 Aug 2026 07:13:24 +0000</pubDate>
      <link>https://dev.to/serpapiorg/how-to-get-google-search-autocomplete-suggestions-via-api-4n83</link>
      <guid>https://dev.to/serpapiorg/how-to-get-google-search-autocomplete-suggestions-via-api-4n83</guid>
      <description>&lt;p&gt;If you have ever tried to build a keyword research tool or an autocomplete search feature, you probably first reached for the Google Places API. I have seen countless engineering teams waste development budget on Google Maps credits only to realize that the Places API is strictly limited to physical addresses and local businesses—not organic web search predictions. &lt;/p&gt;

&lt;p&gt;Since there is no official, documented public API for Google Search suggestions, we have to look under the hood at how browsers fetch these predictions in real-time.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Undocumented Autocomplete Endpoint
&lt;/h3&gt;

&lt;p&gt;When you type into the Chrome address bar, the browser sends HTTP GET requests to an undocumented endpoint. We can query this exact same pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;https://suggestqueries.google.com/complete/search?client=chrome&amp;amp;q={query}&amp;amp;hl={lang}&amp;amp;gl={country}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the query parameter &lt;code&gt;client=chrome&lt;/code&gt; is critical. It forces Google’s servers to return a clean, nested JSON array. If you use older values like &lt;code&gt;toolbar&lt;/code&gt; or &lt;code&gt;youtube&lt;/code&gt;, you will get back legacy XML payloads that require heavy parsing libraries and waste CPU cycles.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Role in Request Pipeline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;client&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;chrome&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Forces JSON format instead of XML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;q&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker deploy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The raw partial search string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;&lt;code&gt;en&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Language code for localization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;&lt;code&gt;us&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Country code for geo-targeting&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Building a Basic Python Scraper
&lt;/h3&gt;

&lt;p&gt;Here is a lightweight Python implementation to query this endpoint. In a production environment, you must route requests through rotating residential proxies and mimic browser-level headers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_suggestions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;us&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://suggestqueries.google.com/complete/search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Accept&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*/*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Referer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.google.com/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;client&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chrome&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;country&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# Configure rotating residential proxies to bypass blocks
&lt;/span&gt;    &lt;span class="n"&gt;proxies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://username:password@proxy.example.com:8000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://username:password@proxy.example.com:8000&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;raw_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loads&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c1"&gt;# The suggestion strings live at index 1 of the returned list
&lt;/span&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;raw_data&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="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;429&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Block detected: HTTP 429 Too Many Requests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Request failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;span class="c1"&gt;# Example execution
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetch_suggestions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kubernetes cluster&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Engineering Hurdle: JA3 Fingerprinting &amp;amp; HTTP 429s
&lt;/h3&gt;

&lt;p&gt;If you deploy this script on a VPS (like AWS or DigitalOcean) without proxies, Google's firewalls will block your IP within a few dozen requests. &lt;/p&gt;

&lt;p&gt;Even if you rotate standard HTTP user-agents, Google uses &lt;strong&gt;JA3/TLS Fingerprinting&lt;/strong&gt; to analyze the low-level cryptographic handshake of your HTTP library (such as Python &lt;code&gt;requests&lt;/code&gt; or Node.js &lt;code&gt;axios&lt;/code&gt;). If the TLS signature does not match a real browser version, the connection is instantly throttled.&lt;/p&gt;

&lt;p&gt;To bypass this at scale, you have two options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use tools like &lt;code&gt;curl-impersonate&lt;/code&gt; to spoof TLS signatures.&lt;/li&gt;
&lt;li&gt;Maintain a pool of premium rotating residential proxies (which generally cost between $3 and $15 per gigabyte).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Scaling and Managed Alternatives
&lt;/h3&gt;

&lt;p&gt;To build a deep keyword discovery engine, you can use a &lt;strong&gt;wildcard expansion&lt;/strong&gt; technique. Programmatically loop through your seed keyword appended with letters "a" through "z" (e.g., &lt;code&gt;seed + a&lt;/code&gt;, &lt;code&gt;seed + b&lt;/code&gt;) or prepended with question modifiers ("how to...", "why..."). &lt;/p&gt;

&lt;p&gt;For large-scale, production-ready platforms, managing your own proxy infrastructure and TLS bypasses quickly becomes an engineering money pit. If you want to stop debugging broken scrapers and paying expensive residential proxy invoices, switching to a managed API provider like SerpApi is highly recommended. It handles the proxy rotation, localization, and TLS fingerprinting under a flat-rate billing model, returning clean JSON without the maintenance overhead.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/how-to-get-google-search-autocomplete-suggestions-via-api" rel="noopener noreferrer"&gt;How to get Google search autocomplete suggestions via API&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Bing keyword search volume api: Official vs third-party</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Sat, 08 Aug 2026 10:07:15 +0000</pubDate>
      <link>https://dev.to/serpapiorg/bing-keyword-search-volume-api-official-vs-third-party-43pf</link>
      <guid>https://dev.to/serpapiorg/bing-keyword-search-volume-api-official-vs-third-party-43pf</guid>
      <description>&lt;p&gt;Integrating search data into your application often leads to a "build vs. buy" dilemma. After watching engineering teams lose weeks wrestling with Microsoft’s enterprise authentication, I’ve learned that the path you choose depends entirely on whether you are managing ad budgets or building a lean SaaS product.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architectural Reality
&lt;/h3&gt;

&lt;p&gt;Retrieving keyword data from Microsoft isn't as simple as hitting a public REST endpoint. The ecosystem is split:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Webmaster Tools:&lt;/strong&gt; Designed for site owners, it does not provide an endpoint for bulk keyword volume queries.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Microsoft Advertising (AdInsight Service):&lt;/strong&gt; This is the only official source for volume data, but it is locked behind enterprise-grade security and ad-spend requirements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Official Path
&lt;/h3&gt;

&lt;p&gt;If you opt for the official Microsoft Advertising API, be prepared for significant overhead. Authenticating requires a developer token (subject to a ~10-day manual review), an Azure AD OAuth 2.0 flow, and an active ad account.&lt;/p&gt;

&lt;p&gt;Crucially, if your account lacks active ad spend, Microsoft will return "bucketed" data (e.g., 10k–100k) instead of precise integers. Structurally, you’ll be dealing with XML SOAP envelopes rather than modern JSON. Maintaining WSDL files and handling token rotations is a dedicated engineering task, not a side project.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Third-Party Alternative
&lt;/h3&gt;

&lt;p&gt;Third-party providers (like DataForSEO) abstract this complexity by maintaining their own high-volume authorized accounts. You interact with a standard REST JSON API, receiving clean, un-bucketed historical data.&lt;/p&gt;

&lt;p&gt;This approach is usually the better choice for SaaS developers. You trade a small per-request fee for hundreds of hours of saved development time. It eliminates the need for maintaining SOAP parsers and ensures you never have to "pay to play" with dummy ad campaigns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-time Intent via Autocomplete
&lt;/h3&gt;

&lt;p&gt;Sometimes historical data isn't enough. For spotting emerging trends before they hit the databases, querying live autocomplete data is more effective. Using specialized tools like SerpApi allows you to extract real-time search suggestions in seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Decision Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Official Microsoft Ads API&lt;/th&gt;
&lt;th&gt;Third-Party SEO APIs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;OAuth 2.0 / Azure AD&lt;/td&gt;
&lt;td&gt;API Key (Bearer)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Weeks (Manual review)&lt;/td&gt;
&lt;td&gt;Minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Payload&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Legacy XML SOAP&lt;/td&gt;
&lt;td&gt;Modern JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Quality&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bucketized (without spend)&lt;/td&gt;
&lt;td&gt;Precise / Un-bucketed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  My Recommendation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Go Official if:&lt;/strong&gt; You are building an enterprise ad-tech platform where you are already managing large-scale client budgets and have a team dedicated to infrastructure maintenance.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Go Third-Party if:&lt;/strong&gt; You are building an SEO dashboard, rank tracker, or any application where speed to market and precise data are your priorities.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Use Autocomplete APIs if:&lt;/strong&gt; Your focus is on capturing live user intent and seasonal spikes that haven't hit the historical trend reports yet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most developers, the maintenance cost of the official integration is far higher than the subscription cost of a reliable third-party provider. Start by validating your product with a simple JSON API before committing to the heavy lifting of enterprise-level Microsoft integration.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/bing-keyword-search-volume-api-official-vs-third-party" rel="noopener noreferrer"&gt;Bing keyword search volume api: Official vs third-party&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to use Google Custom Search API with Python in 2026</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Sat, 08 Aug 2026 05:51:14 +0000</pubDate>
      <link>https://dev.to/serpapiorg/how-to-use-google-custom-search-api-with-python-in-2026-50gj</link>
      <guid>https://dev.to/serpapiorg/how-to-use-google-custom-search-api-with-python-in-2026-50gj</guid>
      <description>&lt;p&gt;Getting search data programmatically can be a major headache for developers. Between navigating the often-confusing Google Cloud Console and hitting cryptic &lt;code&gt;403 Forbidden&lt;/code&gt; errors, it is easy to waste hours on setup alone. If you are building an AI-powered pipeline or a simple dashboard, here is the streamlined approach to getting your search integration running in 2026.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Setup: Credentials &amp;amp; CX
&lt;/h3&gt;

&lt;p&gt;First, ignore the outdated documentation. Go to the &lt;a href="https://console.cloud.google.com/" rel="noopener noreferrer"&gt;Google Cloud Console&lt;/a&gt;, create a dedicated project for your search service, and enable the "Custom Search API" in the library. Once enabled, generate an API Key under the "Credentials" tab. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; Always load this key via environment variables (&lt;code&gt;.env&lt;/code&gt; file). Never commit it to GitHub.&lt;/p&gt;

&lt;p&gt;Next, head to the &lt;a href="https://programmablesearchengine.google.com/" rel="noopener noreferrer"&gt;Programmable Search Engine dashboard&lt;/a&gt; to get your Search Engine ID (CX). A common trap here is the "single domain" restriction. When you create your engine, Google forces you to add a site. Add a dummy URL like &lt;code&gt;example.com&lt;/code&gt;, then open the dashboard settings and toggle &lt;strong&gt;"Search the entire web"&lt;/strong&gt; to &lt;strong&gt;ON&lt;/strong&gt;. Finally, remove the dummy URL. Now your CX is ready for global queries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building the Python Integration
&lt;/h3&gt;

&lt;p&gt;While there is an official Google library, I prefer using the standard &lt;code&gt;requests&lt;/code&gt; module. It is lightweight, avoids dependency bloat, and is much faster for serverless environments like AWS Lambda or Google Cloud Functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_search_results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;q&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GOOGLE_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GOOGLE_CX_ID&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.googleapis.com/customsearch/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&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;elif&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Quota exceeded: You hit the 100-request daily limit.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Navigating the JSON Payload
&lt;/h3&gt;

&lt;p&gt;Google’s response is a deeply nested JSON. Accessing it directly with &lt;code&gt;items['title']&lt;/code&gt; will crash your script if no results are found. Always use &lt;code&gt;.get()&lt;/code&gt; for defensive coding.&lt;/p&gt;

&lt;p&gt;For advanced data extraction, look into the &lt;code&gt;pagemap&lt;/code&gt; field. This object contains metadata like Open Graph tags, article authors, and publication dates—often saving you from having to visit the site directly to scrape its HTML.&lt;/p&gt;

&lt;h3&gt;
  
  
  Managing Limits and Scaling
&lt;/h3&gt;

&lt;p&gt;The free tier gives you exactly 100 requests per day. You can paginate results by passing the &lt;code&gt;start&lt;/code&gt; parameter (increments of 10), but you are hard-capped at 100 results per query.&lt;/p&gt;

&lt;p&gt;If you are scaling a production application or an AI ingestion engine, the 100-request limit becomes a massive bottleneck. Managing your own rotating proxy infrastructure to bypass these limits is an engineering time-sink. At this stage, professional developers typically migrate to dedicated search APIs like &lt;a href="https://serpapi.com" rel="noopener noreferrer"&gt;SerpApi&lt;/a&gt;. These services handle proxy rotation, CAPTCHA solving, and parsing, returning clean JSON without the "403" headaches or the maintenance of custom scraping scripts.&lt;/p&gt;

&lt;p&gt;For hobby projects, the native API is fine. For anything in production, save your engineering hours and use a specialized provider that scales with your search volume.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/how-to-use-google-custom-search-api-with-python-in-2026" rel="noopener noreferrer"&gt;How to use Google Custom Search API with Python in 2026&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to reduce Google Search API cost in production</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Fri, 07 Aug 2026 12:12:44 +0000</pubDate>
      <link>https://dev.to/serpapiorg/how-to-reduce-google-search-api-cost-in-production-2eae</link>
      <guid>https://dev.to/serpapiorg/how-to-reduce-google-search-api-cost-in-production-2eae</guid>
      <description>&lt;p&gt;I've seen many engineering teams burn through thousands of dollars on cloud invoices because they treat external search APIs like local databases. Triggering a network request on every keystroke or failing to cache duplicate queries is a classic production bottleneck. Based on my experience managing high-throughput integrations, here is a practical architectural blueprint to optimize your search infrastructure and protect your budget.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Server-Side Redis Caching
&lt;/h3&gt;

&lt;p&gt;Search patterns generally follow a Pareto distribution—about 80% of your users search for the same 20% of queries. Serving these duplicate requests directly from memory is the fastest way to drop your API billing.&lt;/p&gt;

&lt;p&gt;We implement a classic &lt;strong&gt;cache-aside pattern&lt;/strong&gt; using Redis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Normalize inputs:&lt;/strong&gt; Lowercase and trim whitespaces before hashing (e.g., &lt;code&gt;" Database "&lt;/code&gt; and &lt;code&gt;"database"&lt;/code&gt; must match).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Generate consistent keys:&lt;/strong&gt; Create a SHA-256 hash of the normalized query combined with localization parameters (e.g., &lt;code&gt;q=database&amp;amp;gl=us&amp;amp;hl=en&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Define an optimal TTL:&lt;/strong&gt; For general web searches, a 24-hour Time-to-Live (TTL) is ideal. For more dynamic data, a 1-to-4-hour TTL still shields your backend from viral traffic spikes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Client-Side Debouncing and Event Triggers
&lt;/h3&gt;

&lt;p&gt;If your front-end triggers an API call with every keystroke, typing "cloud hosting" fires 13 separate requests. On mobile devices, autocorrect amplifies this issue.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Implement a 300ms debounce window:&lt;/strong&gt; Wait for the user to pause typing before dispatching the fetch request.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Minimum character limits:&lt;/strong&gt; Only fire queries when the input length is at least 3 characters.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Explicit triggers:&lt;/strong&gt; For resource-heavy pages, replace instant search with an explicit action—like pressing "Enter" or clicking a "Search" button. This completely removes accidental API triggers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Hard Quotas and Payload Filtering
&lt;/h3&gt;

&lt;p&gt;To avoid runaway bills due to infinite loops in staging or key scraping attacks, you must configure constraints directly in the Google Cloud Console.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Set Daily Caps:&lt;/strong&gt; Navigate to the API Quotas tab and set a hard "Queries per day" limit that aligns with your daily budget ceiling (e.g., capping requests to stay under a $20/day budget).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Restrict API Keys:&lt;/strong&gt; Lock your production key to specific HTTP referrers (e.g., &lt;code&gt;https://*.yourdomain.com/*&lt;/code&gt;) to prevent unauthorized usage if the key is leaked.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Filter Response Payloads:&lt;/strong&gt; Reduce network overhead by using the &lt;code&gt;fields&lt;/code&gt; query parameter. Requesting only essential fields (e.g., &lt;code&gt;&amp;amp;fields=items(title,link,snippet)&lt;/code&gt;) reduces response sizes by up to 75%, lowering CPU cycles during JSON parsing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Evaluating High-Volume Alternatives
&lt;/h3&gt;

&lt;p&gt;If your application scales past 500,000 monthly queries, Google's flat rate of $5 per 1,000 queries becomes highly inefficient. &lt;/p&gt;

&lt;p&gt;For heavy data-mining or SEO rank-tracking pipelines, migrating to dedicated scraping providers like &lt;strong&gt;SerpApi&lt;/strong&gt; delivers better unit economics. These services offer volume-based discounts, return clean structured JSON for major search engines, and handle complex proxy management and CAPTCHA bypasses natively.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/how-to-reduce-google-search-api-cost-in-production" rel="noopener noreferrer"&gt;How to reduce Google Search API cost in production&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Elasticsearch alternative search api: best options for 2026</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Fri, 07 Aug 2026 07:33:51 +0000</pubDate>
      <link>https://dev.to/serpapiorg/elasticsearch-alternative-search-api-best-options-for-2026-159b</link>
      <guid>https://dev.to/serpapiorg/elasticsearch-alternative-search-api-best-options-for-2026-159b</guid>
      <description>&lt;p&gt;I’ve lost count of how many times I've seen engineering teams provision massive, expensive cloud instances with 4GB JVM heaps just to run basic search queries on a small dataset. Forcing the Java Virtual Machine (JVM) to handle modest search workloads is an architectural money pit. Between garbage collection pauses freezing our search threads and wrestling with deeply nested Query DSL JSON, I finally decided to migrate our stack. &lt;/p&gt;

&lt;p&gt;Here is a practical breakdown of the production-ready options we evaluated to cut memory footprints, simplify query structures, and lower infrastructure overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem: JVM Overhead and Query Complexity
&lt;/h3&gt;

&lt;p&gt;In my experience, managing Elasticsearch's memory footprint is a full-time operational chore. Because it mandates allocating up to 50% of system memory directly to the JVM heap, your database is constantly starving for page cache unless you over-provision. Add to this the licensing shifts to SSPL, and compliance audits quickly become a headache.&lt;/p&gt;

&lt;p&gt;Furthermore, the Elasticsearch Query DSL has a notorious learning curve. A simple filtered search requires building nested blocks containing keywords like &lt;code&gt;must&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, and &lt;code&gt;should&lt;/code&gt;. Modern engines flatten this interaction completely.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Lightweight Contenders: Meilisearch &amp;amp; Typesense
&lt;/h3&gt;

&lt;p&gt;If you need sub-10ms user-facing search without complex tuning, native-compiled engines are the best path forward. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Meilisearch (Rust):&lt;/strong&gt; Runs comfortably on under 150MB of RAM. Its bucket-sort algorithm processes ranking rules sequentially, making typo tolerance work out-of-the-box.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typesense (C++):&lt;/strong&gt; Highly concurrent, optimized for in-memory performance, and keeps its footprint under 100MB of RAM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of writing a 20-line nested JSON query, both engines allow you to search using flat, human-readable REST parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /indexes/products/search?q=phone&amp;amp;filter=category = Electronics&amp;amp;sort=price:asc
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Drop-In Compatibility vs. Cost-Saving Arch
&lt;/h3&gt;

&lt;p&gt;If your infrastructure is tightly integrated with Kibana dashboards, Fluentd, or legacy Logstash pipelines, migrating to &lt;strong&gt;OpenSearch&lt;/strong&gt; is the most practical choice. As an Apache 2.0-licensed fork of ES 7.10, it offers near 1:1 API compatibility. Just keep in mind that since it is still Java-based, you won't save on RAM or escape JVM garbage collection tuning.&lt;/p&gt;

&lt;p&gt;For analytical pipelines and log retention, storing terabytes of data on local SSDs is incredibly expensive. I've found that engines like &lt;strong&gt;Quickwit&lt;/strong&gt; are game-changers here. By decoupling compute from storage, Quickwit writes split-index files directly to cheap object storage (like Amazon S3) and queries them on demand, slashing storage bills by up to 80%.&lt;/p&gt;

&lt;h3&gt;
  
  
  Retrieving External Data Without the Database
&lt;/h3&gt;

&lt;p&gt;If your application needs to retrieve search results from the web rather than indexing internal records, hosting &lt;em&gt;any&lt;/em&gt; database cluster is an anti-pattern. Building scrapers, managing proxy pools, and handling rate limits is a massive waste of engineering time. Utilizing specialized APIs like &lt;strong&gt;SerpApi&lt;/strong&gt; delivers structured JSON results from Google or Bing instantly, bypassing the ingestion pipeline entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Comparison Matrix
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;RAM Footprint&lt;/th&gt;
&lt;th&gt;Primary Language&lt;/th&gt;
&lt;th&gt;Best Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Meilisearch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;lt; 150MB&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;Fast in-app search, autocomplete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Typesense&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&amp;lt; 100MB&lt;/td&gt;
&lt;td&gt;C++&lt;/td&gt;
&lt;td&gt;High-concurrency catalog search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OpenSearch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4GB - 8GB&lt;/td&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;Log analytics, legacy migrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Quickwit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Low (On-demand)&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;Hitting S3 object storage directly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SerpApi&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Zero (Hosted)&lt;/td&gt;
&lt;td&gt;Go / Ruby&lt;/td&gt;
&lt;td&gt;External web search extraction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Selecting your next search engine comes down to your data source. For internal application search, go with Rust or C++ engines to slash your cloud bill. For log aggregation, stick to OpenSearch or Quickwit. And if you are querying the live web, offload the infrastructure entirely to a hosted API.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/elasticsearch-alternative-search-api-best-options-for-2026" rel="noopener noreferrer"&gt;Elasticsearch alternative search api: best options for 2026&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Best search API for WooCommerce: top choices for 2026</title>
      <dc:creator>SerpApi.Org</dc:creator>
      <pubDate>Thu, 06 Aug 2026 11:56:19 +0000</pubDate>
      <link>https://dev.to/serpapiorg/best-search-api-for-woocommerce-top-choices-for-2026-pjc</link>
      <guid>https://dev.to/serpapiorg/best-search-api-for-woocommerce-top-choices-for-2026-pjc</guid>
      <description>&lt;p&gt;After a decade of managing high-traffic e-commerce infrastructure, I’ve seen countless stores lose significant revenue simply because their native WordPress search engine couldn't handle basic typos or complex SKU structures. The bottleneck is simple: native SQL queries perform sequential scans that kill database performance once you cross the 5,000 SKU threshold.&lt;/p&gt;

&lt;p&gt;If you are dealing with high CPU spikes during peak hours or poor site responsiveness, it’s time to move your search architecture off the main database. Here is how you can architect a faster, more reliable search experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Native SQL Search Bottlenecks
&lt;/h3&gt;

&lt;p&gt;Standard MySQL &lt;code&gt;LIKE&lt;/code&gt; queries are not built for search. They scan rows one by one, which scales linearly and poorly. In a recent audit, I saw concurrent searches on a 12,000-SKU store lock up the database for four seconds, essentially freezing the checkout process during a flash sale. Furthermore, native search lacks the "fuzzy matching" logic customers expect—if a user mistypes "shurt" instead of "shirt," they get a zero-results page, which is a major conversion killer.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Power of External APIs
&lt;/h3&gt;

&lt;p&gt;Offloading search execution to a dedicated engine moves the load from your PHP/MySQL server to a cloud-based inverted index. This shift:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduces Latency:&lt;/strong&gt; Drops response times from 450ms+ to under 25ms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saves Resources:&lt;/strong&gt; Bypasses PHP execution, allowing your database to focus on transactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improves Accuracy:&lt;/strong&gt; Supports typo tolerance and advanced tokenization for alphanumeric SKUs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Evaluating Your Options
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Algolia&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SaaS&lt;/td&gt;
&lt;td&gt;Stores wanting a turnkey, lightning-fast "Search-as-a-Service" with minimal maintenance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Elasticsearch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;td&gt;Enterprise setups requiring total control over ranking, synonyms, and index customization.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Meilisearch&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;td&gt;A balanced, developer-friendly alternative that provides fast, typo-tolerant search.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Technical Best Practices
&lt;/h3&gt;

&lt;p&gt;When integrating, keep these three rules in mind to maintain performance and security:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Client-Side Rendering:&lt;/strong&gt; Always use direct AJAX requests from the browser to the search API. Never route these requests through &lt;code&gt;admin-ajax.php&lt;/code&gt;, as that re-triggers the WordPress overhead you are trying to avoid.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security through Scoping:&lt;/strong&gt; When connecting your WooCommerce store to an external index, use &lt;strong&gt;read-only API credentials&lt;/strong&gt;. Ensure these keys are scoped only to public product data so that sensitive customer info and draft products remain protected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle SKUs Properly:&lt;/strong&gt; Standard tokenizers often strip hyphens or slashes, breaking your SKU lookups. Configure your engine to use an &lt;code&gt;edge-ngram&lt;/code&gt; tokenizer or specific analyzer rules that treat alphanumeric strings as atomic units.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Building Competitive Intelligence
&lt;/h3&gt;

&lt;p&gt;Once your internal search is optimized, look toward external data. For developers building market intelligence engines, tools like &lt;strong&gt;SerpApi&lt;/strong&gt; are invaluable for tracking competitor pricing and search visibility in real-time. By integrating structured search endpoints into your pipeline, you can gain insights into market trends and adjust your pricing strategy dynamically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottom line:&lt;/strong&gt; If your catalog is growing, the default database approach will eventually become a liability. Offloading to an external index isn't just about speed—it's about building a resilient, professional-grade infrastructure that can handle traffic spikes without breaking.&lt;/p&gt;




&lt;p&gt;Originally published at &lt;a href="https://serpapi.org/posts/best-search-api-for-woocommerce-top-choices-for-2026" rel="noopener noreferrer"&gt;Best search API for WooCommerce: top choices for 2026&lt;/a&gt;&lt;/p&gt;

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