{"id":21130432,"url":"https://github.com/serpapi/serpapi-ruby","last_synced_at":"2025-07-09T01:33:30.388Z","repository":{"id":39798323,"uuid":"472166331","full_name":"serpapi/serpapi-ruby","owner":"serpapi","description":"Official Ruby wrapper for SerpApi HTTP endpoints","archived":false,"fork":false,"pushed_at":"2025-06-10T02:56:03.000Z","size":187,"stargazers_count":9,"open_issues_count":0,"forks_count":1,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-06-30T09:15:16.804Z","etag":null,"topics":["api","ruby","search","search-engine","serp","serpapi"],"latest_commit_sha":null,"homepage":"https://serpapi.com","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/serpapi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-03-21T02:53:53.000Z","updated_at":"2025-06-10T02:51:04.000Z","dependencies_parsed_at":"2025-05-28T06:29:30.618Z","dependency_job_id":null,"html_url":"https://github.com/serpapi/serpapi-ruby","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/serpapi/serpapi-ruby","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serpapi%2Fserpapi-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serpapi%2Fserpapi-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serpapi%2Fserpapi-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serpapi%2Fserpapi-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/serpapi","download_url":"https://codeload.github.com/serpapi/serpapi-ruby/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/serpapi%2Fserpapi-ruby/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264375571,"owners_count":23598402,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","ruby","search","search-engine","serp","serpapi"],"created_at":"2024-11-20T05:33:25.324Z","updated_at":"2025-07-09T01:33:30.374Z","avatar_url":"https://github.com/serpapi.png","language":"Ruby","readme":"# SerpApi Ruby Library\n\n[![serpapi-ruby](https://github.com/serpapi/serpapi-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/serpapi/serpapi-ruby/actions/workflows/ci.yml) [![Gem Version](https://badge.fury.io/rb/serpapi.svg)](https://badge.fury.io/rb/serpapi) \n\nIntegrate search data into your AI workflow, RAG / fine tuning or ruby application using this official wrapper for [SerpApi](https://serpapi.com). \n\nSerpApi supports Google, Google Maps, Google Shopping, Baidu, Yandex, Yahoo, eBay, App Stores, and [more.](https://serpapi.com). \n\nFast query at scale a vast range of data, including web search results, flight schedule, stock market data, news headlines, and [more.](https://serpapi.com). \n\n## Features\n  * `persistent` → Keep socket connection open to save on SSL handshake / reconnection (2x faster).  [Search at scale](#Search-At-Scale)\n  * `async` → Support non-blocking job submission. [Search Asynchronous](#Search-Asynchronous)\n  * extensive documentation → easy to follow\n  * real world examples → included throughout\n\n## Installation\n\nTo achieve optimal performance, it is essential to have Ruby 3.1+ (preferably version 3.4) installed. \n\n| Older versions such as Ruby 1.9, 2.x, and JRuby are compatible with [serpapi older library](https://github.com/serpapi/google-search-results-ruby), which continues to function effectively. see [migration guide](#Migration-quick-guide) if you are using the older library.\n\n### Bundler\n```ruby\ngem 'serpapi', '~\u003e 1.0.0'\n```\n\n### Gem \n```bash\n$ gem install serpapi\n```\n\n[Ruby Gem page](https://rubygems.org/gems/serpapi/)\n\n## Simple Usage\n\n```ruby\nrequire 'serpapi'\nclient = SerpApi::Client.new(engine: \"google\", api_key: \"\u003cSERPAPI_KEY\u003e\")\nresults = client.search(q: \"coffee\")\npp results\n ```\n\nThis example runs a search for \"coffee\" on Google. It then returns the results as a regular Ruby Hash.\n See the [playground](https://serpapi.com/playground) to generate your own code.\n\nThe SerpApi key can be obtained from [serpapi.com/signup](https://serpapi.com/users/sign_up?plan=free).\n\nEnvironment variables are a secure, safe, and easy way to manage secrets.\n Set `export SERPAPI_KEY=\u003csecret_serpapi_key\u003e` in your shell.\n Ruby accesses these variables from `ENV['SERPAPI_KEY']`.\n\n\n## Search API advanced usage with Google search engine\n\nThis example dives into all the available parameters for the Google search engine.\n The set of parameters is extensive and depends on the search engine you choose.\n\n```ruby\n# load gem\nrequire 'serpapi'\n\n# serpapi client created with default parameters\nclient = SerpApi::Client.new(\n  engine: 'google',\n  api_key: ENV['SERPAPI_KEY'],\n  # HTTP client configuration\n  async: false, # non blocking HTTP request see: Search Asynchronous (default: false)\n  persistent: true, # leave socket connection open for faster response time see: Search at scale (default: true)\n  timeout: 5, # HTTP timeout in seconds on the client side only. (default: 120s)\n  symbolize_names: true # turn on/off JSON keys to symbols (default: on more efficient)\n)\n\n# search query overview (more fields available depending on search engine)\nparams = {\n  # overview of parameter for Google search engine which one of many search engine supported.\n  # select the search engine (full list: https://serpapi.com/)\n  engine: \"google\",\n  # actual search query\n  q: \"Coffee\",\n  # then adds search engine specific options.\n  # for example: google specific parameters: https://serpapi.com/search-api\n  google_domain: \"Google Domain\",\n  # example: Portland,Oregon,United States [ * doc: Location API](#Location-API)\n  location: \"Location Requested\",\n  device: \"desktop|mobile|tablet\",\n  hl: \"Google UI Language\",\n  gl: \"Google Country\",\n  safe: \"Safe Search Flag\",\n  num: \"Number of Results\",\n  start: \"Pagination Offset\",\n  tbm: \"nws|isch|shop\",\n  tbs: \"custom to be client criteria\",\n}\n\n# search results as a symbolized Hash (per performance)\nresults = client.search(params)\n\n# search results as a raw HTML string\nraw_html = client.html(params) # Corrected parameter reference\n```\n → [SerpApi documentation](https://serpapi.com/search-api).\n\n#### Documentations\nThis library is well documented, and you can find the following resources:\n * [Full documentation on SerpApi.com](https://serpapi.com)\n * [Library Github page](https://github.com/serpapi/serpapi-ruby)\n * [Library GEM page](https://rubygems.org/gems/serpapi/)\n * [Library API documentation](https://rubydoc.info/github/serpapi/serpapi-ruby/master)\n * [API health status](https://serpapi.com/status)\n\n## Advanced search API usage\n### Search Asynchronous\n\nSearch API features non-blocking search using the option: `async=true`.\n - Non-blocking - async=true - a single parent process can handle unlimited concurrent searches.\n - Blocking - async=false - many processes must be forked and synchronized to handle concurrent searches. This strategy is I/O usage because each client would hold a network connection.\n\nSearch API enables `async` search.\n - Non-blocking (`async=true`) : the development is more complex, but this allows handling many simultaneous connections.\n - Blocking (`async=false`) : it is easy to write the code but more compute-intensive when the parent process needs to hold many connections.\n\nHere is an example of asynchronous searches using Ruby \n```ruby\nrequire 'serpapi'\n\ncompany_list = %w[meta amazon apple netflix google]\nclient = SerpApi::Client.new(engine: 'google', async: true, persistent: true, api_key: ENV.fetch('SERPAPI_KEY', nil))\nschedule_search = Queue.new\nresult = nil\ncompany_list.each do |company|\n  result = client.search({ q: company })\n  puts \"#{company}: search results found in cache for: #{company}\" if result[:search_metadata][:status] =~ /Cached/\n\n  schedule_search.push(result[:search_metadata][:id])\nend\n\nputs \"Last search submited at: #{result[:search_metadata][:created_at]}\"\n\nputs 'wait 10s for all requests to be completed '\nsleep(10)\n\nputs 'wait until all searches are cached or success'\nuntil schedule_search.empty?\n  search_id = schedule_search.pop\n\n  search_archived = client.search_archive(search_id)\n\n  company = search_archived[:search_parameters][:q]\n\n  if search_archived[:search_metadata][:status] =~ /Cached|Success/\n    puts \"#{search_archived[:search_parameters][:q]}: search results found in archive for: #{company}\"\n    next\n  end\n\n  schedule_search.push(result)\nend\n\nschedule_search.close\nputs 'done'\n```\n\n * source code: [demo/demo_async.rb](https://github.com/serpapi/serpapi-ruby/blob/master/demo/demo_async.rb)\n\nThis code shows a simple solution to batch searches asynchronously into a [queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)). \nEach search takes a few seconds before completion by SerpApi service and the search engine. By the time the first element pops out of the queue. The search result might be already available in the archive. If not, the `search_archive` method blocks until the search results are available. \n\n### Search at scale\nThe provided code snippet is a Ruby spec test case that demonstrates the use of thread pools to execute multiple HTTP requests concurrently.\n\n```ruby\nrequire 'serpapi'\nrequire 'connection_pool'\n\n# create a thread pool of 4 threads with a persistent connection to serpapi.com\npool = ConnectionPool.new(size: n, timeout: 5) do\n    SerpApi::Client.new(engine: 'google', api_key: ENV['SERPAPI_KEY'], timeout: 30, persistent: true)\nend\n\n# run user thread to search for your favorites coffee type\nthreads = %w(latte espresso cappuccino americano mocha macchiato frappuccino cold_brew).map do |query|\n  Thread.new do\n    pool.with { |socket| socket.search({q: query }).to_s }\n  end\nend\nresponses = threads.map(\u0026:value)\n```\n\nThe code aims to demonstrate how thread pools can be used to \nimprove performance by executing multiple tasks concurrently. In \nthis case, it makes multiple HTTP requests to an API endpoint using \na thread pool of persistent connections.\n\n**Benefits:**\n\n* Improved performance by avoiding the overhead of creating and \ndestroying connections for each request.\n* Efficient use of resources by sharing connections among multiple \nthreads.\n* Concurrency and parallelism, allowing multiple requests to be \nprocessed simultaneously.\n\nbenchmark: (demo/demo_thread_pool.rb)\n\n### Real world search without persistency\n\n```ruby\nrequire 'serpapi'\n\nrequire 'pp'\n\ndefault_params = {\n  engine: 'google',\n  api_key: ENV.fetch('SERPAPI_KEY', nil)\n}\nclient = SerpApi::Client.new(default_params)\nparams = {\n  q: 'coffee'\n}\nresults = client.search(params)\nif !results[:organic_results]\n  puts 'organic results found'\n  exit 1\nend\npp results[:organic_results]\nputs 'done'\nexit 0\n```\n\n * source code: [demo/demo.rb](https://github.com/serpapi/serpapi-ruby/blob/master/demo/demo.rb)\n\n## APIs supported\n### Location API\n\n```ruby\nrequire 'serpapi'\nclient = SerpApi::Client.new() \nlocation_list = client.location(q: \"Austin\", limit: 3)\nputs \"number of location: #{location_list.size}\"\npp location_list\n```\n\nit prints the first 3 locations matching Austin (Texas, Texas, Rochester)\n```ruby\n[{\n  :id=\u003e\"585069bdee19ad271e9bc072\",\n  :google_id=\u003e200635,\n  :google_parent_id=\u003e21176,\n  :name=\u003e\"Austin, TX\",\n  :canonical_name=\u003e\"Austin,TX,Texas,United States\",\n  :country_code=\u003e\"US\",\n  :target_type=\u003e\"DMA Region\",\n  :reach=\u003e5560000,\n  :gps=\u003e[-97.7430608, 30.267153],\n  :keys=\u003e[\"austin\", \"tx\", \"texas\", \"united\", \"states\"]\n  }\n  # ...\n]\n```\n\nNOTE: api_key is not required for this endpoint.\n\n### Search Archive API\n\nThis API allows retrieving previous search results.\nTo fetch earlier results from the search_id.\n\nFirst, you need to run a search and save the search id.\n\n```ruby\nrequire 'serpapi'\nclient = SerpApi::Client.new(engine: 'google', api_key: ENV['SERPAPI_KEY'])\nresults = client.search(q: \"Coffee\", location: \"Portland\")\nsearch_id = results[:search_metadata][:id]\n```\n\nNow we can retrieve the previous search results from the archive using the search id (free of charge).\n\n```ruby\nrequire 'serpapi'\nclient = SerpApi::Client.new(api_key: ENV['SERPAPI_KEY'])\nresults = client.search_archive(search_id)\npp results\n```\n\nThis code prints the search results from the archive. :)\n\n### Account API\n```ruby\nrequire 'serpapi'\nclient = SerpApi::Client.new(api_key: ENV['SERPAPI_KEY'])\npp client.account\n```\n\nIt prints your account information as:\n```ruby\n{\n account_id: \"1234567890\",\n api_key: \"your_secret_key\",\n account_email: \"email@company.com\",\n account_status: \"Active\",\n plan_id: \"free\",\n plan_name: \"Free Plan\",\n plan_monthly_price: 0.0,\n searches_per_month: 100,\n plan_searches_left: 0,\n extra_credits: 100,\n total_searches_left: 10,\n this_month_usage: 100,\n this_hour_searches: 0,\n last_hour_searches: 0,\n account_rate_limit_per_hour: 100\n } \n ```\n\n## Basic example per search engine\n\n### Search google\n\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_spec.rb)\nsee: [https://serpapi.com/search-api](https://serpapi.com/search-api)\n\n### Search google light\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_light', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/google-light-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_light_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_light_spec.rb)\nsee: [https://serpapi.com/google-light-api](https://serpapi.com/google-light-api)\n\n### Search google scholar\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_scholar', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'biology'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/google-scholar-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_scholar_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_scholar_spec.rb)\nsee: [https://serpapi.com/google-scholar-api](https://serpapi.com/google-scholar-api)\n\n### Search google autocomplete\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_autocomplete', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:suggestions]\n# doc: https://serpapi.com/google-autocomplete-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_autocomplete_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_autocomplete_spec.rb)\nsee: [https://serpapi.com/google-autocomplete-api](https://serpapi.com/google-autocomplete-api)\n\n### Search google product\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_product', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee',\n  product_id: '4887235756540435899'\n})\n\n# print the output of the response in formatted JSON\npp results[:product_results]\n# doc: https://serpapi.com/google-product-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_product_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_product_spec.rb)\nsee: [https://serpapi.com/google-product-api](https://serpapi.com/google-product-api)\n\n### Search google reverse image\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_reverse_image', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  image_url: 'https://i.imgur.com/5bGzZi7.jpg'\n})\n\n# print the output of the response in formatted JSON\npp results[:image_sizes]\n# doc: https://serpapi.com/google-reverse-image\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_reverse_image_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_reverse_image_spec.rb)\nsee: [https://serpapi.com/google-reverse-image](https://serpapi.com/google-reverse-image)\n\n### Search google events\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_events', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:events_results]\n# doc: https://serpapi.com/google-events-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_events_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_events_spec.rb)\nsee: [https://serpapi.com/google-events-api](https://serpapi.com/google-events-api)\n\n### Search google local services\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_local_services', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'electrician',\n  data_cid: '6745062158417646970'\n})\n\n# print the output of the response in formatted JSON\npp results[:local_ads]\n# doc: https://serpapi.com/google-local-services-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_local_services_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_local_services_spec.rb)\nsee: [https://serpapi.com/google-local-services-api](https://serpapi.com/google-local-services-api)\n\n### Search google maps\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_maps', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'Coffee',\n  ll: '@40.7455096,-74.0083012,14z',\n  type: 'search'\n})\n\n# print the output of the response in formatted JSON\npp results[:local_results]\n# doc: https://serpapi.com/google-maps-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_maps_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_maps_spec.rb)\nsee: [https://serpapi.com/google-maps-api](https://serpapi.com/google-maps-api)\n\n### Search google jobs\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_jobs', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:jobs_results]\n# doc: https://serpapi.com/google-jobs-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_jobs_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_jobs_spec.rb)\nsee: [https://serpapi.com/google-jobs-api](https://serpapi.com/google-jobs-api)\n\n### Search google play\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_play', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'kite',\n  store: 'apps'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/google-play-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_play_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_play_spec.rb)\nsee: [https://serpapi.com/google-play-api](https://serpapi.com/google-play-api)\n\n### Search google images\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_images', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  tbm: 'isch',\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:images_results]\n# doc: https://serpapi.com/images-results\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_images_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_images_spec.rb)\nsee: [https://serpapi.com/images-results](https://serpapi.com/images-results)\n\n### Search google lens\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_lens', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  url: 'https://i.imgur.com/HBrB8p0.png'\n})\n\n# print the output of the response in formatted JSON\npp results[:visual_matches]\n# doc: https://serpapi.com/google-lens-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_lens_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_lens_spec.rb)\nsee: [https://serpapi.com/google-lens-api](https://serpapi.com/google-lens-api)\n\n### Search google images light\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_images_light', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'Coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:images_results]\n# doc: https://serpapi.com/google-images-light-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_images_light_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_images_light_spec.rb)\nsee: [https://serpapi.com/google-images-light-api](https://serpapi.com/google-images-light-api)\n\n### Search google hotels\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_hotels', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'Bali Resorts',\n  check_in_date: '2025-05-26',\n  check_out_date: '2025-05-27',\n  adults: '2',\n  currency: 'USD',\n  gl: 'us',\n  hl: 'en'\n})\n\n# print the output of the response in formatted JSON\npp results[:properties]\n# doc: https://serpapi.com/google-hotels-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_hotels_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_hotels_spec.rb)\nsee: [https://serpapi.com/google-hotels-api](https://serpapi.com/google-hotels-api)\n\n### Search google flights\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_flights', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  departure_id: 'PEK',\n  arrival_id: 'AUS',\n  outbound_date: '2025-05-26',\n  return_date: '2025-06-01',\n  currency: 'USD',\n  hl: 'en'\n})\n\n# print the output of the response in formatted JSON\npp results[:best_flights]\n# doc: https://serpapi.com/google-flights-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_flights_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_flights_spec.rb)\nsee: [https://serpapi.com/google-flights-api](https://serpapi.com/google-flights-api)\n\n### Search google finance\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_finance', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'GOOG:NASDAQ'\n})\n\n# print the output of the response in formatted JSON\npp results[:markets]\n# doc: https://serpapi.com/google-finance-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_finance_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_finance_spec.rb)\nsee: [https://serpapi.com/google-finance-api](https://serpapi.com/google-finance-api)\n\n### Search google ai overview\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_ai_overview', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  page_token: 'KIVu-nictZPdjrI4GMeTPdkrWU8cFXV0dBKyKbUgiigy6OgJQawFQapUBpmzvZe9qr2aLYzO6I5vsm-yW0Ip7dPn4__L88efoR8Ff_36i3c87tlzrZamaZVQSkJcdemu5rAscmsbGrLY9X5PkhCLaRkC1VCh6hivs_e1EiaaPA2xIr9r8ixxXqfhEkova0UWlq-jEgnFhJW8UMRRKXsTmyWXiUIJ-2JTJ2jZxnTINvK-8zgJBtEiM4JSEVG0Vw7DW57Qactqdo1PwW_NHv-psiqObMusqpNU7ZM-OFlWFbNWdVxzdtwE_NsBv5YSJMblF5K71vwcgkAqlvk0569vIPXsx0D5pALt0Tbd6yAqUD4jJfxVZYAu0dN8gc6H9MfREVKlyu2WWszcgQx4zCKlD0dGnmJ_wEu6mI5BBfQJHkknc_69LGK8gP5e65BzXTeDDEziu0wH0KitCRdXqK1i_qnXYpZLDV-6ApW7TlzvmoJE585mMs2icNfe4-28-dYBDwVGl31yZNcc9acEefre8kxQ1apS_YLQGFMuZZ7OAPSl_T0cXAD0hZDXTPjDUMp3ehlfAj3fAL2Uu3G55eJyL_isTbLgl7NcPpRLJ5-lLdwWMCDKD-E4FyvHE3CEfTrN0JkAzC8qCliQQ35jiMk5pQ9FFx-6WoU5gmBiqJIKJBW6eRflSYaFMTpXQhDwB8EtQgDMuyJcj-EP9iVwh5nSSA9O3PXh-MWakaC52oRuJREk3dxcmNHd6qeaz_1_uHq8NZMzV3if621rEmkOL62Za4KMnKuhX7XmmesIKAieuSZXXOFPcEXWKG_N71zTgitvTatgm3M1tv_k-l-1ZoEXf3xu-zTZkm_92obr02LIdCKkM_9oyVJMuo2t5Wmx8WBvdsfnfUzJg-2vn6XG4JitSwfRo2l5TTErO_GxnNI4KPtR2YnWMfXXpV0YU1FwWvG7NyOVXlyJvK129AUN6TFI3JPk4MZ4OfLdKNzoShtnpl3RfNxij748svedxMtmmI3e-gc6kgJFVye-qg48j7Rwo71OcbA7dA9-NBe2o2napHMzmuMFQWqr9zSVtJXmKbbej73jI7XHPaymnfBdEIqsmPg6RI_L1URaVmiJuY6N2ZtYb3U3zSen3mjV611h0y3tyDHbi_W_AU9HHA0'\n})\n\n# print the output of the response in formatted JSON\npp results[:ai_overview]\n# doc: https://serpapi.com/google-ai-overview-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_ai_overview_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_ai_overview_spec.rb)\nsee: [https://serpapi.com/google-ai-overview-api](https://serpapi.com/google-ai-overview-api)\n\n### Search google news\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_news', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'pizza',\n  gl: 'us',\n  hl: 'en'\n})\n\n# print the output of the response in formatted JSON\npp results[:news_results]\n# doc: https://serpapi.com/google-news-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_news_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_news_spec.rb)\nsee: [https://serpapi.com/google-news-api](https://serpapi.com/google-news-api)\n\n### Search google news light\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_news_light', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'pizza'\n})\n\n# print the output of the response in formatted JSON\npp results[:news_results]\n# doc: https://serpapi.com/google-news-light-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_news_light_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_news_light_spec.rb)\nsee: [https://serpapi.com/google-news-light-api](https://serpapi.com/google-news-light-api)\n\n### Search google patents\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_patents', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: '(Coffee)'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/google-patents-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_patents_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_patents_spec.rb)\nsee: [https://serpapi.com/google-patents-api](https://serpapi.com/google-patents-api)\n\n### Search google trends\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_trends', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee,milk,bread,pasta,steak',\n  data_type: 'TIMESERIES'\n})\n\n# print the output of the response in formatted JSON\npp results[:interest_over_time]\n# doc: https://serpapi.com/google-trends-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_trends_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_trends_spec.rb)\nsee: [https://serpapi.com/google-trends-api](https://serpapi.com/google-trends-api)\n\n### Search google shopping\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_shopping', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'Macbook M4'\n})\n\n# print the output of the response in formatted JSON\npp results[:shopping_results]\n# doc: https://serpapi.com/google-shopping-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_shopping_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_shopping_spec.rb)\nsee: [https://serpapi.com/google-shopping-api](https://serpapi.com/google-shopping-api)\n\n### Search google immersive product\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_immersive_product', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:immersive_product_results]\n# doc: https://serpapi.com/google-immersive-product-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_immersive_product_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_immersive_product_spec.rb)\nsee: [https://serpapi.com/google-immersive-product-api](https://serpapi.com/google-immersive-product-api)\n\n### Search google videos\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'google_videos', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/google-videos-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_google_videos_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_google_videos_spec.rb)\nsee: [https://serpapi.com/google-videos-api](https://serpapi.com/google-videos-api)\n\n### Search amazon\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'amazon', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/amazon-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_amazon_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_amazon_spec.rb)\nsee: [https://serpapi.com/amazon-search-api](https://serpapi.com/amazon-search-api)\n\n### Search baidu\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'baidu', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/baidu-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_baidu_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_baidu_spec.rb)\nsee: [https://serpapi.com/baidu-search-api](https://serpapi.com/baidu-search-api)\n\n### Search yahoo\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'yahoo', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  p: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/yahoo-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_yahoo_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_yahoo_spec.rb)\nsee: [https://serpapi.com/yahoo-search-api](https://serpapi.com/yahoo-search-api)\n\n### Search youtube\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'youtube', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  search_query: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:video_results]\n# doc: https://serpapi.com/youtube-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_youtube_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_youtube_spec.rb)\nsee: [https://serpapi.com/youtube-search-api](https://serpapi.com/youtube-search-api)\n\n### Search walmart\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'walmart', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  query: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/walmart-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_walmart_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_walmart_spec.rb)\nsee: [https://serpapi.com/walmart-search-api](https://serpapi.com/walmart-search-api)\n\n### Search ebay\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'ebay', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  _nkw: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/ebay-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_ebay_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_ebay_spec.rb)\nsee: [https://serpapi.com/ebay-search-api](https://serpapi.com/ebay-search-api)\n\n### Search naver\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'naver', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  query: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:ads_results]\n# doc: https://serpapi.com/naver-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_naver_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_naver_spec.rb)\nsee: [https://serpapi.com/naver-search-api](https://serpapi.com/naver-search-api)\n\n### Search home depot\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'home_depot', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'table'\n})\n\n# print the output of the response in formatted JSON\npp results[:products]\n# doc: https://serpapi.com/home-depot-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_home_depot_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_home_depot_spec.rb)\nsee: [https://serpapi.com/home-depot-search-api](https://serpapi.com/home-depot-search-api)\n\n### Search apple app store\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'apple_app_store', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  term: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/apple-app-store\n```\n\n * source code: [spec/serpapi/client/example/example_search_apple_app_store_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_apple_app_store_spec.rb)\nsee: [https://serpapi.com/apple-app-store](https://serpapi.com/apple-app-store)\n\n### Search duckduckgo\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'duckduckgo', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  q: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/duckduckgo-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_duckduckgo_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_duckduckgo_spec.rb)\nsee: [https://serpapi.com/duckduckgo-search-api](https://serpapi.com/duckduckgo-search-api)\n\n### Search yandex\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'yandex', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  text: 'coffee'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/yandex-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_yandex_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_yandex_spec.rb)\nsee: [https://serpapi.com/yandex-search-api](https://serpapi.com/yandex-search-api)\n\n### Search yelp\n```ruby\nrequire 'serpapi'\n# initialize the serp api client\nclient = SerpApi::Client.new(engine: 'yelp', api_key: ENV['SERPAPI_KEY'])\n# run a search using serpapi service\nresults = client.search({\n  find_desc: 'Coffee',\n  find_loc: 'New York, NY, USA'\n})\n\n# print the output of the response in formatted JSON\npp results[:organic_results]\n# doc: https://serpapi.com/yelp-search-api\n```\n\n * source code: [spec/serpapi/client/example/example_search_yelp_spec.rb](https://github.com/serpapi/serpapi-ruby/blob/master/spec/serpapi/client/example/example_search_yelp_spec.rb)\nsee: [https://serpapi.com/yelp-search-api](https://serpapi.com/yelp-search-api)\n\n## Migration quick guide\n\nif you were already using (google-search-results-ruby gem)[https://github.com/serpapi/google-search-results-ruby], here are the changes.\n\n```\n# load library\n# old way \nrequire 'google_search_results'\n# new way\nrequire 'serpapi'\n\n# define a search\n# old way to describe the search\nsearch = GoogleSearch.new(search_params)\n# new way \ndefault_parameter = {api_key: \"secret_key\", engine: \"google\"}\nclient = SerpApi::Client.new(default_parameter)\n# an instance of the serpapi client is created\n# where the default parameters are stored in the client.\n#   like api_key, engine\n#  then each subsequent API call can be made with additional parameters.\n\n# override an existing parameter\n# old way\nsearch.params[:location] = \"Portland,Oregon,United States\"\n# new way\n# just provided the search call with the parameters.\nresults = client.search({location: \"Portland,Oregon,United States\", q: \"Coffe\"})\n\n# search format return as raw html\n# old way\nhtml_results = search.get_html\n# new way\nraw_html = client.html(params)\n# where params is Hash containing additional key / value\n\n# search format returns a Hash\n# old way\nhash_results = search.get_hash\n# new way\nresults = client.search(params)\n# where params is the search parameters (override the default search parameters in the constructor). \n\n# search as raw JSON format\n# old way\njson_results = search.get_json\n# new way\nresults = client.search(params)\n\n# The prefix get_ is removed from all other methods.\n#  Because it's evident that a method returns something.\n# old -\u003e new way\nsearch.get_search_archive -\u003e client.search_archive\nsearch.get_account -\u003e client.account\nsearch.get_location -\u003e client.location\n```\n\nMost notable improvements:\n - Removing parameters check on the client side. (most of the bugs)\n - Reduce logic complexity in our implementation. (faster performance)\n - Better documentation.\n\n## Supported Ruby version.\nRuby versions validated by Github Actions:\n - 3.1\n - 3.4\n * doc: [Github Actions.](https://github.com/serpapi/serpapi-ruby/actions/workflows/ci.yml)\n\n## Change logs\n * [2025-07-01] 1.0.0 Full API support\n\n## Developer Guide\n### Key goals\n - Brand centric instead of search engine based\n   - No hard-coded logic per search engine\n - Simple HTTP client (lightweight, reduced dependency)\n   - No magic default values\n   - Thread safe\n - Easy extension\n - Defensive code style (raise a custom exception)\n - TDD - Test driven development\n - Best API coding practice per platform\n - KiSS principles\n\n### Inspirations\nThis project source code and coding style was inspired by the most awesome Ruby Gems:\n - [bcrypt](https://github.com/bcrypt-ruby/bcrypt-ruby)\n - [Nokogiri](https://nokogiri.org)\n - [Cloudfare](https://rubygems.org/gems/cloudflare/versions/2.1.0)\n - [rest-client](https://rubygems.org/gems/rest-client)\n - [stripe](https://rubygems.org/gems/stripe)\n \n### Code quality expectations\n - 0 lint offense: `rake lint`\n - 100% tests passing: `rake test`\n - 100% code coverage: `rake test` (simple-cov)\n\n# Developer Guide\n## Design : UML diagram\n### Class diagram\n```mermaid\nclassDiagram\n  Application *-- serpapi \n  serpapi *-- Client\n  class Client {\n    engine String\n    api_key String\n    params Hash\n    search() Hash\n    html() String\n    location() String\n    search_archive() Hash\n    account() Hash\n  }\n  openuri \u003c.. Client\n  json \u003c.. Client\n  Ruby \u003c.. openuri\n  Ruby \u003c.. json\n```\n### search() : Sequence diagram\n```mermaid\nsequenceDiagram\n    Client-\u003e\u003eSerpApi.com: search() : http request \n    SerpApi.com--\u003e\u003eSerpApi.com: query search engine\n    SerpApi.com--\u003e\u003eSerpApi.com: parse HTML into JSON\n    SerpApi.com--\u003e\u003eClient: JSON string payload\n    Client--\u003e\u003eClient: decode JSON into Hash\n```\nwhere:\n  - The end user implements the application.\n  - Client refers to SerpApi:Client.\n  - SerpApi.com is the backend HTTP / REST service.\n  - Engine refers to Google, Baidu, Bing, and more.\n\nThe SerpApi.com service (backend)\n - executes a scalable search on `engine: \"google\"` using the search query: `q: \"coffee\"`.\n - parses the messy HTML responses from Google on the backend.\n - returns a standardized JSON response.\nThe class SerpApi::Client (client side / ruby):\n - Format the request to SerpApi.com server.\n - Execute HTTP Get request.\n - Parse JSON into Ruby Hash using a standard JSON library.\nEt voila!\n\n## Continuous integration\nWe love [continuous integration](https://en.wikipedia.org/wiki/Continuous_integration) (CI) and [Test-Driven Development](https://en.wikipedia.org/wiki/Test-driven_development) (TDD) at SerpApi. \n We use RSpec and Github Actions to test our infrastructure around the clock, and that includes all changes to our clients.\n\nThe directory spec/ includes specification which serves the dual purposes of examples and functional tests.\n\nSet your secret API key in your shell before running a test. \n The SerpApi key can be obtained from [serpapi.com/signup](https://serpapi.com/users/sign_up?plan=free).\n```bash\nexport SERPAPI_KEY=\"your_secret_key\"\n```\nInstall testing dependency\n```bash\n$ bundle install\n# or\n$ rake dependency\n```\n\nCheck code quality using Lint.\n```bash\n$ rake lint\n```\n\nRun basic test\n```bash\n$ rake test\n```\n\nReview coverage report generated by `rake test`\n```sh\nopen coverage/index.html\n```\n\nReview documentation generated by `rake doc`\n```sh\nopen doc/index.html\n```\n\nRun full regression test suite on the examples.\n```bash\nrake regression\n```\n\nTest the actuall packaged gem locally using the demo scripts.\n```bash\n$ rake oobt\n```\n\nOpen ./Rakefile for more information.\n\nContributions are welcome. Feel to submit a pull request!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserpapi%2Fserpapi-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fserpapi%2Fserpapi-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fserpapi%2Fserpapi-ruby/lists"}