# Agent Skills Source: https://docs.hasdata.com/agent-skill Ready-made skills that teach AI coding agents how to use HasData. HasData ships a small set of agent skills at [github.com/HasData/agent-skills](https://github.com/HasData/agent-skills). Drop them into Claude Code (or any agentskills.io-compatible client) and your agent stops guessing endpoints and parameters. Two skills are available: * **`hasdata`** wires the HasData APIs into your code (Python, TypeScript, Go). Covers SERP, all Scraper APIs (Amazon, Zillow, Maps, Indeed, Instagram, and so on), and the async Scraper Jobs lifecycle. * **`hasdata-cli`** is for terminal work: shell pipelines, CI jobs, one-off lookups using the [HasData CLI](/cli). ## Prerequisites 1. A HasData account ([sign up](https://app.hasdata.com)). 2. Your API key in the `HASDATA_API_KEY` environment variable. 3. The [HasData CLI](/cli) installed if you want to use the `hasdata-cli` skill. ## Install ```bash Universal theme={null} npx skills add hasdata/agent-skills ``` ```bash Claude Code theme={null} /plugin marketplace add https://github.com/HasData/agent-skills /plugin install hasdata@hasdata-agent-skills /plugin install hasdata-cli@hasdata-agent-skills ``` For Cursor, Windsurf, or VS Code, clone the repo and point your agent at the local `skills/` directory. For anything else, reference the individual `SKILL.md` files directly. ## What's inside the `hasdata` skill The skill loads on demand and pulls in topical reference files only when relevant, so your context stays small: * `web-scraping.md` for Web Scraping API parameters and gotchas. * `search.md` for Google SERP, AI Mode, and Bing. * `ecommerce.md` for Amazon and Shopify. * `real-estate.md` for Zillow, Redfin, and Airbnb. * `local-business.md` for Google Maps, Yelp, and Yellow Pages. * `jobs.md` for Indeed and Glassdoor. * `scraper-jobs.md` for the async submit, poll, paginate, stop flow. * `code-recipes.md` for working snippets in Python, TypeScript, and Go. ## Usage Once installed, the skill activates on its own when your prompt looks like a HasData job: web scraping, SERP, lead enrichment, RAG ingestion, price tracking, and so on. You can also invoke it explicitly with `/hasdata` or `/hasdata-cli`. ## Updating Skills update with the API. Re-run `npx skills add hasdata/agent-skills` to refresh, or `git pull` if you cloned the repo. # API Status Codes Source: https://docs.hasdata.com/api-codes The API will return a specific status code after every request depending on whether the request was successful, failed or some other error occurred. To avoid timing out your request remember to set your timeout to 300 seconds. In cases where a request fails after 300 seconds, you will not be charged for the unsuccessful request. You are only charged for successful requests. We are considering successful requests that have 200 status code & `status: "ok"` in the response JSON. ## Status Codes | Code | Details | | ---- | ---------------------------------------------------------------------------------------------------------------------- | | 200 | Successful response. | | 404 | Requested page does not exists. | | 500 | HasData server error. If you received 500 status code retry request, if the problem is not solved contact our support. | | 429 | You are sending requests too fast, and exceeding your concurrency limit. | | 403 | You have used app all your API credits. | | 401 | Invalid API key. | ## Handling Occasional Errors In rare cases (1–2% of requests), especially on harder-to-scrape websites, a request might fail due to temporary issues on the target site. * **Automatic Retry**: Set up your code to retry failed requests. Most of the time, a retry will succeed. * **Consistent Failures**: If a request keeps failing, double-check your parameters and request structure. * **Persistent Failures**: If requests to a particular target keep failing, open a support ticket and we'll investigate. These situations are uncommon, but it’s a good idea to handle errors gracefully to ensure smooth data collection. # Airbnb Listing Scraper API Source: https://docs.hasdata.com/apis/airbnb/listing The Airbnb Listing Scraper API allows users to retrieve listings from Airbnb based on location and check-in/check-out dates. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Airbnb. Airbnb is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Airbnb Listing Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/airbnb/listing' \ --data-urlencode 'checkIn=2026-09-20' \ --data-urlencode 'checkOut=2026-09-24' \ --data-urlencode 'neLat=40.8' \ --data-urlencode 'neLng=-73.9' \ --data-urlencode 'swLat=40.6' \ --data-urlencode 'swLng=-74.1' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata airbnb-listing \ --check-in 2026-09-20 \ --check-out 2026-09-24 \ --ne-lat 40.8 \ --ne-lng -73.9 \ --sw-lat 40.6 \ --sw-lng -74.1 ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/airbnb/listing', params: { checkIn: '2026-09-20', checkOut: '2026-09-24', neLat: '40.8', neLng: '-73.9', swLat: '40.6', swLng: '-74.1' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/airbnb/listing" querystring = {"checkIn":"2026-09-20","checkOut":"2026-09-24","neLat":"40.8","neLng":"-73.9","swLat":"40.6","swLng":"-74.1"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "2026-09-20", "checkOut" => "2026-09-24", "neLat" => "40.8", "neLng" => "-73.9", "swLat" => "40.6", "swLng" => "-74.1", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/airbnb/listing?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/airbnb/listing") .newBuilder() .addQueryParameter("checkIn", "2026-09-20") .addQueryParameter("checkOut", "2026-09-24") .addQueryParameter("neLat", "40.8") .addQueryParameter("neLng", "-73.9") .addQueryParameter("swLat", "40.6") .addQueryParameter("swLng", "-74.1") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["checkIn"] = "2026-09-20"; query["checkOut"] = "2026-09-24"; query["neLat"] = "40.8"; query["neLng"] = "-73.9"; query["swLat"] = "40.6"; query["swLng"] = "-74.1"; var url = $"https://api.hasdata.com/scrape/airbnb/listing?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/airbnb/listing") params = { "checkIn" => "2026-09-20", "checkOut" => "2026-09-24", "neLat" => "40.8", "neLng" => "-73.9", "swLat" => "40.6", "swLng" => "-74.1", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/airbnb/listing") .query(&[("checkIn", "2026-09-20")]) .query(&[("checkOut", "2026-09-24")]) .query(&[("neLat", "40.8")]) .query(&[("neLng", "-73.9")]) .query(&[("swLat", "40.6")]) .query(&[("swLng", "-74.1")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("checkIn", "2026-09-20") params.Set("checkOut", "2026-09-24") params.Set("neLat", "40.8") params.Set("neLng", "-73.9") params.Set("swLat", "40.6") params.Set("swLng", "-74.1") u := "https://api.hasdata.com/scrape/airbnb/listing?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `location` | - | No | The location to search for listings. Required unless a full map bounding box (neLat, neLng, swLat, swLng) is provided. | | `checkIn` | 2026-09-20 | Yes | The check-in date for the listings. | | `checkOut` | 2026-09-24 | No | The check-out date for the listings. | | `adults` | - | No | Number of adults.
| | `children` | - | No | Number of children.
| | `infants` | - | No | Number of infants.
| | `pets` | - | No | Number of pets.
| | `neLat` | 40.8 | No | North-east corner latitude of the map bounding box. When all four bounding-box coordinates are provided, listings are searched within the box instead of by location.
| | `neLng` | -73.9 | No | North-east corner longitude of the map bounding box.
| | `swLat` | 40.6 | No | South-west corner latitude of the map bounding box.
| | `swLng` | -74.1 | No | South-west corner longitude of the map bounding box.
| | `nextPageToken` | - | No | The token used to retrieve the next page of results. | # Airbnb Property Scraper API Source: https://docs.hasdata.com/apis/airbnb/property The Airbnb Property Scraper API allows users to retrieve detailed information about a specific Airbnb listing using its URL. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Airbnb. Airbnb is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Airbnb Property Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/airbnb/property' \ --data-urlencode 'url=https://www.airbnb.com/rooms/7777642' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata airbnb-property \ --url 'https://www.airbnb.com/rooms/7777642' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/airbnb/property', params: {url: 'https://www.airbnb.com/rooms/7777642'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/airbnb/property" querystring = {"url":"https://www.airbnb.com/rooms/7777642"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "https://www.airbnb.com/rooms/7777642", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/airbnb/property?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/airbnb/property") .newBuilder() .addQueryParameter("url", "https://www.airbnb.com/rooms/7777642") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["url"] = "https://www.airbnb.com/rooms/7777642"; var url = $"https://api.hasdata.com/scrape/airbnb/property?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/airbnb/property") params = { "url" => "https://www.airbnb.com/rooms/7777642", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/airbnb/property") .query(&[("url", "https://www.airbnb.com/rooms/7777642")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("url", "https://www.airbnb.com/rooms/7777642") u := "https://api.hasdata.com/scrape/airbnb/property?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | ---------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------ | | `url` | [https://www.airbnb.com/rooms/7777642](https://www.airbnb.com/rooms/7777642) | Yes | The URL of the Airbnb listing. Must be a valid Airbnb listing URL. | # Amazon Product Scraper API Source: https://docs.hasdata.com/apis/amazon/product The Amazon Product Scraper API allows users to get product details from Amazon based on the specified ASIN and domain. This API enables retrieving detailed information about a specific product on Amazon. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Amazon. Amazon is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Amazon Product Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/amazon/product' \ --data-urlencode 'asin=B0DHJ7SBDR' \ --data-urlencode 'otherSellers=true' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata amazon-product \ --asin B0DHJ7SBDR \ --other-sellers ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/amazon/product', params: {asin: 'B0DHJ7SBDR', otherSellers: 'true'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/amazon/product" querystring = {"asin":"B0DHJ7SBDR","otherSellers":"true"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "B0DHJ7SBDR", "otherSellers" => "true", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/amazon/product?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/amazon/product") .newBuilder() .addQueryParameter("asin", "B0DHJ7SBDR") .addQueryParameter("otherSellers", "true") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["asin"] = "B0DHJ7SBDR"; query["otherSellers"] = "true"; var url = $"https://api.hasdata.com/scrape/amazon/product?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/amazon/product") params = { "asin" => "B0DHJ7SBDR", "otherSellers" => "true", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/amazon/product") .query(&[("asin", "B0DHJ7SBDR")]) .query(&[("otherSellers", "true")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("asin", "B0DHJ7SBDR") params.Set("otherSellers", "true") u := "https://api.hasdata.com/scrape/amazon/product?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------------ | ------------- | -------- | ------------------------------------------------------------------------------ | | `asin` | B0DHJ7SBDR | Yes | The Amazon Standard Identification Number (ASIN) of the product. | | `domain` | - | No | Amazon domain to use. Default is [www.amazon.com](http://www.amazon.com). | | `language` | - | No | Optional Amazon language code. Supported values depend on the selected domain. | | `deliveryZip` | - | No | Postal code of the delivery location. | | `shippingLocation` | - | No | The two-letter country code to define the country of the delivery address. | | `otherSellers` | true | No | If set to true, extracts the other sellers block from the product page. | # Amazon Search Scraper API Source: https://docs.hasdata.com/apis/amazon/search The Amazon Search Scraper API allows users to get search results from Amazon based on the specified query and domain. This API enables searching for products on Amazon. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Amazon. Amazon is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Amazon Search Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/amazon/search' \ --data-urlencode 'q=Laptop' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata amazon-search \ --q Laptop ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/amazon/search', params: {q: 'Laptop'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/amazon/search" querystring = {"q":"Laptop"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Laptop", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/amazon/search?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/amazon/search") .newBuilder() .addQueryParameter("q", "Laptop") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Laptop"; var url = $"https://api.hasdata.com/scrape/amazon/search?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/amazon/search") params = { "q" => "Laptop", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/amazon/search") .query(&[("q", "Laptop")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Laptop") u := "https://api.hasdata.com/scrape/amazon/search?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------------ | ------------- | -------- | ------------------------------------------------------------------------------------- | | `q` | Laptop | Yes | The search term for which to get the search results. | | `domain` | - | No | Amazon domain to use. Default is [www.amazon.com](http://www.amazon.com). | | `language` | - | No | Optional Amazon language code. Supported values depend on the selected domain. | | `page` | - | No | Page number for pagination (e.g., 1 for the first page, 2 for the second page, etc.). | | `deliveryZip` | - | No | Postal code of the delivery location. | | `shippingLocation` | - | No | The two-letter country code to define the country of the delivery address. | | `sortBy` | - | No | Parameter used for sorting results | # Amazon Seller Scraper API Source: https://docs.hasdata.com/apis/amazon/seller The Amazon Seller Scraper API allows users to retrieve detailed information about a specific Amazon seller using the seller ID, with optional domain and language settings. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Amazon. Amazon is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Amazon Seller Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/amazon/seller' \ --data-urlencode 'sellerId=ATQQBVXK188KS' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata amazon-seller \ --seller-id ATQQBVXK188KS ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/amazon/seller', params: {sellerId: 'ATQQBVXK188KS'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/amazon/seller" querystring = {"sellerId":"ATQQBVXK188KS"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "ATQQBVXK188KS", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/amazon/seller?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/amazon/seller") .newBuilder() .addQueryParameter("sellerId", "ATQQBVXK188KS") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["sellerId"] = "ATQQBVXK188KS"; var url = $"https://api.hasdata.com/scrape/amazon/seller?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/amazon/seller") params = { "sellerId" => "ATQQBVXK188KS", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/amazon/seller") .query(&[("sellerId", "ATQQBVXK188KS")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("sellerId", "ATQQBVXK188KS") u := "https://api.hasdata.com/scrape/amazon/seller?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------- | ------------- | -------- | ------------------------------------------------------------------------------ | | `sellerId` | ATQQBVXK188KS | Yes | The unique Amazon seller ID. | | `domain` | - | No | Amazon domain to use. Default is [www.amazon.com](http://www.amazon.com). | | `language` | - | No | Optional Amazon language code. Supported values depend on the selected domain. | # Amazon Seller Products Scraper API Source: https://docs.hasdata.com/apis/amazon/seller-products The Amazon Seller Products Scraper API allows users to retrieve products listed by a specific Amazon seller using the seller ID, with optional domain, language, and page settings. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Amazon. Amazon is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Amazon Seller Products Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/amazon/seller-products' \ --data-urlencode 'sellerId=ATQQBVXK188KS' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata amazon-seller-products \ --seller-id ATQQBVXK188KS ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/amazon/seller-products', params: {sellerId: 'ATQQBVXK188KS'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/amazon/seller-products" querystring = {"sellerId":"ATQQBVXK188KS"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "ATQQBVXK188KS", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/amazon/seller-products?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/amazon/seller-products") .newBuilder() .addQueryParameter("sellerId", "ATQQBVXK188KS") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["sellerId"] = "ATQQBVXK188KS"; var url = $"https://api.hasdata.com/scrape/amazon/seller-products?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/amazon/seller-products") params = { "sellerId" => "ATQQBVXK188KS", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/amazon/seller-products") .query(&[("sellerId", "ATQQBVXK188KS")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("sellerId", "ATQQBVXK188KS") u := "https://api.hasdata.com/scrape/amazon/seller-products?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------- | ------------- | -------- | ------------------------------------------------------------------------------------- | | `sellerId` | ATQQBVXK188KS | Yes | The unique Amazon seller ID. | | `domain` | - | No | Amazon domain to use. Default is [www.amazon.com](http://www.amazon.com). | | `language` | - | No | Optional Amazon language code. Supported values depend on the selected domain. | | `page` | - | No | Page number for pagination (e.g., 1 for the first page, 2 for the second page, etc.). | # Bing SERP API Source: https://docs.hasdata.com/apis/bing/serp The Bing SERP API provides real-time access to structured Bing search results with a high success rate at scale. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Bing SERP API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/bing/serp' \ --data-urlencode 'q=Coffee' \ --data-urlencode 'location=Austin, Texas, United States' \ --data-urlencode 'deviceType=desktop' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata bing-serp \ --q Coffee \ --location 'Austin, Texas, United States' \ --device-type desktop ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/bing/serp', params: {q: 'Coffee', location: 'Austin, Texas, United States', deviceType: 'desktop'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/bing/serp" querystring = {"q":"Coffee","location":"Austin, Texas, United States","deviceType":"desktop"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Coffee", "location" => "Austin, Texas, United States", "deviceType" => "desktop", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/bing/serp?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/bing/serp") .newBuilder() .addQueryParameter("q", "Coffee") .addQueryParameter("location", "Austin, Texas, United States") .addQueryParameter("deviceType", "desktop") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Coffee"; query["location"] = "Austin, Texas, United States"; query["deviceType"] = "desktop"; var url = $"https://api.hasdata.com/scrape/bing/serp?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/bing/serp") params = { "q" => "Coffee", "location" => "Austin, Texas, United States", "deviceType" => "desktop", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/bing/serp") .query(&[("q", "Coffee")]) .query(&[("location", "Austin, Texas, United States")]) .query(&[("deviceType", "desktop")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Coffee") params.Set("location", "Austin, Texas, United States") params.Set("deviceType", "desktop") u := "https://api.hasdata.com/scrape/bing/serp?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------ | ---------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Coffee | Yes | Specify the search term for which you want to scrape the SERP. | | `location` | Austin, Texas, United States | No | Defines the search’s origin location as free text (e.g. `Austin, Texas`). It is resolved to coordinates to localize the results. For realistic results, set location at the city level. If both `lat` and `lon` are provided, they take precedence and `location` is ignored. If omitted, the proxy’s location may be used. | | `lat` | - | No | GPS latitude for the search origin. | | `lon` | - | No | GPS longitude for the search origin. | | `mkt` | - | No | The two-letter country code for the country to search from. | | `cc` | - | No | The two-letter country code for the country to search from. | | `setLang` | - | No | The language of the user interface and preferred result language. Accepts a two-letter language code (e.g. `en`, `de`) or a locale/script variant (e.g. `en-gb`, `zh-hans`, `pt-br`). | | `safeSearch` | - | No | Adult Content Filtering option. | | `filters` | - | No | Allows applying various filters to narrow search results, including date-based options:

- `ex1:"ez1"` – past 24 hours
- `ex1:"ez2"` – past week
- `ex1:"ez3"` – past month

For complex filters, run a Bing search and copy the filters parameter from the URL.
| | `deviceType` | desktop | No | Specify the device type for the search. | | `first` | - | No | This parameter specifies the number of search results to skip and is used for implementing pagination. For example, a value of 1 (default) indicates the first page of results, 11 refers to the second page, and 21 to the third page.
| # Booking.com Place Scraper API Source: https://docs.hasdata.com/apis/booking/place The Booking.com Place API returns full details for a single Booking.com property along with the list of available room suites for the requested stay dates and guest composition. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Booking.com. Booking.com is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Booking.com Place Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/booking/place' \ --data-urlencode 'url=https://www.booking.com/hotel/fr/le-bristol-paris.html' \ --data-urlencode 'checkInDate=2026-09-20' \ --data-urlencode 'checkOutDate=2026-09-24' \ --data-urlencode 'rooms=1' \ --data-urlencode 'adults=2' \ --data-urlencode 'children=0' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/booking/place', params: { url: 'https://www.booking.com/hotel/fr/le-bristol-paris.html', checkInDate: '2026-09-20', checkOutDate: '2026-09-24', rooms: '1', adults: '2', children: '0' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/booking/place" querystring = {"url":"https://www.booking.com/hotel/fr/le-bristol-paris.html","checkInDate":"2026-09-20","checkOutDate":"2026-09-24","rooms":"1","adults":"2","children":"0"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "https://www.booking.com/hotel/fr/le-bristol-paris.html", "checkInDate" => "2026-09-20", "checkOutDate" => "2026-09-24", "rooms" => "1", "adults" => "2", "children" => "0", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/booking/place?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/booking/place") .newBuilder() .addQueryParameter("url", "https://www.booking.com/hotel/fr/le-bristol-paris.html") .addQueryParameter("checkInDate", "2026-09-20") .addQueryParameter("checkOutDate", "2026-09-24") .addQueryParameter("rooms", "1") .addQueryParameter("adults", "2") .addQueryParameter("children", "0") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["url"] = "https://www.booking.com/hotel/fr/le-bristol-paris.html"; query["checkInDate"] = "2026-09-20"; query["checkOutDate"] = "2026-09-24"; query["rooms"] = "1"; query["adults"] = "2"; query["children"] = "0"; var url = $"https://api.hasdata.com/scrape/booking/place?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/booking/place") params = { "url" => "https://www.booking.com/hotel/fr/le-bristol-paris.html", "checkInDate" => "2026-09-20", "checkOutDate" => "2026-09-24", "rooms" => "1", "adults" => "2", "children" => "0", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/booking/place") .query(&[("url", "https://www.booking.com/hotel/fr/le-bristol-paris.html")]) .query(&[("checkInDate", "2026-09-20")]) .query(&[("checkOutDate", "2026-09-24")]) .query(&[("rooms", "1")]) .query(&[("adults", "2")]) .query(&[("children", "0")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("url", "https://www.booking.com/hotel/fr/le-bristol-paris.html") params.Set("checkInDate", "2026-09-20") params.Set("checkOutDate", "2026-09-24") params.Set("rooms", "1") params.Set("adults", "2") params.Set("children", "0") u := "https://api.hasdata.com/scrape/booking/place?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | -------------- | ---------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `url` | [https://www.booking.com/hotel/fr/le-bristol-paris.html](https://www.booking.com/hotel/fr/le-bristol-paris.html) | Yes | Full Booking.com URL of the property page. Only `booking.com` and `www.booking.com` hosts are accepted. | | `checkInDate` | 2026-09-20 | Yes | Check-in date in `YYYY-MM-DD` format. Must be in the future and earlier than `checkOutDate`. | | `checkOutDate` | 2026-09-24 | Yes | Check-out date in `YYYY-MM-DD` format. Must be later than `checkInDate`. | | `rooms` | 1 | Yes | Number of rooms to book. | | `adults` | 2 | Yes | Number of adult guests across all rooms. | | `children` | - | Yes | Number of child guests across all rooms (0–10). Pass `0` if there are no children. | | `childrenAges` | - | No | Comma-separated list of child ages, one entry per child (each `0`–`17`). Required when `children > 0` and the number of ages must equal `children`.

Example: `1,3,7`
| | `language` | - | No | Language of the Booking.com interface and localized fields in the response. | | `currency` | - | No | Currency of the prices returned in the response. Use `hotelCurrency` to keep each property's native currency. | # Booking.com Search Scraper API Source: https://docs.hasdata.com/apis/booking/search The Booking.com Search API returns the collection of accommodations from a Booking.com search results page for a given destination and stay dates, with rich filtering by property type, rating, facilities, price and more. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Booking.com. Booking.com is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Booking.com Search Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/booking/search' \ --data-urlencode 'keyword=Paris' \ --data-urlencode 'checkInDate=2026-09-20' \ --data-urlencode 'checkOutDate=2026-09-24' \ --data-urlencode 'rooms=1' \ --data-urlencode 'adults=2' \ --data-urlencode 'children=0' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/booking/search', params: { keyword: 'Paris', checkInDate: '2026-09-20', checkOutDate: '2026-09-24', rooms: '1', adults: '2', children: '0' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/booking/search" querystring = {"keyword":"Paris","checkInDate":"2026-09-20","checkOutDate":"2026-09-24","rooms":"1","adults":"2","children":"0"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Paris", "checkInDate" => "2026-09-20", "checkOutDate" => "2026-09-24", "rooms" => "1", "adults" => "2", "children" => "0", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/booking/search?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/booking/search") .newBuilder() .addQueryParameter("keyword", "Paris") .addQueryParameter("checkInDate", "2026-09-20") .addQueryParameter("checkOutDate", "2026-09-24") .addQueryParameter("rooms", "1") .addQueryParameter("adults", "2") .addQueryParameter("children", "0") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["keyword"] = "Paris"; query["checkInDate"] = "2026-09-20"; query["checkOutDate"] = "2026-09-24"; query["rooms"] = "1"; query["adults"] = "2"; query["children"] = "0"; var url = $"https://api.hasdata.com/scrape/booking/search?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/booking/search") params = { "keyword" => "Paris", "checkInDate" => "2026-09-20", "checkOutDate" => "2026-09-24", "rooms" => "1", "adults" => "2", "children" => "0", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/booking/search") .query(&[("keyword", "Paris")]) .query(&[("checkInDate", "2026-09-20")]) .query(&[("checkOutDate", "2026-09-24")]) .query(&[("rooms", "1")]) .query(&[("adults", "2")]) .query(&[("children", "0")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("keyword", "Paris") params.Set("checkInDate", "2026-09-20") params.Set("checkOutDate", "2026-09-24") params.Set("rooms", "1") params.Set("adults", "2") params.Set("children", "0") u := "https://api.hasdata.com/scrape/booking/search?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `keyword` | Paris | Yes | Free-text destination query. Usually a city, region or neighborhood (e.g. `Paris`, `Manhattan, New York`); a specific property name is also accepted. | | `sort` | - | No | Sort order applied by Booking.com to the results page. | | `checkInDate` | 2026-09-20 | Yes | Check-in date in `YYYY-MM-DD` format. Must be in the future and earlier than `checkOutDate`. | | `checkOutDate` | 2026-09-24 | Yes | Check-out date in `YYYY-MM-DD` format. Must be later than `checkInDate`. | | `rooms` | 1 | Yes | Number of rooms to book. | | `adults` | 2 | Yes | Number of adult guests across all rooms. | | `children` | - | Yes | Number of child guests across all rooms (0–10). Pass `0` if there are no children. | | `childrenAges` | - | No | Comma-separated list of child ages, one entry per child (each `0`–`17`). Required when `children > 0` and the number of ages must equal `children`.

Example: `1,3,7`
| | `price[min]` | - | No | Minimum total price for the stay, in the requested `currency`. Must be `>= 10`. Required if `price[max]` is omitted. | | `price[max]` | - | No | Maximum total price for the stay, in the requested `currency`. Must be `>= 20` and greater than `price[min]`. Required if `price[min]` is omitted. | | `bedrooms` | - | No | Minimum number of bedrooms in the property. | | `bathrooms` | - | No | Minimum number of bathrooms in the property. | | `propertyType[]` | - | No | Filter by property type. Multiple values are combined with OR. | | `rating[]` | - | No | Filter by official star rating. Multiple values are combined with OR. | | `reviewScore[]` | - | No | Filter by minimum guest review score bucket. Multiple values are combined with OR. | | `distanceFromCenter[]` | - | No | Filter by distance from the destination center. Multiple values are combined with OR. | | `propertyAccessibility[]` | - | No | Filter by property-level accessibility features. Multiple values are combined with OR. | | `meals[]` | - | No | Filter by available meal plans. Multiple values are combined with OR. | | `facilities[]` | - | No | Filter by property-level facilities. Multiple values are combined with OR. | | `roomFacilities[]` | - | No | Filter by in-room facilities. Multiple values are combined with OR. | | `roomAccessibility[]` | - | No | Filter by in-room accessibility features. Multiple values are combined with OR. | | `bedPreference[]` | - | No | Filter by bed configuration. Multiple values are combined with OR. | | `reservationPolicy[]` | - | No | Filter by reservation flexibility. Multiple values are combined with OR. | | `onlinePayment[]` | - | No | Filter by online payment options. | | `travelGroup[]` | - | No | Filter by travel-group oriented stay options. Multiple values are combined with OR. | | `language` | - | No | Language of the Booking.com interface and localized fields in the response. | | `currency` | - | No | Currency of the prices returned in the response. Use `hotelCurrency` to keep each property's native currency. | | `page` | - | No | Page number of the search results. Booking.com returns 25 results per page; pass `2` for results 26–50, `3` for 51–75, etc. | # DuckDuckGo SERP API Source: https://docs.hasdata.com/apis/duckduckgo/serp The DuckDuckGo SERP API provides real-time access to structured DuckDuckGo search results with a high success rate at scale. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the DuckDuckGo SERP API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/duckduckgo/serp' \ --data-urlencode 'q=Coffee' \ --data-urlencode 'deviceType=desktop' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/duckduckgo/serp', params: {q: 'Coffee', deviceType: 'desktop'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/duckduckgo/serp" querystring = {"q":"Coffee","deviceType":"desktop"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Coffee", "deviceType" => "desktop", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/duckduckgo/serp?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/duckduckgo/serp") .newBuilder() .addQueryParameter("q", "Coffee") .addQueryParameter("deviceType", "desktop") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Coffee"; query["deviceType"] = "desktop"; var url = $"https://api.hasdata.com/scrape/duckduckgo/serp?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/duckduckgo/serp") params = { "q" => "Coffee", "deviceType" => "desktop", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/duckduckgo/serp") .query(&[("q", "Coffee")]) .query(&[("deviceType", "desktop")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Coffee") params.Set("deviceType", "desktop") u := "https://api.hasdata.com/scrape/duckduckgo/serp?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Coffee | No | Specify the search term for which you want to scrape the SERP. Required unless `nextPageToken` is provided (which carries the query of the page it continues). | | `kl` | - | No | DuckDuckGo region code in `-` form (e.g. `us-en`, `de-de`). Sets country and interface language at once; takes precedence over `cc`/`setLang`. Use `wt-wt` for no region. | | `cc` | - | No | The two-letter country code for the country to search from. Combined with `setLang` to form the DuckDuckGo region. Ignored if `kl` is set. | | `setLang` | - | No | The preferred result/interface language code — usually two letters (e.g. `en`, `de`), with script-tag variants for some languages (e.g. `zh-hans`, `zh-hant`). Combined with `cc` to form the DuckDuckGo region. Ignored if `kl` is set. | | `safeSearch` | - | No | Adult Content Filtering option. | | `deviceType` | desktop | No | Specify the device type for the search. | | `nextPageToken` | - | No | Opaque token returned in each response as `nextPageToken`. Pass it back (in place of `q`) to fetch the next page of results. It carries a pre-signed page URL bound to the original request's session, so it must be used as-is and cannot be constructed manually. Absent when there are no further pages.
| # Glassdoor Job Scraper API Source: https://docs.hasdata.com/apis/glassdoor/job The Glassdoor Job Scraper API allows you to retrieve detailed information about a specific job listing based on the provided vacancy URL. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Glassdoor. Glassdoor is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Glassdoor Job Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/glassdoor/job' \ --data-urlencode 'url=https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata glassdoor-job \ --url 'https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/glassdoor/job', params: { url: 'https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/glassdoor/job" querystring = {"url":"https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/glassdoor/job?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/glassdoor/job") .newBuilder() .addQueryParameter("url", "https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["url"] = "https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500"; var url = $"https://api.hasdata.com/scrape/glassdoor/job?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/glassdoor/job") params = { "url" => "https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/glassdoor/job") .query(&[("url", "https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("url", "https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500") u := "https://api.hasdata.com/scrape/glassdoor/job?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------- | | `url` | [https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV\_IC1147431\_KO0,39\_KE40,46.htm?jl=1009846893500](https://www.glassdoor.com/job-listing/engineering-analyst-anti-scraper-search-google-JV_IC1147431_KO0,39_KE40,46.htm?jl=1009846893500) | Yes | The URL of the job vacancy to retrieve details for. | # Glassdoor Listing Scraper API Source: https://docs.hasdata.com/apis/glassdoor/listing The Glassdoor Listing Scraper API allows you to retrieve job listings from Glassdoor based on various search parameters. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Glassdoor. Glassdoor is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Glassdoor Listing Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/glassdoor/listing' \ --data-urlencode 'keyword=software engineer' \ --data-urlencode 'location=New York, NY' \ --data-urlencode 'sort=recent' \ --data-urlencode 'domain=www.glassdoor.com' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata glassdoor-listing \ --keyword 'software engineer' \ --location 'New York, NY' \ --sort recent \ --domain www.glassdoor.com ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/glassdoor/listing', params: { keyword: 'software engineer', location: 'New York, NY', sort: 'recent', domain: 'www.glassdoor.com' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/glassdoor/listing" querystring = {"keyword":"software engineer","location":"New York, NY","sort":"recent","domain":"www.glassdoor.com"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "software engineer", "location" => "New York, NY", "sort" => "recent", "domain" => "www.glassdoor.com", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/glassdoor/listing?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/glassdoor/listing") .newBuilder() .addQueryParameter("keyword", "software engineer") .addQueryParameter("location", "New York, NY") .addQueryParameter("sort", "recent") .addQueryParameter("domain", "www.glassdoor.com") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["keyword"] = "software engineer"; query["location"] = "New York, NY"; query["sort"] = "recent"; query["domain"] = "www.glassdoor.com"; var url = $"https://api.hasdata.com/scrape/glassdoor/listing?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/glassdoor/listing") params = { "keyword" => "software engineer", "location" => "New York, NY", "sort" => "recent", "domain" => "www.glassdoor.com", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/glassdoor/listing") .query(&[("keyword", "software engineer")]) .query(&[("location", "New York, NY")]) .query(&[("sort", "recent")]) .query(&[("domain", "www.glassdoor.com")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("keyword", "software engineer") params.Set("location", "New York, NY") params.Set("sort", "recent") params.Set("domain", "www.glassdoor.com") u := "https://api.hasdata.com/scrape/glassdoor/listing?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | --------------------------------------------- | -------- | -------------------------------------------- | | `keyword` | software engineer | Yes | The keyword used to search for job listings. | | `location` | New York, NY | Yes | The location to search for job listings. | | `sort` | recent | No | The sorting option for the search results. | | `domain` | [www.glassdoor.com](http://www.glassdoor.com) | No | The domain of the Glassdoor site (optional). | | `nextPageToken` | - | No | Token for fetching the next page of jobs. | # Quickstart - Google AI Mode API Source: https://docs.hasdata.com/apis/google-ai-mode/quickstart The Google AI Mode SERP API captures Gemini-powered AI responses from Google Search. Get structured, conversational answers with links, summaries, and subtopic breakdowns—ideal for next-gen search and content tools. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google AI Mode API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/ai-mode' \ --data-urlencode 'q=Is coffee good for health?' \ --data-urlencode 'location=Austin,Texas,United States' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-ai-mode \ --q 'Is coffee good for health?' \ --location 'Austin,Texas,United States' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/ai-mode', params: {q: 'Is coffee good for health?', location: 'Austin,Texas,United States'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/ai-mode" querystring = {"q":"Is coffee good for health?","location":"Austin,Texas,United States"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Is coffee good for health?", "location" => "Austin,Texas,United States", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/ai-mode?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/ai-mode") .newBuilder() .addQueryParameter("q", "Is coffee good for health?") .addQueryParameter("location", "Austin,Texas,United States") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Is coffee good for health?"; query["location"] = "Austin,Texas,United States"; var url = $"https://api.hasdata.com/scrape/google/ai-mode?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/ai-mode") params = { "q" => "Is coffee good for health?", "location" => "Austin,Texas,United States", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/ai-mode") .query(&[("q", "Is coffee good for health?")]) .query(&[("location", "Austin,Texas,United States")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Is coffee good for health?") params.Set("location", "Austin,Texas,United States") u := "https://api.hasdata.com/scrape/google/ai-mode?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ```json theme={null} { "requestMetadata":{ "id":"504e446a-481a-416c-8a21-4f0f691288b4", "status":"ok", "html":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/504e446a-481a-416c-8a21-4f0f691288b4.html", "url":"https://www.google.com/search?q=Is+coffee+good+for+health%3F&udm=50&uule=w%2BCAIQICIaQXVzdGluLFRleGFzLFVuaXRlZCBTdGF0ZXM%3D" }, "textBlocks":[ { "type":"paragraph", "snippet":"Whether coffee is good for your health depends on various factors, including the amount consumed and individual health conditions.However, studies increasingly suggest that coffee consumption can have significant health benefits when consumed in moderation.", "snippetHighlightedWords":[ "coffee consumption can have significant health benefits when consumed in moderation" ] }, { "type":"paragraph", "snippet":"Potential Health Benefits of Coffee:", "snippetHighlightedWords":[ "Potential Health Benefits of Coffee:" ] }, { "type":"list", "list":[ { "snippet":"Reduced risk of certain diseases: Moderate coffee consumption has been linked to a reduced risk of various conditions such as Type 2 diabetes, Parkinson's disease, liver disease (including cirrhosis and liver cancer), and potentially certain types of cancer like colon and endometrial cancer." }, { "snippet":"Improved mood and alertness: Coffee is known to enhance alertness, decrease mental fatigue, and improve mood due to its caffeine content, which acts as a stimulant." }, { "snippet":"Protection against Alzheimer's and Parkinson's disease: Research suggests a lower risk of developing these neurodegenerative diseases in coffee drinkers." }, { "snippet":"Heart health benefits: Contrary to past concerns, moderate coffee intake is associated with a reduced risk of heart failure and may even lower the risk of stroke." }, { "snippet":"Rich in antioxidants: Coffee contains a significant amount of antioxidants, like polyphenols, which can help protect cells from damage and may contribute to various health benefits." }, { "snippet":"Improved athletic performance: Caffeine can enhance athletic performance, particularly for endurance exercises." } ] }, { "type":"paragraph", "snippet":"Important Considerations and Potential Drawbacks:", "snippetHighlightedWords":[ "Important Considerations and Potential Drawbacks:" ] }, { "type":"list", "list":[ { "snippet":"Moderation is key: Excessive coffee consumption (often considered more than 4-5 cups per day or exceeding 400 mg of caffeine) can lead to negative side effects like increased heart rate, anxiety, restlessness, insomnia, and digestive issues." }, { "snippet":"Individual sensitivity to caffeine varies: Some people are more sensitive to caffeine and may experience adverse effects even with moderate intake." }, { "snippet":"Impact on sleep: Drinking coffee, especially later in the day, can interfere with sleep quality. It's generally recommended to avoid caffeine several hours before bedtime." }, { "snippet":"Adding unhealthy ingredients: Adding excessive sugar, cream, or flavored syrups can significantly increase the calorie and sugar content, negating the potential health benefits of coffee." }, { "snippet":"Certain health conditions: Individuals with severe anxiety, cardiovascular disease, or who are pregnant or breastfeeding should consult with their healthcare provider about caffeine consumption." }, { "snippet":"Unfiltered coffee: Methods like French press or Turkish coffee that don't filter out cafestol, a compound found in coffee, can slightly raise LDL (bad) cholesterol levels." } ] }, { "type":"paragraph", "snippet":"In summary, enjoying coffee in moderation (typically 3-5 cups per day, or up to 400 mg of caffeine) can be a part of a healthy diet for most people.However, it's essential to be mindful of individual sensitivity to caffeine, avoid excessive intake, and be aware of how you prepare your coffee to maximize its potential health benefits and minimize any negative impacts.", "snippetHighlightedWords":[ "In summary, enjoying coffee in moderation (typically 3-5 cups per day, or up to 400 mg of caffeine) can be a part of a healthy diet for most people." ] } ], "references":[ { "link":"https://utswmed.org/medblog/is-coffee-good-for-you/#:~:text=Drinking%20coffee%20in%20moderation%20has,for%20people%20across%20the%20world.", "title":"Is coffee good for you? | Diet and Nutrition", "snippet":"Is coffee good for you? ... Drinking coffee in moderation has been associated with a lower risk of heart failure and stroke, among other potential benefits. If ...", "source":"utswmed.org", "index":1 }, { "link":"https://www.healthline.com/nutrition/coffee-good-or-bad#:~:text=Coffee%20drinkers%20have%20a%20lower%20risk%20of%20liver%20diseases,of%20liver%20cancer%20(%2018%20).", "title":"Coffee — Good or Bad? - Healthline", "snippet":"Oct 4, 2024 — Coffee — Good or Bad? ... Coffee is a popular beverage with many health benefits, including high amounts of antioxidants. That said, its main active ingredient,", "source":"Healthline", "index":2 }, { "link":"https://www.healthline.com/nutrition/coffee-good-or-bad#:~:text=Coffee%20drinkers%20have%20a%20lower%20risk%20of%20liver%20diseases,of%20liver%20cancer%20(%2018%20).", "title":"Coffee — Good or Bad? - Healthline", "snippet":"Oct 4, 2024 — Coffee drinkers have a lower risk of liver diseases. Your liver is an incredibly important organ that has hundreds of different functions in your body. It is se...", "source":"Healthline", "index":3 }, { "link":"https://www.mayoclinic.org/healthy-lifestyle/nutrition-and-healthy-eating/in-depth/caffeine/art-20045678#:~:text=Headache,length%20of%20time%20you%20sleep.", "title":"Caffeine: How much is too much? - Mayo Clinic", "snippet":"Caffeine in powder or liquid form can provide toxic levels of caffeine, the U.S. Food and Drug Administration has cautioned. Just one teaspoon of powdered caffe...", "source":"Mayo Clinic", "index":4 }, { "link":"https://www.hopkinsmedicine.org/health/wellness-and-prevention/9-reasons-why-the-right-amount-of-coffee-is-good-for-you", "title":"9 Reasons Why (the Right Amount of) Coffee Is Good for You", "snippet":"9 Reasons Why (the Right Amount of) Coffee Is Good for You. ... Ah, coffee. Whether you're cradling a travel mug on your way to work or dashing out after spin c...", "source":"Johns Hopkins Medicine", "index":5 }, { "link":"https://www.mayoclinic.org/healthy-lifestyle/nutrition-and-healthy-eating/expert-answers/coffee-and-health/faq-20058339", "title":"Coffee and health: What does the research say? - Mayo Clinic", "snippet":"Drinking coffee with caffeine has been linked with improved mood and a lower risk of depression in some groups. Drinking 3 to 4 cups of coffee a day is linked t...", "source":"Mayo Clinic", "index":6 }, { "link":"https://www.healthline.com/nutrition/caffeine-side-effects#:~:text=Rhabdomyolysis%20is%20a%20serious%20condition,effect%20on%20the%20nervous%20system.", "title":"9 Side Effects of Too Much Caffeine - Healthline", "snippet":"Jan 13, 2025 — Here are 9 side effects of too much caffeine. * 1. Anxiety. Caffeine is known to increase alertness. It works by blocking the effects of adenosine, a brain chem...", "source":"Healthline", "index":7 }, { "link":"https://www.health.harvard.edu/staying-healthy/moderate-amounts-of-coffee-are-the-best", "title":"Moderate amounts of coffee are the best - Harvard Health", "snippet":"Nov 1, 2020 — In the journals. ... Coffee has had a hot-and-cold reputation when it comes to health benefits. Drinking two to five daily cups of coffee may protect against he...", "source":"Harvard Health", "index":8 }, { "link":"https://www.fda.gov/consumers/consumer-updates/spilling-beans-how-much-caffeine-too-much", "title":"Spilling the Beans: How Much Caffeine is Too Much? - FDA", "snippet":"Aug 28, 2024 — “Energy Drinks” and Children and Teens. ... Too much caffeine in children and teens can cause increased heart rate, heart palpitations, high blood pressure, anx...", "source":"U.S. Food and Drug Administration (.gov)", "index":9 }, { "link":"https://nutritionsource.hsph.harvard.edu/food-features/coffee/#:~:text=A%20plain%20%E2%80%9Cblack%E2%80%9D%20cup%20of,calories%20to%20your%20daily%20cup.", "title":"Coffee - The Nutrition Source - Harvard University", "snippet":"Source Of. ... One 8-ounce cup of brewed coffee contains about 95 mg of caffeine. A moderate amount of coffee is generally defined as 3-5 cups a day, or on aver...", "source":"The Nutrition Source", "index":10 }, { "link":"https://www.acc.org/About-ACC/Press-Releases/2022/03/23/17/55/Good-News-for-Coffee-Lovers-Daily-Coffee-May-Benefit-the-Heart#:~:text=Kistler%2C%20MD%2C%20professor%20and%20head,with%20benefits%20to%20heart%20health.%E2%80%9D", "title":"Good News for Coffee Lovers: Daily Coffee May Benefit the ...", "snippet":"Mar 24, 2022 — Drinking two to three cups a day was associated with greatest heart benefits * Drinking coffee—particularly two to three cups a day—is not only associated with ...", "source":"American College of Cardiology", "index":11 }, { "link":"https://hsph.harvard.edu/news/is-coffee-good-or-bad-for-your-health/#:~:text=Early%20research%20linked%20coffee%20to,Good%20for%20You%20or%20Not?", "title":"Is coffee good or bad for your health?", "snippet":"Apr 9, 2021 — Early research linked coffee to diseases ranging from heart disease and asthma. But Hu noted that many participants in those studies also smoked, which may have...", "source":"Harvard T.H. Chan School of Public Health", "index":12 }, { "link":"https://www.heartandstroke.ca/articles/myths-and-truths-about-coffee#:~:text=Truth:%20It's%20all%20about%20moderation,Learn%20more%20about:", "title":"Myths and truths about coffee | Heart and Stroke Foundation", "snippet":"Oct 20, 2024 — Does coffee cause heart disease? The answer may surprise you. ... If you start your day with coffee, you're in luck. Packed with antioxidants and hydrating flui...", "source":"Heart and Stroke Foundation of Canada", "index":13 }, { "link":"https://www.sleepfoundation.org/nutrition/caffeine-and-sleep#:~:text=Sensitivity%20to%20caffeine%20varies%20among,insomnia%2C%20anxiety%2C%20or%20headaches.", "title":"Caffeine and Sleep Problems - Sleep Foundation", "snippet":"Apr 17, 2024 — * Caffeine promotes wakefulness by blocking adenosine, a sleep-inducing chemical. * Sensitivity to caffeine varies among individuals and depends on how often it...", "source":"Sleep Foundation", "index":14 }, { "link":"https://www.ncbi.nlm.nih.gov/books/NBK519490/", "title":"Caffeine - StatPearls - NCBI Bookshelf", "snippet":"May 29, 2024 — Administration * Available Dosage Forms and Strengths. * Specific Patient Populations. * Hepatic impairment: Caffeine's product labeling does not specify dosage...", "source":"National Institutes of Health (NIH) | (.gov)", "index":15 }, { "link":"https://www.medicalnewstoday.com/articles/326443", "title":"Does coffee make you tired? Here's why - Medical News Today", "snippet":"Jun 26, 2023 — Insomnia. Share on Pinterest Drinking coffee close to bedtime may cause insomnia. People who drink coffee before going to bed may have trouble falling asleep. *", "source":"Medical News Today", "index":16 }, { "link":"https://www.piedmont.org/living-real-change/is-coffee-good-for-your-health", "title":"Is coffee good for your health? - Piedmont Healthcare", "snippet":"Here are five ways coffee may be good for your health: * 1. It lowers the risk of type 2 diabetes. A report in the American Chemical Society's Journal of Agricu...", "source":"Piedmont Healthcare", "index":17 }, { "link":"https://mcpress.mayoclinic.org/nutrition-fitness/your-morning-cup-of-coffee-may-have-unexpected-health-benefits/#:~:text=The%20bottom%20line%20on%20coffee,Hensrud.", "title":"Your morning cup of coffee may have unexpected health benefits", "snippet":"Oct 24, 2024 — Your morning cup of coffee may have unexpected health benefits * Coffee — An unexpected ally for wellness. It will likely come as no surprise that coffee can of...", "source":"Mayo Clinic Press", "index":18 } ] } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------- | -------------------------- | -------- | ---------------------------------------------------------------------------- | | `q` | Is coffee good for health? | Yes | Specify the search term for which you want to scrape the SERP. | | `location` | Austin,Texas,United States | No | Google canonical location for the search. | | `uule` | - | No | The encoded location parameter. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | # Code Source: https://docs.hasdata.com/apis/google-ai-mode/rich-snippets/code ```json Response theme={null} { "textBlocks":[ { "type":"code", "language":"javascript", "snippet":"const fs = require('fs'); // Import the file system module\nconst crypto = require('crypto'); // Import the crypto module\n\nconst filePath = '/path/to/your/file.txt'; // Replace with the actual file path\nconst algorithm = 'sha256'; // Choose your desired hashing algorithm (e.g., 'sha1', 'md5', 'sha256')\n\nconst hash = crypto.createHash(algorithm); // Create a hash object with the specified algorithm\n\nconst stream = fs.createReadStream(filePath); // Create a read stream from the file\n\nstream.on('error', (err) => { // Handle potential errors during file reading\n console.error('Error reading the file:', err);\n});\n\nstream.on('data', (chunk) => { // When data chunks are received from the stream\n hash.update(chunk); // Update the hash with the data chunk\n});\n\nstream.on('end', () => { // When the stream finishes reading the file\n const fileHash = hash.digest('hex'); // Calculate the final hash and get it in hexadecimal format\n console.log(`The ${algorithm} hash of the file is: ${fileHash}`);\n});\n\n" } ] } ``` # List Source: https://docs.hasdata.com/apis/google-ai-mode/rich-snippets/list ```json Response theme={null} { "textBlocks":[ { "type":"list", "list":[ { "snippet":"Explore Local Parks: Go for a hike, pack a picnic, or simply relax and enjoy nature at a park near you. You could even explore a new park or visit a national park if one is nearby." }, { "snippet":"Go Camping: Pitch a tent in your backyard for a fun and convenient camping experience. Alternatively, find a nearby campsite for a more immersive experience in nature." }, { "snippet":"Have a Water Escape: Visit a local water park, pool, lake, or beach to cool off and have fun in the sun. You can also create your own water park at home with sprinklers and water balloons." }, { "snippet":"Go on a Bike Ride: Explore your neighborhood or local trails on two wheels." }, { "snippet":"Try Kayaking or Canoeing: Enjoy the water and get some exercise by renting kayaks or canoes." } ] } ] } ``` # Local Results Source: https://docs.hasdata.com/apis/google-ai-mode/rich-snippets/local-results ```json Response theme={null} { "textBlocks":[ { "type":"localResults", "localResults":[ { "position":1, "title":"Siragusa's Taste of Italy", "thumbnail":"https://lh3.googleusercontent.com/p/AF1QipMs4Qt83-h19YB6S6jX7-AK4wXsGYHI01P8Orfo=w300-h224-n-k-no", "address":"4115 S Redwood Rd", "openState":"Open", "reviews":2200, "rating":4.4, "type":"Italian" }, { "position":2, "title":"La Dolce Vita Ristorante Italiano", "thumbnail":"https://lh3.googleusercontent.com/p/AF1QipPxB7aSGdakj5B9uuvWJYdhVGJlDiBpqmDrxNKH=w300-h225-n-k-no", "address":"61 N 100 E", "openState":"Open", "reviews":1200, "rating":4.2, "type":"Italian" }, { "position":3, "title":"Stoneground Italian Kitchen", "thumbnail":"https://lh3.googleusercontent.com/gps-cs-s/AC9h4nqj_8cV66BCLW346c6zDsVQHSz-wrdvxTA1fdpsnVSmh4T_1sMhr2FecC515OYBIQOiMYermmQHX2srRdDCiimpzlZpAL7TaSgk5W3Shs9_oiw6VYOsGZ_PeXANV0IW7IXr02P8Xg=w300-h400-n-k-no", "address":"249 E 400 S", "openState":"Open", "reviews":1100, "rating":4.5, "type":"Italian" }, { "position":4, "title":"Bartolo's Sugar House", "thumbnail":"https://lh3.googleusercontent.com/p/AF1QipP2-JdihMmXB1zaiPIsNc29DWUrNeEBrcKvWYYR=w300-h168-n-k-no", "address":"1270 S 1100 E", "openState":"Open", "reviews":610, "rating":4.4, "type":"Italian" } ] } ] } ``` # Paragraph Source: https://docs.hasdata.com/apis/google-ai-mode/rich-snippets/paragraph ```json Response theme={null} { "textBlocks":[ { "type":"paragraph", "snippet":"Enjoy a relaxing and fun summer without traveling far! Here are some ideas for your staycation:" } ] } ``` # References Source: https://docs.hasdata.com/apis/google-ai-mode/rich-snippets/references ```json Response theme={null} { "references":[ { "link":"https://www.rtings.com/laptop/reviews/best/by-usage/college", "title":"The 6 Best Laptops For College of 2025 - RTINGS.com", "snippet":"* Best Laptop For College. See our test results. Apple MacBook Air 13 (M4, 2025)4. SEE PRICE. BestBuy.com. SEE PRICE. Amazon.com. SEE PRICE. Walmart.com. School...", "source":"RTINGS.com", "index":1 }, { "link":"https://www.rtings.com/laptop/reviews/best/by-usage/college", "title":"The 6 Best Laptops For College of 2025 - RTINGS.com", "snippet":"* Best Laptop For College. See our test results. Apple MacBook Air 13 (M4, 2025)4. SEE PRICE. BestBuy.com. SEE PRICE. Amazon.com. SEE PRICE. Walmart.com. School...", "source":"RTINGS.com", "index":2 }, { "link":"https://www.rtings.com/laptop/reviews/best/by-usage/college", "title":"The 6 Best Laptops For College of 2025 - RTINGS.com", "snippet":"* Best Laptop For College. See our test results. Apple MacBook Air 13 (M4, 2025)4. SEE PRICE. BestBuy.com. SEE PRICE. Amazon.com. SEE PRICE. Walmart.com. School...", "source":"RTINGS.com", "index":3 }, { "link":"https://www.rtings.com/laptop/reviews/best/by-usage/college", "title":"The 6 Best Laptops For College of 2025 - RTINGS.com", "snippet":"* Best Laptop For College. See our test results. Apple MacBook Air 13 (M4, 2025)4. SEE PRICE. BestBuy.com. SEE PRICE. Amazon.com. SEE PRICE. Walmart.com. School...", "source":"RTINGS.com", "index":4 }, { "link":"https://www.pcworld.com/article/557622/the-best-laptop-for-college.html", "title":"Best laptops for college students 2025: 7 picks for every budget - PCWorld", "snippet":"Table_title: At a glance Table_content: header: | Best overall Asus Zenbook 14 OLED ↓ Learn More | Best Price Today $849 at Walmart | VIEW DEAL | row: | Best ov...", "source":"PCWorld", "index":5 }, { "link":"https://www.pcworld.com/article/557622/the-best-laptop-for-college.html", "title":"Best laptops for college students 2025: 7 picks for every budget", "snippet":"Table_title: At a glance Table_content: header: | Best overall Asus Zenbook 14 OLED ↓ Learn More | Best Price Today $849 at Walmart | VIEW DEAL | row: | Best ov...", "source":"PCWorld", "index":6 }, { "link":"https://www.tomsguide.com/best-picks/best-laptops-for-college-students", "title":"Best laptops for college students in 2025 — tested and rated", "snippet":"The quick list * Best overall. 1. MacBook Air M4. View at P.C. Richard & Son. View at Amazon. View at Amazon. The MacBook Air M4 is my go-to recommendation for ...", "source":"Tom's Guide", "index":7 }, { "link":"https://www.pcworld.com/article/436674/best-pc-laptops.html", "title":"Best laptops 2025: Premium, budget, gaming, 2-in-1, and more - PCWorld", "snippet":"Table_title: At a glance Table_content: header: | Best overall Asus Zenbook 14 OLED ↓ Learn More | Best Price Today $849 at Walmart | VIEW DEAL | row: | Best ov...", "source":"PCWorld", "index":8 }, { "link":"https://www.cnet.com/tech/computing/best-laptop-for-college/", "title":"Best Laptop for College Students: Top Laptops for School in 2025", "snippet":"* Best laptop for college. M4 MacBook Air (13-Inch, 2025) Jump to details. $849 at Amazon. Jump to details. * Best Windows laptop for college. Asus Zenbook A14.", "source":"CNET", "index":9 }, { "link":"https://forum.practical-golf.com/t/7-best-laptops-for-students-in-2025-that-actually-make-the-grade/4528", "title":"7 Best Laptops For Students in 2025 That Actually Make the Grade", "snippet":"Whether you're in the dorm, library, study room, or your car between classes, these will keep you moving. * 1. MacBook Air M4 13-inch. image2400×1520 1.06 MB. B...", "source":"Practical Golf Forum", "index":10 }, { "link":"https://www.cnet.com/tech/computing/best-budget-laptop/", "title":"Best Cheap Laptop for 2025 - Budget Computers Under $500 - CNET", "snippet":"* Best budget laptop overall. Apple MacBook Air M1. Jump to details. $649 at Walmart. Jump to details. * Best budget gaming laptop. Acer Predator Helios Neo 16.", "source":"CNET", "index":11 }, { "link":"https://www.tomshardware.com/best-picks/best-college-laptops", "title":"Best College Laptops: Tested Picks for Research, Writing, Gaming and More", "snippet":"Recommended reading * Ultrabooks and Ultraportables Best Ultrabooks and Premium Laptops 2025. * Gaming Laptops Best Gaming Laptops 2025: Tested, benchmarked and...", "source":"Tom's Hardware", "index":12 }, { "link":"https://www.lenovo.com/us/en/d/laptops-for-college/", "title":"Best Laptops for College Students - Lenovo", "snippet":"So, to help a bit more, we've broken down our top college laptops and computers by area of study. * • Our best laptop for architecture students: * ○ ThinkPad P ...", "source":"Lenovo", "index":13 }, { "link":"https://www.pcmag.com/picks/the-best-budget-laptops", "title":"The Best Cheap Laptops for 2025 - PCMag", "snippet":"These days, you can pick up a capable budget laptop—whether a full-size classic clamshell, an ultraportable, or a 2-in-1 convertible powerful enough for home, w...", "source":"PCMag", "index":14 }, { "link":"https://research.com/education/best-student-laptops", "title":"21 Best Laptops for College Students for 2025: Budget & Premium ...", "snippet":"21 Best Student Laptops 2025 Table of Contents * Lenovo Chromebook Duet 5 13\" * Acer Aspire Vero. * MSI Modern 14. * Microsoft Surface Laptop Go 2. * HP Envy x3...", "source":"Research.com", "index":15 }, { "link":"https://www.nssi.com/blog/student-discounts-on-laptops-find-the-best-deals", "title":"Student Discounts on Laptops: Where to Find the Best Deals - NSSI", "snippet":"Here's a guide on where to find the best student discounts and score those sweet deals. * Apple. Apple offers student discounts on MacBooks and iPads through th...", "source":"National Student Services Inc", "index":16 } ] } ``` # Shopping Results Source: https://docs.hasdata.com/apis/google-ai-mode/rich-snippets/shopping-results ```json Response theme={null} { "textBlocks":[ { "type":"shoppingResults", "shoppingResults":[ { "position":1, "title":"Asus Zenbook 14 OLED Core Ultra UX3405MA-PH77", "thumbnail":"https://encrypted-tbn3.gstatic.com/shopping?q=tbn:ANd9GcRfi7A2QfZ4xPHW7ewrWvJS3iDDTkgBuCVW5eT7URIxpznuo7HMpw_f19J1D00&usqp=CAE", "price":"$999.99", "extractedPrice":999.99, "reviews":1000, "rating":4.5, "immersiveProductPageToken":"eyJhbGciOiJIUzI1NiIsInJkcyI6IlBDXzM2MTQ1OTExMjU2ODQ5OTg4MTB8UFJPRF9QQ18zNjE0NTkxMTI1Njg0OTk4ODEwIiwicHZ0IjoiaGciLCJwcm9kdWN0aWQiOiIxMTM4NjQ1OTQxNDI5MTY1OTkwNiIsImNhdGFsb2dpZCI6IjE0OTIzNjE0NDgxNDE1MTAwOTE4IiwiaGVhZGxpbmVPZmZlckRvY2lkIjoiNjQ0OTAxNzAzMzMwOTcxOTYwMCIsImltYWdlRG9jaWQiOiI2NjE3MTAyNjA5NDAwNzcwNzkiLCJncGNpZCI6IjM2MTQ1OTExMjU2ODQ5OTg4MTAiLCJtaWQiOiI1NzY0NjI3NTA5Mzg0MDYwMTYiLCJxIjoicHJvZHVjdCJ9", "hasdataLink":"https://api.hasdata.com/scrape/google/immersive-product?pageToken=eyJhbGciOiJIUzI1NiIsInJkcyI6IlBDXzM2MTQ1OTExMjU2ODQ5OTg4MTB8UFJPRF9QQ18zNjE0NTkxMTI1Njg0OTk4ODEwIiwicHZ0IjoiaGciLCJwcm9kdWN0aWQiOiIxMTM4NjQ1OTQxNDI5MTY1OTkwNiIsImNhdGFsb2dpZCI6IjE0OTIzNjE0NDgxNDE1MTAwOTE4IiwiaGVhZGxpbmVPZmZlckRvY2lkIjoiNjQ0OTAxNzAzMzMwOTcxOTYwMCIsImltYWdlRG9jaWQiOiI2NjE3MTAyNjA5NDAwNzcwNzkiLCJncGNpZCI6IjM2MTQ1OTExMjU2ODQ5OTg4MTAiLCJtaWQiOiI1NzY0NjI3NTA5Mzg0MDYwMTYiLCJxIjoicHJvZHVjdCJ9" }, { "position":2, "title":"Dell Inspiron 16 Plus Laptop", "thumbnail":"https://encrypted-tbn1.gstatic.com/shopping?q=tbn:ANd9GcTsYPgAZ-2r7HgmcUhg1WvzdKkdCXbEdgTVvre_1B4NkgSXhgm-RUWnx-WUhg&usqp=CAE", "price":"$849.99", "extractedPrice":849.99, "oldPrice":"$1,099.99", "extractedOldPrice":1099.99, "reviews":279, "rating":4.5, "immersiveProductPageToken":"eyJhbGciOiJIUzI1NiIsInJkcyI6IlBDXzM2NzE2Nzg4NDU2MzQ3MjUyNnxQUk9EX1BDXzM2NzE2Nzg4NDU2MzQ3MjUyNiIsInB2dCI6ImhnIiwicHJvZHVjdGlkIjoiMzMwODk4NzU2OTcwNTc5Njc5NyIsImNhdGFsb2dpZCI6IjEzNTg2MDgxNTAyNzgwNzI5NTA2IiwiaGVhZGxpbmVPZmZlckRvY2lkIjoiMjI5NjAwODI5NTQ0OTkzMTM5MSIsImltYWdlRG9jaWQiOiIxMzM4MjQzNTg4NzM5NjA3NDk3IiwiZ3BjaWQiOiIxNjQ2MjQwNDU3NDAwNjU1MjcxIiwibWlkIjoiNTc2NDYyODM0OTg3ODk1NTQyIiwicSI6InByb2R1Y3QifQ", "hasdataLink":"https://api.hasdata.com/scrape/google/immersive-product?pageToken=eyJhbGciOiJIUzI1NiIsInJkcyI6IlBDXzM2NzE2Nzg4NDU2MzQ3MjUyNnxQUk9EX1BDXzM2NzE2Nzg4NDU2MzQ3MjUyNiIsInB2dCI6ImhnIiwicHJvZHVjdGlkIjoiMzMwODk4NzU2OTcwNTc5Njc5NyIsImNhdGFsb2dpZCI6IjEzNTg2MDgxNTAyNzgwNzI5NTA2IiwiaGVhZGxpbmVPZmZlckRvY2lkIjoiMjI5NjAwODI5NTQ0OTkzMTM5MSIsImltYWdlRG9jaWQiOiIxMzM4MjQzNTg4NzM5NjA3NDk3IiwiZ3BjaWQiOiIxNjQ2MjQwNDU3NDAwNjU1MjcxIiwibWlkIjoiNTc2NDYyODM0OTg3ODk1NTQyIiwicSI6InByb2R1Y3QifQ" }, { "position":3, "title":"HP Envy x360 2-in-1 Laptop Computer", "thumbnail":"https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcR8t8GXsvO75ADxFE6yNK8n8j3cb5tedEdxq56gUUP1fpgvZnb6&usqp=CAE", "price":"$524.99", "extractedPrice":524.99, "reviews":47, "rating":4.3, "immersiveProductPageToken":"eyJhbGciOiJIUzI1NiIsInJkcyI6IlBDXzE4MTQzNjUxOTIwOTYwOTQzMzgyfFBST0RfUENfMTgxNDM2NTE5MjA5NjA5NDMzODIiLCJwdnQiOiJoZyIsInByb2R1Y3RpZCI6IjI5NzA4NDU3Nzc1NDU4MTc4MzMiLCJjYXRhbG9naWQiOiI0OTM3NDY3OTQ3MzM4MjU5MzAzIiwiaGVhZGxpbmVPZmZlckRvY2lkIjoiMTYwMDcyNDUzMDcyMTI0MzcwMDQiLCJpbWFnZURvY2lkIjoiMTUxNzY4NTI1MTk4NDIwNTI3MDYiLCJncGNpZCI6IjE4MTQzNjUxOTIwOTYwOTQzMzgyIiwibWlkIjoiNTc2NDYyODMzMjMzMDAzNzkzIiwicSI6InByb2R1Y3QifQ", "hasdataLink":"https://api.hasdata.com/scrape/google/immersive-product?pageToken=eyJhbGciOiJIUzI1NiIsInJkcyI6IlBDXzE4MTQzNjUxOTIwOTYwOTQzMzgyfFBST0RfUENfMTgxNDM2NTE5MjA5NjA5NDMzODIiLCJwdnQiOiJoZyIsInByb2R1Y3RpZCI6IjI5NzA4NDU3Nzc1NDU4MTc4MzMiLCJjYXRhbG9naWQiOiI0OTM3NDY3OTQ3MzM4MjU5MzAzIiwiaGVhZGxpbmVPZmZlckRvY2lkIjoiMTYwMDcyNDUzMDcyMTI0MzcwMDQiLCJpbWFnZURvY2lkIjoiMTUxNzY4NTI1MTk4NDIwNTI3MDYiLCJncGNpZCI6IjE4MTQzNjUxOTIwOTYwOTQzMzgyIiwibWlkIjoiNTc2NDYyODMzMjMzMDAzNzkzIiwicSI6InByb2R1Y3QifQ" } ] } ] } ``` # Table Source: https://docs.hasdata.com/apis/google-ai-mode/rich-snippets/table ```json Response theme={null} { "textBlocks":[ { "type":"table", "rows":[ [ "Feature", "Apple MacBook Air (M3, 2024)", "Asus Zenbook 14 OLED", "Microsoft Surface Pro 11th Edition (2024)", "Acer Swift Go 14 (2024)", "Lenovo ThinkPad X1 Carbon Gen 12", "Acer Aspire Go 15" ], [ "Best For", "Overall, Creative students", "Overall, Performance/Display", "Note-takers, 2-in-1 users", "Mid-Range, Value", "Business, Portability", "Budget" ], [ "CPU", "Apple M3", "Intel Core Ultra 7 155H", "Qualcomm Snapdragon X Elite", "Intel Core Ultra 5/7", "Intel Core Ultra 7 155H", "Intel Core i3" ], [ "GPU", "Integrated (10-core)", "Integrated (Intel Arc)", "Integrated (Qualcomm Adreno)", "Integrated (Intel Arc/Iris Xe)", "Integrated (Intel Arc)", "Integrated" ], [ "Display", "13.5-inch Liquid Retina", "14-inch OLED touchscreen", "13-inch OLED PixelSense Flow", "14-inch IPS/OLED", "14-inch OLED (120Hz)", "15.6-inch Full HD" ], [ "Battery Life", "Excellent (15+ hours)", "Good (approx. 16 hours)", "Long (e.g., 10 hours)", "Decent (approx. 11 hours)", "Middling (with OLED)", "Approx. 12 hours" ], [ "Weight", "2.7 pounds (13-inch)", "2.82 pounds", "1.97 pounds (without keyboard)", "3.1 pounds", "2.42 pounds", "Not specified" ], [ "Starting Price", "$1,099", "$849 (at Walmart)", "$999.99 (currently discounted)", "Around $700 (with OLED)", "$1,424.25 (discounted)", "$299" ] ] } ] } ``` # Google Images API Source: https://docs.hasdata.com/apis/google-images/images Provides real-time access to Google image search results, tailored to specific parameters, ensuring efficient and reliable retrieval at scale. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Images API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/images' \ --data-urlencode 'q=Coffee' \ --data-urlencode 'location=Austin,Texas,United States' \ --data-urlencode 'deviceType=desktop' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-images \ --q Coffee \ --location 'Austin,Texas,United States' \ --device-type desktop ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/images', params: {q: 'Coffee', location: 'Austin,Texas,United States', deviceType: 'desktop'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/images" querystring = {"q":"Coffee","location":"Austin,Texas,United States","deviceType":"desktop"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Coffee", "location" => "Austin,Texas,United States", "deviceType" => "desktop", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/images?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/images") .newBuilder() .addQueryParameter("q", "Coffee") .addQueryParameter("location", "Austin,Texas,United States") .addQueryParameter("deviceType", "desktop") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Coffee"; query["location"] = "Austin,Texas,United States"; query["deviceType"] = "desktop"; var url = $"https://api.hasdata.com/scrape/google/images?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/images") params = { "q" => "Coffee", "location" => "Austin,Texas,United States", "deviceType" => "desktop", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/images") .query(&[("q", "Coffee")]) .query(&[("location", "Austin,Texas,United States")]) .query(&[("deviceType", "desktop")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Coffee") params.Set("location", "Austin,Texas,United States") params.Set("deviceType", "desktop") u := "https://api.hasdata.com/scrape/google/images?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------ | -------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Coffee | Yes | Search query term for retrieving image results. | | `location` | Austin,Texas,United States | No | Google canonical location for the search. | | `uule` | - | No | The encoded location parameter. | | `domain` | - | No | Google domain to use. Default is google.com. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `tbs` | - | No | `tbs` parameter for the Google Images API customizes image search results with various filters that can be combined using commas. Here are the available options:

Image Size Filters:
- `isz:l` - Search for large images.
- `isz:m` - Search for medium images.
- `isz:i` - Search for icon-sized images.
- `isz:lt,islt:qsvga` - Filter for images larger than 400×300.
- `isz:lt,islt:vga` - Filter for images larger than 640×480.
- `isz:lt,islt:svga` - Filter for images larger than 800×600.
- `isz:lt,islt:xga` - Filter for images larger than 1024×768.
- `isz:lt,islt:2mp` - Filter for images larger than 1600×1200.
- `isz:lt,islt:4mp` - Filter for images larger than 2272×1704.
- `isz:ex,iszw:1000,iszh:1000` - Search for images exactly 1000×1000.

Color Filters:
- `ic:color` - Search for full-color images.
- `ic:gray` - Search for black and white images.
- `ic:specific,isc:red` (and other colors such as orange, yellow, green, etc.) - Search for images predominantly in specified colors.

Image Type Filters:
- `itp:face` - Search for images of faces.
- `itp:photo` - Search for photographs.
- `itp:clipart` - Search for clipart images.
- `itp:lineart` - Search for line drawings.
- `itp:animated` - Search for animated images (GIFs).
| | `safe` | - | No | Adult Content Filtering option. | | `filter` | - | No | Defines whether to enable or disable the filters for 'Similar Results' and 'Omitted Results'. Set to 1 (default) to enable these filters, or 0 to disable them.
| | `deviceType` | desktop | No | Specify the device type for the search. | | `ijn` | - | No | Page number for paginated results, where 0 is the first page. | # Google Maps Contributor Reviews API Source: https://docs.hasdata.com/apis/google-maps/contributor-reviews The Google Maps Contributor Reviews API allows to retrieve reviews submitted by specific users on Google Maps. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Maps Contributor Reviews API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google-maps/contributor-reviews' \ --data-urlencode 'contributorId=117472887966458832611' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-maps-contributor-reviews \ --contributor-id 117472887966458832611 ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google-maps/contributor-reviews', params: {contributorId: '117472887966458832611'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google-maps/contributor-reviews" querystring = {"contributorId":"117472887966458832611"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "117472887966458832611", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google-maps/contributor-reviews?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google-maps/contributor-reviews") .newBuilder() .addQueryParameter("contributorId", "117472887966458832611") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["contributorId"] = "117472887966458832611"; var url = $"https://api.hasdata.com/scrape/google-maps/contributor-reviews?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google-maps/contributor-reviews") params = { "contributorId" => "117472887966458832611", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google-maps/contributor-reviews") .query(&[("contributorId", "117472887966458832611")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("contributorId", "117472887966458832611") u := "https://api.hasdata.com/scrape/google-maps/contributor-reviews?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | --------------------- | -------- | ----------------------------------------------------------------------------- | | `contributorId` | 117472887966458832611 | Yes | Google Maps Contributor ID. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `num` | - | No | Number of results per page, ranging from 10 to 200. | | `nextPageToken` | - | No | Defines the next page token. It is used for retrieving the next page results. | # Google Maps Photos API Source: https://docs.hasdata.com/apis/google-maps/photos The Google Maps Photos API returns photos for a place on Google Maps. Use either dataId or placeId with optional language, category, and pagination. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Maps Photos API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google-maps/photos' \ --data-urlencode 'dataId=0x80cc0654bd27e08d:0xb1c2554442d42e8d' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-maps-photos \ --data-id '0x80cc0654bd27e08d:0xb1c2554442d42e8d' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google-maps/photos', params: {dataId: '0x80cc0654bd27e08d:0xb1c2554442d42e8d'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google-maps/photos" querystring = {"dataId":"0x80cc0654bd27e08d:0xb1c2554442d42e8d"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "0x80cc0654bd27e08d:0xb1c2554442d42e8d", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google-maps/photos?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google-maps/photos") .newBuilder() .addQueryParameter("dataId", "0x80cc0654bd27e08d:0xb1c2554442d42e8d") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["dataId"] = "0x80cc0654bd27e08d:0xb1c2554442d42e8d"; var url = $"https://api.hasdata.com/scrape/google-maps/photos?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google-maps/photos") params = { "dataId" => "0x80cc0654bd27e08d:0xb1c2554442d42e8d", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google-maps/photos") .query(&[("dataId", "0x80cc0654bd27e08d:0xb1c2554442d42e8d")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("dataId", "0x80cc0654bd27e08d:0xb1c2554442d42e8d") u := "https://api.hasdata.com/scrape/google-maps/photos?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | ------------------------------------- | -------- | ----------------------------------------------------------------------------------- | | `dataId` | 0x80cc0654bd27e08d:0xb1c2554442d42e8d | No | Google Maps data ID. Either dataId or placeId should be set. | | `placeId` | - | No | Unique reference to a place on Google Maps. Either dataId or placeId should be set. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `categoryId` | - | No | Filters photos by category. | | `nextPageToken` | - | No | Token for fetching the next page of photos. | # Google Maps Posts API Source: https://docs.hasdata.com/apis/google-maps/posts The Google Maps Posts API provides access to posts (offers, events, announcements) published by businesses on their Google Maps listings, identified by data ID or place ID. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Maps Posts API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google-maps/posts' \ --data-urlencode 'dataId=0x873312ae759b4d15:0x1f38a9bec9912029' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google-maps/posts', params: {dataId: '0x873312ae759b4d15:0x1f38a9bec9912029'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google-maps/posts" querystring = {"dataId":"0x873312ae759b4d15:0x1f38a9bec9912029"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "0x873312ae759b4d15:0x1f38a9bec9912029", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google-maps/posts?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google-maps/posts") .newBuilder() .addQueryParameter("dataId", "0x873312ae759b4d15:0x1f38a9bec9912029") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["dataId"] = "0x873312ae759b4d15:0x1f38a9bec9912029"; var url = $"https://api.hasdata.com/scrape/google-maps/posts?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google-maps/posts") params = { "dataId" => "0x873312ae759b4d15:0x1f38a9bec9912029", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google-maps/posts") .query(&[("dataId", "0x873312ae759b4d15:0x1f38a9bec9912029")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("dataId", "0x873312ae759b4d15:0x1f38a9bec9912029") u := "https://api.hasdata.com/scrape/google-maps/posts?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | ------------------------------------- | -------- | ------------------------------------------------------------------------------------ | | `dataId` | 0x873312ae759b4d15:0x1f38a9bec9912029 | No | Google Maps data ID. | | `placeId` | - | No | Unique reference to a place on a Google Map. Either dataId or placeId should be set. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `nextPageToken` | - | No | Defines the next page token. It is used for retrieving the next page results. | # Google Maps Reviews API Source: https://docs.hasdata.com/apis/google-maps/reviews The Google Maps Reviews API provides access to reviews from Google Maps, with options to specify the data ID, place ID, language, sorting parameters, and topic filters. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Maps Reviews API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google-maps/reviews' \ --data-urlencode 'dataId=0x873312ae759b4d15:0x1f38a9bec9912029' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-maps-reviews \ --data-id '0x873312ae759b4d15:0x1f38a9bec9912029' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google-maps/reviews', params: {dataId: '0x873312ae759b4d15:0x1f38a9bec9912029'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google-maps/reviews" querystring = {"dataId":"0x873312ae759b4d15:0x1f38a9bec9912029"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "0x873312ae759b4d15:0x1f38a9bec9912029", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google-maps/reviews?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google-maps/reviews") .newBuilder() .addQueryParameter("dataId", "0x873312ae759b4d15:0x1f38a9bec9912029") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["dataId"] = "0x873312ae759b4d15:0x1f38a9bec9912029"; var url = $"https://api.hasdata.com/scrape/google-maps/reviews?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google-maps/reviews") params = { "dataId" => "0x873312ae759b4d15:0x1f38a9bec9912029", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google-maps/reviews") .query(&[("dataId", "0x873312ae759b4d15:0x1f38a9bec9912029")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("dataId", "0x873312ae759b4d15:0x1f38a9bec9912029") u := "https://api.hasdata.com/scrape/google-maps/reviews?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | ------------------------------------- | -------- | ------------------------------------------------------------------------------------ | | `dataId` | 0x873312ae759b4d15:0x1f38a9bec9912029 | No | Google Maps data ID. | | `placeId` | - | No | Unique reference to a place on a Google Map. Either dataId or placeId should be set. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `sortBy` | - | No | Parameter used for sorting and refining results. | | `topicId` | - | No | Defines the ID of the topic you want to use for filtering reviews. | | `nextPageToken` | - | No | Defines the next page token. It is used for retrieving the next page results. | # Google Maps Search API Source: https://docs.hasdata.com/apis/google-maps/search The Google Maps Search API allows users to search for locations using keyword, coordinates, and various filters. The API returns relevant location details and map data. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Maps Search API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google-maps/search' \ --data-urlencode 'q=Pizza' \ --data-urlencode 'll=@40.7455096,-74.0083012,14z' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-maps \ --q Pizza \ --ll '@40.7455096,-74.0083012,14z' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google-maps/search', params: {q: 'Pizza', ll: '@40.7455096,-74.0083012,14z'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google-maps/search" querystring = {"q":"Pizza","ll":"@40.7455096,-74.0083012,14z"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Pizza", "ll" => "@40.7455096,-74.0083012,14z", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google-maps/search?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google-maps/search") .newBuilder() .addQueryParameter("q", "Pizza") .addQueryParameter("ll", "@40.7455096,-74.0083012,14z") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Pizza"; query["ll"] = "@40.7455096,-74.0083012,14z"; var url = $"https://api.hasdata.com/scrape/google-maps/search?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google-maps/search") params = { "q" => "Pizza", "ll" => "@40.7455096,-74.0083012,14z", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google-maps/search") .query(&[("q", "Pizza")]) .query(&[("ll", "@40.7455096,-74.0083012,14z")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Pizza") params.Set("ll", "@40.7455096,-74.0083012,14z") u := "https://api.hasdata.com/scrape/google-maps/search?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | --------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Pizza | Yes | Search query term or phrase. | | `domain` | - | No | Google domain to use. Default is google.com. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `start` | - | No | Specifies the result offset for pagination purposes. The offset dictates the number of rows to skip from the beginning of the results. This is useful for accessing subsequent pages of search results. For example, an offset of 0 (the default value) returns the first page of results, 20 returns the second page, 40 returns the third page, and so on. This parameter is especially relevant when used in conjunction with the 'll' parameter for location-based searches.
| | `ll` | @40.7455096,-74.0083012,14z | No | GPS coordinates of the location where the search query is to be performed. This parameter is required if the 'start' parameter is present. The format for the `ll` parameter is `@` followed by latitude, longitude, and zoom level, separated by commas. The latitude and longitude should be in decimal degrees, and the zoom level is an integer. Example: `@40.7455096,-74.0083012,14z`.
| # Google Scholar Cite API Source: https://docs.hasdata.com/apis/google-scholar/cite Provides real-time access to Google Scholar citation formats and reference-manager export links for a single organic search result. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Scholar Cite API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/scholar-cite' \ --data-urlencode 'q=EQ8shYj8Ai8J' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/scholar-cite', params: {q: 'EQ8shYj8Ai8J'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/scholar-cite" querystring = {"q":"EQ8shYj8Ai8J"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "EQ8shYj8Ai8J", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/scholar-cite?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/scholar-cite") .newBuilder() .addQueryParameter("q", "EQ8shYj8Ai8J") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "EQ8shYj8Ai8J"; var url = $"https://api.hasdata.com/scrape/google/scholar-cite?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/scholar-cite") params = { "q" => "EQ8shYj8Ai8J", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/scholar-cite") .query(&[("q", "EQ8shYj8Ai8J")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "EQ8shYj8Ai8J") u := "https://api.hasdata.com/scrape/google/scholar-cite?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | ------------- | -------- | ---------------------------------------------------------------------------------------------- | | `q` | EQ8shYj8Ai8J | Yes | The `resultId` of a Google Scholar organic result, as returned by the google/scholar endpoint. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | # Google Scholar API Source: https://docs.hasdata.com/apis/google-scholar/scholar Provides real-time access to Google Scholar search results, including papers, citations, and related scholarly metadata. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Scholar API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/scholar' \ --data-urlencode 'q=machine learning' \ --data-urlencode 'asYlo=2020' \ --data-urlencode 'asYhi=2024' \ --data-urlencode 'asSdt=0,5' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/scholar', params: {q: 'machine learning', asYlo: '2020', asYhi: '2024', asSdt: '0,5'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/scholar" querystring = {"q":"machine learning","asYlo":"2020","asYhi":"2024","asSdt":"0,5"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "machine learning", "asYlo" => "2020", "asYhi" => "2024", "asSdt" => "0,5", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/scholar?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/scholar") .newBuilder() .addQueryParameter("q", "machine learning") .addQueryParameter("asYlo", "2020") .addQueryParameter("asYhi", "2024") .addQueryParameter("asSdt", "0,5") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "machine learning"; query["asYlo"] = "2020"; query["asYhi"] = "2024"; query["asSdt"] = "0,5"; var url = $"https://api.hasdata.com/scrape/google/scholar?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/scholar") params = { "q" => "machine learning", "asYlo" => "2020", "asYhi" => "2024", "asSdt" => "0,5", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/scholar") .query(&[("q", "machine learning")]) .query(&[("asYlo", "2020")]) .query(&[("asYhi", "2024")]) .query(&[("asSdt", "0,5")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "machine learning") params.Set("asYlo", "2020") params.Set("asYhi", "2024") params.Set("asSdt", "0,5") u := "https://api.hasdata.com/scrape/google/scholar?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | ---------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | machine learning | Yes | Search query. Supports Google Scholar search helpers such as `author:` and `source:`. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `lr` | - | No | The 'lr' parameter specifies the language of the websites to return results from. This parameter filters results based on the language of the web content. | | `start` | - | No | Result offset for pagination, where 0 is the first result. | | `num` | - | No | Maximum number of results to return per page. | | `asYlo` | 2020 | No | Return results published from this year onward. | | `asYhi` | 2024 | No | Return results published up to and including this year. | | `scisbd` | - | No | Sort results by date instead of relevance: 1 for abstracts only, 2 for everything. Omit for relevance sorting. | | `cluster` | - | No | Unique article ID to look up all indexed versions of that article, as returned in a result's `versions.clusterId`. | | `cites` | - | No | Unique article ID to look up articles that cite it, as returned in a result's `citedBy.citesId`. | | `asSdt` | 0,5 | No | Search type/filter, e.g. `0,5` for the default Articles filter, `4` for case law with court codes, or `0`/`7` for patents. | | `safe` | - | No | Adult content filtering option. | | `filter` | - | No | Defines whether to enable or disable the filters for 'Similar Results' and 'Omitted Results'. Set to 1 (default) to enable these filters, or 0 to disable them.
| | `asVis` | - | No | Set to 1 to exclude citations from the results, or 0 (default) to include them. | | `asRr` | - | No | Set to 1 to return review articles only, or 0 (default) to return all articles. | # Google SERP API Parameters Source: https://docs.hasdata.com/apis/google-serp-api/api-params This page lists all parameters for the **Google SERP API**. You must include at least the `q` parameter (search query). Everything else is optional. ## Search Query Search term to query Google for. Example: `coffee beans` ## Geographic Location Google canonical location for the search. Example: `Austin,Texas,United States` Full list available [here](https://developers.google.com/google-ads/api/data/geotargets). Encoded canonical location string (Google internal format). ## Localization Google domain to use. Full list available [here](/apis/google-serp-api/domains-list). The two-letter country code for the country you want to limit the search to. Full list available [here](/apis/google-serp-api/gl-list). The two-letter language code for the language you want to use for the search. Full list available [here](/apis/google-serp-api/hl-list). Filters results based on the language of the web content. Full list available [here](/apis/google-serp-api/lr-list). ## Advanced Filters This parameter supports various filters that can be combined by separating them with a comma. Here are examples of these filters: * Specific Time Range: `cdr:1,cd_min:10/17/2018,cd_max:3/8/2021` - Filter results to show only those within the defined date range. * Sort by Date: `sbd:1` - Results are sorted by date, from the most recent to the oldest. * Sort by Relevance: `sbd:0` - Results are sorted by relevance to the search query. * Sites with Images: `img:1` - Only show results from webpages that contain images. Quick Date Range (qdr): * `qdr:h` - Show results from the past hour. * `qdr:d` - Limit results to the past day. * `qdr:w` - Filter results from the week. * `qdr:m` - Display results from the past month. * `qdr:y` - Show results from the past year. * `qdr:h10`, `qdr:d10`, `qdr:w10`, `qdr:m10`, `qdr:y10` - Specify a number to show results from the last 10 hours, days, weeks, months, or years respectively. These filters enhance the control over search results, allowing for precise retrieval of information based on specific criteria. Adult Content Filtering option. Options: `active`, `off`. Defines whether to enable or disable the filters for 'Similar Results' and 'Omitted Results'. Set to 1 (default) to enable these filters, or 0 to disable them. Controls if auto-corrected results are shown. 0 includes them (default), 1 shows only the original query. Google may still return auto-corrected results if no others are available. ## Pagination This parameter specifies the number of search results to skip and is used for implementing pagination. For example, a value of 0 (default) indicates the first page of results, 10 refers to the second page, and 20 to the third page. For Google Local Results(`tmb=lcl`), the start value must be in multiples of 20, such as 20 for the second page, 40 for the third page, etc. Number of results per page, ranging from 10 to 100. ## Search Type Type of search. Options: `isch` = images, `vid` = videos, `nws` = news, `shop` = shopping, `lcl` = local. ## Device Type Emulate Google results on a specific device. Options: `desktop`, `mobile`, `tablet`. ## Advanced Parameters The Google Place ID for a specific location. Additional Google Place ID. Google Knowledge Graph ID. Google Cached Search Parameters ID. # Batch API Source: https://docs.hasdata.com/apis/google-serp-api/batch-api Use the **Batch API** to submit multiple search queries in a single request. Each query runs independently and returns structured results just like the standard SERP API. This is useful when you need to check multiple keywords at once — for rank tracking, content monitoring, or search comparison tools. ## Submit a Batch API Job Each object in `queries` uses the same parameters as the single-query SERP API. ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrape/batch/google/serp' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"requests":[{"q":"best vpn 2025","gl":"us","hl":"en"},{"q":"cheap flights to berlin","gl":"de","hl":"de"},{"q":"ai content detection tools","gl":"us","hl":"en"}]}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrape/batch/google/serp', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { requests: [ {q: 'best vpn 2025', gl: 'us', hl: 'en'}, {q: 'cheap flights to berlin', gl: 'de', hl: 'de'}, {q: 'ai content detection tools', gl: 'us', hl: 'en'} ] } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/batch/google/serp" payload = { "requests": [ { "q": "best vpn 2025", "gl": "us", "hl": "en" }, { "q": "cheap flights to berlin", "gl": "de", "hl": "de" }, { "q": "ai content detection tools", "gl": "us", "hl": "en" } ] } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} [["q" => "best vpn 2025", "gl" => "us", "hl" => "en"], ["q" => "cheap flights to berlin", "gl" => "de", "hl" => "de"], ["q" => "ai content detection tools", "gl" => "us", "hl" => "en"]], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/batch/google/serp", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "requests": [ { "q": "best vpn 2025", "gl": "us", "hl": "en" }, { "q": "cheap flights to berlin", "gl": "de", "hl": "de" }, { "q": "ai content detection tools", "gl": "us", "hl": "en" } ] } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/batch/google/serp") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "requests": [ { "q": "best vpn 2025", "gl": "us", "hl": "en" }, { "q": "cheap flights to berlin", "gl": "de", "hl": "de" }, { "q": "ai content detection tools", "gl": "us", "hl": "en" } ] } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrape/batch/google/serp") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrape/batch/google/serp") payload = { "requests" => [{"q" => "best vpn 2025", "gl" => "us", "hl" => "en"}, {"q" => "cheap flights to berlin", "gl" => "de", "hl" => "de"}, {"q" => "ai content detection tools", "gl" => "us", "hl" => "en"}], } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "requests": [ { "q": "best vpn 2025", "gl": "us", "hl": "en" }, { "q": "cheap flights to berlin", "gl": "de", "hl": "de" }, { "q": "ai content detection tools", "gl": "us", "hl": "en" } ] }); let res = client .post("https://api.hasdata.com/scrape/batch/google/serp") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "requests": [ { "q": "best vpn 2025", "gl": "us", "hl": "en" }, { "q": "cheap flights to berlin", "gl": "de", "hl": "de" }, { "q": "ai content detection tools", "gl": "us", "hl": "en" } ] }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrape/batch/google/serp", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Response ```json theme={null} { "jobId": "9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0", "status": "ok" } ``` This means the batch job was accepted and is being processed asynchronously. ## Get Job Status & Results To check the status of your batch job: ```bash cURL theme={null} curl --request GET \ --url 'https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0") .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` To retrieve results once ready (supports pagination): ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results' \ --data-urlencode 'page=1' \ --data-urlencode 'limit=100' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results', params: {page: '1', limit: '100'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results" querystring = {"page":"1","limit":"100"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "1", "limit" => "100", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results") .newBuilder() .addQueryParameter("page", "1") .addQueryParameter("limit", "100") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["page"] = "1"; query["limit"] = "100"; var url = $"https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results") params = { "page" => "1", "limit" => "100", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results") .query(&[("page", "1")]) .query(&[("limit", "100")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("page", "1") params.Set("limit", "100") u := "https://api.hasdata.com/scrape/batch/google/serp/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ```javascript theme={null} { "page": 0, "limit": 100, "total": 3, "results": [ { "query": { "q": "ai content detection tools", "gl": "us", "hl": "en" }, "result": { "id": "5c3c1eef-eca5-4427-820b-24da63e594e6", "status": "ok", "html": "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/5c3c1eef-eca5-4427-820b-24da63e594e6.html", "json": "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/5c3c1eef-eca5-4427-820b-24da63e594e6.json", "url": "https://www.google.com/search?q=ai+content+detection+tools&hl=en&gl=us&sourceid=chrome&ie=UTF-8" } }, { "query": { "q": "cheap flights to berlin", "gl": "de", "hl": "de" }, "result": { "id": "57090249-780b-4a53-add6-aec16c700e7c", "status": "ok", "html": "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/57090249-780b-4a53-add6-aec16c700e7c.html", "json": "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/57090249-780b-4a53-add6-aec16c700e7c.json", "url": "https://www.google.com/search?q=cheap+flights+to+berlin&hl=de&gl=de&sourceid=chrome&ie=UTF-8" } }, { "query": { "q": "best vpn 2025", "gl": "us", "hl": "en" }, "result": { "id": "b434d79b-cdff-42f5-87c1-a38b883e9a38", "status": "ok", "html": "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/b434d79b-cdff-42f5-87c1-a38b883e9a38.html", "json": "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/b434d79b-cdff-42f5-87c1-a38b883e9a38.json", "url": "https://www.google.com/search?q=best+vpn+2025&hl=en&gl=us&sourceid=chrome&ie=UTF-8" } } ] } ``` Each result matches the format of a regular Google SERP API response, except it’s returned as part of an array. ## Notes * Maximum batch size: **10,000 queries** * Failed queries do **not** consume credits # Google Search Domain Parameter – Supported Domains Source: https://docs.hasdata.com/apis/google-serp-api/domains-list | domain | | | ------------- | - | | google.ac | | | google.ad | | | google.ae | | | google.al | | | google.am | | | google.as | | | google.at | | | google.az | | | google.ba | | | google.be | | | google.bf | | | google.bg | | | google.bi | | | google.bj | | | google.bs | | | google.bt | | | google.by | | | google.ca | | | google.cd | | | google.cf | | | google.cg | | | google.ch | | | google.ci | | | google.cl | | | google.cm | | | google.co.ao | | | google.co.bw | | | google.co.ck | | | google.co.cr | | | google.co.id | | | google.co.il | | | google.co.in | | | google.co.jp | | | google.co.ke | | | google.co.kr | | | google.co.ls | | | google.co.ma | | | google.co.mz | | | google.co.nz | | | google.co.th | | | google.co.tz | | | google.co.ug | | | google.co.uk | | | google.co.uz | | | google.co.ve | | | google.co.vi | | | google.co.za | | | google.co.zm | | | google.co.zw | | | google.com | | | google.com.af | | | google.com.ag | | | google.com.ai | | | google.com.ar | | | google.com.au | | | google.com.bd | | | google.com.bh | | | google.com.bn | | | google.com.bo | | | google.com.br | | | google.com.bz | | | google.com.co | | | google.com.cu | | | google.com.cy | | | google.com.do | | | google.com.ec | | | google.com.eg | | | google.com.et | | | google.com.fj | | | google.com.gh | | | google.com.gi | | | google.com.gt | | | google.com.hk | | | google.com.jm | | | google.com.kh | | | google.com.kw | | | google.com.lb | | | google.com.ly | | | google.com.mm | | | google.com.mt | | | google.com.mx | | | google.com.my | | | google.com.na | | | google.com.ng | | | google.ng | | | google.com.nf | | | google.com.ni | | | google.com.np | | | google.com.om | | | google.com.pa | | | google.com.pe | | | google.com.pg | | | google.com.ph | | | google.com.pk | | | google.com.pr | | | google.com.py | | | google.com.qa | | | google.com.sa | | | google.com.sb | | | google.com.sg | | | google.com.sl | | | google.com.sv | | | google.com.tj | | | google.com.tr | | | google.com.tw | | | google.com.ua | | | google.com.uy | | | google.com.vc | | | google.com.vn | | | google.cat | | | google.cn | | | google.cv | | | google.cz | | | google.de | | | google.dj | | | google.dk | | | google.dm | | | google.dz | | | google.ee | | | google.es | | | google.fi | | | google.fm | | | google.fr | | | google.ga | | | google.ge | | | google.gg | | | google.gl | | | google.gm | | | google.gp | | | google.gr | | | google.gy | | | google.hn | | | google.hr | | | google.ht | | | google.hu | | | google.ie | | | google.im | | | google.iq | | | google.is | | | google.it | | | google.je | | | google.jo | | | google.kg | | | google.ki | | | google.kz | | | google.la | | | google.li | | | google.lk | | | google.lt | | | google.lu | | | google.lv | | | google.md | | | google.me | | | google.mg | | | google.mk | | | google.ml | | | google.mn | | | google.ms | | | google.mu | | | google.mv | | | google.mw | | | google.ne | | | google.nl | | | google.no | | | google.nr | | | google.nu | | | google.pl | | | google.pn | | | google.ps | | | google.pt | | | google.ro | | | google.rs | | | google.ru | | | google.rw | | | google.sc | | | google.se | | | google.sh | | | google.si | | | google.sk | | | google.sm | | | google.sn | | | google.so | | | google.sr | | | google.st | | | google.td | | | google.tg | | | google.tk | | | google.tl | | | google.tm | | | google.tn | | | google.to | | | google.tt | | | google.vg | | | google.vu | | | google.ws | | # Google Search GL Parameter – Country Codes Source: https://docs.hasdata.com/apis/google-serp-api/gl-list | gl | Country | | -- | -------------------------------------------- | | ac | Ascension Island | | af | Afghanistan | | al | Albania | | dz | Algeria | | as | American Samoa | | ad | Andorra | | ao | Angola | | ai | Anguilla | | aq | Antarctica | | ag | Antigua and Barbuda | | ar | Argentina | | am | Armenia | | aw | Aruba | | au | Australia | | at | Austria | | az | Azerbaijan | | bs | Bahamas | | bh | Bahrain | | bd | Bangladesh | | bb | Barbados | | by | Belarus | | be | Belgium | | bz | Belize | | bj | Benin | | bm | Bermuda | | bt | Bhutan | | bo | Bolivia | | ba | Bosnia and Herzegovina | | bw | Botswana | | bv | Bouvet Island | | br | Brazil | | io | British Indian Ocean Territory | | bn | Brunei Darussalam | | bg | Bulgaria | | bf | Burkina Faso | | bi | Burundi | | kh | Cambodia | | cm | Cameroon | | ca | Canada | | cv | Cape Verde | | ky | Cayman Islands | | cf | Central African Republic | | td | Chad | | cl | Chile | | cn | China | | cx | Christmas Island | | cc | Cocos (Keeling) Islands | | co | Colombia | | km | Comoros | | cg | Congo | | cd | Congo, the Democratic Republic of the | | ck | Cook Islands | | cr | Costa Rica | | ci | Cote D'ivoire | | hr | Croatia | | cu | Cuba | | cy | Cyprus | | cz | Czech Republic | | dk | Denmark | | dj | Djibouti | | dm | Dominica | | do | Dominican Republic | | ec | Ecuador | | eg | Egypt | | sv | El Salvador | | gq | Equatorial Guinea | | er | Eritrea | | ee | Estonia | | et | Ethiopia | | fk | Falkland Islands (Malvinas) | | fo | Faroe Islands | | fj | Fiji | | fi | Finland | | fr | France | | gf | French Guiana | | pf | French Polynesia | | tf | French Southern Territories | | ga | Gabon | | gm | Gambia | | ge | Georgia | | gg | Guernsey | | de | Germany | | gh | Ghana | | gi | Gibraltar | | gr | Greece | | gl | Greenland | | gd | Grenada | | gp | Guadeloupe | | gu | Guam | | gt | Guatemala | | gn | Guinea | | gw | Guinea-Bissau | | gy | Guyana | | ht | Haiti | | hm | Heard Island and Mcdonald Islands | | va | Holy See (Vatican City State) | | hn | Honduras | | hk | Hong Kong | | hu | Hungary | | im | Isle of Man | | is | Iceland | | in | India | | id | Indonesia | | ir | Iran, Islamic Republic of | | iq | Iraq | | ie | Ireland | | il | Israel | | it | Italy | | je | Jersey | | jm | Jamaica | | jp | Japan | | jo | Jordan | | kz | Kazakhstan | | ke | Kenya | | ki | Kiribati | | kp | Korea, Democratic People's Republic of | | kr | Korea, Republic of | | kw | Kuwait | | kg | Kyrgyzstan | | la | Lao People's Democratic Republic | | lv | Latvia | | lb | Lebanon | | ls | Lesotho | | lr | Liberia | | ly | Libyan Arab Jamahiriya | | li | Liechtenstein | | lt | Lithuania | | lu | Luxembourg | | me | Montenegro | | mo | Macao | | mk | Macedonia, the Former Yugoslav Republic of | | mg | Madagascar | | mw | Malawi | | my | Malaysia | | mv | Maldives | | ml | Mali | | mt | Malta | | mh | Marshall Islands | | mq | Martinique | | mr | Mauritania | | mu | Mauritius | | yt | Mayotte | | mx | Mexico | | fm | Micronesia, Federated States of | | md | Moldova, Republic of | | mc | Monaco | | mn | Mongolia | | ms | Montserrat | | ma | Morocco | | mz | Mozambique | | mm | Myanmar | | na | Namibia | | nr | Nauru | | np | Nepal | | nl | Netherlands | | an | Netherlands Antilles | | nc | New Caledonia | | nz | New Zealand | | ni | Nicaragua | | ne | Niger | | ng | Nigeria | | nu | Niue | | nf | Norfolk Island | | mp | Northern Mariana Islands | | no | Norway | | om | Oman | | pk | Pakistan | | pw | Palau | | ps | Palestinian Territory, Occupied | | pa | Panama | | pg | Papua New Guinea | | py | Paraguay | | pe | Peru | | ph | Philippines | | pn | Pitcairn | | pl | Poland | | pt | Portugal | | pr | Puerto Rico | | qa | Qatar | | re | Reunion | | ro | Romania | | ru | Russian Federation | | rw | Rwanda | | sh | Saint Helena | | kn | Saint Kitts and Nevis | | lc | Saint Lucia | | pm | Saint Pierre and Miquelon | | vc | Saint Vincent and the Grenadines | | ws | Samoa | | sm | San Marino | | st | Sao Tome and Principe | | sa | Saudi Arabia | | sn | Senegal | | rs | Serbia and Montenegro | | sc | Seychelles | | sl | Sierra Leone | | sg | Singapore | | sk | Slovakia | | si | Slovenia | | sb | Solomon Islands | | so | Somalia | | za | South Africa | | gs | South Georgia and the South Sandwich Islands | | es | Spain | | lk | Sri Lanka | | sd | Sudan | | sr | Suriname | | sj | Svalbard and Jan Mayen | | sz | Swaziland | | se | Sweden | | ch | Switzerland | | sy | Syrian Arab Republic | | tw | Taiwan, Province of China | | tj | Tajikistan | | tz | Tanzania, United Republic of | | th | Thailand | | tl | Timor-Leste | | tg | Togo | | tk | Tokelau | | to | Tonga | | tt | Trinidad and Tobago | | tn | Tunisia | | tr | Turkey | | tm | Turkmenistan | | tc | Turks and Caicos Islands | | tv | Tuvalu | | ug | Uganda | | ua | Ukraine | | ae | United Arab Emirates | | uk | United Kingdom | | gb | United Kingdom | | us | United States | | um | United States Minor Outlying Islands | | uy | Uruguay | | uz | Uzbekistan | | vu | Vanuatu | | ve | Venezuela | | vn | Viet Nam | | vg | Virgin Islands, British | | vi | Virgin Islands, U.S. | | wf | Wallis and Futuna | | eh | Western Sahara | | ye | Yemen | | zm | Zambia | | zw | Zimbabwe | # Google Search HL Parameter - Language Codes Source: https://docs.hasdata.com/apis/google-serp-api/hl-list | hl | Language | | ---------- | ------------------------ | | af | Afrikaans | | ak | Akan | | sq | Albanian | | ws | Samoa | | am | Amharic | | ar | Arabic | | hy | Armenian | | az | Azerbaijani | | eu | Basque | | be | Belarusian | | bem | Bemba | | bn | Bengali | | bh | Bihari | | xx-bork | Bork, bork, bork! | | bs | Bosnian | | br | Breton | | bg | Bulgarian | | bt | Bhutanese | | km | Cambodian | | ca | Catalan | | chr | Cherokee | | ny | Chichewa | | zh-cn | Chinese (Simplified) | | zh-tw | Chinese (Traditional) | | zh-hk | Hong Kong (Traditional) | | co | Corsican | | hr | Croatian | | cs | Czech | | da | Danish | | nl | Dutch | | xx-elmer | Elmer Fudd | | en | English | | eo | Esperanto | | et | Estonian | | ee | Ewe | | fo | Faroese | | tl | Filipino | | fil | Filipino | | fi | Finnish | | fr | French | | fy | Frisian | | gaa | Ga | | gl | Galician | | ka | Georgian | | de | German | | el | Greek | | kl | Greenlandic | | gn | Guarani | | gu | Gujarati | | xx-hacker | Hacker | | ht | Haitian Creole | | ha | Hausa | | haw | Hawaiian | | iw | Hebrew | | he | Hebrew | | hi | Hindi | | hu | Hungarian | | is | Icelandic | | ig | Igbo | | id | Indonesian | | ia | Interlingua | | ga | Irish | | it | Italian | | ja | Japanese | | jw | Javanese | | kn | Kannada | | kk | Kazakh | | rw | Kinyarwanda | | rn | Kirundi | | xx-klingon | Klingon | | kg | Kongo | | ko | Korean | | kri | Krio (Sierra Leone) | | ku | Kurdish | | ckb | Kurdish (Soranî) | | ky | Kyrgyz | | lo | Laothian | | la | Latin | | lv | Latvian | | ln | Lingala | | lt | Lithuanian | | loz | Lozi | | lg | Luganda | | ach | Luo | | mk | Macedonian | | mg | Malagasy | | my | Myanmar | | ml | Malayalam | | mt | Maltese | | mv | Maldives | | mi | Maori | | mr | Marathi | | mfe | Mauritian Creole | | mo | Moldavian | | mn | Mongolian | | ms | Malay | | sr-me | Montenegrin | | ne | Nepali | | pcm | Nigerian Pidgin | | nso | Northern Sotho | | no | Norwegian | | nn | Norwegian (Nynorsk) | | oc | Occitan | | or | Oriya | | om | Oromo | | ps | Pashto | | fa | Persian | | xx-pirate | Pirate | | pl | Polish | | pt | Portuguese | | pt-br | Portuguese (Brazil) | | pt-pt | Portuguese (Portugal) | | pa | Punjabi | | qu | Quechua | | ro | Romanian | | rm | Romansh | | nyn | Runyakitara | | ru | Russian | | gd | Scots Gaelic | | sr | Serbian | | sh | Serbo-Croatian | | st | Sesotho | | tn | Setswana | | crs | Seychellois Creole | | sn | Shona | | sd | Sindhi | | si | Sinhalese | | sk | Slovak | | sl | Slovenian | | so | Somali | | es | Spanish | | es-419 | Spanish (Latin American) | | su | Sundanese | | sw | Swahili | | sv | Swedish | | tg | Tajik | | ta | Tamil | | tt | Tatar | | te | Telugu | | th | Thai | | ti | Tigrinya | | to | Tonga | | lua | Tshiluba | | tum | Tumbuka | | tr | Turkish | | tk | Turkmen | | tw | Twi | | ug | Uighur | | uk | Ukrainian | | ur | Urdu | | uz | Uzbek | | vu | Vanuatu | | vi | Vietnamese | | cy | Welsh | | wo | Wolof | | xh | Xhosa | | yi | Yiddish | | yo | Yoruba | | zu | Zulu | # Google Search LR Parameter - Supported Languages Source: https://docs.hasdata.com/apis/google-serp-api/lr-list | lr | Language | | ----------- | -------- | | lang\_ar | ar | | lang\_hy | hy | | lang\_bg | bg | | lang\_ca | ca | | lang\_cs | cs | | lang\_da | da | | lang\_de | de | | lang\_el | el | | lang\_en | en | | lang\_es | es | | lang\_et | et | | lang\_tl | tl | | lang\_fi | fi | | lang\_fr | fr | | lang\_hr | hr | | lang\_hi | hi | | lang\_hu | hu | | lang\_id | id | | lang\_is | is | | lang\_it | it | | lang\_iw | iw | | lang\_he | he | | lang\_ja | ja | | lang\_ko | ko | | lang\_lt | lt | | lang\_lv | lv | | lang\_nl | nl | | lang\_no | no | | lang\_fa | fa | | lang\_pl | pl | | lang\_pt | pt | | lang\_ro | ro | | lang\_ru | ru | | lang\_sk | sk | | lang\_sl | sl | | lang\_sr | sr | | lang\_sv | sv | | lang\_th | th | | lang\_tr | tr | | lang\_uk | uk | | lang\_vi | vi | | lang\_zh-CN | zh-CN | | lang\_zh-TW | zh-TW | # Quickstart - Google SERP API Source: https://docs.hasdata.com/apis/google-serp-api/quickstart The **Google SERP API** lets you programmatically search Google and extract structured results - titles, links, snippets, ads, maps, videos, and more. Use it to check rankings, extract competitor URLs, monitor brand mentions, or analyze query results in real time. ## Get Your API Key Sign in at [hasdata.com](http://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google SERP API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/serp' \ --data-urlencode 'q=Coffee' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-serp \ --q Coffee ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/serp', params: {q: 'Coffee'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/serp" querystring = {"q":"Coffee"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Coffee", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/serp?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/serp") .newBuilder() .addQueryParameter("q", "Coffee") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Coffee"; var url = $"https://api.hasdata.com/scrape/google/serp?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/serp") params = { "q" => "Coffee", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/serp") .query(&[("q", "Coffee")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Coffee") u := "https://api.hasdata.com/scrape/google/serp?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` The `html`, `json` and `preview` links in `requestMetadata`, and result thumbnails under `files.hasdata.com`, are private to your workspace — fetch them with your API key in the `x-api-key` header, or browse them from the dashboard. ```json theme={null} { "requestMetadata":{ "id":"59208867-8c59-46d7-a883-5c2700b0e0df", "status":"ok", "html":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/59208867-8c59-46d7-a883-5c2700b0e0df.html", "url":"https://www.google.com/search?q=Coffee&uule=w+CAIQICIaQXVzdGluLFRleGFzLFVuaXRlZCBTdGF0ZXM%3D&hl=en&gl=us&sourceid=chrome&ie=UTF-8" }, "searchInformation":{ "totalResults":"4110000000", "timeTaken":0.35 }, "organicResults":[ { "position":1, "title":"Coffee", "link":"https://en.wikipedia.org/wiki/Coffee", "displayedLink":"https://en.wikipedia.org › wiki › Coffee", "source":"Wikipedia", "snippet":"Coffee is a beverage brewed from roasted, ground coffee beans. Darkly colored, bitter, and slightly acidic, coffee has a stimulating effect on humans, ...", "snippetHighlitedWords":[ "Coffee" ], "sitelinks":{ "inline":[ { "title":"Coffee bean", "link":"https://en.wikipedia.org/wiki/Coffee_bean" }, { "title":"History", "link":"https://en.wikipedia.org/wiki/History_of_coffee" }, { "title":"Coffee preparation", "link":"https://en.wikipedia.org/wiki/Coffee_preparation" }, { "title":"Coffee production", "link":"https://en.wikipedia.org/wiki/Coffee_production" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRjBOBPc7QPR8fE5TGXgsOQ28R6xsX_d9xz8kPAXHvd6JWJrCqwOlZg&usqp=CAE&s" ] }, { "position":2, "title":"Coffee roasters or shops that sell coffee beans/quality ...", "link":"https://www.reddit.com/r/austinfood/comments/18mb2bn/coffee_roasters_or_shops_that_sell_coffee/", "displayedLink":"30+ comments · 1 year ago", "source":"Reddit · r/austinfood", "snippet":"Any good recommendations? Whether it be a local coffee shop or store I can buy them at. I love coffee but not much of a coffee enthusiast to know a good roast.", "snippetHighlitedWords":[ "coffee", "coffee", "coffee" ], "sitelinks":{ "list":[ { "title":"r/Coffee - Reddit", "link":"https://www.reddit.com/r/Coffee/", "snippet":"Mar 6, 2014" }, { "title":"Cheapest coffee in Austin? : r/austinfood - Reddit", "link":"https://www.reddit.com/r/austinfood/comments/1iuuk0f/cheapest_coffee_in_austin/", "snippet":"Feb 21, 2025" } ] } }, { "position":3, "title":"Jo's Coffee - Austin", "link":"https://www.joscoffee.com/", "displayedLink":"https://www.joscoffee.com", "source":"Jo's Coffee", "snippet":"Jo's Coffee is an iconic Austin coffee shop known for its coffee, pastries, sandwiches, and breakfast tacos with multiple locations throughout Texas.", "snippetHighlitedWords":[ "an iconic Austin coffee shop" ] }, { "position":4, "title":"Buy Coffee, Tea, Powders Online | The Coffee Bean & Tea ...", "link":"https://www.coffeebean.com/", "displayedLink":"https://www.coffeebean.com", "source":"The Coffee Bean & Tea Leaf", "snippet":"Buy exceptional coffee, tea, powders, equipment and drinkware at The Coffee Bean & Tea Leaf® online store to enjoy our globally sourced products at home.", "snippetHighlitedWords":[ "Buy exceptional coffee, tea, powders, equipment and drinkware" ] }, { "position":5, "title":"Peet's Coffee | The Original Craft Coffee Since 1966", "link":"https://www.peets.com/", "displayedLink":"https://www.peets.com", "source":"Peet's Coffee", "snippet":"Since 1966, Peet's Coffee has sourced and offered superior coffees and teas adhered to strict high-quality and taste standards. Shop online today.", "snippetHighlitedWords":[ "Peet's Coffee" ], "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTosOIgUz-4lHJoAfS5uUhXY5vrsv6ltGFJJuWPhAm4OOtgBWaSisHx&usqp=CAE&s" ] }, { "position":6, "title":"Starbucks Coffee Company", "link":"https://www.starbucks.com/", "displayedLink":"https://www.starbucks.com", "source":"Starbucks", "snippet":"More than just great coffee. Explore the menu, sign up for Starbucks® Rewards, manage your gift card and more.", "snippetHighlitedWords":[ "coffee" ], "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRChKfiV87kDO6bYuYGocHw1k9ZVBDKAPM-1X8bMO8WKxH-3T83uMBr&usqp=CAE&s" ] }, { "position":7, "title":"Scooter's Coffee | Be Amazing", "link":"https://www.scooterscoffee.com/", "displayedLink":"https://www.scooterscoffee.com", "source":"Scooter's Coffee", "snippet":"Wake up to the ahhh-mazing aroma of quality. Subscribe to Scooter's Coffee® delivery and enjoy 100% Arabica beans, sourced directly from farmers who take pride ...", "snippetHighlitedWords":[ "100% Arabica beans" ], "richSnippet":{ "top":{ "extensions":[ "2–9 day delivery" ] } }, "sitelinks":{ "inline":[ { "title":"Locations", "link":"https://www.scooterscoffee.com/locations" }, { "title":"Menu", "link":"https://www.scooterscoffee.com/menu" }, { "title":"At-Home Coffee", "link":"https://www.scooterscoffee.com/shop/at-home-coffee" }, { "title":"Relationship Coffee", "link":"https://www.scooterscoffee.com/relationship-coffee" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQIq-YbdBa3Ee0YilmBe82CUhJeuw3x6vZbnHq86zrT10y70BpirBI-&usqp=CAE&s" ] }, { "position":8, "title":"Counter Culture Coffee", "link":"https://counterculturecoffee.com/?srsltid=AfmBOoo2fhZ4u7Qz4b5BU7gbqpoN5C9mo1wXgiSKItAJLnrjJN4Gm5lY", "displayedLink":"https://counterculturecoffee.com", "source":"Counter Culture Coffee", "snippet":"Counter Culture Coffee is a specialty coffee roaster sourcing exceptional single-origin and specialty coffee. Fresh-roasted coffee to your doorstep.", "snippetHighlitedWords":[ "Counter Culture Coffee" ], "richSnippet":{ "top":{ "extensions":[ "Free delivery over $30" ] } }, "sitelinks":{ "inline":[ { "title":"Shop", "link":"https://counterculturecoffee.com/collections/coffee" }, { "title":"Training Centers", "link":"https://counterculturecoffee.com/pages/training-centers" }, { "title":"History", "link":"https://counterculturecoffee.com/pages/history" }, { "title":"Shop All Coffee", "link":"https://counterculturecoffee.com/collections/all" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQz_d_d3C-XU96xCrdXoLPyeXJVnRCovCUtnHZ2sedjHrFVcIg1sUtW&usqp=CAE&s" ] }, { "position":9, "title":"Chamberlain Coffee - Cold Brew, Matcha, & More", "link":"https://chamberlaincoffee.com/?srsltid=AfmBOooBJA3q3JdlnEBH-NNg5Jn2xKfnBkWhW3qS0BR4wku6P7-XMMou", "displayedLink":"https://chamberlaincoffee.com", "source":"Chamberlain Coffee", "snippet":"At Chamberlain Coffee, we're passionate about providing high quality, delicious beverages. So you can enjoy every sip, slurp and spill (it happens) with the ...", "snippetHighlitedWords":[ "high quality, delicious beverages" ], "richSnippet":{ "top":{ "detectedExtensions":{ "rating":4.8, "reviews":44 }, "extensions":[ "4.8store rating (44)", "14–25 day delivery", "14-day returns" ] } }, "sitelinks":{ "inline":[ { "title":"Coffee Beans", "link":"https://chamberlaincoffee.com/collections/coffee-beans" }, { "title":"Cold Brew Coffee", "link":"https://chamberlaincoffee.com/collections/cold-brew-coffee" }, { "title":"Organic vanilla coffee blend", "link":"https://chamberlaincoffee.com/products/vanilla-medium-roast-coffee-blend" }, { "title":"Store locator", "link":"https://chamberlaincoffee.com/pages/store-locator" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQqswIVDboifAYTfntryPfbUWYB7lDoZmk3P2Og4K26yMlmEr0klNgD&usqp=CAE&s" ] } ], "localResults":{ "places":[ { "position":1, "title":"Houndstooth Coffee", "rating":4.6, "reviews":1100, "reviewsOriginal":"(1.1K)", "address":"401 Congress Ave. #100c", "hours":"Cozy hangout for carefully sourced brews", "placeId":"11265938073076301333", "description":"Cozy hangout for carefully sourced brews" }, { "position":2, "title":"The Hideout Coffee House", "rating":4.4, "reviews":613, "reviewsOriginal":"(613)", "address":"617 Congress Ave.", "hours":"Area institution with a theater upstairs", "placeId":"15498522356495312950", "description":"Area institution with a theater upstairs" }, { "position":3, "title":"Revolución", "rating":4.4, "reviews":321, "reviewsOriginal":"(321)", "address":"207 San Jacinto Blvd Suite 200", "hours":"Cozy spot with organic, plant-forward breakfast, lunch, and dinner options, plus fresh juices.", "placeId":"2574271126412631236", "description":"Cozy spot with organic, plant-forward breakfast, lunch, and dinner options, plus fresh juices." } ], "moreLocationsLink":"https://www.google.com/search?sca_esv=51ee083cf20858f1&hl=en&gl=us&tbm=lcl&q=Coffee&rflfq=1&num=10&uule=w+CAIQICIaQXVzdGluLFRleGFzLFVuaXRlZCBTdGF0ZXM%3D&sa=X&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQjGp6BAg4EAE" }, "relatedSearches":[ { "query":"Coffee near me", "link":"https://www.google.com/search?sca_esv=51ee083cf20858f1&hl=en&gl=us&q=Coffee+near+me&sa=X&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ1QJ6BQihARAB" }, { "query":"Coffee Bean menu", "link":"https://www.google.com/search?sca_esv=51ee083cf20858f1&hl=en&gl=us&q=Coffee+Bean+menu&sa=X&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ1QJ6BQifARAB" }, { "query":"Coffee menu", "link":"https://www.google.com/search?sca_esv=51ee083cf20858f1&hl=en&gl=us&q=Coffee+menu&sa=X&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ1QJ6BQicARAB" }, { "query":"Coffee png", "link":"https://www.google.com/search?sca_esv=51ee083cf20858f1&hl=en&gl=us&q=Coffee+png&sa=X&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ1QJ6BQiWARAB" }, { "query":"Coffee brand", "link":"https://www.google.com/search?sca_esv=51ee083cf20858f1&hl=en&gl=us&q=Coffee+brand&sa=X&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ1QJ6BQiUARAB" }, { "query":"Coffee recipe", "link":"https://www.google.com/search?sca_esv=51ee083cf20858f1&hl=en&gl=us&q=Coffee+recipe&sa=X&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ1QJ6BQiRARAB" }, { "query":"Coffee Table", "link":"https://www.google.com/search?sca_esv=51ee083cf20858f1&hl=en&gl=us&q=Coffee+Table&sa=X&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ1QJ6BQiOARAB" }, { "query":"Coffee images", "link":"https://www.google.com/search?sca_esv=51ee083cf20858f1&hl=en&gl=us&q=Coffee+images&sa=X&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ1QJ6BQiNARAB" } ], "relatedQuestions":[ { "snippet":"Translated to coffee making, this means that you can create 80% of the perfect cup of coffee by focusing on the right 20% of the process. Consider the coffee/water ratio, the temperature of the water and, for example, the brewing time.", "link":"https://zwarteroes.nl/en-int/blogs/koffie-zetten/wat-is-de-80-20-regel-voor-koffie#:~:text=Translated%20to%20coffee%20making%2C%20this,for%20example%2C%20the%20brewing%20time.", "title":"What is the 80-20 rule for coffee? - Zwarte Roes", "displayedLink":"https://zwarteroes.nl › wat-is-de-80-20-regel-voor-koffie", "question":"What is the 80/20 rule for coffee?" }, { "snippet":"The history of coffee dates back centuries, first from its origin in Ethiopia and later in Yemen. It was already known in Mecca in the 15th century. Also, in the 15th century, Sufi monasteries in Yemen employed coffee as an aid to concentration during prayers.", "link":"https://en.wikipedia.org/wiki/History_of_coffee#:~:text=The%20history%20of%20coffee%20dates,aid%20to%20concentration%20during%20prayers.", "title":"History of coffee - Wikipedia", "displayedLink":"https://en.wikipedia.org › wiki › History_of_coffee", "question":"Where does coffee originate?" }, { "date":"Feb 14, 2025", "link":"https://www.foodnetwork.com/how-to/packages/shopping/best-coffee-brands", "title":"10 Best Coffee Brands of 2025, Tested and Reviewed - Food Network", "displayedLink":"https://www.foodnetwork.com › packages › shopping", "list":[ "Best Overall. La Colombe. Read Review From $9 at Amazon.", "Best Budget. Cafe Bustelo. Read Review From $6 at Amazon.", "Best Splurge. Intelligentsia. ... ", "Best Espresso. Stumptown Hairbender. ... ", "Best Flavored. Chicago French Press. ... ", "Best K-Cups. The Organic Coffee Co. ... ", "Best Decaf. Peet's Coffee Major Dickason's Blend." ], "question":"What is the best quality coffee?" }, { "snippet":"The main constituents of coffee are caffeine, tannin, fixed oil, carbohydrates, and proteins. It contains 2–3% caffeine, 3–5% tannins, 13% proteins, and 10–15% fixed oils. In the seeds, caffeine is present as a salt of chlorogenic acid (CGA). Also it contains oil and wax [2].", "link":"https://www.intechopen.com/chapters/71528#:~:text=The%20main%20constituents%20of%20coffee,oil%20and%20wax%20%5B2%5D.", "title":"A Detail Chemistry of Coffee and Its Analysis - IntechOpen", "displayedLink":"https://www.intechopen.com › chapters", "question":"What ingredients are in coffee?" } ], "knowledgeGraph":{ "title":"Coffee", "type":"Beverages" }, "perspectives":[ { "index":1, "author":"motivationaldoc", "source":"YouTube", "duration":"3:08", "extensions":[ "18.9K+ views" ], "thumbnail":"https://img.youtube.com/vi/lg35eFr5-5s/hqdefault.jpg", "title":"Never Drink Coffee at THIS Time – Most People Get It Wrong! Dr. Mandell", "link":"https://www.youtube.com/watch?v=lg35eFr5-5s", "date":"10 hours ago" }, { "index":2, "author":"lionfield", "source":"TikTok", "duration":"0:33", "extensions":[ "154.6K+ views" ], "thumbnail":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTDWesbdGNveXiQLtyYNSmtobRaAwe82xoru-L_C20TXgKDdrIOgTPga9MQzw&usqp=CAI&s", "title":"8594 Mi piace, 61 commenti. \"We tried the best affogato in Italy”", "link":"https://www.tiktok.com/@lionfieldmusic/video/7493218611058822430", "date":"4 hours ago" }, { "index":3, "author":"r/fednews", "source":"Reddit", "extensions":[ "1.3K+ comments" ], "title":"This is not a joke, they’re taking away our coffee.", "link":"https://www.reddit.com/r/fednews/comments/1jw0yzm/this_is_not_a_joke_theyre_taking_away_our_coffee/", "date":"4 days ago", "snippet":" Top comment · Starting May 20th all employees will be required to go barefoot. On May 21 legos will be spread on to all floors" } ], "immersiveProducts":[ { "position":1, "category":"Popular products", "title":"Folgers Coffee Ground Classic Roast", "productId":"16914877625280977865", "productLink":"https://www.google.com/shopping/product/16914877625280977865", "price":"$5.78", "extractedPrice":5.78, "source":"Walmart", "reviews":15000, "rating":4.6, "extensions":[ "Nearby, 12 mi" ], "thumbnail":"https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcTyiImkxm7BL7GGtNo3eTT3YchvlhF9N6A5fg92bH1gXOoc4Ge2JumU5jzDDB5Df0Z-7bIz-Yi3DfDymwcdOyYdRkUGhln0dtjQDjQdP_caCgiSqkMLD-iX" }, { "position":2, "category":"Popular products", "title":"Death Wish Coffee Coffee", "productId":"984394624832565634", "productLink":"https://www.google.com/shopping/product/984394624832565634", "price":"$14.83", "extractedPrice":14.83, "source":"Amazon.com - Seller", "reviews":6600, "rating":4.8, "extensions":[ "Also nearby" ], "thumbnail":"https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcSeniafbHH1sjQTnOcf_8zrvELx8AENL0sqhQEXn2MBfB74VC6env1bDAUUredJ_R9bkb3Fls79Q5_09xARMICjT5XXYgP3RbmoZ5cBN5MHqk1nIG6-xxw" }, { "position":3, "category":"Popular products", "title":"Ground Bones Coffee 5 Bag Sample Pack", "productId":"7733553032036677584", "productLink":"https://www.google.com/shopping/product/7733553032036677584", "price":"$33.00", "extractedPrice":33, "source":"Bones Coffee Company", "reviews":11000, "rating":4.8, "delivery":"Free delivery on $75+", "thumbnail":"https://encrypted-tbn1.gstatic.com/shopping?q=tbn:ANd9GcSraT7OVtMhg6QutGI2A2KdWz-jCFqQp4esNHj27_GSCG_HqLrJvA4NiW14IYiQ__nSpbevLv3Z46RG5zuaCARh2Zt_btlKX1AqK4MJILm6InwPLe1LNoRd1w" }, { "position":4, "category":"Popular products", "title":"Black Rifle Coffee Company Freedom Fuel Coffee", "productId":"18134019833504388210", "productLink":"https://www.google.com/shopping/product/18134019833504388210", "price":"$15.99", "extractedPrice":15.99, "source":"Black Rifle Coffee Company", "reviews":737, "rating":4.8, "delivery":"Free delivery on $75+", "thumbnail":"https://encrypted-tbn1.gstatic.com/shopping?q=tbn:ANd9GcQN_CC0gH6MlQF0lxouaL9ffMwqGDzOLJx7nMgSUegEGJtEHDqeDozUhk_QbccwjLxuQSWFUN61cOBtjBsKbZB4B_4Tbr_pOV_6HadyDwDBWg3Izexr5Ymo" }, { "position":5, "category":"Popular products", "title":"Build-A-Box of Whole Bean Samples", "productId":"18102357511625218034", "productLink":"https://www.google.com/shopping/product/18102357511625218034", "price":"$12.00", "extractedPrice":12, "source":"Geek Grind Coffee", "thumbnail":"https://encrypted-tbn0.gstatic.com/shopping?q=tbn:ANd9GcSF9wp4H22u-T2POvy_NootW6IEi0Wso-b55uVXZdX3aXm0eOKj7K7KaJGZ7in4YIZQoair_-AUjWA21LniZoMI9Awe6192WyZNZQB_7DNoXddCeAJznL25" }, { "position":6, "category":"Popular products", "title":"Dunkin Ground Coffee Original Blend", "productId":"13144439343082777610", "productLink":"https://www.google.com/shopping/product/13144439343082777610", "price":"$8.46", "extractedPrice":8.46, "source":"Walmart", "reviews":8200, "rating":4.7, "extensions":[ "Nearby, 12 mi" ], "thumbnail":"https://encrypted-tbn0.gstatic.com/shopping?q=tbn:ANd9GcTKcRu7x2iC7m8Gj_B5WccJ1bGARryX_7mNJqEDT0W3TsRX94EMD1j8VuRGOSjJ5gN3vHK1ul0E926hdZdCSZL9K_ot2kyFLFOxmyoux2-pUTqXBhyYhX4Q" }, { "position":7, "category":"Popular products", "title":"Maxwell House 100% Colombian Ground Coffee", "productId":"2390242872178784621", "productLink":"https://www.google.com/shopping/product/2390242872178784621", "price":"$9.99", "extractedPrice":9.99, "source":"Amazon", "reviews":841, "rating":4.4, "extensions":[ "Also nearby" ], "thumbnail":"https://encrypted-tbn0.gstatic.com/shopping?q=tbn:ANd9GcROT9pozFZzSw1dpByZdRfcUp4ZrFYfJsARkfBhUKHTiiv1zWq7K-yddOZfIS1sKwcjrwlZmdMvbVrRcdLogVRc12MgbLErDWVRxqucE4Xr4uzQzxmPOVpBSA" }, { "position":8, "category":"Popular products", "title":"Victor Allen's Coffee Donut Shop Blend Medium Roast", "productId":"7763548679529248666", "productLink":"https://www.google.com/shopping/product/7763548679529248666", "price":"$18.79", "extractedPrice":18.79, "source":"Victor Allen's Coffee", "reviews":1800, "rating":4.8, "thumbnail":"https://encrypted-tbn0.gstatic.com/shopping?q=tbn:ANd9GcQfqtER4Cn5mjo7uDVNK2kY0kD-u8HNW5THur8avUAcSQLy5YzLTsfSmXxNgRHPkJiSnaYNdaaq9f03qFfA61kOHCpbCmPAr4EF0eyKWoK6uI_DKHug91MO-w" } ], "pagination":{ "next":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=10&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8NMDegQICRAW", "pages":[ { "2":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=10&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8tMDegQICRAE" }, { "3":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=20&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8tMDegQICRAG" }, { "4":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=30&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8tMDegQICRAI" }, { "5":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=40&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8tMDegQICRAK" }, { "6":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=50&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8tMDegQICRAM" }, { "7":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=60&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8tMDegQICRAO" }, { "8":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=70&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8tMDegQICRAQ" }, { "9":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=80&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8tMDegQICRAS" }, { "10":"https://www.google.com/search?q=Coffee&sca_esv=51ee083cf20858f1&hl=en&gl=us&ei=zIH9Z8nxGJyOvr0PnMzrgAc&start=90&sa=N&sstk=Af40H4WhIrulMlZd2J6Ympy_8mGRLYW_KKmz38bRnswd1GS_SbIz2-CYC09aXkx4FmHURLADZGUsjMqJQ3D9Jwf-MBn2XQTZlTng3Q&ved=2ahUKEwjJh8Wuv9iMAxUch68BHRzmGnAQ8tMDegQICRAU" } ] } } ``` # Ad Results Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/ad-results ```json Response theme={null} { "ads":[ { "position":1, "blockPosition":"top", "title":"Walmart® Official Site", "link":"https://www.walmart.com/", "displayedLink":"https://www.walmart.com/", "trackingLink":"https://www.google.com/aclk?sa=l&ai=DChcSEwir-9uvzNqMAxUO1hYFHYRcKh4YABABGgJ0bA&co=1&gclid=EAIaIQobChMIq_vbr8zajAMVDtYWBR2EXCoeEAAYASAAEgJFzPD_BwE&sig=AOD64_3XkGhPgN8e9YnAYzBHqp-Ih1YS4A&q&adurl", "description":"Shop Online Now — Save Money And Time With A Walmart+ Membership. Enjoy Low Prices, Free Delivery And More! Groceries, essentials & more delivered in as fast as an hour. Try Express Delivery!" }, { "position":1, "blockPosition":"bottom", "title":"Walmart® Official Site - Shop Online Today", "link":"/aclk?sa=l&ai=DChcSEwir-9uvzNqMAxUO1hYFHYRcKh4YABAAGgJ0bA&co=1&gclid=EAIaIQobChMIq_vbr8zajAMVDtYWBR2EXCoeEAMYASAAEgJT8fD_BwE&sig=AOD64_1559Ktj0jZtvE93ZHGBeBLL3dMxQ&adurl=&q=", "displayedLink":"https://www.walmart.com/", "trackingLink":"https://www.google.com/aclk?sa=l&ai=DChcSEwir-9uvzNqMAxUO1hYFHYRcKh4YABAAGgJ0bA&co=1&gclid=EAIaIQobChMIq_vbr8zajAMVDtYWBR2EXCoeEAMYASAAEgJT8fD_BwE&sig=AOD64_1559Ktj0jZtvE93ZHGBeBLL3dMxQ&q&adurl", "description":"Walmart+ Free Shipping No Order Minimum Needed - Free Next-Day Shipping From Walmart.com. Fresh Groceries Delivered Same Day with 100% Freshness Guarantee. Start Your Free Trial! Free Store Pickup. Reorder Items. Walmart MoneyCard." } ] } ``` # AI Overview Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/ai-overview ## Typical Result ```json Response theme={null} { "aiOverview":{ "textBlocks":[ { "type":"paragraph", "snippet":"Core Web Vitals are a set of metrics defined by Google to quantify user experience (UX) on the web, focusing on loading performance, visual stability, and interactivity. They are a subset of Web Vitals, a broader initiative by Google to improve web quality. These metrics are used to assess how users experience a website and can impact its search engine ranking.", "snippetHighlightedWords":[ "a set of metrics defined by Google to quantify user experience (UX) on the web, focusing on loading performance, visual stability, and interactivity" ], "referenceIndexes":[ 0, 1, 3 ], "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/b5a043af-ae9f-41f2-a3fe-9b2d64f46d7e.png" }, { "type":"paragraph", "snippet":"Here's a breakdown of the key metrics:" }, { "type":"list", "list":[ { "title":"Largest Contentful Paint (LCP):", "snippet":"Measures the time it takes for the largest content element (image, video, or text block) to load and become visible.", "referenceIndexes":[ 1, 2 ] }, { "title":"Cumulative Layout Shift (CLS):", "snippet":"Measures the visual stability of a page by quantifying unexpected shifts in the layout as it loads.", "referenceIndexes":[ 1, 4 ] }, { "title":"Interaction to Next Paint (INP):", "snippet":"Measures the responsiveness of a page by tracking the delay between a user's interaction (like a click or tap) and the next visual update.", "referenceIndexes":[ 1, 5 ] } ] }, { "type":"paragraph", "snippet":"Why are Core Web Vitals important?" }, { "type":"list", "list":[ { "title":"SEO:", "snippet":"Google uses Core Web Vitals as a ranking factor, meaning that websites that perform well in these metrics may have an advantage in search results.", "referenceIndexes":[ 1, 3 ] }, { "title":"User Experience:", "snippet":"Core Web Vitals directly reflect how users perceive a website's speed, stability, and responsiveness, which are crucial for a positive user experience.", "referenceIndexes":[ 1, 3 ] }, { "title":"Performance Optimization:", "snippet":"By understanding and optimizing Core Web Vitals, website owners can identify and address performance bottlenecks, leading to faster, more engaging websites.", "referenceIndexes":[ 1, 3, 6, 7 ] } ] } ], "references":[ { "index":0, "title":"Web Vitals | Articles - web.dev", "link":"https://web.dev/articles/vitals#:~:text=Philip%20Walton,challenging%20to%20keep%20up%20with.", "snippet":"May 4, 2020 — Philip Walton. Published: May 4, 2020. Optimizing for quality of user experience is key to the long-term success of any...", "source":"web.dev" }, { "index":1, "title":"What are Core Web Vitals? - Dynatrace", "link":"https://www.dynatrace.com/knowledge-base/core-web-vitals/#:~:text=Core%20Web%20Vitals%20are%20three,and%20determining%20website%20UX%20success.", "snippet":"Core Web Vitals are three key metrics of web page performance that measure a page's loading performance, interactivity, and visual...", "source":"Dynatrace" }, { "index":2, "title":"Core Web Vitals: What They Are & How to Improve Them - Semrush", "link":"https://www.semrush.com/blog/core-web-vitals/#:~:text=%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B,next%20visual%20update%20is%20displayed", "snippet":"Mar 19, 2024 — ​​​​​What Are the Core Web Vitals? Google's Core Web Vitals are a collection of metrics that indicate how user-friendl...", "source":"Semrush" }, { "index":3, "title":"Everything You Have to Know About Core Web Vitals - Calibre", "link":"https://calibreapp.com/blog/core-web-vitals#:~:text=Karolina%20Szczur,traffic%2C%20conversions%2C%20and%20more.", "snippet":"Feb 8, 2024 — Karolina Szczur. November 3, 2021 (Updated: February 8, 2024) Dozens of metrics measure aspects of site speed and perfo...", "source":"calibreapp.com" }, { "index":4, "title":"The Ultimate Guide to Core Web Vitals - Conductor", "link":"https://www.conductor.com/academy/core-web-vitals/#:~:text=dev.-,Cumulative%20Layout%20Shift%20(CLS),how%20CLS%20is%20calculated%20here%20.", "snippet":"Jun 20, 2024 — Cumulative Layout Shift (CLS) Cumulative Layout Shift (CLS) is a Core Web Vital that measures the cumulative score of ...", "source":"Conductor" }, { "index":5, "title":"Google Core Web Vitals Explained - Akamai", "link":"https://www.akamai.com/glossary/what-are-google-core-web-vitals#:~:text=Interaction%20to%20Next%20Paint%20(INP,(FID)%20in%20March%202024.", "snippet":"Interaction to Next Paint (INP): This measures latency of all clicks, taps, and keyboard interactions with the page throughout its...", "source":"Akamai" }, { "index":6, "title":"Unleashing the Power of Core Web Vitals: Enhancing User Experience and Business Success", "link":"https://www.linkedin.com/pulse/unleashing-power-core-web-vitals-enhancing-user-success-saeed-?trk=article-ssr-frontend-pulse_more-articles_related-content-card#:~:text=It%20(%20Core%20Web%20Vitals%20report%20),a%20smooth%20browsing%20experience%20for%20their%20users.", "snippet":"Jul 7, 2023 — It ( Core Web Vitals report ) helps website owners identify specific performance issues that may be affecting their pag...", "source":"LinkedIn" }, { "index":7, "title":"What Does a Web Developer Do?", "link":"https://trios.com/blog/what-does-a-web-developer-do/#:~:text=Optimization%20and%20Performance%20Tuning:%20As%20websites%20grow,enhance%20loading%20speed%2C%20responsiveness%2C%20and%20user%20experience.", "snippet":"Apr 9, 2024 — Optimization and Performance Tuning: As websites grow in complexity, optimizing performance becomes increasingly crucia...", "source":"triOS College" } ] } } ``` ## Nested List ```json Response theme={null} { "textBlocks":[ { "type":"list", "list":[ { "title":"Potential legal pitfalls to watch out for:", "list":[ { "snippet":"Intellectual Property Infringement: Selling counterfeit goods or products that infringe on trademarks, copyrights, or patents can lead to legal trouble.", "referenceIndexes":[ 31, 33 ] }, { "snippet":"Product Safety and Liability: Even if you didn't manufacture the product, you could be held liable if it causes harm.", "referenceIndexes":[ 31, 33 ] }, { "snippet":"Consumer Protection Laws: You need to ensure your business practices are fair and transparent, including advertising, return policies, and shipping practices.", "referenceIndexes":[ 31, 33 ] }, { "snippet":"Taxes and Business Registration: You must register your business, obtain necessary permits, and comply with tax laws.", "referenceIndexes":[ 31, 33 ] } ] } ] } ] } ``` ## Table Result ```json Response theme={null} { "textBlocks":[ { "type":"table", "rows":[ [ "Feature", "Samsung Galaxy S24 Ultra", "iPhone 15 Pro" ], [ "Display", "6.8-inch Dynamic AMOLED 2x", "6.1-inch Super Retina XDR display" ], [ "Processor", "Snapdragon 8 Gen 3(US) / Exynos 2400 (other regions)", "A17 Pro" ], [ "Operating System", "Android 14 with One UI", "iOS 17" ], [ "Camera", "Quad-camera system (200MP main, 12MP ultrawide, 10MP telephoto with 10x optical zoom)", "Triple camera system(48MP main, 12MP ultrawide, 12MP telephoto with 5x optical zoom)" ], [ "Special Features", "S Pen, Galaxy AI", "Dynamic Island, Action button" ], [ "Software Updates", "7 years of updates", "5 years of updates" ] ], "links":[ { "column":1, "link":"https://google.com/search?hl=en&gl=us&cs=0&sca_esv=a200e05b38ad46df&q=Apple+A17+Bionic&sa=X&ved=2ahUKEwim-pHLhMmOAxUfh68BHZarN-kQxccNegQILhAB", "row":2, "title":"Apple A17 Bionic" }, { "column":2, "link":"https://google.com/search?hl=en&gl=us&cs=0&sca_esv=a200e05b38ad46df&q=Snapdragon+8+Gen+3+for+Galaxy&sa=X&ved=2ahUKEwim-pHLhMmOAxUfh68BHZarN-kQxccNegQIKhAB", "row":2, "title":"Snapdragon 8 Gen 3 for Galaxy" }, { "column":1, "link":"https://google.com/search?hl=en&gl=us&cs=0&sca_esv=a200e05b38ad46df&q=iOS+17&sa=X&ved=2ahUKEwim-pHLhMmOAxUfh68BHZarN-kQxccNegQIEBAB", "row":11, "title":"iOS 17" }, { "column":2, "link":"https://google.com/search?hl=en&gl=us&cs=0&sca_esv=a200e05b38ad46df&q=Android+14+with+One+UI&sa=X&ved=2ahUKEwim-pHLhMmOAxUfh68BHZarN-kQxccNegQIDxAB", "row":11, "title":"Android 14 with One UI" } ] } ] } ``` ## Paragraph With Video ```json Response theme={null} { "textBlocks":[ { "snippet":"This video explains how Dalvik and ART work in Android:", "type":"paragraph", "video":{ "channel":"Paulina talks Android", "date":"Apr 7, 2021", "link":"https://www.youtube.com/watch?v=0J1bm585UCc&t=221", "preview":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcSpdBzhFw_8Ds8uOFCPNJRLmokBHIT04yYSFQ", "source":"YouTube", "thumbnail":"https://i.ytimg.com/vi/0J1bm585UCc/mqdefault.jpg?sqp=-oaymwEGCPgEEOQC&rs=AMzJL3mbwAuBiGaQDToJ_PX4pLjyzY37Lg" } } ] } ``` ## Images Carousel ```json Response theme={null} { "textBlocks":[ { "type":"carousel", "images":[ { "image":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/9143f466-d595-4246-a762-bdc7bd85848a.png", "source":"https://www.briantracy.com/blog/personal-success/inspirational-quotes/" }, { "image":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/a50f37c0-8ca4-4f25-b382-4e2b5d1c16d1.jpeg", "source":"https://www.briantracy.com/blog/personal-success/inspirational-quotes/" }, { "image":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/5efbbf7f-e39b-4f59-9963-fcdcb64cf39d.jpeg", "source":"https://www.shopify.com/blog/motivational-quotes" }, { "image":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/f3aceaef-857a-4455-982e-7d28f25ca977.jpeg", "source":"https://www.shopify.com/blog/motivational-quotes" }, { "image":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/60349118-e634-47c0-9413-aba911e2a9da.jpeg", "source":"https://www.shopify.com/blog/motivational-quotes" }, { "image":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/41b0db1d-91ef-47f4-86b4-987f6d849c06.jpeg", "source":"https://www.briantracy.com/blog/personal-success/inspirational-quotes/" } ] } ] } ``` ## Code Block ```json Response theme={null} { "textBlocks":[ { "type":"code", "language":"JavaScript", "snippet":"const crypto = require('crypto');\nconst fs = require('fs');\n\n/**\n * Calculates the SHA256 hash of a given file.\n * @param {string} filePath - The path to the file.\n * @returns {Promise} A Promise that resolves with the hexadecimal hash.\n */\nfunction calculateFileHash(filePath) {\n return new Promise((resolve, reject) => {\n const hash = crypto.createHash('sha256'); // You can change 'sha256' to 'md5', 'sha512', etc.\n const stream = fs.createReadStream(filePath);\n\n stream.on('data', (chunk) => {\n hash.update(chunk);\n });\n\n stream.on('end', () => {\n resolve(hash.digest('hex'));\n });\n\n stream.on('error', (err) => {\n reject(err);\n });\n });\n}\n\n// Example usage:\nconst filePath = 'path/to/your/file.txt'; // Replace with the actual path to your file\n\ncalculateFileHash(filePath)\n .then((hash) => {\n console.log(`SHA256 hash of ${filePath}: ${hash}`);\n })\n .catch((err) => {\n console.error(`Error calculating hash: ${err.message}`);\n });" } ] } ``` ## AI Overview with Extra Request In some searches, Google returns AI Overview content via a separate request instead of including it directly in the main SERP response. When this happens, HasData will provide two fields in the `aiOverview` object: * `pageToken`: A short-lived token used to fetch AI Overview content via the [Google AI Overview API](/apis/google-serp/ai-overview). * `hasdataLink`: A direct link to fetch the AI Overview response using HasData's API. `pageToken` and `hasdataLink` expire within 4 minutes of the original search. Be sure to use them immediately. ```json Response theme={null} { "aiOverview": { "pageToken": "eyJhbGciOiJIUzI1NiIsInV1bGUiOiJ3IENBSVFJQ0lhUVhWemRHbHVMRlJsZUdGekxGVnVhWFJsWkNCVGRHRjBaWE09IiwiaGwiOiJlbiIsImdsIjoidXMiLCJ5diI6IjMiLCJjcyI6IjAiLCJlaSI6IkVLcUlhTld5RHFTbDVOb1B3OTNyNkE0IiwiYXN5bmMiOiJfYmFzZWpzOi94anMvXy9qcy9rPXhqcy5zLmVuLmRvd2h2emd1SXVFLjIwMTguTy9hbT1BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBZ0FBQUFBQUFBQUFBQUFBQUFBQUFJQUFBUUFFQkFBSUFBQUFBQUFBQUVBQWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBZ1FBRUFBQUFrQUFBQUFBQUFBSUFBQUFBQUFBR0NBQUFBQVFRQUNCUUFBRkFJQUFBQUFBQUFBQUFDQUFJQUFBQUFBQUFsSUFQemZId3dBQUFBQUFBQUFJQUFBQUFBQUFBUUFFZ0FBQUFBQUFBQUFBRndBQUFRVUE0QkFBZ2dBQUFBQUFBQUFBQUFBUUFBQUFBQUFBRUFBQUFBZ0FBQUlBQUFBb0FBQUFBQUFBQUFBQUFBQWdBQUFBQUFBQUFBQUFFQUFBQURnQUFBQUFBZ0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUNNQUFBQUFBQUFBQUFGQUFnZ0I4QUFBQUFBQURBQVFBQUNBRUFBSUFqaWdZQUFBQUFBQUFBY2dCNFBJQkRDZ29BQUFBQUFBQUFBQUFBQUFBQUFFQUFDb0k1a0g1QWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVNCRTBzZFlBQUFFL2RnPTAvYnI9MS9ycz1BQ1Q5MG9FbzVYR3VDaUJla1lMeDYxWi1DanF6bVJTeGlnLF9iYXNlY3NzOi94anMvXy9zcy9rPXhqcy5zLmFqV0NKTHJFS3drLkwuQjEuTy9hbT1BQkFDQUFTRUFBQUFBQmdBQUFCQUNBQklBUkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVJBQUFBQUFBZ0FBQUFBZ0FBQUFBQUFBUUFBQUFBQUFBUkFBQUxGQ0dBUUFBQUNCNFFRQWdCUWdBQUFBQTRBTVk1Q29BQWdnQUFBQUJBQUFBQUFrQUFBQUFDQkRBQUFBZ0FDQUFnTUNHZ0FBQVFBQkNCQUFBRUFvQUVCR0FBSUlFQUFFUkFKQUlBQUNRQ0FCQkJnQUFJQWdZQUFDQUFBQUFBQUFCQU1EN0FBUVdBQUFCQVFNQUFBQ0FCa0FBQUFBVUE0QUFBa0VBQUFBQUNBQUVBQUFBQUFBZ1VBQUFBRUFBQUFBd0FGMEl3Z0FJcUFDd2RIQUVBUkFBQUFBQUVBSUFFQkFBQUFBQUFnQ2dCQURpQVFBQVFBRUFBakFBOEFRUThBQUFBQUFSZ0FnQVFBSUFJQUFBQUlBQUFBQUFGQUlBQVlBTEFBRUFBQURBS0FBQUdBQUFGb0FqaWdZQUFBQUFBQUFBUUFBd0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUVBQkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBRS9icj0xL3JzPUFDVDkwb0dEMEtXSGl6TmlUaEJjN1A2VmtNem1HdW5uWGcsX2Jhc2Vjb21iOi94anMvXy9qcy9rPXhqcy5zLmVuLmRvd2h2emd1SXVFLjIwMTguTy9jaz14anMucy5haldDSkxyRUt3ay5MLkIxLk8vYW09QUJBQ0FBU0VBQUFBQUJnQUFBQkFDQUJJQVJBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFSQUFBQUFBQWdBQUFBQWdBQUFBQUFBQVFBQUFBSUFBQVJBRUJMRktHQVFBQUFDQjRVUUFnQlFnQUFBQUE0QU1ZNUNvQUFnZ0FBQWdSQUVBQUFBa0FBQUFBQ0JEQUlBQWdBQ0FBZ09DR2dBQUFRUUJDQlFBQUZBb0FFQkdBQUlJRUFBR1JBSkFJQUFDUUNBbEpCdnpmUHd3WUFBQ0FBQUFBSUFBQkFNRDdBQVFXRWdBQkFRTUFBQUNBQmx3QUFBUVVBNEJBQWtrQUFBQUFDQUFFQUFBQVFBQWdVQUFBQUVBQUFBQXdBRjBJd2dBSXFBQ3dkSEFFQVJBQUFBQUFrQUlBRUJBQUFBQUFBa0NnQkFEaUFRQUFRQWtBQWpBQThBUVE4QUFBQUFBUmdBZ0FRQUlDTUFBQUFJQUFBQUFBRkFJZ2daOExBQUVBQUFEQUtRQUFHQUVBRm9BamlnWUFBQUFBQUFBQWNnQjRQSUJEQ2dvQUFBQUFBQUFBQUFBQUFBQUFBRUFBQ29JNWtINUJnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFTQkUwc2RZQUFBRS9kPTEvZWQ9MS9kZz0wL2JyPTEvdWpnPTEvcnM9QUNUOTBvRjhJWmZwTE1SSll1dDBnU1RNZHNOd1FweDFWUSxfZm10OnByb2csX2lkOkIySnR5ZCIsInEiOiJob3cgdG8gc3RhcnQgZHJvcCBzaGlwcGluZyBidXNpbmVzcyBhbmQgcGljayBhIG5pY2hlIiwibWxybyI6IjBhNnMxU2k0bG9VOHAzT1o2VnNMaGVvck50dGtwaldjR3R3ZzNmLUdEdGwzbG1pVENZUko0QjdTVGRHU2VKR1B6YmNwYi1MVzVTaUd0cWM3dnk4STJnNGQxaE5mdmJWOElvWXBkUEhXZXhfUEg3MXhkYVpKdlZtcDM0eUtnM08zTTQySW9QOUVKQm03S1VnVWZoNCIsIm1scm9zIjoieEprb1hDbXI1T1UiLCJtYWRzZSI6IjEiLCJtcmMiOiJDQUE0a0FOUUFRIiwic2NhX2VzdiI6ImU5NDhiYWZlYzlmMzlmOGMiLCJtZ3R5cCI6IjQxIiwiZGV2aWNlIjoiZGVza3RvcCJ9", "hasdataLink": "https://api.hasdata.com/scrape/google/ai-overview?pageToken=eyJhbGciOiJIUzI1NiIsInV1bGUiOiJ3IENBSVFJQ0lhUVhWemRHbHVMRlJsZUdGekxGVnVhWFJsWkNCVGRHRjBaWE09IiwiaGwiOiJlbiIsImdsIjoidXMiLCJ5diI6IjMiLCJjcyI6IjAiLCJlaSI6IkVLcUlhTld5RHFTbDVOb1B3OTNyNkE0IiwiYXN5bmMiOiJfYmFzZWpzOi94anMvXy9qcy9rPXhqcy5zLmVuLmRvd2h2emd1SXVFLjIwMTguTy9hbT1BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBZ0FBQUFBQUFBQUFBQUFBQUFBQUFJQUFBUUFFQkFBSUFBQUFBQUFBQUVBQWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBZ1FBRUFBQUFrQUFBQUFBQUFBSUFBQUFBQUFBR0NBQUFBQVFRQUNCUUFBRkFJQUFBQUFBQUFBQUFDQUFJQUFBQUFBQUFsSUFQemZId3dBQUFBQUFBQUFJQUFBQUFBQUFBUUFFZ0FBQUFBQUFBQUFBRndBQUFRVUE0QkFBZ2dBQUFBQUFBQUFBQUFBUUFBQUFBQUFBRUFBQUFBZ0FBQUlBQUFBb0FBQUFBQUFBQUFBQUFBQWdBQUFBQUFBQUFBQUFFQUFBQURnQUFBQUFBZ0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUNNQUFBQUFBQUFBQUFGQUFnZ0I4QUFBQUFBQURBQVFBQUNBRUFBSUFqaWdZQUFBQUFBQUFBY2dCNFBJQkRDZ29BQUFBQUFBQUFBQUFBQUFBQUFFQUFDb0k1a0g1QWdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVNCRTBzZFlBQUFFL2RnPTAvYnI9MS9ycz1BQ1Q5MG9FbzVYR3VDaUJla1lMeDYxWi1DanF6bVJTeGlnLF9iYXNlY3NzOi94anMvXy9zcy9rPXhqcy5zLmFqV0NKTHJFS3drLkwuQjEuTy9hbT1BQkFDQUFTRUFBQUFBQmdBQUFCQUNBQklBUkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQVJBQUFBQUFBZ0FBQUFBZ0FBQUFBQUFBUUFBQUFBQUFBUkFBQUxGQ0dBUUFBQUNCNFFRQWdCUWdBQUFBQTRBTVk1Q29BQWdnQUFBQUJBQUFBQUFrQUFBQUFDQkRBQUFBZ0FDQUFnTUNHZ0FBQVFBQkNCQUFBRUFvQUVCR0FBSUlFQUFFUkFKQUlBQUNRQ0FCQkJnQUFJQWdZQUFDQUFBQUFBQUFCQU1EN0FBUVdBQUFCQVFNQUFBQ0FCa0FBQUFBVUE0QUFBa0VBQUFBQUNBQUVBQUFBQUFBZ1VBQUFBRUFBQUFBd0FGMEl3Z0FJcUFDd2RIQUVBUkFBQUFBQUVBSUFFQkFBQUFBQUFnQ2dCQURpQVFBQVFBRUFBakFBOEFRUThBQUFBQUFSZ0FnQVFBSUFJQUFBQUlBQUFBQUFGQUlBQVlBTEFBRUFBQURBS0FBQUdBQUFGb0FqaWdZQUFBQUFBQUFBUUFBd0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUVBQkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBRS9icj0xL3JzPUFDVDkwb0dEMEtXSGl6TmlUaEJjN1A2VmtNem1HdW5uWGcsX2Jhc2Vjb21iOi94anMvXy9qcy9rPXhqcy5zLmVuLmRvd2h2emd1SXVFLjIwMTguTy9jaz14anMucy5haldDSkxyRUt3ay5MLkIxLk8vYW09QUJBQ0FBU0VBQUFBQUJnQUFBQkFDQUJJQVJBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFSQUFBQUFBQWdBQUFBQWdBQUFBQUFBQVFBQUFBSUFBQVJBRUJMRktHQVFBQUFDQjRVUUFnQlFnQUFBQUE0QU1ZNUNvQUFnZ0FBQWdSQUVBQUFBa0FBQUFBQ0JEQUlBQWdBQ0FBZ09DR2dBQUFRUUJDQlFBQUZBb0FFQkdBQUlJRUFBR1JBSkFJQUFDUUNBbEpCdnpmUHd3WUFBQ0FBQUFBSUFBQkFNRDdBQVFXRWdBQkFRTUFBQUNBQmx3QUFBUVVBNEJBQWtrQUFBQUFDQUFFQUFBQVFBQWdVQUFBQUVBQUFBQXdBRjBJd2dBSXFBQ3dkSEFFQVJBQUFBQUFrQUlBRUJBQUFBQUFBa0NnQkFEaUFRQUFRQWtBQWpBQThBUVE4QUFBQUFBUmdBZ0FRQUlDTUFBQUFJQUFBQUFBRkFJZ2daOExBQUVBQUFEQUtRQUFHQUVBRm9BamlnWUFBQUFBQUFBQWNnQjRQSUJEQ2dvQUFBQUFBQUFBQUFBQUFBQUFBRUFBQ29JNWtINUJnQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFTQkUwc2RZQUFBRS9kPTEvZWQ9MS9kZz0wL2JyPTEvdWpnPTEvcnM9QUNUOTBvRjhJWmZwTE1SSll1dDBnU1RNZHNOd1FweDFWUSxfZm10OnByb2csX2lkOkIySnR5ZCIsInEiOiJob3cgdG8gc3RhcnQgZHJvcCBzaGlwcGluZyBidXNpbmVzcyBhbmQgcGljayBhIG5pY2hlIiwibWxybyI6IjBhNnMxU2k0bG9VOHAzT1o2VnNMaGVvck50dGtwaldjR3R3ZzNmLUdEdGwzbG1pVENZUko0QjdTVGRHU2VKR1B6YmNwYi1MVzVTaUd0cWM3dnk4STJnNGQxaE5mdmJWOElvWXBkUEhXZXhfUEg3MXhkYVpKdlZtcDM0eUtnM08zTTQySW9QOUVKQm03S1VnVWZoNCIsIm1scm9zIjoieEprb1hDbXI1T1UiLCJtYWRzZSI6IjEiLCJtcmMiOiJDQUE0a0FOUUFRIiwic2NhX2VzdiI6ImU5NDhiYWZlYzlmMzlmOGMiLCJtZ3R5cCI6IjQxIiwiZGV2aWNlIjoiZGVza3RvcCJ9" } } ``` # Answer Box Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/answer-box ```json Response theme={null} { "answerBox":{ "type":"organicResult", "title":"Understanding Core Web Vitals and Google search results", "link":"https://developers.google.com/search/docs/appearance/core-web-vitals#:~:text=Core%20Web%20Vitals%20is%20a,a%20great%20user%20experience%20generally.", "displayedLink":"https://developers.google.com › ... › Documentation", "snippet":"Core Web Vitals is a set of metrics that measure real-world user experience for loading performance, interactivity, and visual stability of the page. We highly recommend site owners achieve good Core Web Vitals for success with Search and to ensure a great user experience generally.", "snippetHighlitedWords":[ "a set of metrics that measure real-world user experience for loading performance, interactivity, and visual stability of the page" ], "source":"Google for Developers" } } ``` # Discussions and Forums Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/discussions-and-forums ```json Response theme={null} { "discussionsAndForums":[ { "title":"Best current web scraping solutions / stack for large projects?", "link":"https://www.reddit.com/r/learnpython/comments/1c08y8p/best_current_web_scraping_solutions_stack_for/", "date":"1 year ago", "extensions":[ "r/learnpython", "20+ comments" ], "source":"Reddit", "replies":[ { "title":"Beautiful soup is a staple but if you’re looking for stacked up solutions then probably something ...", "link":"https://www.reddit.com/r/learnpython/comments/1c08y8p/best_current_web_scraping_solutions_stack_for/kzqkkcn/", "extensions":[ "Top answer", "23 votes", "11 months ago" ] }, { "title":"In general if you can avoid literal HTML scraping you can be a lot more resilient and faster. ...", "link":"https://www.reddit.com/r/learnpython/comments/1c08y8p/best_current_web_scraping_solutions_stack_for/kyvejj9/", "extensions":[ "16 votes", "a year ago" ] } ] }, { "title":"Is ScraperAPI the best tool for web data scraping? Why or why not?", "link":"https://www.quora.com/Is-ScraperAPI-the-best-tool-for-web-data-scraping-Why-or-why-not", "date":"2 years ago", "extensions":[ "3 answers" ], "source":"Quora" }, { "title":"Which is best web data scraping API to use for crawling?", "link":"https://www.quora.com/Which-is-best-web-data-scraping-API-to-use-for-crawling", "date":"4 years ago", "extensions":[ "5 answers" ], "source":"Quora" } ] } ``` # Immersive Products Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/immersive-products ```json Response theme={null} { "immersiveProducts":[ { "position":1, "category":"Popular products", "title":"Folgers Coffee Ground Classic Roast", "productId":"16914877625280977865", "productLink":"https://www.google.com/shopping/product/16914877625280977865", "price":"$5.78", "extractedPrice":5.78, "source":"Walmart", "reviews":15000, "rating":4.6, "extensions":[ "Nearby, 12 mi" ], "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/30ba0064-23bc-4757-9bd9-c9f1281b2033.webp" }, { "position":2, "category":"Popular products", "title":"Black Rifle Coffee Company Freedom Fuel Coffee", "productId":"18134019833504388210", "productLink":"https://www.google.com/shopping/product/18134019833504388210", "price":"$15.99", "extractedPrice":15.99, "source":"Black Rifle Coffee Company", "reviews":743, "rating":4.8, "delivery":"Free delivery on $75+", "extensions":[ "Also nearby" ], "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/860679ac-ea82-4c58-95df-27dbc1647c29.webp" }, { "position":3, "category":"Popular products", "title":"Build-A-Box of Whole Bean Samples", "productId":"909394965502829081", "productLink":"https://www.google.com/shopping/product/909394965502829081", "price":"$12.00", "extractedPrice":12, "source":"Geek Grind Coffee", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/7c498d52-c23d-40dc-8def-3528405ef4f2.webp" }, ... { "position":10, "category":"Popular products", "title":"Black Rifle Coffee Company Silencer Smooth Coffee", "productId":"15691016733691520892", "productLink":"https://www.google.com/shopping/product/15691016733691520892", "price":"$15.99", "extractedPrice":15.99, "source":"Black Rifle Coffee Company", "reviews":601, "rating":4.8, "delivery":"Free delivery on $75+", "extensions":[ "Also nearby" ], "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/6d6a9b5a-bae5-48f0-95b1-9dbe5e637e38.webp" } ] } ``` # Inline Images Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/inline-images ```json Response theme={null} { "inlineImages":[ { "source":"https://www.pexels.com/search/coffee/", "title":"60,000+ Best Coffee Photos · 100% Free Download · Pexels ...", "sourceName":"Pexels", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/cb5867ee-d9b4-4179-8724-c63cf8954889.jpeg" }, { "source":"https://www.istockphoto.com/photos/coffee", "title":"2,994,700+ Coffee Stock Photos, Pictures & Royalty-Free ...", "sourceName":"iStock", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/84006a4f-734b-4617-bc81-9535d3736cf1.jpeg" }, { "source":"https://unsplash.com/s/photos/coffee", "title":"100+ Coffee Pictures | Download Free Images on Unsplash", "sourceName":"Unsplash", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/0b48ca13-c5ad-4595-8c9d-d3cee73e8afe.jpeg" }, { "source":"https://stock.adobe.com/search?k=coffee", "title":"Coffee Images – Browse 13,009,128 Stock Photos, Vectors, and ...", "sourceName":"Adobe Stock", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/c894bd68-35da-42c9-a785-2bf881ba86ab.jpeg" }, { "source":"https://www.cnn.com/2017/09/29/health/coffee-healthy-food-drayer/index.html", "title":"Is coffee healthy? | CNN", "sourceName":"CNN", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/c4563bbc-dcc5-4f24-8019-c6a8c5a32a70.jpeg" }, { "source":"https://www.istockphoto.com/photos/coffee", "title":"2,994,700+ Coffee Stock Photos, Pictures & Royalty-Free ...", "sourceName":"iStock", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/0abdcc6f-30e4-47e0-afa5-5bc198c26626.jpeg" }, { "source":"https://pixabay.com/images/search/coffee/", "title":"Stylish Coffee Pics: 10,000+ Free HD Images of Coffee ...", "sourceName":"Pixabay", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/4ddeff69-086b-4807-8a5d-97596af29628.jpeg" }, { "source":"https://www.vecteezy.com/free-photos/coffee", "title":"Coffee Stock Photos, Images and Backgrounds for Free Download", "sourceName":"Vecteezy", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/49740cfc-e3aa-41e4-8c91-7c1b2a569988.jpeg" }, { "source":"https://www.pexels.com/search/coffee/", "title":"60,000+ Best Coffee Photos · 100% Free Download · Pexels ...", "sourceName":"Pexels", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/bbfbe241-ae92-4b36-9c20-f1e6d0629976.jpeg" }, { "source":"https://stock.adobe.com/search?k=coffee", "title":"Coffee Images – Browse 13,009,128 Stock Photos, Vectors, and ...", "sourceName":"Adobe Stock", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/f4cc932e-ef64-45a3-a54b-144b47e3931b.jpeg" } ] } ``` # Inline Shopping Results Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/inline-shopping-results ```json Response theme={null} { "shoppingResults":[ { "position":1, "title":"White Boards - Dry Erase Board with Aluminum Frame 6 x 4' - H-1840", "price":"US$195.00", "extractedPrice":195, "link":"https://www.uline.com/Product/Detail/H-1840/Boards-Easels/Nonmagnetic-Melamine-Dry-Erase-Board-6-x-4?pricode=WA9289", "source":"ULINE", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/dc42b7e0-884d-48ee-acab-3af70f4da5cc.webp", "extensions":[ "72\" x 48\"", "Standard" ] }, { "position":2, "title":"Magnetic Glass Whiteboard 72” x 48”, 1/4\" thick Magnetic Glass Dry Erase board 6' x 4'", "price":"US$285.00", "extractedPrice":285, "link":"https://www.pegasusav.us/pegasus-magnetic-glass-marker-board-white-surface-44872.html", "source":"Pegasus White...", "shipping":"Get it by 23/04", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/c4b950a3-bb3e-4950-b797-bf139c73ba6b.webp", "extensions":[ "72\" x 48\"", "Standard" ] }, { "position":3, "title":"Magnetic Glass Dry Erase Board - White, 3 x 2' - ULINE - H-9023", "price":"US$155.00", "extractedPrice":155, "link":"https://www.uline.com/Product/Detail/H-9023/Boards-Easels/Magnetic-Glass-Dry-Erase-Board-White-3-x-2?pricode=WB6679", "source":"ULINE", "shipping":"Get it by 16/04", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/76518458-cc84-4dac-9c57-dd530eef3da5.webp", "extensions":[ "36\" x 24\"", "Standard" ] }, { "position":4, "title":"Nonmagnetic Melamine Dry Erase Board - 3 x 2' - Quartet - H-616", "price":"US$50.00", "extractedPrice":50, "link":"https://www.uline.com/Product/Detail/H-616/Boards-Easels/Nonmagnetic-Melamine-Dry-Erase-Board-3-x-2?pricode=WA9289", "source":"ULINE", "shipping":"Get it by 16/04", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/a66e6674-a2e2-48ec-becb-93781a1fd27b.webp" }, { "position":5, "title":"Magnetic Steel Dry Erase Board - 8 x 4' - ULINE - H-5830", "price":"US$375.00", "extractedPrice":375, "link":"https://www.uline.com/Product/Detail/H-5830/Boards-Easels/Magnetic-Steel-Dry-Erase-Board-8-x-4?pricode=WA9289", "source":"ULINE", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/1d492d40-3aa1-4ec7-b3ad-853a89f86a5f.webp", "extensions":[ "96\" x 48\"", "Standard" ] }, { "position":6, "title":"Magnetic Glass Dry Erase Board - White, 8 x 4' - ULINE - H-7805", "price":"US$710.00", "extractedPrice":710, "link":"https://www.uline.com/Product/Detail/H-7805/Boards-Easels/Magnetic-Glass-Dry-Erase-Board-White-8-x-4?pricode=WB6679", "source":"ULINE", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/f8c8acd9-f26d-46b9-91d9-5318bdfbe3b4.webp", "extensions":[ "96\" x 48\"", "Standard" ] }, { "position":7, "title":"Magnetic Dry-Erase Whiteboard, 48\" x 72\", Silver Frame ODFN951851", "price":"US$88.45", "extractedPrice":88.45, "link":"https://www.officesupply.com/school-supplies/classroom-resources/classroom-furniture/erase-boards/magnetic-erase-whiteboard-silver-frame/p788758.html?ref=pla&utm_source=google&utm_medium=pla_organic&utm_campaign=surfaces%20across%20google", "source":"OfficeSupply", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/213e4610-8a6c-4531-be72-bcd301e3f55c.webp" }, { "position":8, "title":"Amazon Basics Magnetic Dry Erase Whiteboard, 36\"W x 24\"H, Aluminum Frame, Silver/White", "price":"US$24.55", "extractedPrice":24.55, "link":"https://www.amazon.com/amazonbasics-Magnetic-Erase-Board-Aluminum/dp/B07K6B8Q5V?source=ps-sl-shoppingads-lpcontext&ref_=fplfs&psc=1&smid=ATVPDKIKX0DER", "source":"Amazon.com", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/d67504c4-b604-42d6-bcf6-c2f98b67ddf2.webp", "extensions":[ "36\" x 24\"", "Standard" ] }, { "position":9, "title":"Mobile Whiteboard - Dry Erase Board with Aluminum Frame 6 x 4' - ULINE - H-3955", "price":"US$710.00", "extractedPrice":710, "link":"https://www.uline.com/Product/Detail/H-3955/Boards-Easels/Nonmagnetic-Melamine-Mobile-Dry-Erase-Board-6-x-4?pricode=WA9642", "source":"ULINE", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/2a8d4603-c58e-4c38-8d34-0cb7d5fc24e5.webp", "extensions":[ "72\" x 48\"", "Standard" ] }, { "position":10, "title":"Nonmagnetic Melamine Dry Erase Board - 4 x 3' - Quartet - H-617", "price":"US$88.00", "extractedPrice":88, "link":"https://www.uline.com/Product/Detail/H-617/Boards-Easels/Nonmagnetic-Melamine-Dry-Erase-Board-4-x-3?pricode=WA9289", "source":"ULINE", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/0319cb56-a16c-44ef-9c1a-9d2dc9bd5718.webp" }, { "position":11, "title":"Frameless Glass Dry Erase Board - Magnetic - White, 4 x 3' - ULINE - H-7180", "price":"US$280.00", "extractedPrice":280, "link":"https://www.uline.com/Product/Detail/H-7180/Boards-Easels/Magnetic-Glass-Dry-Erase-Board-White-4-x-3?pricode=WB6679", "source":"ULINE", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/afb8d8ba-7f18-4d2a-a90d-a457e201e97e.webp", "extensions":[ "48\" x 36\"", "Standard" ] }, { "position":12, "title":"Mobile Reversible Whiteboard with Silver Frame, 72\"W x 48\"H Global Industrial", "price":"US$339.95", "extractedPrice":339.95, "link":"https://www.globalindustrial.com/p/72w-x-40h-mobile-reversible-magnetic-whiteboard", "source":"Global Industrial", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/b92242d4-ef9d-4c8b-ae78-1a9ebc4b5b09.webp", "extensions":[ "72\" x 48\"", "Standard" ] }, { "position":13, "title":"Magnetic Steel Mobile Dry Erase Board - 8 x 4' - ULINE - H-7804", "price":"US$1,325.00", "extractedPrice":1, "link":"https://www.uline.com/Product/Detail/H-7804/Boards-Easels/Magnetic-Steel-Mobile-Dry-Erase-Board-8-x-4?pricode=WA9642", "source":"ULINE", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/30263e71-9de5-43ee-94a7-67cdf0b09097.webp", "extensions":[ "96\" x 48\"", "Standard" ] }, { "position":14, "title":"Flash Furniture YU-YCI-003-GG Hercules 48\" x 35 1/4\" Double-Sided Whiteboard with Powder-Coated Aluminum Frame and Mobile Stand", "price":"US$124.99", "extractedPrice":124.99, "link":"https://www.webstaurantstore.com/flash-furniture-yu-yci-003-gg-hercules-48-x-35-1-4-double-sided-whiteboard-with-powder-coated-aluminum-frame-and-mobile-stand/354YCI6465.html", "source":"WebstaurantSto...", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/a7eaa0bb-eb16-4936-ab66-f7db279926aa.webp" }, { "position":15, "title":"Rolling Whiteboard - Magnetic, Aluminum Frame 6 x 4' - ULINE - H-4576", "price":"US$920.00", "extractedPrice":920, "link":"https://www.uline.com/Product/Detail/H-4576/Boards-Easels/Magnetic-Porcelain-Mobile-Dry-Erase-Board-6-x-4?pricode=WA9642", "source":"ULINE", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/000a21a8-5199-4794-a1ec-90fee479641f.webp", "extensions":[ "72\" x 48\"", "Standard" ] }, { "position":16, "title":"Amazon Basics Magnetic Whiteboard/Dry Erase Board, 36 x 48-inch, Aluminum Frame, Silver/White", "price":"US$58.06", "extractedPrice":58.06, "link":"https://www.amazon.com/amazonbasics-Magnetic-Erase-Board-Aluminum/dp/B07K67LPWR?source=ps-sl-shoppingads-lpcontext&ref_=fplfs&psc=1&smid=ATVPDKIKX0DER", "source":"Amazon.com", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/400de671-55a3-4f44-a5d3-0e2830c0d323.webp", "extensions":[ "48\" x 36\"", "Standard" ] } ] } ``` # Inline Videos Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/inline-videos ```json Response theme={null} { "inlineVideos":[ { "position":1, "title":"The Best Tools to Scrape Data in 2024", "link":"https://www.youtube.com/watch?v=00yQfxC7PFU", "duration":"11:43", "platform":"YouTube", "channel":"John Watson Rooney", "date":"Apr 10, 2024" }, { "position":2, "title":"Comparing Top 5 AI Web Scraping Tools (updated 2024)", "link":"https://www.youtube.com/watch?v=qziiZ4BmZHQ", "duration":"12:30", "platform":"YouTube", "channel":"Bardeen", "date":"Jul 4, 2024" }, { "position":3, "title":"Scrape Any Website for FREE Using DeepSeek & Crawl4AI", "link":"https://www.youtube.com/watch?v=Osl4NgAXvRk", "duration":"22:46", "platform":"YouTube", "channel":"aiwithbrandon", "date":"Feb 3, 2025" } ] } ``` # Knowledge Graph Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/knowledge-graph ```json Response theme={null} { "knowledgeGraph":{ "title":"Walmart", "type":"Retailer corporation", "customerService":"1 (800) 925-6278", "headquarters":"Bentonville, AR", "headquartersLinks":[ { "text":"Bentonville, AR", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Bentonville&si=APYL9bu1Sl4M4TWndGcDs6ZL5WJXWNYEL_kgEEwAe0iMZIocdVEGgfB8pMk6IVg2BNnPVgyVMrLYO_-DUAmG7-2SyQ5rjjIHdiwDNyAhYEAUH509aqzirKGOTM5Lg8_9UQ6WzmAbAamXDJZBDcefCONAlAco-cp11cJ1yWy84FwrWCqTInaYs4EMOOMIBFDhBK5GZAW61HM4&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQmxMoAHoECEoQAg" } ], "owner":"Walton family", "ownerLinks":[ { "text":"Walton family", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Walton+family&si=APYL9btMsmZl0P9CyeA1NmMZFYv4xkDb-_Q4WCJadY9pxozSRYOf7gNVa7FVTpnWgD73ecmlAKSMbBzzAB7TM3f0ao361TWr8Drya00EmzxHxiltQMGnilxRe3taTub_DpRVI1VJX3--7kR3lV68W8mzEqVFwpbbXiIIo3fI_2ety7Enpc9e-7vG0tEsV3cQHx9Ptbt_nFF5&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQmxMoAHoECD4QAg" } ], "customerServiceChat":"Online Chat", "customerServiceChatLinks":[ { "text":"Online Chat", "link":"https://www.google.comhttps://help.walmart.com/app/ask" } ], "founders":"Sam Walton, Bud Walton", "foundersLinks":[ { "text":"Sam Walton", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Sam+Walton&si=APYL9btMsmZl0P9CyeA1NmMZFYv4xkDb-_Q4WCJadY9pxozSRTiaabCwC9VO7kyKFLH5drYAnTDRjZzwAPIB0HmTgTghMtLwIjWXhBk1EaluJHQk3AaVnjmm1SNQ0IVdjNvmzPBwVR9LZeALUx05McGGsSjuMqjcplA5WBSzwexWRy2lxAPkigDov-hHqTEH7AISxXgFpiPPorE1kesoXS6LutqZe6N-Sx4kHqYz8HRyL0BtAoEo_yt45X4fCBB5V1jjPMxHE-0P&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQmxMoAHoECEEQAg" }, { "text":"Bud Walton", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Bud+Walton&si=APYL9btMsmZl0P9CyeA1NmMZFYv4xkDb-_Q4WCJadY9pxozSRWGYur6u4MXULGr0XQL0iBR9h8qjR2rMebyUR7Sj9WUNdBXtsKIlLQV_je7_7_dw6Owm3rbzTKXkq2nsH94Gi98DnPzPJ7MPtILcPrqGYA2nl76vVYsTN_6NAe6IdU9ZkRBtv7BQjYuFu6xW-uHLKYmBD9kP1PjavkHeHu215sni5d-DPjDaeE7JdCAASG7_IFSQIqoVZrdgOsoqCfKrYxkSNKBL&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQmxMoAXoECEEQAw" } ], "stockPrice":"WMT (NYSE) $94.75 +0.02 (+0.02%)Apr 15, 1:23 PM EDT - Disclaimer", "stockPriceLinks":[ { "text":"WMT", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=NYSE:+WMT&stick=H4sIAAAAAAAAAONgecRoyi3w8sc9YSmdSWtOXmNU4-IKzsgvd80rySypFJLgYoOy-KR4uLj0c_UNzKtycs1TeBaxcvpFBrtaKYT7hgAASH9Mz0YAAAA&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQsRV6BAg4EAI" }, { "text":"Disclaimer", "link":"https://www.google.com/intl/en-US_US/googlefinance/disclaimer/" } ], "founded":"July 2, 1962, Rogers, AR", "foundedLinks":[ { "text":"Rogers, AR", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Rogers,+Arkansas&si=APYL9bu1Sl4M4TWndGcDs6ZL5WJXWNYEL_kgEEwAe0iMZIocdZCrG1uIiMIIWV52Rocj8-K0mjTTRbT1Yb-gDCOtj3IhpOYFTlCL5gsHGDDv8jB6l-ZLWTIT4LXLbSXVKx_jSz8tTAn7ThoNF79Ka3zvKpKybUheRGtgqZRIxA2EjjhoKIUP64zRC0OKuyPqpeu28NDsj21P&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQmxMoAHoECFEQAg" } ], "president":"Doug McMillon", "presidentLinks":[ { "text":"Doug McMillon", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Doug+McMillon&si=APYL9btKi1TLoawpxIKkhA47KIc3RH36yjJAdk2TmwBtOZld-lx73X4HJZ2cItHVIidKAyrs3_L1xUd8sJD5p-OWvY1khQmNHJZokvY7oY9M8oL0vIK-wSgC5vFbpM2HrOGBN_6ZPFwzR5WF-7DdAScIsqR_3ADzeuKlZTyln1NxIw0D4EijOVtf2l7orKYaIDSz7l9uEpNb&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQmxMoAHoECEMQAg" } ] } } ``` # Local Ads Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/local-ads ```json Response theme={null} { "localAds":{ "title":"Plumbers | Austin", "badge":"GOOGLE GUARANTEED", "link":"https://www.google.com/localservices/prolist?g2lbs=AAEPWCulbe8EGpKAiYJxr2VHgxy0tJHJanksUw48vWozOzk-pfcNcq9PvmidcmOksdPee4tABMZn&hl=en-US&gl=us&ssta=1&src=1&gsas=1&scp=Cih4Y2F0OnNlcnZpY2VfYXJlYV9idXNpbmVzc19wbHVtYmVyOmVuLVVTEiAaEgkvA8ygmbVEhhF61WnUS0abXSIGQXVzdGluOJnRPioIUGx1bWJpbmdKFQoTCM3jt7vU2owDFSidWgUdBXcRSw%3D%3D&slp=OpwEQ2hNSXplTzN1OVRhakFNVktKMWFCUjBGZHhGTEVpTUlCQkFCR2d3SXhxNkMzQUlRN196OXhna2dnWWZhSlRDQS1MTTFPTUNEN1JKSUFCSW1DQVFRQWhvTUNPenN2SVlCRUtpNTdhMEpJTGV5dFRNd2dQaXpOVGliMmRvWlNJRDgyUm9TSmdnRUVBTWFEQWp5a1pEM0JCRC1wZExXRGlDMXg3RXpNSUQ0c3pVNDJ1UFlHVWlBX05rYUVpWUlCQkFFR2d3STF0VGxoUUVReDliYXJRa2cyY0tZTXpDQS1MTTFPS3loekJsSWdQelpHaElsQ0FRUUJSb0xDUDNwOW44UXFyUDVyQWtncE1IUE16Q0EtTE0xT05MZzV4bElnUHpaR2hJbUNBUVFCaG9NQ0tmV3NjOERFSzZRc2U0SklPanpoalV3Z1Bpek5UajB1Y01hU0lEODJSb1NKZ2dFRUFjYURBajFoTjdvQXhDazQ1dmpDU0Ryd1p3MU1JRDRzelU0OWFET0draUFfTmthRWlZSUJCQUlHZ3dJOHJyZWlBRVFndFNKcmdrZ3FmYXJNRENBLUxNMU9KVDdsUmhJZ1B6WkdpSUdDQVFRQWhnSUtBd3lPTEtwc1FLOHZiRUNsNnV4QXJpYnNRS2F6YkVDMmNpeEF0YklzUUxvdHJFQ3lLQ3hBc1dnc1FMR29MRUN4NkN4QXNQUnNRS2JuN0VD&q=plumbing&sa=X&ved=2ahUKEwiWqLG71NqMAxWwQzABHdnZKzcQl5UCegUIBhCFAQ", "ads":[ { "position":1, "title":"Doug The Plumber", "link":"https://www.google.com/localservices/prolist?g2lbs=AAEPWCu9GwyZ_NdJqht9b1rtvZYrgiHctbrJVbyN8etP_A_NkPQkzsGRX25T0mD1yk3cRcS1V5qc&hl=en-US&gl=us&ssta=1&src=1&gsas=1&slp=OpwEQ2hNSXplTzN1OVRhakFNVktKMWFCUjBGZHhGTEVpTUlCQkFCR2d3SXhxNkMzQUlRN196OXhna2dnWWZhSlRDQS1MTTFPTUNEN1JKSUFCSW1DQVFRQWhvTUNPenN2SVlCRUtpNTdhMEpJTGV5dFRNd2dQaXpOVGliMmRvWlNJRDgyUm9TSmdnRUVBTWFEQWp5a1pEM0JCRC1wZExXRGlDMXg3RXpNSUQ0c3pVNDJ1UFlHVWlBX05rYUVpWUlCQkFFR2d3STF0VGxoUUVReDliYXJRa2cyY0tZTXpDQS1MTTFPS3loekJsSWdQelpHaElsQ0FRUUJSb0xDUDNwOW44UXFyUDVyQWtncE1IUE16Q0EtTE0xT05MZzV4bElnUHpaR2hJbUNBUVFCaG9NQ0tmV3NjOERFSzZRc2U0SklPanpoalV3Z1Bpek5UajB1Y01hU0lEODJSb1NKZ2dFRUFjYURBajFoTjdvQXhDazQ1dmpDU0Ryd1p3MU1JRDRzelU0OWFET0draUFfTmthRWlZSUJCQUlHZ3dJOHJyZWlBRVFndFNKcmdrZ3FmYXJNRENBLUxNMU9KVDdsUmhJZ1B6WkdpSUdDQVFRQWhnSUtBd3lPTEtwc1FLOHZiRUNsNnV4QXJpYnNRS2F6YkVDMmNpeEF0YklzUUxvdHJFQ3lLQ3hBc1dnc1FMR29MRUN4NkN4QXNQUnNRS2JuN0VD&spp=ElcKEgjGroLcAhDv_P3GCRj_x6-gJRIoeGNhdDpzZXJ2aWNlX2FyZWFfYnVzaW5lc3NfcGx1bWJlcjplbi1VU0ITCM3jt7vU2owDFSidWgUdBXcRS0gEUAE%3D&scp=Cih4Y2F0OnNlcnZpY2VfYXJlYV9idXNpbmVzc19wbHVtYmVyOmVuLVVTEiAaEgkvA8ygmbVEhhF61WnUS0abXSIGQXVzdGluOJnRPioIUGx1bWJpbmdKFQoTCM3jt7vU2owDFSidWgUdBXcRSw%3D%3D&q=plumbing", "rating":5, "ratingCount":740, "type":"Plumbers", "serviceArea":"Serves Austin", "hours":"Open now", "yearsInBusiness":"18+ years in business", "phone":"+15129572887", "highlighted_details":[ "Free in-home estimate", "Local business" ] }, { "position":2, "title":"Strand Brothers Service Experts Plumbing", "link":"https://www.google.com/localservices/prolist?g2lbs=AAEPWCvPx5otoIUW_DiJmrsDQjlsYoV1sMmgfZN9RJ2kVFT5Gt65eGOkmJcZ1qx8JhDc5EYo9zoB&hl=en-US&gl=us&ssta=1&src=1&gsas=1&slp=OpwEQ2hNSXplTzN1OVRhakFNVktKMWFCUjBGZHhGTEVpTUlCQkFCR2d3SXhxNkMzQUlRN196OXhna2dnWWZhSlRDQS1MTTFPTUNEN1JKSUFCSW1DQVFRQWhvTUNPenN2SVlCRUtpNTdhMEpJTGV5dFRNd2dQaXpOVGliMmRvWlNJRDgyUm9TSmdnRUVBTWFEQWp5a1pEM0JCRC1wZExXRGlDMXg3RXpNSUQ0c3pVNDJ1UFlHVWlBX05rYUVpWUlCQkFFR2d3STF0VGxoUUVReDliYXJRa2cyY0tZTXpDQS1MTTFPS3loekJsSWdQelpHaElsQ0FRUUJSb0xDUDNwOW44UXFyUDVyQWtncE1IUE16Q0EtTE0xT05MZzV4bElnUHpaR2hJbUNBUVFCaG9NQ0tmV3NjOERFSzZRc2U0SklPanpoalV3Z1Bpek5UajB1Y01hU0lEODJSb1NKZ2dFRUFjYURBajFoTjdvQXhDazQ1dmpDU0Ryd1p3MU1JRDRzelU0OWFET0draUFfTmthRWlZSUJCQUlHZ3dJOHJyZWlBRVFndFNKcmdrZ3FmYXJNRENBLUxNMU9KVDdsUmhJZ1B6WkdpSUdDQVFRQWhnSUtBd3lPTEtwc1FLOHZiRUNsNnV4QXJpYnNRS2F6YkVDMmNpeEF0YklzUUxvdHJFQ3lLQ3hBc1dnc1FMR29MRUN4NkN4QXNQUnNRS2JuN0VD&spp=ElcKEgjs7LyGARCoue2tCRj9hu6uCRIoeGNhdDpzZXJ2aWNlX2FyZWFfYnVzaW5lc3NfcGx1bWJlcjplbi1VU0ITCM3jt7vU2owDFSidWgUdBXcRS0gEUAI%3D&scp=Cih4Y2F0OnNlcnZpY2VfYXJlYV9idXNpbmVzc19wbHVtYmVyOmVuLVVTEiAaEgkvA8ygmbVEhhF61WnUS0abXSIGQXVzdGluOJnRPioIUGx1bWJpbmdKFQoTCM3jt7vU2owDFSidWgUdBXcRSw%3D%3D&q=plumbing", "rating":4.8, "ratingCount":6800, "type":"Plumbers", "service_area":"Serves Austin", "hours":"Open 24/7", "yearsInBusiness":"46+ years in business", "phone":"+15126074597", "highlighted_details":[ "Accepts urgent jobs", "Free in-home estimate" ] } ] } } ``` # Local Results Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/local-results ```json Response theme={null} { "localResults":{ "places":[ { "position":1, "title":"Apple Barton Creek", "label":"A", "phone":"(512) 634-0520", "address":"2901 S Capital of Texas Hwy", "hours":"Open ⋅ Closes 8 PM", "serviceOptions":{ "inStoreShopping":true, "inStorePickup":true, "delivery":true }, "links":{ "website":"https://www.apple.com/retail/bartoncreek?cid=aos-us-seo-maps", "directions":"https://www.google.com/maps/dir//Apple+Barton+Creek,+2901+S+Capital+of+Texas+Hwy,+Austin,+TX+78746/data=!4m6!4m5!1m1!4e2!1m2!1m1!1s0x865b4ae78499618f:0x946dba1a0d09b573?sa=X&ved=2ahUKEwiSwu7Oy9qMAxXQjpUCHUb4KEEQ48ADegQIKhAA&hl=en&gl=us" }, "placeId":"10695409311125452147", "description":"In-store shopping·In-store pickup·Delivery" }, { "position":2, "title":"Apple Domain NORTHSIDE", "label":"B", "phone":"(512) 691-4800", "address":"3121 Palm Way", "hours":"Open ⋅ Closes 9 PM", "serviceOptions":{ "inStoreShopping":true, "inStorePickup":true, "delivery":true }, "links":{ "website":"https://www.apple.com/retail/domainnorthside?cid=aos-us-seo-maps", "directions":"https://www.google.com/maps/dir//Apple+Domain+NORTHSIDE,+3121+Palm+Way,+Austin,+TX+78758/data=!4m6!4m5!1m1!4e2!1m2!1m1!1s0x864686b5be4fd0fd:0x73f04695da0ab476?sa=X&ved=2ahUKEwiSwu7Oy9qMAxXQjpUCHUb4KEEQ48ADegQILBAA&hl=en&gl=us" }, "placeId":"8354254918194476150", "description":"In-store shopping·In-store pickup·Delivery" }, { "position":3, "title":"Austin MacWorks-Apple Authorized Service Provider & Reseller", "label":"C", "phone":"(512) 476-7000", "address":"450 W 2nd St", "hours":"Open ⋅ Closes 6 PM", "serviceOptions":{ "inStorePickup":true }, "links":{ "website":"http://www.austinmacworks.com/", "directions":"https://www.google.com/maps/dir//Austin+MacWorks-Apple+Authorized+Service+Provider+%26+Reseller,+450+W+2nd+St,+Austin,+TX+78701/data=!4m6!4m5!1m1!4e2!1m2!1m1!1s0x8644b50f3fff1c6f:0x678bed2f8cc71b40?sa=X&ved=2ahUKEwiSwu7Oy9qMAxXQjpUCHUb4KEEQ48ADegQIKxAA&hl=en&gl=us" }, "placeId":"7461317996150463296", "description":"In-store pickup" } ], "moreLocationsLink":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&tbm=lcl&q=apple&rflfq=1&num=10&uule=w+CAIQICIaQXVzdGluLFRleGFzLFVuaXRlZCBTdGF0ZXM%3D&sa=X&ved=2ahUKEwiSwu7Oy9qMAxXQjpUCHUb4KEEQjGp6BAhWEAE" } } ``` # News Results Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/news-results ```json Response theme={null} { "newsResults":[ { "position":1, "title":"NASA Sets Coverage for SpaceX 32nd Station Resupply Launch, Arrival", "link":"https://www.nasa.gov/news-release/nasa-sets-coverage-for-spacex-32nd-station-resupply-launch-arrival/", "source":"NASA (.gov)", "snippet":"NASA and SpaceX are targeting 4:15 a.m. EDT, Monday, April 21, for the next launch to deliver science investigations, supplies,...", "date":"4 days ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/594a5a29-b78d-4742-a34d-091a73c43ca2.jpeg" }, { "position":2, "title":"DOGE Cuts Hobble Office That Would Aid NASA and SpaceX Mars Landings", "link":"https://www.nytimes.com/2025/04/14/science/astrogeology-mars-maps-spacex.html", "source":"The New York Times", "snippet":"The Astrogeology Science Center, which has helped astronauts and robots reach other worlds safely, is facing a substantial number of job...", "date":"1 day ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/23d3a295-5f10-4e22-8b70-7cd883b25f9d.jpeg" }, { "position":3, "title":"SpaceX launches Falcon 9 rocket booster on record-setting 27th time on midnight Starlink flight", "link":"https://spaceflightnow.com/2025/04/13/live-coverage-spacex-to-launch-27-starlink-satellites-on-falcon-9-rocket-from-cape-canaveral/", "source":"Spaceflight Now", "snippet":"Update 12:34 a.m. EDT: SpaceX landed its first stage booster on the droneship, 'Just Read the Instructions.' SpaceX notched another new...", "date":"1 day ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/f07a56c2-fb15-4c93-8282-97951d64e32d.jpeg" }, { "position":4, "title":"Lauren Sanchez’s all-female space flight is about to blast off – and will challenge Elon Musk’s SpaceX", "link":"https://www.theguardian.com/science/2025/apr/13/lauren-sanchezs-all-female-space-flight-is-about-to-blast-off-and-will-challenge-elon-musks-spacex", "source":"The Guardian", "snippet":"Jeff Bezos's Blue Origin rocket blasts off on Monday, with his fiancee, Katy Perry and three others on board. But is it more than just a...", "date":"2 days ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/6463d264-092f-438d-8669-8ab3b9354c12.jpeg" }, { "position":5, "title":"Elon Musk’s SpaceX is giving up to $100,000 to anyone who can hack into…", "link":"https://timesofindia.indiatimes.com/technology/tech-news/elon-musks-spacex-is-giving-up-to-100000-to-anyone-who-can-hack-into/articleshow/120281932.cms", "source":"Times of India", "snippet":"TECH NEWS : SpaceX is incentivizing security researchers to identify vulnerabilities within its Starlink satellite internet system through a...", "date":"14 hours ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/a6516d6d-017e-47db-aaf3-69a82460fe38.jpeg" }, { "position":6, "title":"After two days of delay, SpaceX launches rocket Saturday night from Kennedy Space Center", "link":"https://www.floridatoday.com/story/tech/science/space/spacex/2025/04/12/spacex-launches-falcon-9-starlink-rocket-from-kennedy-space-center-florida-saturday-night/83006047007/", "source":"Florida Today", "snippet":"After two scrubs, the Starlink 12-17 mission finally launched into the Saturday night sky.", "date":"2 days ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/8b64d979-4374-4cc6-b160-ea7f4e45cf27.jpeg" }, { "position":7, "title":"SpaceX starts 2025 with Falcon records and Starship problems", "link":"https://www.nasaspaceflight.com/2025/04/spacex-roundup-q12025/", "source":"NASASpaceFlight.com -", "snippet":"SpaceX kicked off 2025 by continuing its record-breaking pace of Falcon 9 launches while also setting new firsts with its Dragon program.", "date":"2 days ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/7e144dee-a55d-474a-8e50-45c63ee555d6.jpeg" }, { "position":8, "title":"SpaceX launch recap: Live updates from Monday midnight Starlink mission from Cape Canaveral", "link":"https://www.yahoo.com/news/spacex-launch-tonight-everything-know-124535029.html", "source":"Yahoo", "snippet":"Live updates from Monday's 12 a.m. SpaceX Starlink 6-73 mission that launched a Falcon 9 rocket from Cape Canaveral Space Force Station in...", "date":"2 days ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/c4868ea5-fb9d-4fa2-860e-d81c2872ac08.jpeg" }, { "position":9, "title":"Incredible Views Of SpaceX Starship Re-Entering Earth's Atmosphere", "link":"https://www.msn.com/en-us/news/technology/incredible-views-of-spacex-starship-re-entering-earth-s-atmosphere/vi-AA1CXhFi", "source":"MSN", "snippet":"Incredible Views Of SpaceX Starship Re-Entering Earth's Atmosphere. Credit: SpaceX.", "date":"4 hours ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/b0033f9d-6d42-4107-8f34-361ae09b24fb.jpeg" }, { "position":10, "title":"SpaceX Rival Jumps On Two Hypersonic Testing Contracts", "link":"https://www.investors.com/news/rocket-lab-stock-rklb-hypersonic-testing-contracts-us-uk-multi-billion/", "source":"Investor's Business Daily", "snippet":"Rocket Lab stock surged early Tuesday after the SpaceX rival announced it was selected to participate in two multibillion dollar contracts...", "date":"5 hours ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/10d39041-72b0-41cb-bd6f-c74e33240d4e.jpeg" } ] } ``` # Organic Results Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/organic-results ```json Response theme={null} { "organicResults":[ { "position":1, "title":"Coffee", "link":"https://en.wikipedia.org/wiki/Coffee", "displayedLink":"https://en.wikipedia.org › wiki › Coffee", "source":"Wikipedia", "snippet":"Coffee is a beverage brewed from roasted, ground coffee beans. Darkly colored, bitter, and slightly acidic, coffee has a stimulating effect on humans, ...", "snippetHighlitedWords":[ "Coffee" ], "sitelinks":{ "inline":[ { "title":"History", "link":"https://en.wikipedia.org/wiki/History_of_coffee" }, { "title":"Coffee preparation", "link":"https://en.wikipedia.org/wiki/Coffee_preparation" }, { "title":"List of coffee drinks", "link":"https://en.wikipedia.org/wiki/List_of_coffee_drinks" }, { "title":"Coffee bean", "link":"https://en.wikipedia.org/wiki/Coffee_bean" } ] }, "images":[ "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/8134471a-b670-4ac9-9def-e6951b0a459e.jpeg" ] }, { "position":2, "title":"Buy Coffee, Tea, Powders Online | The Coffee Bean & Tea ...", "link":"https://www.coffeebean.com/", "displayedLink":"https://www.coffeebean.com", "source":"The Coffee Bean & Tea Leaf", "snippet":"Buy exceptional coffee, tea, powders, equipment and drinkware at The Coffee Bean & Tea Leaf® online store to enjoy our globally sourced products at home.", "snippetHighlitedWords":[ "Buy exceptional coffee, tea, powders, equipment and drinkware" ], "sitelinks":{ "inline":[ { "title":"Coffee", "link":"https://www.coffeebean.com/collections/coffee" }, { "title":"Drinkware", "link":"https://www.coffeebean.com/collections/drinkware" }, { "title":"Our Story", "link":"https://www.coffeebean.com/pages/about-us" }, { "title":"Ground Coffee", "link":"https://www.coffeebean.com/collections/ground-coffee" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTsIOSeY1yNSUPrbAV20oIxM9MHxytyL5EZu5EuSAS-BQrihKnkqSBn&usqp=CAE&s" ] }, { "position":3, "title":"Starbucks Coffee Company", "link":"https://www.starbucks.com/", "displayedLink":"https://www.starbucks.com", "source":"Starbucks", "snippet":"More than just great coffee. Explore the menu, sign up for Starbucks® Rewards, manage your gift card and more.", "snippetHighlitedWords":[ "coffee" ], "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRChKfiV87kDO6bYuYGocHw1k9ZVBDKAPM-1X8bMO8WKxH-3T83uMBr&usqp=CAE&s" ] }, { "position":4, "title":"What is coffee? - NCA", "link":"https://www.aboutcoffee.org/origins/what-is-coffee/", "displayedLink":"https://www.aboutcoffee.org › Origins", "source":"aboutcoffee.org", "snippet":"Coffee trees have range. They can be anything from small shrubs to tall trees, and if they're not pruned, they can grow to more than 30 feet (9 meters) high.", "snippetHighlitedWords":[ "They can be anything from small shrubs to tall trees" ], "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ0BjQhb_djMD_AOoW9kD4Qli5eKdDVEEMeFiald8Jvh05Ykvtzqwop&usqp=CAE&s" ] }, { "position":5, "title":"Jo's Coffee - Austin", "link":"https://www.joscoffee.com/", "displayedLink":"https://www.joscoffee.com", "source":"Jo's Coffee", "snippet":"Jo's Coffee is an iconic Austin coffee shop known for its coffee, pastries, sandwiches, and breakfast tacos with multiple locations throughout Texas.", "snippetHighlitedWords":[ "an iconic Austin coffee shop" ], "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcThtpw68uh70fbqGC3t5xIlb-9r_6lJOmBLouIZ8o3WZqEEj1RWvDdw&usqp=CAE&s" ] }, { "position":6, "title":"Scooter's Coffee | Be Amazing", "link":"https://www.scooterscoffee.com/", "displayedLink":"https://www.scooterscoffee.com", "source":"Scooter's Coffee", "snippet":"Wake up to the ahhh-mazing aroma of quality. Subscribe to Scooter's Coffee® delivery and enjoy 100% Arabica beans, sourced directly from farmers who take pride ...", "snippetHighlitedWords":[ "100% Arabica beans" ], "richSnippet":{ "top":{ "extensions":[ "2–9 day delivery" ] } }, "sitelinks":{ "inline":[ { "title":"Locations", "link":"https://www.scooterscoffee.com/locations" }, { "title":"Menu", "link":"https://www.scooterscoffee.com/menu" }, { "title":"At-Home Coffee", "link":"https://www.scooterscoffee.com/shop/at-home-coffee" }, { "title":"Relationship Coffee", "link":"https://www.scooterscoffee.com/relationship-coffee" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQIq-YbdBa3Ee0YilmBe82CUhJeuw3x6vZbnHq86zrT10y70BpirBI-&usqp=CAE&s" ] }, { "position":7, "title":"Peet's Coffee | The Original Craft Coffee Since 1966", "link":"https://www.peets.com/", "displayedLink":"https://www.peets.com", "source":"Peet's Coffee", "snippet":"Since 1966, Peet's Coffee has sourced and offered superior coffees and teas adhered to strict high-quality and taste standards. Shop online today.", "snippetHighlitedWords":[ "Peet's Coffee" ] }, { "position":8, "title":"Coffee - Walmart.com", "link":"https://www.walmart.com/cp/coffee/1086446", "displayedLink":"https://www.walmart.com › coffee", "source":"Walmart", "snippet":"Shop for Coffee at Walmart.com. Buy Ground coffee, coffee pods, instant coffee, and whole bean coffee. Save money. Live better.", "snippetHighlitedWords":[ "Shop for Coffee at Walmart.com" ], "richSnippet":{ "top":{ "extensions":[ "$121.00", "In stock", "Free delivery", "Free 30-day returns" ] } }, "sitelinks":{ "inline":[ { "title":"Instant Coffee", "link":"https://www.walmart.com/browse/food/instant-coffee/976759_1086446_1229650" }, { "title":"Bottled Coffee in Coffee(1000+)", "link":"https://www.walmart.com/browse/food/bottled-coffee/976759_1086446_1229654" }, { "title":"Coffee in Coffee(1000+)", "link":"https://www.walmart.com/browse/food/coffee/976759_1086446_8753286" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTfd-UtgpP455JL42o19keMC2EQ2jc74MxvOeZ6zYJu5ngR_HTydG0V&usqp=CAE&s" ] }, { "position":9, "title":"Coffee & Tea Junkie", "link":"https://coffeeandteajunkie.com/", "displayedLink":"https://coffeeandteajunkie.com", "source":"Coffee Junkie", "snippet":"We roast only the highest quality, Certified Organic coffee beans and flavor with NO sugar, NO calories, NO allergens and NO alcohol.", "snippetHighlitedWords":[ "Certified Organic coffee beans" ], "richSnippet":{ "top":{ "extensions":[ "$3 to $100", "Free delivery over $75", "30-day returns" ] } }, "sitelinks":{ "inline":[ { "title":"Taste of Patti's Place", "link":"https://coffeeandteajunkie.com/products/taste-of-pattis-place" }, { "title":"A Coffee for Every Season...", "link":"https://coffeeandteajunkie.com/products/copy-of-holiday-k-cup-collection" }, { "title":"K Cups", "link":"https://coffeeandteajunkie.com/collections/k-cups-1" }, { "title":"Flavored Coffees", "link":"https://coffeeandteajunkie.com/collections/flavored-coffees-1" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQwKgE09mfLfupgaHNI2_vnPu72gyJ53nf3uYKK054&usqp=CAE&s" ] } ] } ``` # Pagination Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/pagination ```json Response theme={null} { "pagination":{ "next":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=10&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8NMDegUIgQEQFg", "pages":[ { "2":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=10&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8tMDegUIgQEQBA" }, { "3":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=20&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8tMDegUIgQEQBg" }, { "4":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=30&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8tMDegUIgQEQCA" }, { "5":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=40&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8tMDegUIgQEQCg" }, { "6":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=50&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8tMDegUIgQEQDA" }, { "7":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=60&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8tMDegUIgQEQDg" }, { "8":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=70&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8tMDegUIgQEQEA" }, { "9":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=80&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8tMDegUIgQEQEg" }, { "10":"https://www.google.com/search?q=walmart&sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&ei=35v-Z6DMOZLq1e8P-6jruA8&start=90&sa=N&sstk=Af40H4XLhXgox0NOVgGuC3PHNciDdxT6rZXbLI6qdSjuOMVwUWnZq7AX4C2cpJ0KAVKgp0JmNW6_Ehs1QiOf2SkPnWXstMKrcxSgNg&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ8tMDegUIgQEQFA" } ] } } ``` # Perspectives Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/perspectives ```json Response theme={null} { "perspectives":[ { "index":1, "author":"CoffeeCrazyClub", "source":"Facebook", "extensions":[ "470+ reactions" ], "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/1768ced6-1f19-4ccf-9ce3-8ce1d671c6f5.jpeg", "title":"Crazy for Coffee", "link":"https://m.facebook.com/CoffeeCrazyClub/photos/d41d8cd9/1114381217395106/", "date":"5 days ago" }, { "index":2, "author":"Coffee with Humor – Hot Sips & Daily Deals Hunters", "source":"Facebook", "extensions":[ "380+ reactions" ], "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/0357ec8b-37d5-4c07-be54-17b89da5bbb4.jpeg", "title":"Here are a few coffee AI images I created. Enjoy!!", "link":"https://www.facebook.com/groups/967522380825591/posts/1743847493193072/", "date":"3 weeks ago" }, { "index":3, "author":"maythecoffeebewithyou", "source":"Facebook", "extensions":[ "4 reactions" ], "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/27079b2b-acfc-4218-88ac-626c37afac02.png", "title":"Coffee", "link":"https://m.facebook.com/100047736182702/photos/1199359928331869/", "date":"5 days ago" } ] } ``` # Recipes Results Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/recipes-results ```json Response theme={null} { "recipesResults":[ { "position":1, "title":"Easy Apple Pie", "link":"https://littlespoonfarm.com/apple-pie-recipe/", "source":"Little Spoon Farm", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/38dcdd23-b740-4a89-ae65-af8f476da2b5.jpeg", "rating":5, "reviews":800, "reviewsOriginal":"(800)", "totalTime":"2 hr" }, { "position":2, "title":"Apple Pie by Grandma Ople", "link":"https://www.allrecipes.com/recipe/12682/apple-pie-by-grandma-ople/", "source":"Allrecipes", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/9667064c-419a-44d9-8d3d-caf0614c3f63.jpeg", "rating":4.8, "reviews":13000, "reviewsOriginal":"(13K)", "totalTime":"1 hr 30 min" }, { "position":3, "title":"My Best Apple Pie Recipe", "link":"https://sallysbakingaddiction.com/apple-pie-recipe/", "source":"Sally's Baking Addiction", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/09bfcb0d-0ac1-4e27-a3ed-4f00b9ecefc7.jpeg", "rating":4.8, "reviews":108, "reviewsOriginal":"(108)", "totalTime":"7 hr" } ] } ``` # Related Questions Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/related-questions ```json Response theme={null} { "relatedQuestions":[ { "link":"https://www.seriouseats.com/food-lab-top-nine-tips-for-perfect-apple-pie", "title":"The Food Lab's Top 9 Tips For Perfect Apple Pie - Serious Eats", "displayedLink":"https://www.seriouseats.com › food-lab-top-nine-tips-for...", "list":[ "Keep Your Ingredients Cold.", "Stick With an All-Butter Crust.", "Make a Butter-Flour Paste.", "Use Vodka (or Don't)", "Fold in Liquid With a Spatula.", "Choose Tart Apples.", "Go Easy on the Seasoning.", "Par-Cook Your Apples." ], "question":"What is the secret to a good apple pie?" }, { "aiOverview":{ "textBlocks":[ { "type":"paragraph", "snippet":"Yes, precooking apples before adding them to a pie filling is generally recommended.", "snippetHighlightedWords":[ "Yes, precooking apples before adding them to a pie filling is generally recommended" ] }, { "type":"paragraph", "snippet":"Here's why precooking is beneficial:" }, { "type":"list", "list":[ { "title":"Prevents Soggy Crust:", "snippet":"Raw apples release a lot of liquid during baking, which can make the bottom crust soggy. Precooking helps reduce this moisture." }, { "title":"Reduces Crust Gap:", "snippet":"As apples cook, they can shrink and create a gap between the filling and the top crust. Precooking helps prevent this gap by reducing the volume of the apples before baking." }, { "title":"More Apples, Less Collapse:", "snippet":"Precooking allows you to pack more apples into the pie without the risk of the top crust collapsing due to the weight of the wet filling." }, { "title":"Flavor and Texture:", "snippet":"Precooking also helps the flavors of the sugar and spices to meld evenly throughout the apples, and the apples become more tender." } ] }, { "type":"paragraph", "snippet":"While some recipes may call for uncooked apples, precooking is generally considered the better method for achieving a delicious and structurally sound apple pie." } ], "references":[ { "link":"https://food52.com/hotline/8529-i-am-making-apple-pies-do-apple-pie-experts-prefer-to-precook-their-apples-before-baking#:~:text=Precooking%20the%20apples%20lets%20you%20add%20flavors%2D,small%20(if%20you%20like%20playing%20with%20knives).&text=When%20making%20apple%20pies%20I%20slightly%20pre%2Dcook,of%20the%20sugar%20and%20spices%20to%20combine.", "title":"I am making apple pies. Do apple pie experts prefer to precook ... - Food52", "snippet":"Oct 14, 2011 — Precooking the apples lets you add flavors- for a standard pie, you can limit the top crust problem somewhat by cubing...", "source":"Food52", "index":0 }, { "link":"https://www.bonappetit.com/test-kitchen/cooking-tips/article/one-thing-need-know-apple-pie-game#:~:text=Pre%2Droasting%20apples%20and%20stone%20fruits%20before%20putting,the%20sog%20factor%20in%20your%20fruit%20desserts.&text=But%2C%20when%20you%20pre%2Droast%20your%20fruit%2C%20you,and%20concentrate%20both%20its%20sweetness%20and%20tartness.", "title":"The One Thing You Need to Know to Up Your Apple Pie Game", "snippet":"Sep 8, 2015 — Pre-roasting apples and stone fruits before putting them into pies, cobblers, cakes, or crumbles is an easy way to add ...", "source":"Bon Appetit", "index":1 }, { "link":"https://www.thekitchn.com/apple-pie-filling-recipe-23234853#:~:text=Pre%2Dcooked%20apple%20filling%20=%20no,of%20the%20crust%20collapsing%20in.", "title":"Apple Pie Filling Recipe (Make-Ahead!) | The Kitchn", "snippet":"Pre-cooked apple filling = no gaps in your pie. I love pre-cooked apple pie filling versus using sliced raw apples. Since so much ...", "source":"The Kitchn", "index":2 }, { "link":"https://www.quora.com/Do-you-pre-bake-Apple-pie-filling#:~:text=Pre%2Dcooking%20your%20filling%20gives,that%20can%20happen%20during%20baking.", "title":"Do you pre-bake Apple pie filling? - Quora", "snippet":"Nov 23, 2021 — Pre-cooking your filling gives softer apples, blends spices evenly throughout and allows you to have more apples in yo...", "source":"Quora", "index":3 }, { "link":"https://www.thekitchn.com/why-you-should-cook-your-apples-for-apple-pie-225757#:~:text=Precook%20to%20Make%20a%20More,apples%20from%20bottom%20to%20top.", "title":"Why You Should Cook Your Apples for Apple Pie - The Kitchn", "snippet":"May 1, 2019 — Precook to Make a More Sturdy Pie The biggest advantage to precooking the apple filling is making a more sturdy pie. Ha...", "source":"The Kitchn", "index":4 }, { "link":"https://www.mccormick.com/articles/lifehacker/the-crucial-step-youre-missing-with-fruit-pie#:~:text=Why%20you%20should%20cook%20your,fruit%20and%20the%20upper%20crust.", "title":"The Crucial Step You're Missing With Fruit Pie - McCormick", "snippet":"Jun 19, 2022 — Why you should cook your fruit filling first. The two recurring issues with pie recipes that use a raw fruit filling a...", "source":"McCormick", "index":5 } ] }, "question":"Should you cook apples before putting them in a pie?" }, { "date":"Oct 30, 2018", "link":"https://entertainingwithbeth.com/10-tips-for-the-best-apple-pie/", "title":"Beth's Foolproof Apple Pie Recipe - Entertaining with Beth", "displayedLink":"https://entertainingwithbeth.com › 10-tips-for-the-best-ap...", "list":[ "Adding a little cornstarch to the bottom of your crust, before filling the pie with apples, will create a barrier to moisture and will ensure a crisp bottom crust!", "It's the simplest trick that I learned from my Aunt Nancy, the ``original'' pie boss of my family!" ], "question":"How do you keep the bottom crust of apple pie from getting soggy?" }, { "snippet":"A cornstarch slurry made of cornstarch and water is what I consider the best thickener for apple pie filling. It thickens the apple mixture quickly, and the filling remains smooth and glossy. You can also use tapioca starch or all-purpose flour for a similar effect.", "link":"https://preppykitchen.com/apple-pie-filling/", "title":"Apple Pie Filling Recipe - Preppy Kitchen", "displayedLink":"https://preppykitchen.com › apple-pie-filling", "question":"What is the best thickener for apple pie filling?" } ] } ``` # Related Searches Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/related-searches ```json Response theme={null} { "relatedSearches":[ { "query":"Walmart near Me", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Walmart+near+Me&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ1QJ6BAh_EAE" }, { "query":"Walmart careers", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Walmart+careers&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ1QJ6BAh-EAE" }, { "query":"Walmart number", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Walmart+number&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ1QJ6BAh4EAE" }, { "query":"Walmart hours", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Walmart+hours&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ1QJ6BAhyEAE" }, { "query":"Walmart Austin", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Walmart+Austin&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ1QJ6BAhxEAE" }, { "query":"Walmart Pharmacy", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Walmart+Pharmacy&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ1QJ6BAhwEAE" }, { "query":"Walmart login", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Walmart+login&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ1QJ6BAhqEAE" }, { "query":"Walmart app download", "link":"https://www.google.com/search?sca_esv=f9f1a50abb3c6f24&hl=en&gl=us&q=Walmart+app+download&sa=X&ved=2ahUKEwjgt9evzNqMAxUSdfUHHXvUGvcQ1QJ6BAhpEAE" } ] } ``` # Search Information Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/search-information ```json Response theme={null} { "searchInformation": { "totalResults":"617000000", "timeTaken":0.41 } } ``` # Short videos Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/short-videos ```json Response theme={null} { "shortVideos":[ { "title":"Top Places In Paris France 🇫🇷 #placesinparis #paristopplaces", "source":"YouTube", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/8ff95ef6-9148-4d4e-9034-61b6bcc38004.png", "date":"Jul 31, 2024", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcShaRSyDNdpR_eFQLzhGvOq0f8nM5HkbmnHaA", "profileName":"TraverseXP", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/d8101078-4097-4d58-ba5b-a2af5134521a.png", "link":"https://m.youtube.com/watch?v=ZukQHVZ_xVQ", "position":1 }, { "title":"12 top sights in Paris | From the Eiffel Tower to the Louvre - we ...", "source":"Facebook", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/eca0dce6-1958-4e23-81f7-8f2f1c971e85.png", "date":"Jul 23, 2024", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcTAf9gngS7EaI8xJvEleFgNfrL4KNovAIpj0g", "profileName":"DW Travel", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/05bc77b9-5d1e-4126-8800-9faff502e990.png", "link":"https://www.facebook.com/dw.travel/videos/12-top-sights-in-paris/472724845709475/", "position":2 }, { "title":"Top 10 Things To Do in Paris France", "source":"YouTube", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/5a6db319-2f4d-426f-a4bc-070bf79be8f8.png", "date":"Feb 3, 2025", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcSKvSAKQ8VQwYMyFThmQ5Y8MA9xDwR2wJ3Lyw", "profileName":"Travel Time", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/d260f714-5bbd-4478-8370-480a2fd1f364.png", "link":"https://www.youtube.com/watch?v=Fkxt5_pXFCs", "position":3 }, { "title":"Top 5 Must-Visit Attractions in Paris | Travel Guide", "source":"TikTok", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/0d90f0a2-8ffe-491f-8f44-3bcb03aee704.png", "date":"Jun 15, 2024", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcQwV8VQYE5pltt2AAeL-Auxn2vw-zg7dzsUwg", "profileName":"bnntravel", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/c3662af3-3b50-4fd7-9ac0-2847a84e7594.png", "link":"https://www.tiktok.com/@bnntravel/video/7380893639666322704", "position":4 }, { "title":"Top Paris Sights You Can’t Miss | Top Paris Sights You Can’t ...", "source":"Facebook", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/a21d7c05-5ab4-4c3e-9def-e38fc061d5f0.png", "date":"Jan 27, 2025", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcRCa960YgJJVfbdAGklCd_noTxa00NRFn9E_g", "profileName":"Wind Virtual University", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/86c6c2ca-b8e1-4c06-a4c3-efa4baf5a846.png", "link":"https://www.facebook.com/Shahram.Design/videos/top-paris-sights-you-cant-miss/1147175034081030/", "position":5 }, { "title":"Top 10 Things to do in Paris", "source":"YouTube", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/0a564358-63ff-4d9e-9302-a31d2a63906e.png", "date":"Jul 13, 2024", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcQbosixkwn-PhXSQr1yI_ZBhRgi1stsUzMFLQ", "profileName":"y Travel Blog", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/0c741ddb-d3ed-48f9-9db0-854781046118.png", "link":"https://www.youtube.com/watch?v=hRfQZ73RiaM", "position":6 }, { "title":"The Ultimate Guide to Exploring Paris: Top Attractions and ...", "source":"TikTok", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/8fbaf26c-652f-4757-bec1-2fc3a616a404.png", "date":"Feb 11, 2024", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcQBkeDSLznwGZDC0MU38ruTTQZK4v-XuGV5FA", "profileName":"mia.in.france", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/3a3fe11f-3d9b-4d0a-93c0-3c17d3622e57.png", "link":"https://www.tiktok.com/@mia.in.france/video/7334370276165111073", "position":7 }, { "title":"【PARIS】Must-See Tourist Attractions - Louvre Museum", "source":"YouTube", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/c7ce7e60-91de-4322-bcf6-bca846cdc35a.png", "date":"Jul 20, 2024", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcTOZrC_2wRQV7sb5hkh3mTVk0WSaM9F2NOH2w", "profileName":"By Kyoto Local", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/e81fcb17-a81a-4cf1-ad27-e8a2b0d61739.png", "link":"https://www.youtube.com/watch?v=y4PIZjUsov0", "position":8 }, { "title":"Discover the Magic of Paris: Top Attractions", "source":"YouTube", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/cf6f6cd5-85dd-40d2-9d14-05bbcc246d64.png", "date":"Nov 12, 2024", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcRaeSbolR-F4yD6fORrhsP_JZwl3r6AIDiM7g", "profileName":"Woxo", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/a9114827-7c44-435a-a807-73bd0c6d434d.png", "link":"https://m.youtube.com/shorts/4B-2bfBFDOw", "position":9 }, { "title":"Top 20 Things to do in Paris | Paris Itinerary | Paris Travel ...", "source":"YouTube", "sourceLogo":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/daafa458-7802-4f06-b8dc-192d343dc414.png", "date":"Feb 28, 2025", "clip":"https://encrypted-vtbn0.gstatic.com/video?q=tbn:ANd9GcTtAJcs3V9sxELpHQTqVdKlO5a3ouEs-yR-EA", "profileName":"World of Veshali", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/82b4cfcf-e036-4b15-9caf-a0f044cffbf8.png", "link":"https://www.youtube.com/watch?v=QXMaB2cAaqc", "position":10 } ] } ``` # Top Stories Source: https://docs.hasdata.com/apis/google-serp-api/rich-snippets/top-stories ```json Response theme={null} { "topStories":[ { "title":"Atomic Clock and Plant DNA Research Launching Aboard NASA’s SpaceX CRS-32 Mission", "link":"https://science.nasa.gov/science-research/biological-physical-sciences/atomic-clock-and-plant-dna-research-launching-aboard-nasas-spacex-crs-32-mission/", "source":"NASA Science (.gov)", "date":"2 hours ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/bf5cd820-7a14-4f7f-9fe9-066dff87b2ba.jpeg" }, { "title":"DOGE Cuts Hobble Office That Would Aid NASA and SpaceX Mars Landings", "link":"https://www.nytimes.com/2025/04/14/science/astrogeology-mars-maps-spacex.html", "source":"The New York Times", "date":"1 day ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/6fbfd3ee-3b16-415c-80bc-42c5670edbac.jpeg" }, { "title":"SpaceX, ULA rocket launches from Vandenberg, California, may be visible in Arizona, too", "link":"https://www.vcstar.com/picture-gallery/news/2025/04/15/california-rocket-launch-photos-spacex-phoenix-arizona-vandenberg/83096499007/", "source":"Ventura County Star", "date":"4 minutes ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/c4ccb440-0b2a-4f55-af3d-c63269c1e821.jpeg" }, { "title":"SpaceX vs. Blue Origin: Who's Really Winning the Space Race?", "link":"https://www.ceotodaymagazine.com/2025/04/spacex-vs-blue-origin-whos-really-winning-the-space-race/", "source":"CEO Today", "date":"3 hours ago", "thumbnail":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/27616bf3-66f1-494b-857a-1f065d9941f1.jpeg" } ] } ``` # Google AI Overview API Source: https://docs.hasdata.com/apis/google-serp/ai-overview Retrieves AI-generated answers from Google SERP when AI Overview content is loaded via a separate background request. Requires a pageToken provided in the `aiOverview` block of the Google SERP API. Token is valid for 4 minutes. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google AI Overview API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET \ --url 'https://api.hasdata.com/scrape/google/ai-overview' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/ai-overview', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/ai-overview" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrape/google/ai-overview", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/google/ai-overview") .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.hasdata.com/scrape/google/ai-overview"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/ai-overview") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/ai-overview") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.hasdata.com/scrape/google/ai-overview", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ----------- | ------------- | -------- | ---------------------------------------------------------------------- | | `pageToken` | - | Yes | Token from `aiOverview` block in Google SERP API. Valid for 4 minutes. | # Google Events API Source: https://docs.hasdata.com/apis/google-serp/events The Google Events API allows users to retrieve information about events based on specified search terms, locations, and various filter options. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Events API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/events' \ --data-urlencode 'q=Events in New York' \ --data-urlencode 'location=Austin,Texas,United States' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-events \ --q 'Events in New York' \ --location 'Austin,Texas,United States' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/events', params: {q: 'Events in New York', location: 'Austin,Texas,United States'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/events" querystring = {"q":"Events in New York","location":"Austin,Texas,United States"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Events in New York", "location" => "Austin,Texas,United States", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/events?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/events") .newBuilder() .addQueryParameter("q", "Events in New York") .addQueryParameter("location", "Austin,Texas,United States") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Events in New York"; query["location"] = "Austin,Texas,United States"; var url = $"https://api.hasdata.com/scrape/google/events?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/events") params = { "q" => "Events in New York", "location" => "Austin,Texas,United States", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/events") .query(&[("q", "Events in New York")]) .query(&[("location", "Austin,Texas,United States")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Events in New York") params.Set("location", "Austin,Texas,United States") u := "https://api.hasdata.com/scrape/google/events?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------- | -------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Events in New York | Yes | Specify the search term for which you want to scrape the SERP. | | `location` | Austin,Texas,United States | No | Google canonical location for the search. | | `uule` | - | No | The encoded location parameter. | | `domain` | - | No | Google domain to use. Default is google.com. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `start` | - | No | This parameter specifies the number of search results to skip and is used for implementing pagination. For example, a value of 0 (default) indicates the first page of results, 10 refers to the second page, and 20 to the third page.
| | `htichips` | - | No | Filter parameter for refining event search results. Supports various filters for events. Multiple filters can be passed using a comma. The available filters are:

- `date:today`: Today's Events
- `date:tomorrow`: Tomorrow's Events
- `date:week`: This Week's Events
- `date:weekend`: This Weekend's Events
- `date:next_week`: Next Week's Events
- `date:month`: This Month's Events
- `date:next_month`: Next Month's Events
- `event_type:Virtual-Event`: Online Events

For example, to filter for today's online events, use: `event_type:Virtual-Event,date:today`.
| # Google Immersive Product API Source: https://docs.hasdata.com/apis/google-serp/immersive-product With the Google Immersive Product API, you can fetch extended product information from the "Immersive Product" block, which displays a pop-up with complete details when clicked. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Immersive Product API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/immersive-product' \ --data-urlencode 'pageToken=eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-immersive-product \ --page-token eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9 ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/immersive-product', params: { pageToken: 'eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/immersive-product" querystring = {"pageToken":"eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/immersive-product?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/immersive-product") .newBuilder() .addQueryParameter("pageToken", "eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["pageToken"] = "eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9"; var url = $"https://api.hasdata.com/scrape/google/immersive-product?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/immersive-product") params = { "pageToken" => "eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/immersive-product") .query(&[("pageToken", "eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("pageToken", "eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9") u := "https://api.hasdata.com/scrape/google/immersive-product?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `pageToken` | eyJyZHMiOiJQQ18zMjQ1NDc2NDAwODMzNTUxOTQ4fFBST0RfUENfMzI0NTQ3NjQwMDgzMzU1MTk0OCIsInByb2R1Y3RpZCI6IjE2NTYxODg2MzMwNjI5NzA1MjY5IiwiY2F0YWxvZ2lkIjoiMTA5MDU3MjEzODE1NDM1NDgwMCIsImhlYWRsaW5lT2ZmZXJEb2NpZCI6IjEwNTQwMDUxMzg0NjEzOTczOTg1IiwiaW1hZ2VEb2NpZCI6IjE3MjMwMzM3NDkwMTYzODIyNjMiLCJncGNpZCI6IjgyOTk1MTI3NTExOTg2NzE2MjIiLCJtaWQiOiI1NzY0NjI2MTIyODAxMzA0ODEiLCJxIjoiYnV5IGNvZmZlZSIsImhsIjoiZW4iLCJnbCI6InVzIiwiY29va2llcyI6Il9fU2VjdXJlLVNUUlA9QU5tWndhMHZsZUx5TFN3SDZKcmFHRU15RGxnbEhJN3NJelN2NFVJcXhZUDhFQk5kd1FXNTRoRHVsX3RZRl9hSFBsQjM3ajhNMWZRY1NwOVhTMy1icmVOdzIwa1RybjhnajhCaDsgQUVDPUFkSlZFYXR5TE1ZbHktUk5IRGxTVm04MGkySWRhWm4yeE5mWlVBX3JzV3pDX0xyTFFTeUwzTGJ3TkJnOyBOSUQ9NTMyPWtadG5CQnpoNE02cU5lTW9VM1Rjekd1d0VKdmtkcjBZMzFFbmNPTlZUT084TmlVX0oyUTVucmR3Q0dWUU5pWVlvWUROSEdWTE9BdUd0SWI2ZjEwSDk3OHM3bk9hajFFTVN1ellIaDVTMzdDTkJDZkdwLWlmcThVenV4aHR3TTR0YmNidXdnbVBNUHJHeXBlMS1aQmZtTEVCOXpTam9aMFpGOUZHQ3ZQdkc3aGdXZzRCcndvb1RYclhnTHdhc3BtYXpUVi1YYUg1bzJjV2lUNTUwc0dHNG5pRVpYLUI1aFZsbllYQ1QxZU91LXU0Tjk4MXQtUnYzYi1RZS1nTGV2NmV4ZGNFdlE7IERWPU02U2J0ZDljdGtvc1VKSEhKMHhOMXZfa3lxX0M5Tm42MHAxSjhPd3dCd1FBQUFBIiwieHNyZiI6IkFGNXRTTzRGb3VnZDItOVJPN09YU29oMzlvWnhLUzZGNVE6MTc4MzY4OTMxMzM5MiIsIm9hcHZmYyI6IkVvc0RDc3dDUVVwcFZEUjBTMGMwTmxObk16TktTRmxmYW05SlpUbFNNM1ZaVTFJeWJ6ZENlRGgwWm5kRVNGWTFja2hzZFVZNVMzWnVOMVUxYkVSSU1YTlVSMUpyV1VwWFpVWlNUVVY0Y2s5ak1EaElYMWd3UVRaR1RVbzJTVmxpZVdGdU5IRklVV1o0WTJ4d1RVUm1hRFZPT1dSbGFXOVZaVFpNT1ZaT1VXZHJNMlJTTlZNMlQzWlhiSEI1UW01aU5DMHlUR0psYnpWTVJEVkhSazVoYlZkZlVFUmxlbkIwTlc1U2FtRjJOVUprVWkxTloxcFJhbHBsY21kc1VXbDNXVWcxY1dKeFdtTjZWR0ZEVDB0a2RISldTekYwYzB0MVlqaHBiR1o2TFc1cFZsODNjV296VTI5RVgydDVkSE13WlVNNVJVaGhhRTU0WHpKT2ExY3plR3BXY1VGMlJXVjBhVmN5T1ZkNk9WaEVialV5VldVNGNtdHlPVUV4Ym1ZdFNYRjRkM1J3VUMxdFNYUjZORUk0Y3pCV1REUlhkbTVHUldodE1ETnVaaTFNTFZSUlRuUm9PVmRDWDNoaVoyNXVkVWtTRmxsUVFsRmhjV1ZrVFZCWGRIRjBjMUEwV1U5elRWRWFJa0ZFYzNJNVpsRjZSMVpNTkZKR2IwRmhZbmhQWmpSRFRqbHBNRTVCWjAxcFowRSIsInZlcnNpb24iOjJ9 | Yes | Token for displaying more product info in the Google immersive pop-up, available in the Google Shopping API response as the `immersiveProductPageToken` property. | | `moreStores` | - | No | Fetch additional store results in a single search. By default it returns 3–5 stores, and when true it returns up to 13 or the maximum available for the product. | | `nextPageToken` | - | No | Token used to retrieve the next page of store results. | # Google News API Source: https://docs.hasdata.com/apis/google-serp/news Real-time access to structured Google News results with a high success rate at scale. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google News API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET \ --url 'https://api.hasdata.com/scrape/google/news' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-news ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/news', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/news" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrape/google/news", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/google/news") .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.hasdata.com/scrape/google/news"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/news") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/news") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.hasdata.com/scrape/google/news", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------------ | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- | | `q` | - | No | Free-text query as used on news.google.com. Not allowed with `topicToken`, `storyToken`, or `publicationToken`. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `topicToken` | - | No | Token for a Google News topic such as World, Business, or Technology. Not allowed with `q`, `storyToken`, or `publicationToken`. | | `sectionToken` | - | No | Token for a sub-section under a topic, for example Business → Economy. Use only when `topicToken` or `publicationToken` is present. | | `publicationToken` | - | No | Token for a specific publisher such as CNN or BBC. Not allowed with `q`, `storyToken`, or `topicToken`. | | `storyToken` | - | No | Token for a single news story cluster (the “Full coverage” page). | | `so` | - | No | Sort order for articles in a story. Use only with storyToken. | # Google SERP Light API Source: https://docs.hasdata.com/apis/google-serp/serp-light Google Light SERP API offers real-time access to Google search results parsed from the lightweight layout — organic results, AI Overview, answer box, knowledge graph, related questions and searches, inline images, local pack and search filters — for faster response times and lower costs. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google SERP Light API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google-light/serp' \ --data-urlencode 'q=Coffee' \ --data-urlencode 'location=Austin,Texas,United States' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-serp-light \ --q Coffee \ --location 'Austin,Texas,United States' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google-light/serp', params: {q: 'Coffee', location: 'Austin,Texas,United States'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google-light/serp" querystring = {"q":"Coffee","location":"Austin,Texas,United States"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Coffee", "location" => "Austin,Texas,United States", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google-light/serp?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google-light/serp") .newBuilder() .addQueryParameter("q", "Coffee") .addQueryParameter("location", "Austin,Texas,United States") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Coffee"; query["location"] = "Austin,Texas,United States"; var url = $"https://api.hasdata.com/scrape/google-light/serp?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google-light/serp") params = { "q" => "Coffee", "location" => "Austin,Texas,United States", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google-light/serp") .query(&[("q", "Coffee")]) .query(&[("location", "Austin,Texas,United States")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Coffee") params.Set("location", "Austin,Texas,United States") u := "https://api.hasdata.com/scrape/google-light/serp?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------- | -------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Coffee | Yes | Specify the search term for which you want to scrape the SERP. | | `location` | Austin,Texas,United States | No | Google canonical location for the search. | | `uule` | - | No | The encoded location parameter. | | `domain` | - | No | Google domain to use. Default is google.com. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `lr` | - | No | The 'lr' parameter specifies the language of the websites to return results from. This parameter filters results based on the language of the web content. | | `tbs` | - | No | This parameter supports various filters that can be combined by separating them with a comma. Here are examples of these filters:

- Specific Time Range: `cdr:1,cd_min:10/17/2018,cd_max:3/8/2021` - Filter results to show only those within the defined date range.
- Sort by Date: `sbd:1` - Results are sorted by date, from the most recent to the oldest.
- Sort by Relevance: `sbd:0` - Results are sorted by relevance to the search query.
- Sites with Images: `img:1` - Only show results from webpages that contain images.

Quick Date Range (qdr):
- `qdr:h` - Show results from the past hour.
- `qdr:d` - Limit results to the past day.
- `qdr:w` - Filter results from the week.
- `qdr:m` - Display results from the past month.
- `qdr:y` - Show results from the past year.
- `qdr:h10`, `qdr:d10`, `qdr:w10`, `qdr:m10`, `qdr:y10` - Specify a number to show results from the last 10 hours, days, weeks, months, or years respectively.

These filters enhance the control over search results, allowing for precise retrieval of information based on specific criteria.
| | `safe` | - | No | Adult Content Filtering option. | | `filter` | - | No | Defines whether to enable or disable the filters for 'Similar Results' and 'Omitted Results'. Set to 1 (default) to enable these filters, or 0 to disable them.
| | `start` | - | No | This parameter specifies the number of search results to skip and is used for implementing pagination. For example, a value of 0 (default) indicates the first page of results, 10 refers to the second page, and 20 to the third page.

For Google Local Results, the start value must be in multiples of 20, such as 20 for the second page, 40 for the third page, etc.
| | `num` | - | No | Number of results per page, ranging from 10 to 100. | # Google Shopping API Source: https://docs.hasdata.com/apis/google-serp/shopping The Google Shopping API gives real-time access to structured product listings from Google Shopping with a high success rate at scale. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Shopping API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/shopping' \ --data-urlencode 'q=Coffee' \ --data-urlencode 'location=Austin,Texas,United States' \ --data-urlencode 'deviceType=desktop' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-shopping \ --q Coffee \ --location 'Austin,Texas,United States' \ --device-type desktop ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/shopping', params: {q: 'Coffee', location: 'Austin,Texas,United States', deviceType: 'desktop'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/shopping" querystring = {"q":"Coffee","location":"Austin,Texas,United States","deviceType":"desktop"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Coffee", "location" => "Austin,Texas,United States", "deviceType" => "desktop", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/shopping?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/shopping") .newBuilder() .addQueryParameter("q", "Coffee") .addQueryParameter("location", "Austin,Texas,United States") .addQueryParameter("deviceType", "desktop") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Coffee"; query["location"] = "Austin,Texas,United States"; query["deviceType"] = "desktop"; var url = $"https://api.hasdata.com/scrape/google/shopping?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/shopping") params = { "q" => "Coffee", "location" => "Austin,Texas,United States", "deviceType" => "desktop", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/shopping") .query(&[("q", "Coffee")]) .query(&[("location", "Austin,Texas,United States")]) .query(&[("deviceType", "desktop")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Coffee") params.Set("location", "Austin,Texas,United States") params.Set("deviceType", "desktop") u := "https://api.hasdata.com/scrape/google/shopping?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------ | -------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Coffee | Yes | Specify the search term for which you want to scrape the SERP. | | `location` | Austin,Texas,United States | No | Google canonical location for the search. | | `uule` | - | No | The encoded location parameter. | | `domain` | - | No | Google domain to use. Default is google.com. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `tbs` | - | No | This parameter supports various filters that can be combined by separating them with a comma. Here are examples of these filters:

- Specific Time Range: `cdr:1,cd_min:10/17/2018,cd_max:3/8/2021` - Filter results to show only those within the defined date range.
- Sort by Date: `sbd:1` - Results are sorted by date, from the most recent to the oldest.
- Sort by Relevance: `sbd:0` - Results are sorted by relevance to the search query.
- Sites with Images: `img:1` - Only show results from webpages that contain images.

Quick Date Range (qdr):
- `qdr:h` - Show results from the past hour.
- `qdr:d` - Limit results to the past day.
- `qdr:w` - Filter results from the week.
- `qdr:m` - Display results from the past month.
- `qdr:y` - Show results from the past year.
- `qdr:h10`, `qdr:d10`, `qdr:w10`, `qdr:m10`, `qdr:y10` - Specify a number to show results from the last 10 hours, days, weeks, months, or years respectively.

These filters enhance the control over search results, allowing for precise retrieval of information based on specific criteria.
| | `shoprs` | - | No | Specifies the helper ID for applying search filters. Must be used with the updated `q` parameter, which includes the selected filter (e.g., Coffee sale).

To apply filters, use the `hasdata_link` from `filters[index].options[index]` in the JSON. Apply multiple filters by following each `hasdata_link` one by one.

To remove a filter, follow its specific `hasdata_link`.
| | `deviceType` | desktop | No | Specify the device type for the search. | | `start` | - | No | This parameter specifies the number of search results to skip and is used for implementing pagination. For example, a value of 0 (default) indicates the first page of results, 40 refers to the second page, and 80 to the third page.
| # Google Short Videos API Source: https://docs.hasdata.com/apis/google-serp/short-videos The Google Short Videos API provides real-time access to short-form video content indexed by Google, allowing users to retrieve videos based on specific queries, topics, platforms, and customizable filters for highly relevant video results. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Short Videos API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/short-videos' \ --data-urlencode 'q=Coffee' \ --data-urlencode 'location=Austin,Texas,United States' \ --data-urlencode 'deviceType=desktop' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-short-videos \ --q Coffee \ --location 'Austin,Texas,United States' \ --device-type desktop ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/short-videos', params: {q: 'Coffee', location: 'Austin,Texas,United States', deviceType: 'desktop'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/short-videos" querystring = {"q":"Coffee","location":"Austin,Texas,United States","deviceType":"desktop"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Coffee", "location" => "Austin,Texas,United States", "deviceType" => "desktop", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/short-videos?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/short-videos") .newBuilder() .addQueryParameter("q", "Coffee") .addQueryParameter("location", "Austin,Texas,United States") .addQueryParameter("deviceType", "desktop") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Coffee"; query["location"] = "Austin,Texas,United States"; query["deviceType"] = "desktop"; var url = $"https://api.hasdata.com/scrape/google/short-videos?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/short-videos") params = { "q" => "Coffee", "location" => "Austin,Texas,United States", "deviceType" => "desktop", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/short-videos") .query(&[("q", "Coffee")]) .query(&[("location", "Austin,Texas,United States")]) .query(&[("deviceType", "desktop")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Coffee") params.Set("location", "Austin,Texas,United States") params.Set("deviceType", "desktop") u := "https://api.hasdata.com/scrape/google/short-videos?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------ | -------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Coffee | Yes | Search query term for retrieving short videos results. | | `location` | Austin,Texas,United States | No | Google canonical location for the search. | | `uule` | - | No | The encoded location parameter. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `lr` | - | No | The 'lr' parameter specifies the language of the websites to return results from. This parameter filters results based on the language of the web content. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `cr` | - | No | The country code for the country you want to limit the search to. | | `page` | - | No | Page number for paginated results, where 0 is the first page. | | `deviceType` | desktop | No | Specify the device type for the search. | # Google Flights API Source: https://docs.hasdata.com/apis/google-travel/flights The Google Flights API provides real-time access to structured flight search results, enabling users to find flights based on various criteria. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Flights API consumes **API Credits** from your account balance. * **Cost per request:** 15 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/flights' \ --data-urlencode 'departureId=LHR' \ --data-urlencode 'arrivalId=JFK' \ --data-urlencode 'outboundDate=2026-09-20' \ --data-urlencode 'returnDate=2026-09-27' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-flights \ --departure-id LHR \ --arrival-id JFK \ --outbound-date 2026-09-20 \ --return-date 2026-09-27 ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/flights', params: { departureId: 'LHR', arrivalId: 'JFK', outboundDate: '2026-09-20', returnDate: '2026-09-27' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/flights" querystring = {"departureId":"LHR","arrivalId":"JFK","outboundDate":"2026-09-20","returnDate":"2026-09-27"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "LHR", "arrivalId" => "JFK", "outboundDate" => "2026-09-20", "returnDate" => "2026-09-27", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/flights?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/flights") .newBuilder() .addQueryParameter("departureId", "LHR") .addQueryParameter("arrivalId", "JFK") .addQueryParameter("outboundDate", "2026-09-20") .addQueryParameter("returnDate", "2026-09-27") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["departureId"] = "LHR"; query["arrivalId"] = "JFK"; query["outboundDate"] = "2026-09-20"; query["returnDate"] = "2026-09-27"; var url = $"https://api.hasdata.com/scrape/google/flights?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/flights") params = { "departureId" => "LHR", "arrivalId" => "JFK", "outboundDate" => "2026-09-20", "returnDate" => "2026-09-27", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/flights") .query(&[("departureId", "LHR")]) .query(&[("arrivalId", "JFK")]) .query(&[("outboundDate", "2026-09-20")]) .query(&[("returnDate", "2026-09-27")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("departureId", "LHR") params.Set("arrivalId", "JFK") params.Set("outboundDate", "2026-09-20") params.Set("returnDate", "2026-09-27") u := "https://api.hasdata.com/scrape/google/flights?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | -------------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `departureId` | LHR | Yes | Specifies the departure airport code (IATA) or location kgmid.

- **IATA Code**: A 3-letter uppercase code (e.g., SFO for San Francisco, LHR for London Heathrow). Search on [IATA](https://www.iata.org/en/publications/directories/code-search).
- **Location kgmid**: A string starting with `/m/`, found in Wikidata under "Freebase ID" (e.g., `/m/02_286` for New York, NY).

Multiple values can be separated by commas (e.g., `JFK,LGA,/m/0hptm`).
| | `arrivalId` | JFK | Yes | Specifies the arrival airport code (IATA) or location kgmid.

- **IATA Code**: A 3-letter uppercase code (e.g., `SFO` for San Francisco, `LHR` for London Heathrow). Search on [IATA](https://www.iata.org/en/publications/directories/code-search).
- **Location kgmid**: A string starting with `/m/`, found in Wikidata under "Freebase ID" (e.g., `/m/02_286` for New York, NY).

Multiple values can be separated by commas (e.g., `JFK,LGA,/m/0hptm`).
| | `outboundDate` | 2026-09-20 | Yes | The outbound travel date in 'yyyy-MM-dd' format.
| | `returnDate` | 2026-09-27 | No | The return travel date in 'yyyy-MM-dd' format. Required when **type** is `roundTrip`.
| | `type` | - | No | Specifies the type of flight. Options:

- `roundTrip` (default)
- `oneWay`
- `multiCity` (requires `multiCityJson` for flight details)

For round trips, retrieve return flight details with a separate request using `departureToken`.
| | `multiCityJson` | - | No | This parameter specifies flight details for multi-city trips. It is a JSON string containing multiple flight objects. Each object must include the following fields:

- **departureId** – The departure airport code or location KGMID. Uses the same format as the main `departureId` parameter.
- **arrivalId** – The arrival airport code or location KGMID. Uses the same format as the main `arrivalId` parameter.
- **date** – The flight date. Uses the same format as the `outboundDate` parameter.
- **times** *(optional)* – The time range for the flight. Uses the same format as the `outboundTimes` parameter.
| | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `currency` | - | No | Parameter defines the currency of the returned prices | | `travelClass` | - | No | The travel class for the flight (Economy, Premium Economy, Business, or First).
| | `showHidden` | - | No | Indicates whether to include hidden options in the results.
| | `adults` | - | No | Number of adult passengers (>= 1 if specified).
| | `children` | - | No | Number of child passengers.
| | `infantsInSeat` | - | No | Number of infants occupying seats.
| | `infantsOnLap` | - | No | Number of infants sitting on an adult's lap.
| | `sortBy` | - | No | Sort the flight results based on price, departure time, arrival time, etc.
| | `stops` | - | No | Restrict the number of stops (layovers) in the flight itinerary.
| | `excludeAirlines` | - | No | A comma separated list of airline codes to exclude from results. You can search for airline codes on [IATA](https://www.iata.org/en/publications/directories/code-search). For example, `UA` is United Airlines.
| | `includeAirlines` | - | No | A comma separated list of airline codes to exclusively include in results. You can search for airline codes on [IATA](https://www.iata.org/en/publications/directories/code-search). For example, `UA` is United Airlines.

`excludeAirlines` and `includeAirlines` parameters can't be used together.
| | `bags` | - | No | Number of carry-on bags per passenger.
| | `maxPrice` | - | No | Maximum price limit for the flight search, in the selected currency.
| | `outboundTimes` | - | No | Set up to 4 time boundaries (2 for departure, 2 for arrival) to filter flights. Each number represents the start of an hour.

Examples:
- `6,20` → 6:00 AM - 9:00 PM departure
- `1,15` → 1:00 AM - 4:00 PM departure
- `7,18,2,21` → 7:00 AM - 9:00 PM departure, 2:00 AM - 10:00 PM arrival
| | `returnTimes` | - | No | Set up to 4 time boundaries (2 for departure, 2 for arrival) to filter return flights. Each number represents the start of an hour.

Examples:
- `6,20` → 6:00 AM - 9:00 PM departure
- `1,15` → 1:00 AM - 4:00 PM departure
- `7,18,2,21` → 7:00 AM - 9:00 PM departure, 2:00 AM - 10:00 PM arrival
| | `lessEmissions` | - | No | Prefer flight options with lower carbon emissions.
| | `layoverDuration` | - | No | Set the maximum layover duration in minutes to filter flights. For example, `120, 360` filters layovers between 2 hours and 6 hours, while `45, 180` allows layovers from 45 minutes to 3 hours.
| | `includeConnections` | - | No | A comma separated list of specific airports to allow as connections.
| | `excludeConnections` | - | No | A comma separated list of specific airports to exclude as connections.
| | `maxDuration` | - | No | The maximum total flight duration in minutes.
| | `deepSearch` | - | No | Enable deep search. Returns the same results as Google Flights in a browser, but takes longer to respond. Default is `false`.
| | `departureToken` | - | No | Used to select a flight and retrieve return flights for a round trip or the next leg of the itinerary for a multi-city trip.
| | `bookingToken` | - | No | Used to request booking options for selected flights. This token is found in the flight results and cannot be used with `departureToken`.
| # Google Hotels API Source: https://docs.hasdata.com/apis/google-travel/hotels The Google Hotels API provides real-time access to structured Google Hotels search results, including property listings, prices, ratings, amenities, and pagination. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Hotels API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/hotels' \ --data-urlencode 'q=Hotels in New York' \ --data-urlencode 'checkInDate=2026-09-20' \ --data-urlencode 'checkOutDate=2026-09-24' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/hotels', params: {q: 'Hotels in New York', checkInDate: '2026-09-20', checkOutDate: '2026-09-24'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/hotels" querystring = {"q":"Hotels in New York","checkInDate":"2026-09-20","checkOutDate":"2026-09-24"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Hotels in New York", "checkInDate" => "2026-09-20", "checkOutDate" => "2026-09-24", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/hotels?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/hotels") .newBuilder() .addQueryParameter("q", "Hotels in New York") .addQueryParameter("checkInDate", "2026-09-20") .addQueryParameter("checkOutDate", "2026-09-24") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Hotels in New York"; query["checkInDate"] = "2026-09-20"; query["checkOutDate"] = "2026-09-24"; var url = $"https://api.hasdata.com/scrape/google/hotels?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/hotels") params = { "q" => "Hotels in New York", "checkInDate" => "2026-09-20", "checkOutDate" => "2026-09-24", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/hotels") .query(&[("q", "Hotels in New York")]) .query(&[("checkInDate", "2026-09-20")]) .query(&[("checkOutDate", "2026-09-24")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Hotels in New York") params.Set("checkInDate", "2026-09-20") params.Set("checkOutDate", "2026-09-24") u := "https://api.hasdata.com/scrape/google/hotels?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------------ | ------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Hotels in New York | Yes | The search query for Google Hotels (e.g., a city, neighborhood, or hotel name).
| | `checkInDate` | 2026-09-20 | Yes | The check-in date in 'yyyy-MM-dd' format.
| | `checkOutDate` | 2026-09-24 | Yes | The check-out date in 'yyyy-MM-dd' format.
| | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `currency` | - | No | Parameter defines the currency of the returned prices | | `adults` | - | No | Number of adult guests (1-6).
| | `children` | - | No | Number of child guests (1-5). Total guests (adults + children) cannot exceed 6.
| | `childrenAges` | - | No | Comma-separated list of children ages (e.g., `5,8,12`). Must match the number of children.
| | `sortBy` | - | No | Sort hotel results. Options:

- `lowestPrice` — lowest price
- `highestRating` — highest rating
- `mostReviewed` — most reviewed
| | `minPrice` | - | No | Minimum price per night, in the selected currency.
| | `maxPrice` | - | No | Maximum price per night, in the selected currency.
| | `propertyType[]` | - | No | List of property types to filter by (e.g., `hotelResort,hotelMotel`).

Values prefixed `hotel*` apply when searching hotels (the default mode). Values prefixed `rental*` apply when `vacationRentals=true`.

The two sets are disjoint because Google Hotels exposes different property-type catalogs for each mode — pass values matching the mode you're querying.
| | `amenity[]` | - | No | List of amenities to filter by (e.g., `hotelFreeWifi,hotelPool`).

Values prefixed `hotel*` apply when searching hotels (the default mode). Values prefixed `rental*` apply when `vacationRentals=true`.

The two sets are disjoint because Google Hotels exposes different amenity catalogs for each mode — pass values matching the mode you're querying.
| | `rating` | - | No | Filter by minimum overall guest rating. Options:

- `threePointFivePlus` — 3.5 stars or higher
- `fourPlus` — 4.0 stars or higher
- `fourPointFivePlus` — 4.5 stars or higher
| | `brands` | - | No | Comma-separated list of brand IDs to filter by. Brand IDs are returned in the response under `brands` for the same query.
| | `hotelClass` | - | No | Comma-separated list of hotel star classes to include (e.g., `2,3,4,5`).
| | `freeCancellation` | - | No | Show only properties offering free cancellation.
| | `specialOffers` | - | No | Show only properties with special offers.
| | `ecoCertified` | - | No | Show only eco-certified properties.
| | `vacationRentals` | - | No | Search vacation rentals instead of hotels.
| | `bedrooms` | - | No | Minimum number of bedrooms (vacation rentals only).
| | `bathrooms` | - | No | Minimum number of bathrooms (vacation rentals only).
| | `nextPageToken` | - | No | Token to fetch the next page of hotel results. Returned in the `pagination` field of a previous response.
| | `propertyToken` | - | No | Token used to retrieve details for a specific property. Returned in each property in the results.
| # Google Trends API Source: https://docs.hasdata.com/apis/google-trends/search The Google Trends API provides real-time access to Google Trends data, offering insights into the popularity of search terms over time and across regions. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Google Trends API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google-trends/search' \ --data-urlencode 'q=Coffee' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-trends \ --q Coffee ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google-trends/search', params: {q: 'Coffee'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google-trends/search" querystring = {"q":"Coffee"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Coffee", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google-trends/search?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google-trends/search") .newBuilder() .addQueryParameter("q", "Coffee") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Coffee"; var url = $"https://api.hasdata.com/scrape/google-trends/search?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google-trends/search") params = { "q" => "Coffee", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google-trends/search") .query(&[("q", "Coffee")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Coffee") u := "https://api.hasdata.com/scrape/google-trends/search?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | Coffee | Yes | Specify the search term for which you want to retrieve trends data. | | `geo` | - | No | Specifies the location for the search. Defaults to Worldwide if not set or empty. | | `region` | - | No | Used to get more specific results when using "Interest by region" data type. Other data types do not accept this parameter. The default value depends on the geo location that is set.

Available options:
- `country`: Country
- `region`: Subregion
- `dma`: Metro
- `city`: City

Note: Not all region options will return results for every geo location.
| | `dataType` | - | No | Defines the type of search to perform.

Available options:
- `timeseries`: Interest over time (default). Accepts both single and multiple queries per search.
- `geoMap`: Interest by region. Accepts both single and multiple queries per search.
- `relatedTopics`: Related topics. Accepts only single query per search.
- `relatedQueries`: Related queries. Accepts only single query per search.
| | `tz` | - | No | Defines a time zone offset in minutes. The default value is 420 (Pacific Daylight Time (PDT): UTC-7). The valid range for this parameter is from -1439 to 1439.

To calculate the `tz` value for a specific time zone, you can use the time difference between UTC +0 and the desired time zone.

Examples:
- `420`: Pacific Daylight Time (PDT)
- `60`: Central European Time (CET)
- `-540`: Japan Standard Time
| | `cat` | - | No | Category of the search term. The default value is 0 ("All categories"). | | `gprop` | - | No | Sorts results by a specific property. The default property is Web Search (applied when the gprop parameter is not set or empty).

Available options:
- `images`: Image Search
- `news`: News Search
- `froogle`: Google Shopping
- `youtube`: YouTube Search
| | `date` | - | No | Defines a date range for the search. Available options:

- `now 1-H`: Past hour
- `now 4-H`: Past 4 hours
- `now 1-d`: Past day
- `now 7-d`: Past 7 days
- `today 1-m`: Past 30 days
- `today 3-m`: Past 90 days
- `today 12-m`: Past 12 months
- `today 5-y`: Past 5 years
- `all`: 2004 - present

You can also specify a custom date range using one of the following formats:

- `yyyy-mm-dd yyyy-mm-dd` - (e.g. 2021-10-15 2022-05-25) for dates from 2004 to present.
- `yyyy-mm-ddThh yyyy-mm-ddThh` - (e.g. 2022-05-19T10 2022-05-24T22) for dates with hours within a week range. The hours will be calculated based on the tz (time zone) parameter.
| # Indeed Job Scraper API Source: https://docs.hasdata.com/apis/indeed/job The Indeed Job Scraper API allows you to retrieve detailed information about a specific job listing based on the provided vacancy URL. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Indeed. Indeed is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Indeed Job Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/indeed/job' \ --data-urlencode 'url=https://www.indeed.com/viewjob?jk=3c916f0d7f870c71' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata indeed-job \ --url 'https://www.indeed.com/viewjob?jk=3c916f0d7f870c71' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/indeed/job', params: {url: 'https://www.indeed.com/viewjob?jk=3c916f0d7f870c71'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/indeed/job" querystring = {"url":"https://www.indeed.com/viewjob?jk=3c916f0d7f870c71"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "https://www.indeed.com/viewjob?jk=3c916f0d7f870c71", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/indeed/job?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/indeed/job") .newBuilder() .addQueryParameter("url", "https://www.indeed.com/viewjob?jk=3c916f0d7f870c71") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["url"] = "https://www.indeed.com/viewjob?jk=3c916f0d7f870c71"; var url = $"https://api.hasdata.com/scrape/indeed/job?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/indeed/job") params = { "url" => "https://www.indeed.com/viewjob?jk=3c916f0d7f870c71", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/indeed/job") .query(&[("url", "https://www.indeed.com/viewjob?jk=3c916f0d7f870c71")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("url", "https://www.indeed.com/viewjob?jk=3c916f0d7f870c71") u := "https://api.hasdata.com/scrape/indeed/job?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | -------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------- | | `url` | [https://www.indeed.com/viewjob?jk=3c916f0d7f870c71](https://www.indeed.com/viewjob?jk=3c916f0d7f870c71) | Yes | The URL of the job vacancy to retrieve details for. | # Indeed Listing Scraper API Source: https://docs.hasdata.com/apis/indeed/listing The Indeed Listing Scraper API allows you to retrieve job listings from Indeed based on various search parameters. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Indeed. Indeed is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Indeed Listing Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/indeed/listing' \ --data-urlencode 'keyword=software engineer' \ --data-urlencode 'location=New York, NY' \ --data-urlencode 'sort=date' \ --data-urlencode 'domain=www.indeed.com' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata indeed-listing \ --keyword 'software engineer' \ --location 'New York, NY' \ --sort date \ --domain www.indeed.com ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/indeed/listing', params: { keyword: 'software engineer', location: 'New York, NY', sort: 'date', domain: 'www.indeed.com' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/indeed/listing" querystring = {"keyword":"software engineer","location":"New York, NY","sort":"date","domain":"www.indeed.com"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "software engineer", "location" => "New York, NY", "sort" => "date", "domain" => "www.indeed.com", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/indeed/listing?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/indeed/listing") .newBuilder() .addQueryParameter("keyword", "software engineer") .addQueryParameter("location", "New York, NY") .addQueryParameter("sort", "date") .addQueryParameter("domain", "www.indeed.com") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["keyword"] = "software engineer"; query["location"] = "New York, NY"; query["sort"] = "date"; query["domain"] = "www.indeed.com"; var url = $"https://api.hasdata.com/scrape/indeed/listing?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/indeed/listing") params = { "keyword" => "software engineer", "location" => "New York, NY", "sort" => "date", "domain" => "www.indeed.com", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/indeed/listing") .query(&[("keyword", "software engineer")]) .query(&[("location", "New York, NY")]) .query(&[("sort", "date")]) .query(&[("domain", "www.indeed.com")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("keyword", "software engineer") params.Set("location", "New York, NY") params.Set("sort", "date") params.Set("domain", "www.indeed.com") u := "https://api.hasdata.com/scrape/indeed/listing?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------- | --------------------------------------- | -------- | --------------------------------------------------------- | | `keyword` | software engineer | Yes | The keyword used to search for job listings. | | `location` | New York, NY | Yes | The location to search for job listings. | | `sort` | date | No | The sorting option for the search results. | | `domain` | [www.indeed.com](http://www.indeed.com) | No | The domain of the Indeed site (optional). | | `start` | - | No | The starting index of the results to retrieve (optional). | # Instagram Profile Scraper API Source: https://docs.hasdata.com/apis/instagram/profile The Instagram Profile Scraper API lets you retrieve public profile information for a specific Instagram account using its handle. It returns data such as bio, followers, following, posts count, and other visible profile details. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Instagram. Instagram is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Instagram Profile Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/instagram/profile' \ --data-urlencode 'handle=hasdatadotcom' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata instagram-profile \ --handle hasdatadotcom ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/instagram/profile', params: {handle: 'hasdatadotcom'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/instagram/profile" querystring = {"handle":"hasdatadotcom"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "hasdatadotcom", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/instagram/profile?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/instagram/profile") .newBuilder() .addQueryParameter("handle", "hasdatadotcom") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["handle"] = "hasdatadotcom"; var url = $"https://api.hasdata.com/scrape/instagram/profile?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/instagram/profile") params = { "handle" => "hasdatadotcom", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/instagram/profile") .query(&[("handle", "hasdatadotcom")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("handle", "hasdatadotcom") u := "https://api.hasdata.com/scrape/instagram/profile?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | ------------- | -------- | --------------------------------------------------------------------------------- | | `handle` | hasdatadotcom | Yes | The Instagram username of the profile you want to scrape, without the `@` symbol. | # Redfin Listing Scraper API Source: https://docs.hasdata.com/apis/redfin/listing The Redfin Listing Scraper API allows you to retrieve real estate listings from Redfin based on various search parameters. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Redfin. Redfin is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Redfin Listing Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/redfin/listing' \ --data-urlencode 'keyword=33321' \ --data-urlencode 'type=forSale' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata redfin-listing \ --keyword 33321 \ --type forSale ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/redfin/listing', params: {keyword: '33321', type: 'forSale'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/redfin/listing" querystring = {"keyword":"33321","type":"forSale"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "33321", "type" => "forSale", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/redfin/listing?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/redfin/listing") .newBuilder() .addQueryParameter("keyword", "33321") .addQueryParameter("type", "forSale") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["keyword"] = "33321"; query["type"] = "forSale"; var url = $"https://api.hasdata.com/scrape/redfin/listing?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/redfin/listing") params = { "keyword" => "33321", "type" => "forSale", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/redfin/listing") .query(&[("keyword", "33321")]) .query(&[("type", "forSale")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("keyword", "33321") params.Set("type", "forSale") u := "https://api.hasdata.com/scrape/redfin/listing?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------------------------------ | ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `keyword` | 33321 | Yes | The location to search for listings. Accepts a zipcode (`33321`), a city (`Austin` or `Austin, TX`), a neighborhood (`East Austin`), a school (`BASIS Austin`), a school district (`Austin Independent School District`), an apartment building by its name (`Maizon Brickell`), or a full street address (`5805 Woodview Ave, Austin, TX 78756`), including a single unit (`221 SW 12th St Unit 1716, Miami, FL`). An address or a building returns a single property card instead of a list of listings, and the `type` parameter does not apply to it. | | `type` | forSale | Yes | The type of listing. | | `sort` | - | No | The sorting option for the search results. | | `price[min]` | - | No | The minimum price of the listing. | | `price[max]` | - | No | The maximum price of the listing. | | `monthlyPayment[min]` | - | No | The minimum monthly payment. | | `monthlyPayment[max]` | - | No | The maximum monthly payment. | | `monthlyPayment[interestRate]` | - | No | The mortgage interest rate (percent) used to calculate the monthly payment. | | `monthlyPayment[insuranceRate]` | - | No | The home insurance rate (percent) used to calculate the monthly payment. | | `monthlyPayment[downPaymentPercent]` | - | No | The down payment as a percentage of the home price. | | `monthlyPayment[downPaymentAmount]` | - | No | The down payment as an absolute amount. | | `monthlyPayment[mortgageTerm]` | - | No | The mortgage term used to calculate the monthly payment. | | `cost[hoa]` | - | No | The maximum monthly Homeowners Association (HOA) fee. | | `cost[pricePerSqft][min]` | - | No | The minimum price per square foot. | | `cost[pricePerSqft][max]` | - | No | The maximum price per square foot. | | `cost[excludeLandLeases]` | - | No | If set to true, listings with land leases will be excluded. | | `cost[maxPropertyTaxPerYear]` | - | No | The maximum property tax per year. | | `cost[acceptedFinancing]` | - | No | The accepted financing type. | | `cost[priceReduced]` | - | No | Filter listings by when the price was reduced. | | `homeTypes[]` | - | No | An array of home types to filter the listings. Allowed values depend on the listing `type`. | | `beds[min]` | - | No | The minimum number of bedrooms. | | `beds[max]` | - | No | The maximum number of bedrooms. | | `baths` | - | No | The minimum number of bathrooms. | | `forSaleSquareFeet[min]` | - | No | The minimum square footage for for-sale listings. | | `forSaleSquareFeet[max]` | - | No | The maximum square footage for for-sale listings. | | `forRentSquareFootage[min]` | - | No | The minimum square footage for for-rent listings. | | `forRentSquareFootage[max]` | - | No | The maximum square footage for for-rent listings. | | `lotSize[min]` | - | No | The minimum lot size. | | `lotSize[max]` | - | No | The maximum lot size. | | `yearBuilt[min]` | - | No | The minimum year the property was built. | | `yearBuilt[max]` | - | No | The maximum year the property was built. | | `stories[min]` | - | No | The minimum number of stories. | | `stories[max]` | - | No | The maximum number of stories. | | `listingType[category][]` | - | No | An array of listing categories. | | `listingType[excludeShortSales]` | - | No | If set to true, short sales will be excluded. | | `listingType[redfinListingsOnly]` | - | No | If set to true, only Redfin-listed properties will be included. | | `statusOptions[]` | - | No | An array of listing statuses. | | `onlyWithDealOrPromotion` | - | No | If set to true, only listings with a deal or promotion will be included. | | `exclude55PlusCommunities` | - | No | If set to true, 55+ communities will be excluded. | | `timeOnRedfin` | - | No | How long the listing has been on Redfin. | | `soldWithinOption` | - | No | Filter sold listings by how recently they were sold. | | `moveInDate` | - | No | The desired move-in date in MM/DD/YYYY format. | | `openHouseAndTour[openHouse]` | - | No | Filter listings with an open house. | | `openHouseAndTour[videoTour]` | - | No | If set to true, only listings with a video tour will be included. | | `homeFeatures[options][]` | - | No | An array of home feature flags to filter the listings. | | `homeFeatures[garageSpotsMin]` | - | No | The minimum number of garage spots. | | `homeFeatures[poolType]` | - | No | The type of pool. | | `homeFeatures[basement]` | - | No | The basement type. | | `homeFeatures[keywordSearch]` | - | No | A free-text keyword search applied to listing descriptions. | | `rentalAmenities[]` | - | No | An array of rental amenities to filter the listings. | | `rentalOtherTerms[]` | - | No | An array of additional rental terms. | | `pets[]` | - | No | An array of pet types allowed. | | `schools[greatSchoolRating]` | - | No | The minimum GreatSchools rating (1-10). | | `schools[schoolType][]` | - | No | An array of school types. | | `schools[includeUnratedSchools]` | - | No | If set to true, unrated schools will be included. | | `transportScores[walkScore]` | - | No | The minimum walk score (1-100). | | `transportScores[transitScore]` | - | No | The minimum transit score (1-100). | | `transportScores[bikeScore]` | - | No | The minimum bike score (1-100). | | `page` | - | No | The page number of the results to retrieve. | # Redfin Property Scraper API Source: https://docs.hasdata.com/apis/redfin/property The Redfin Property Scraper API allows users to retrieve detailed information about a specific property using its URL. It provides details such as property features, price, and agent contacts. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Redfin. Redfin is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Redfin Property Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/redfin/property' \ --data-urlencode 'url=https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata redfin-property \ --url 'https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/redfin/property', params: { url: 'https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/redfin/property" querystring = {"url":"https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/redfin/property?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/redfin/property") .newBuilder() .addQueryParameter("url", "https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["url"] = "https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628"; var url = $"https://api.hasdata.com/scrape/redfin/property?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/redfin/property") params = { "url" => "https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/redfin/property") .query(&[("url", "https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("url", "https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628") u := "https://api.hasdata.com/scrape/redfin/property?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ----------------------------------------------------------------------- | | `url` | [https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628](https://www.redfin.com/IL/Chicago/1322-S-Prairie-Ave-60605/unit-1106/home/12694628) | Yes | The URL of the property on Redfin. Must be a valid Redfin property URL. | # Shopify Collections Scraper API Source: https://docs.hasdata.com/apis/shopify/collections The Shopify Collections Scraper API allows users to retrieve information about collections in a Shopify store, including details such as title, handle, description, and image. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Shopify. Shopify is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Shopify Collections Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/shopify/collections' \ --data-urlencode 'url=https://b2bdemoexperience.myshopify.com' \ --data-urlencode 'limit=10' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata shopify-collections \ --url 'https://b2bdemoexperience.myshopify.com' \ --limit 10 ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/shopify/collections', params: {url: 'https://b2bdemoexperience.myshopify.com', limit: '10'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/shopify/collections" querystring = {"url":"https://b2bdemoexperience.myshopify.com","limit":"10"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "https://b2bdemoexperience.myshopify.com", "limit" => "10", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/shopify/collections?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/shopify/collections") .newBuilder() .addQueryParameter("url", "https://b2bdemoexperience.myshopify.com") .addQueryParameter("limit", "10") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["url"] = "https://b2bdemoexperience.myshopify.com"; query["limit"] = "10"; var url = $"https://api.hasdata.com/scrape/shopify/collections?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/shopify/collections") params = { "url" => "https://b2bdemoexperience.myshopify.com", "limit" => "10", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/shopify/collections") .query(&[("url", "https://b2bdemoexperience.myshopify.com")]) .query(&[("limit", "10")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("url", "https://b2bdemoexperience.myshopify.com") params.Set("limit", "10") u := "https://api.hasdata.com/scrape/shopify/collections?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | ---------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- | | `url` | [https://b2bdemoexperience.myshopify.com](https://b2bdemoexperience.myshopify.com) | Yes | The URL of the Shopify store. For example, '[https://b2bdemoexperience.myshopify.com](https://b2bdemoexperience.myshopify.com)'. | | `limit` | 10 | No | The maximum number of collections to retrieve. Must be between 1 and 250. | | `page` | - | No | The page number of the results to retrieve. Must be a positive integer. | # Shopify Products Scraper API Source: https://docs.hasdata.com/apis/shopify/products The Shopify Products Scraper API allows users to retrieve product information from a Shopify store using the provided URL, with options to limit the results and filter by collection. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Shopify. Shopify is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Shopify Products Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/shopify/products' \ --data-urlencode 'url=https://b2bdemoexperience.myshopify.com' \ --data-urlencode 'limit=1' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata shopify-products \ --url 'https://b2bdemoexperience.myshopify.com' \ --limit 1 ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/shopify/products', params: {url: 'https://b2bdemoexperience.myshopify.com', limit: '1'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/shopify/products" querystring = {"url":"https://b2bdemoexperience.myshopify.com","limit":"1"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "https://b2bdemoexperience.myshopify.com", "limit" => "1", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/shopify/products?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/shopify/products") .newBuilder() .addQueryParameter("url", "https://b2bdemoexperience.myshopify.com") .addQueryParameter("limit", "1") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["url"] = "https://b2bdemoexperience.myshopify.com"; query["limit"] = "1"; var url = $"https://api.hasdata.com/scrape/shopify/products?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/shopify/products") params = { "url" => "https://b2bdemoexperience.myshopify.com", "limit" => "1", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/shopify/products") .query(&[("url", "https://b2bdemoexperience.myshopify.com")]) .query(&[("limit", "1")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("url", "https://b2bdemoexperience.myshopify.com") params.Set("limit", "1") u := "https://api.hasdata.com/scrape/shopify/products?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------ | ---------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- | | `url` | [https://b2bdemoexperience.myshopify.com](https://b2bdemoexperience.myshopify.com) | Yes | The URL of the Shopify store. For example, '[https://b2bdemoexperience.myshopify.com](https://b2bdemoexperience.myshopify.com)'. | | `limit` | 1 | No | The maximum number of products to retrieve. Must be between 1 and 250. | | `page` | - | No | The page number of the results to retrieve. Must be a positive integer. | | `collection` | - | No | The handle of the collection to filter the products. Provide the collection handle as a string. | # TikTok Comments Scraper API Source: https://docs.hasdata.com/apis/tiktok/comments The TikTok Comments Scraper API returns the comments on a public TikTok video, or the replies to a specific comment. Each comment includes its text, like count, timestamp, reply count, and author (with links to the author's profile and posts). Results are paginated with a token. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by TikTok. TikTok is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the TikTok Comments Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/tiktok/comments' \ --data-urlencode 'videoId=7667749432279977230' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/tiktok/comments', params: {videoId: '7667749432279977230'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/tiktok/comments" querystring = {"videoId":"7667749432279977230"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "7667749432279977230", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/tiktok/comments?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/tiktok/comments") .newBuilder() .addQueryParameter("videoId", "7667749432279977230") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["videoId"] = "7667749432279977230"; var url = $"https://api.hasdata.com/scrape/tiktok/comments?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/tiktok/comments") params = { "videoId" => "7667749432279977230", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/tiktok/comments") .query(&[("videoId", "7667749432279977230")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("videoId", "7667749432279977230") u := "https://api.hasdata.com/scrape/tiktok/comments?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | ------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ | | `videoId` | 7667749432279977230 | Yes | The numeric id of the video (the number after `/video/` in a TikTok URL). | | `commentId` | - | No | When provided, returns the replies to this comment instead of the video's top-level comments. | | `nextPageToken` | - | No | Defines the next page token. Use the `nextPageToken` value returned by the previous response. Omit it to fetch the first page. | # TikTok Posts Scraper API Source: https://docs.hasdata.com/apis/tiktok/posts The TikTok Posts Scraper API lets you retrieve the videos of a public TikTok account using its handle. It returns each video with description, hashtags, mentions, like/comment/share/play counts, cover and playable video URLs, music, and timestamp. Results are paginated with a token — pass the `nextPageToken` from a response to fetch the next page. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by TikTok. TikTok is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the TikTok Posts Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/tiktok/posts' \ --data-urlencode 'handle=tiktok' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/tiktok/posts', params: {handle: 'tiktok'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/tiktok/posts" querystring = {"handle":"tiktok"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "tiktok", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/tiktok/posts?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/tiktok/posts") .newBuilder() .addQueryParameter("handle", "tiktok") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["handle"] = "tiktok"; var url = $"https://api.hasdata.com/scrape/tiktok/posts?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/tiktok/posts") params = { "handle" => "tiktok", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/tiktok/posts") .query(&[("handle", "tiktok")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("handle", "tiktok") u := "https://api.hasdata.com/scrape/tiktok/posts?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | ------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `handle` | tiktok | Yes | The TikTok username of the account whose videos you want to scrape, with or without the `@` symbol. | | `nextPageToken` | - | No | Defines the next page token. It is used for retrieving the next page of results. Use the `nextPageToken` value returned by the previous response. Omit it to fetch the first page. | # TikTok Profile Scraper API Source: https://docs.hasdata.com/apis/tiktok/profile The TikTok Profile Scraper API lets you retrieve public profile information for a specific TikTok account using its handle. It returns data such as nickname, bio, followers, likes, videos count, and other visible profile details. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by TikTok. TikTok is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the TikTok Profile Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/tiktok/profile' \ --data-urlencode 'handle=nasa' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/tiktok/profile', params: {handle: 'nasa'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/tiktok/profile" querystring = {"handle":"nasa"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "nasa", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/tiktok/profile?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/tiktok/profile") .newBuilder() .addQueryParameter("handle", "nasa") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["handle"] = "nasa"; var url = $"https://api.hasdata.com/scrape/tiktok/profile?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/tiktok/profile") params = { "handle" => "nasa", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/tiktok/profile") .query(&[("handle", "nasa")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("handle", "nasa") u := "https://api.hasdata.com/scrape/tiktok/profile?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | ------------- | -------- | -------------------------------------------------------------------------------------- | | `handle` | nasa | Yes | The TikTok username of the profile you want to scrape, with or without the `@` symbol. | # TikTok Search Scraper API Source: https://docs.hasdata.com/apis/tiktok/search The TikTok Search Scraper API lets you search TikTok by keyword for videos or users. Video results include description, hashtags, stats, cover and playable URLs, and author info; user results include nickname, bio, avatar, verified flag, and follower count. Results are paginated with a token. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by TikTok. TikTok is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the TikTok Search Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/tiktok/search' \ --data-urlencode 'keyword=dance' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/tiktok/search', params: {keyword: 'dance'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/tiktok/search" querystring = {"keyword":"dance"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "dance", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/tiktok/search?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/tiktok/search") .newBuilder() .addQueryParameter("keyword", "dance") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["keyword"] = "dance"; var url = $"https://api.hasdata.com/scrape/tiktok/search?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/tiktok/search") params = { "keyword" => "dance", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/tiktok/search") .query(&[("keyword", "dance")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("keyword", "dance") u := "https://api.hasdata.com/scrape/tiktok/search?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ | | `keyword` | dance | Yes | The phrase to search for on TikTok. | | `type` | - | No | What to search for — videos or users. Defaults to video. | | `nextPageToken` | - | No | Defines the next page token. Use the `nextPageToken` value returned by the previous response. Omit it to fetch the first page. | # Walmart Product Scraper API Source: https://docs.hasdata.com/apis/walmart/product The Walmart Product Scraper API returns the full detail page of a single Walmart item, and optionally the offers of other sellers competing for the same product. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Walmart. Walmart is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Walmart Product Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/walmart/product' \ --data-urlencode 'itemId=14977205582' \ --data-urlencode 'url=https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582' \ --data-urlencode 'language=en' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/walmart/product', params: { itemId: '14977205582', url: 'https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582', language: 'en' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/walmart/product" querystring = {"itemId":"14977205582","url":"https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582","language":"en"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "14977205582", "url" => "https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582", "language" => "en", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/walmart/product?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/walmart/product") .newBuilder() .addQueryParameter("itemId", "14977205582") .addQueryParameter("url", "https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582") .addQueryParameter("language", "en") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["itemId"] = "14977205582"; query["url"] = "https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582"; query["language"] = "en"; var url = $"https://api.hasdata.com/scrape/walmart/product?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/walmart/product") params = { "itemId" => "14977205582", "url" => "https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582", "language" => "en", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/walmart/product") .query(&[("itemId", "14977205582")]) .query(&[("url", "https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582")]) .query(&[("language", "en")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("itemId", "14977205582") params.Set("url", "https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582") params.Set("language", "en") u := "https://api.hasdata.com/scrape/walmart/product?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `itemId` | 14977205582 | No | Walmart item id, taken from a product URL or from the id field of the Walmart Search API response. On walmart.com it is numeric (for example 14977205582), on walmart.ca an alphanumeric code (for example 6NZMJ5CW6MH2). Required unless url is provided. | | `url` | [https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582](https://www.walmart.com/ip/Samsung-Galaxy-S25-Ultra-256GB-Unlocked-Android-Cell-Phone-with-200MP-Camera-Titanium-Blue/14977205582) | No | A full Walmart product URL to scrape as is. When provided, it overrides itemId and the storefront is taken from the URL itself. Required unless itemId is provided. | | `domain` | - | No | Walmart storefront the item belongs to. Each storefront has its own catalog, item ids, prices and currency, so an id from one storefront does not resolve on another. Ignored when url is provided. Default is walmart.com. | | `language` | en | No | Language of the product details. Availability depends on the storefront - walmart.com serves en and es, walmart.ca serves en and fr. A language the storefront does not support falls back to its default. | | `otherOffers` | - | No | Also collect the offers of other sellers competing for this item - each seller name, storefront, price, condition, shipping cost, delivery date and return policy. This takes an extra request to Walmart and costs 5 credits on top of the base 10, whether or not the item turns out to have competing sellers. How many competitors the item advertises, and the cheapest competing price, are returned in the otherOffers block whether the switch is on or off, so it can be left off until the count shows there is something to collect. Default is false. | # Walmart Reviews Scraper API Source: https://docs.hasdata.com/apis/walmart/reviews The Walmart Reviews Scraper API returns the customer reviews of a single Walmart item, ten a page, with the sorting and filtering the product page itself offers. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Walmart. Walmart is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Walmart Reviews Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/walmart/reviews' \ --data-urlencode 'itemId=1028936148' \ --data-urlencode 'url=https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148' \ --data-urlencode 'language=en' \ --data-urlencode 'page=1' \ --data-urlencode 'sort=mostRelevant' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/walmart/reviews', params: { itemId: '1028936148', url: 'https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148', language: 'en', page: '1', sort: 'mostRelevant' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/walmart/reviews" querystring = {"itemId":"1028936148","url":"https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148","language":"en","page":"1","sort":"mostRelevant"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "1028936148", "url" => "https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148", "language" => "en", "page" => "1", "sort" => "mostRelevant", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/walmart/reviews?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/walmart/reviews") .newBuilder() .addQueryParameter("itemId", "1028936148") .addQueryParameter("url", "https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148") .addQueryParameter("language", "en") .addQueryParameter("page", "1") .addQueryParameter("sort", "mostRelevant") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["itemId"] = "1028936148"; query["url"] = "https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148"; query["language"] = "en"; query["page"] = "1"; query["sort"] = "mostRelevant"; var url = $"https://api.hasdata.com/scrape/walmart/reviews?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/walmart/reviews") params = { "itemId" => "1028936148", "url" => "https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148", "language" => "en", "page" => "1", "sort" => "mostRelevant", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/walmart/reviews") .query(&[("itemId", "1028936148")]) .query(&[("url", "https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148")]) .query(&[("language", "en")]) .query(&[("page", "1")]) .query(&[("sort", "mostRelevant")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("itemId", "1028936148") params.Set("url", "https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148") params.Set("language", "en") params.Set("page", "1") params.Set("sort", "mostRelevant") u := "https://api.hasdata.com/scrape/walmart/reviews?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `itemId` | 1028936148 | No | Walmart item id, taken from a product URL or from the id field of the Walmart Search API response. On walmart.com it is numeric (for example 14977205582), on walmart.ca an alphanumeric code (for example 6NZMJ5CW6MH2). Required unless url is provided. | | `url` | [https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148](https://www.walmart.com/ip/Restored-Apple-iPhone-14-Carrier-Unlocked-128-GB-Starlight-MPUN3LL-A-Refurbished/1028936148) | No | A full Walmart product URL whose reviews to scrape. When provided, it overrides itemId and the storefront is taken from the URL itself. Required unless itemId is provided. | | `domain` | - | No | Walmart storefront the item belongs to. Each storefront has its own catalog, item ids and review pool, so an id from one storefront does not resolve on another. Ignored when url is provided. Default is walmart.com. | | `language` | en | No | Language of the review page. Availability depends on the storefront - walmart.com serves en and es, walmart.ca serves en and fr. A language the storefront does not support falls back to its default. Reviews themselves are returned in the language their author wrote them in. | | `page` | 1 | No | Page of reviews to return, ten reviews a page. The response reports the last available page in pagination.totalPages, and the next one in pagination.nextPage. Note that only reviews carrying written text are paginated, so the ceiling follows reviewsInformation.totalReviews rather than the larger totalRatings. Default is 1. | | `sort` | mostRelevant | No | Order of the returned reviews, named as the Walmart review page names it. Default is mostRelevant. | | `rating` | - | No | Return only reviews carrying this star rating. The filters block of the response lists the ratings this item actually has, with a review count for each. | | `aspectId` | - | No | Return only reviews mentioning one topic, given as its id. The topics differ per product - a phone has Battery Life or Display, a coffee has Flavor or Aroma - so take the id from the Frequent mentions group of the filters block in the response rather than guessing it. | | `condition` | - | No | Return only reviews written about one item condition, given as its code. Applies to items sold in several conditions, such as new and restored. Take the code from the Condition group of the filters block in the response. | | `verifiedPurchasesOnly` | - | No | Return only reviews left by customers whose purchase Walmart confirmed. Narrows the pool considerably, since most reviews are unverified or syndicated from the manufacturer. | # Walmart Search Scraper API Source: https://docs.hasdata.com/apis/walmart/search The Walmart Search Scraper API allows users to get search results from Walmart based on the specified query, category and storefront. This API enables searching for products on Walmart. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Walmart. Walmart is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Walmart Search Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/walmart/search' \ --data-urlencode 'q=coffee' \ --data-urlencode 'language=en' \ --data-urlencode 'sort=bestMatch' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/walmart/search', params: {q: 'coffee', language: 'en', sort: 'bestMatch'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/walmart/search" querystring = {"q":"coffee","language":"en","sort":"bestMatch"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "coffee", "language" => "en", "sort" => "bestMatch", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/walmart/search?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/walmart/search") .newBuilder() .addQueryParameter("q", "coffee") .addQueryParameter("language", "en") .addQueryParameter("sort", "bestMatch") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "coffee"; query["language"] = "en"; query["sort"] = "bestMatch"; var url = $"https://api.hasdata.com/scrape/walmart/search?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/walmart/search") params = { "q" => "coffee", "language" => "en", "sort" => "bestMatch", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/walmart/search") .query(&[("q", "coffee")]) .query(&[("language", "en")]) .query(&[("sort", "bestMatch")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "coffee") params.Set("language", "en") params.Set("sort", "bestMatch") u := "https://api.hasdata.com/scrape/walmart/search?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | | | -------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | ----------------------- | | `q` | coffee | No | The search term for which to get the search results. It can be omitted only when catId is provided, to browse a whole category instead of searching. | | | | `catId` | - | No | Walmart category id, taken from a category URL (for example 976759\_1086446\_1229651). Combine it with q to search inside a category, or send it alone to browse the whole category. Required unless q is provided. | | | | `domain` | - | No | Walmart storefront to search. Each storefront has its own catalog, prices and currency. Default is walmart.com. | | | | `language` | en | No | Language of the results. Availability depends on the storefront - walmart.com serves en and es, walmart.ca serves en and fr. A language the storefront does not support falls back to its default. | | | | `sort` | bestMatch | No | The sorting option for the search results. | | | | `url` | - | No | A full Walmart search or category URL to scrape as is. When provided, it overrides q, catId and the other search parameters, and the storefront is taken from the URL itself. | | | | `page` | - | No | Page number for pagination (e.g., 1 for the first page, 2 for the second page, etc.). Walmart stops serving results after roughly page 10, returning an empty page beyond that. | | | | `minPrice` | - | No | Lower bound of the price range, in the storefront currency. | | | | `maxPrice` | - | No | Upper bound of the price range, in the storefront currency. | | | | `deliveryType` | - | No | Keep only the products available with the selected fulfillment method. | | | | `facet` | - | No | Walmart filter in the name:value form, for example brand:Great Value. Every value available for a query is listed in the facets block of the response, each one carrying the exact string to send back here, so a first unfiltered request tells you what can be filtered on. Combine several filters with a double pipe: brand:Great Value | | retailer\_type:Walmart. | # Web Scraping API Parameters Source: https://docs.hasdata.com/apis/web-scraping-api/api-params This page lists all parameters for the **Web Scraping API**. Send a POST request to `https://api.hasdata.com/scrape/web` with a JSON body using the fields below. ## Basic Configuration The URL of the page to scrape. Must be a valid absolute URI (e.g. `https://example.com`). ## Proxy Settings Type of proxy to use. Options: `datacenter`, `residential`. Required if you're targeting geo-restricted or bot-protected content. [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code for proxy location (e.g. `US`, `DE`, `IN`). ## Data Extraction CSS selectors for field-level extraction. Example: `{ "title": "h1", "link": "a @href" }`. Structured AI rules for LLM-based extraction. Supports types: `string`, `number`, `boolean`, `list`, `item`. Example: ```json theme={null} { "company": { "description": "Company name", "type": "string" }, "email": { "type": "string" }, "founded": { "type": "number" }, "isHiring": { "type": "boolean" } } ``` To learn more, see [LLM Extraction](/apis/web-scraping-api/llm-extraction). Capture a screenshot of the page. Extract all email addresses found in the page content. Extract all hyperlinks (``) from the page. ## Timing Delay (in milliseconds) after page load before scraping. Max: 30000. CSS selector to wait for before scraping begins. Example: `.product-listing` ## Resource Control Block loading of images and stylesheets. Block common ad scripts and tracking pixels. Block any network requests containing these substrings or domains. Example: `["googleanalytics", "doubleclick"]` ## JavaScript Options Enable JavaScript rendering (required for SPAs or dynamic content). List of JavaScript actions to run on the page (click, scroll, wait, evaluate, etc.). Example: ```json theme={null} [ { "click": "#buttonId" }, { "fill": [".text_input", "value"] } ] ``` To learn more, see [Page Interactions](/apis/web-scraping-api/features/page-interactions). ## Advanced Settings Custom headers to include in the request. Example: `{ "User-Agent": "custom-agent" }`. To learn more, see [Custom Headers and Cookies](/apis/web-scraping-api/features/custom-headers-and-cookies). Response format(s). Options: `html`, `text`, `markdown`, `json`. Multiple formats allowed. # Batch Scrape Source: https://docs.hasdata.com/apis/web-scraping-api/batch-scrape Use **Batch Scraping** to submit up to **10,000 URLs** in a single API call. This is useful when you need to extract the **same type of data** from a large number of pages — for example, scraping product pages or company profiles at scale. Batch Scrape works by sending an array of requests under the `requests` field. ## When to Use Batch Scraping * Extracting titles, authors, and publish dates from a list of blog or news article URLs * Running `aiExtractRules` across a set of company websites to collect structured data like founding year, services, and contact info * Gathering legal notices or disclaimers from the footer pages of 5,000+ policy URLs ## Submit a Batch Scrape Job ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrape/batch/web' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"requests":[{"url":"https://hasdata.com","outputFormat":["text","html"],"aiExtractRules":{"company":{"type":"string"},"email":{"type":"string"},"yearFounded":{"type":"number"},"isHiring":{"type":"boolean"}}},{"url":"https://example.com","outputFormat":["text","html"],"aiExtractRules":{"company":{"type":"string"},"email":{"type":"string"},"yearFounded":{"type":"number"},"isHiring":{"type":"boolean"}}}]}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrape/batch/web', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { requests: [ { url: 'https://hasdata.com', outputFormat: ['text', 'html'], aiExtractRules: { company: {type: 'string'}, email: {type: 'string'}, yearFounded: {type: 'number'}, isHiring: {type: 'boolean'} } }, { url: 'https://example.com', outputFormat: ['text', 'html'], aiExtractRules: { company: {type: 'string'}, email: {type: 'string'}, yearFounded: {type: 'number'}, isHiring: {type: 'boolean'} } } ] } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/batch/web" payload = { "requests": [ { "url": "https://hasdata.com", "outputFormat": ["text", "html"], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } }, { "url": "https://example.com", "outputFormat": ["text", "html"], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } } ] } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} [["url" => "https://hasdata.com", "outputFormat" => ["text", "html"], "aiExtractRules" => ["company" => ["type" => "string"], "email" => ["type" => "string"], "yearFounded" => ["type" => "number"], "isHiring" => ["type" => "boolean"]]], ["url" => "https://example.com", "outputFormat" => ["text", "html"], "aiExtractRules" => ["company" => ["type" => "string"], "email" => ["type" => "string"], "yearFounded" => ["type" => "number"], "isHiring" => ["type" => "boolean"]]]], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/batch/web", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "requests": [ { "url": "https://hasdata.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } }, { "url": "https://example.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } } ] } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/batch/web") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "requests": [ { "url": "https://hasdata.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } }, { "url": "https://example.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } } ] } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrape/batch/web") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrape/batch/web") payload = { "requests" => [{"url" => "https://hasdata.com", "outputFormat" => ["text", "html"], "aiExtractRules" => {"company" => {"type" => "string"}, "email" => {"type" => "string"}, "yearFounded" => {"type" => "number"}, "isHiring" => {"type" => "boolean"}}}, {"url" => "https://example.com", "outputFormat" => ["text", "html"], "aiExtractRules" => {"company" => {"type" => "string"}, "email" => {"type" => "string"}, "yearFounded" => {"type" => "number"}, "isHiring" => {"type" => "boolean"}}}], } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "requests": [ { "url": "https://hasdata.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } }, { "url": "https://example.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } } ] }); let res = client .post("https://api.hasdata.com/scrape/batch/web") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "requests": [ { "url": "https://hasdata.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } }, { "url": "https://example.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } } ] }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrape/batch/web", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Response ```json theme={null} { "jobId": "9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0", "status": "ok" } ``` This means the batch job was accepted and is being processed asynchronously. ## Get Job Status & Results To check the status of your batch job: ```bash cURL theme={null} curl --request GET \ --url 'https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0") .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` To retrieve results once ready (supports pagination): ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results' \ --data-urlencode 'page=1' \ --data-urlencode 'limit=100' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results', params: {page: '1', limit: '100'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results" querystring = {"page":"1","limit":"100"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "1", "limit" => "100", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results") .newBuilder() .addQueryParameter("page", "1") .addQueryParameter("limit", "100") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["page"] = "1"; query["limit"] = "100"; var url = $"https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results") params = { "page" => "1", "limit" => "100", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results") .query(&[("page", "1")]) .query(&[("limit", "100")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("page", "1") params.Set("limit", "100") u := "https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0/results?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## Example Result ```json theme={null} { "page": 0, "limit": 100, "total": 2, "results": [ { "query": { "url": "https://example.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } }, "result": { "id": "ca061bb6-64d8-462d-8ee9-16dd5aaf5efe", "status": "ok", "json": "https://files-dev.hasdata.com/ca061bb6-64d8-462d-8ee9-16dd5aaf5efe.json" } }, { "query": { "url": "https://hasdata.com", "outputFormat": [ "text", "html" ], "aiExtractRules": { "company": { "type": "string" }, "email": { "type": "string" }, "yearFounded": { "type": "number" }, "isHiring": { "type": "boolean" } } }, "result": { "id": "e6a75ddb-2d3f-40a5-9610-748ec3bd34a2", "status": "ok", "json": "https://files-dev.hasdata.com/e6a75ddb-2d3f-40a5-9610-748ec3bd34a2.json" } } ] } ``` ## Notes * Maximum batch size: **10,000 URLs** * Failed URLs do **not** consume credits # Custom Headers and Cookies Source: https://docs.hasdata.com/apis/web-scraping-api/features/custom-headers-and-cookies Use the `headers` parameter to send custom HTTP headers and cookies with your request. This is useful when the target website requires specific headers (like `User-Agent`, `Referer`, or `Cookie`) to return the expected content. Invalid or mismatched headers may cause the request to be blocked If you override critical headers (e.g. `Accept-Encoding`), it may impact response parsing ## When to Use * Set a `User-Agent` to request the desktop or mobile version of a page * Force a language or locale-specific version of a page (e.g. `Accept-Language: fr-FR`) * Pre-set a consent `Cookie` so cookie-banner or region interstitials don't block the page content * Keep a consistent `Cookie`-based session across multiple requests, e.g. to preserve a currency, search filters, or cart state you set on an earlier request * Pass an `Authorization` header or API key required by an endpoint you have your own legitimate credentials for, such as your own site, a sandbox environment, or a partner API ## Format The `headers` parameter is a JSON object with header names and values. ```json theme={null} { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Referer": "https://example.com/", "Cookie": "session_id=abc123" } ``` ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrape/web' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"url":"https://example.com/products","headers":{"User-Agent":"Mozilla/5.0","Cookie":"consent=accepted; currency=USD"},"outputFormat":["html"]}' ``` ```bash HasData CLI theme={null} hasdata web-scraping \ --url 'https://example.com/products' \ --headers-json '{"User-Agent":"Mozilla/5.0","Cookie":"consent=accepted; currency=USD"}' \ --output-format html ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrape/web', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { url: 'https://example.com/products', headers: {'User-Agent': 'Mozilla/5.0', Cookie: 'consent=accepted; currency=USD'}, outputFormat: ['html'] } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/web" payload = { "url": "https://example.com/products", "headers": { "User-Agent": "Mozilla/5.0", "Cookie": "consent=accepted; currency=USD" }, "outputFormat": ["html"] } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://example.com/products", "headers" => ["User-Agent" => "Mozilla/5.0", "Cookie" => "consent=accepted; currency=USD"], "outputFormat" => ["html"], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/web", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "url": "https://example.com/products", "headers": { "User-Agent": "Mozilla/5.0", "Cookie": "consent=accepted; currency=USD" }, "outputFormat": [ "html" ] } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/web") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "url": "https://example.com/products", "headers": { "User-Agent": "Mozilla/5.0", "Cookie": "consent=accepted; currency=USD" }, "outputFormat": [ "html" ] } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrape/web") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrape/web") payload = { "url" => "https://example.com/products", "headers" => {"User-Agent" => "Mozilla/5.0", "Cookie" => "consent=accepted; currency=USD"}, "outputFormat" => ["html"], } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "url": "https://example.com/products", "headers": { "User-Agent": "Mozilla/5.0", "Cookie": "consent=accepted; currency=USD" }, "outputFormat": [ "html" ] }); let res = client .post("https://api.hasdata.com/scrape/web") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "url": "https://example.com/products", "headers": { "User-Agent": "Mozilla/5.0", "Cookie": "consent=accepted; currency=USD" }, "outputFormat": [ "html" ] }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrape/web", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Notes * All custom headers are passed as-is to the target page * To send cookies, use the `Cookie` header — multiple cookies should be in standard format: `"key=value; key2=value2"` # Output Formats Source: https://docs.hasdata.com/apis/web-scraping-api/features/output-formats The `outputFormat` parameter controls the format of the scraped content returned in the response. ## Supported Formats You can request one or more of the following: * `html` – raw page HTML (default DOM output) * `text` – plain text version of the page * `markdown` – converted Markdown output (good for LLMs and readability) * `json` – **not a content format**, but a wrapper to return all requested formats in a structured JSON response ## Behavior * If you pass a **single format** like `"html"` or `"text"`, the API returns just that content directly as a string. * If you pass **multiple formats**, the response will be a JSON object with each format as a separate key. * If you include `json`, it tells the API to **wrap the response** in a structured JSON object (even for a single format). Use json to always get a structured response that’s easy to work with in code. ## Example: One Format ```json theme={null} { "outputFormat": ["text"] } ``` **Response:** ``` Welcome to Example.com This is a sample page... ``` ## Example: Multiple Formats ```json theme={null} { "outputFormat": ["html", "markdown"] } ``` **Response:** ```json theme={null} { "requestMetadata": { /*...*/ }, "content": "...", "markdown": "# Welcome to Example.com\nThis is a sample page...", "headers": { /*...*/ }, "cookies": [], "screenshot": "https://..." } ``` ## Forcing JSON Format with One Format Inside If you want the response in JSON format but only need Markdown: ```json theme={null} { "outputFormat": ["json", "markdown"] } ``` **Response:** ```javascript theme={null} { "markdown": "# Page title\n...", "requestMetadata": { /*...*/ }, "headers": { /*...*/ }, "cookies": [] } ``` ## Notes * `json` is not a content type — it controls the **response structure** * If you want to include `markdown` or `text` inside a JSON response, add `json` to the list * If you include multiple content formats, response is **always JSON**, even without `"json"` explicitly listed # Page Interactions Source: https://docs.hasdata.com/apis/web-scraping-api/features/page-interactions Use the `jsScenario` parameter to simulate user interactions on the page before scraping. This enables you to handle dynamic pages that require clicking, waiting, or filling inputs to reveal content. The value of `jsScenario` is an **array of steps**, executed sequentially. Each step is an object that defines a single action (e.g. click, scroll, wait, fill). ## Supported Actions * **`click`** – Click an element using a CSS selector * **`wait`** – Pause for a specific time (in milliseconds) * **`waitFor`** – Wait until an element appears in the DOM * **`waitForAndClick`** – Wait for an element and click it * **`evaluate`** – Run custom JavaScript in the page context * **`scrollX`**, **`scrollY`** – Scroll to a horizontal or vertical offset * **`fill`** – Input values into fields using selectors All actions are executed in order, one after another ## Example: Load More and Scroll ```json theme={null} [ { "click": "#loadMoreBtn" }, { "wait": 1500 }, { "scrollY": 2000 } ] ``` This sequence clicks a button, waits and then scrolls the page. ## Example: Fill and Submit a Form ```json theme={null} [ { "fill": ["#email", "user@example.com"] }, { "click": "#submit" }, { "waitFor": ".confirmation" } ] ``` This fills an email field, clicks the submit button, and waits for a confirmation message. ## Example: Evaluate Custom JS ```json theme={null} [ { "evaluate": "document.body.style.background = 'red'" } ] ``` This runs arbitrary JavaScript in the browser context before scraping. ## Notes * If an element is not found (e.g. `click` or `waitFor`), the request will fail * `jsRendering` must be set to `true` for `jsScenario` to work * Use `wait` conservatively - prefer `waitFor` to avoid unnecessary delays # Structured Data Extraction Source: https://docs.hasdata.com/apis/web-scraping-api/features/structured-data-extraction Use the `extractRules` parameter to extract specific content from the page using CSS selectors. This is useful when you want structured JSON output without parsing raw HTML manually. The value is a simple object where each key is the name of the field you want, and the value is the CSS selector used to extract it. Use `extractRules` when you need fast, lightweight structured data without running a [full AI model](/apis/web-scraping-api/llm-extraction/). ## Format ```json theme={null} { "fieldName": "css selector" } ``` Each selector will return the **text content** of the matched element. ## Example: Extract Page Title ```json theme={null} { "title": "h1" } ``` This extracts the text of the first `

` on the page and returns it under the `title` key. ## Example: Extract Multiple Fields ```json theme={null} { "title": "h1", "price": ".product-price", "description": ".product-description" } ``` This returns: ```json theme={null} { "title": "Apple iPhone 14", "price": "$799", "description": "The latest iPhone with A15 Bionic chip..." } ``` ## Attribute Extraction You can extract an attribute by using `@attribute` syntax: ```json theme={null} { "image": "img.product-main @src", "link": "a.buy-button @href" } ``` ## Notes * Only the **first match** per selector is returned * If the selector is not found, the value will be `null` # Wait For Source: https://docs.hasdata.com/apis/web-scraping-api/features/wait-for Use the `waitFor` parameter to delay scraping until a specific HTML element appears on the page. This is useful when the target content is rendered dynamically with JavaScript — for example, when you need to wait for product details, prices, or reviews to load after initial page render. ## How It Works * `waitFor` takes a **CSS selector** as its value (e.g. `.product-title`, `#main`, `div[data-loaded=true]`) * Scraping will begin **only after the element is detected in the DOM** * If the element does not appear the request will fail ## When to Use * The page loads blank or incomplete without JS rendering * You need to wait for a modal, tab, or dynamically loaded section to appear * You want to avoid capturing partial content due to async loading delays ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrape/web' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"url":"https://example.com/product/123","waitFor":".product-details","jsRendering":true,"outputFormat":["html"]}' ``` ```bash HasData CLI theme={null} hasdata web-scraping \ --url 'https://example.com/product/123' \ --wait-for .product-details \ --js-rendering \ --output-format html ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrape/web', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { url: 'https://example.com/product/123', waitFor: '.product-details', jsRendering: true, outputFormat: ['html'] } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/web" payload = { "url": "https://example.com/product/123", "waitFor": ".product-details", "jsRendering": True, "outputFormat": ["html"] } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://example.com/product/123", "waitFor" => ".product-details", "jsRendering" => true, "outputFormat" => ["html"], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/web", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "url": "https://example.com/product/123", "waitFor": ".product-details", "jsRendering": true, "outputFormat": [ "html" ] } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/web") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "url": "https://example.com/product/123", "waitFor": ".product-details", "jsRendering": true, "outputFormat": [ "html" ] } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrape/web") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrape/web") payload = { "url" => "https://example.com/product/123", "waitFor" => ".product-details", "jsRendering" => true, "outputFormat" => ["html"], } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "url": "https://example.com/product/123", "waitFor": ".product-details", "jsRendering": true, "outputFormat": [ "html" ] }); let res = client .post("https://api.hasdata.com/scrape/web") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "url": "https://example.com/product/123", "waitFor": ".product-details", "jsRendering": true, "outputFormat": [ "html" ] }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrape/web", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` In this case, scraping will start only after `.product-details` is present on the page. ## Notes * This feature requires `"jsRendering": true` * Combine with `wait` (time delay in ms) for extra control if needed * If the selector never appears, you’ll receive a 400 response with an appropriate error # LLM Extraction Source: https://docs.hasdata.com/apis/web-scraping-api/llm-extraction Use `aiExtractRules` to define custom rules for extracting structured data from any web page using large language models (LLMs). This is ideal when you don’t want to write manual CSS selectors and need clean, field-level data in JSON format. Each key you define represents a field you want to extract. You provide a `type` and (optionally) a `description` to help the model understand what data to look for. ## Supported Types * `string` – plain text value * `number` – numeric value * `boolean` – true or false * `list` – an array of values * `item` – a nested object (with its own structure under `output`) You can also use `enum` to restrict a string to a fixed set of values. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrape/web' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"url":"https://hasdata.com","aiExtractRules":{"company":{"description":"company name","type":"string"},"reviews":{"type":"list","output":{"review":{"description":"review text","type":"string"},"author":{"type":"string"}}},"clients":{"type":"list","output":"string"},"trial":{"type":"item","output":{"available":{"type":"boolean"},"type":{"type":"string","enum":["paid","free"]}}},"yearFounded":{"type":"number"}}}' ``` ```bash HasData CLI theme={null} hasdata web-scraping \ --url 'https://hasdata.com' \ --ai-extract-rules-json '{"company":{"description":"company name","type":"string"},"reviews":{"type":"list","output":{"review":{"description":"review text","type":"string"},"author":{"type":"string"}}},"clients":{"type":"list","output":"string"},"trial":{"type":"item","output":{"available":{"type":"boolean"},"type":{"type":"string","enum":["paid","free"]}}},"yearFounded":{"type":"number"}}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrape/web', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { url: 'https://hasdata.com', aiExtractRules: { company: {description: 'company name', type: 'string'}, reviews: { type: 'list', output: {review: {description: 'review text', type: 'string'}, author: {type: 'string'}} }, clients: {type: 'list', output: 'string'}, trial: { type: 'item', output: {available: {type: 'boolean'}, type: {type: 'string', enum: ['paid', 'free']}} }, yearFounded: {type: 'number'} } } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/web" payload = { "url": "https://hasdata.com", "aiExtractRules": { "company": { "description": "company name", "type": "string" }, "reviews": { "type": "list", "output": { "review": { "description": "review text", "type": "string" }, "author": { "type": "string" } } }, "clients": { "type": "list", "output": "string" }, "trial": { "type": "item", "output": { "available": { "type": "boolean" }, "type": { "type": "string", "enum": ["paid", "free"] } } }, "yearFounded": { "type": "number" } } } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://hasdata.com", "aiExtractRules" => ["company" => ["description" => "company name", "type" => "string"], "reviews" => ["type" => "list", "output" => ["review" => ["description" => "review text", "type" => "string"], "author" => ["type" => "string"]]], "clients" => ["type" => "list", "output" => "string"], "trial" => ["type" => "item", "output" => ["available" => ["type" => "boolean"], "type" => ["type" => "string", "enum" => ["paid", "free"]]]], "yearFounded" => ["type" => "number"]], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/web", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "url": "https://hasdata.com", "aiExtractRules": { "company": { "description": "company name", "type": "string" }, "reviews": { "type": "list", "output": { "review": { "description": "review text", "type": "string" }, "author": { "type": "string" } } }, "clients": { "type": "list", "output": "string" }, "trial": { "type": "item", "output": { "available": { "type": "boolean" }, "type": { "type": "string", "enum": [ "paid", "free" ] } } }, "yearFounded": { "type": "number" } } } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/web") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "url": "https://hasdata.com", "aiExtractRules": { "company": { "description": "company name", "type": "string" }, "reviews": { "type": "list", "output": { "review": { "description": "review text", "type": "string" }, "author": { "type": "string" } } }, "clients": { "type": "list", "output": "string" }, "trial": { "type": "item", "output": { "available": { "type": "boolean" }, "type": { "type": "string", "enum": [ "paid", "free" ] } } }, "yearFounded": { "type": "number" } } } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrape/web") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrape/web") payload = { "url" => "https://hasdata.com", "aiExtractRules" => {"company" => {"description" => "company name", "type" => "string"}, "reviews" => {"type" => "list", "output" => {"review" => {"description" => "review text", "type" => "string"}, "author" => {"type" => "string"}}}, "clients" => {"type" => "list", "output" => "string"}, "trial" => {"type" => "item", "output" => {"available" => {"type" => "boolean"}, "type" => {"type" => "string", "enum" => ["paid", "free"]}}}, "yearFounded" => {"type" => "number"}}, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "url": "https://hasdata.com", "aiExtractRules": { "company": { "description": "company name", "type": "string" }, "reviews": { "type": "list", "output": { "review": { "description": "review text", "type": "string" }, "author": { "type": "string" } } }, "clients": { "type": "list", "output": "string" }, "trial": { "type": "item", "output": { "available": { "type": "boolean" }, "type": { "type": "string", "enum": [ "paid", "free" ] } } }, "yearFounded": { "type": "number" } } }); let res = client .post("https://api.hasdata.com/scrape/web") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "url": "https://hasdata.com", "aiExtractRules": { "company": { "description": "company name", "type": "string" }, "reviews": { "type": "list", "output": { "review": { "description": "review text", "type": "string" }, "author": { "type": "string" } } }, "clients": { "type": "list", "output": "string" }, "trial": { "type": "item", "output": { "available": { "type": "boolean" }, "type": { "type": "string", "enum": [ "paid", "free" ] } } }, "yearFounded": { "type": "number" } } }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrape/web", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Example Response ```json theme={null} { "requestMetadata": { "id": "784b9b3a-8426-431c-a516-beec621183a0", "status": "ok" }, "content": "...", "aiResponse": { "company": "HasData", "reviews": [ { "review": "Roman from HasData went above and beyond to help us with our scraping needs...", "author": "Michael Bonacina" }, { "review": "I found HasData, which is one of the best scraping services I have ever used...", "author": "Hussein Ali" } ], "clients": [ "Stanford", "Salesforce", "Samsung", "Nvidia", "Mailchimp", "Harvard", "Copyleaks", "LosAngelesTimes", "SurveySparrow" ], "trial": { "available": true, "type": "free" }, "yearFounded": null } } ``` ## Notes * Descriptions are optional but highly recommended for accuracy. * `list` fields can output flat values (`"output": "string"`) or objects (`"output": { ... }`). * Fields with no match will return `null`. # Quickstart - Web Scraping API Source: https://docs.hasdata.com/apis/web-scraping-api/quickstart The **Web Scraping API** lets you scrape any public web page without managing proxies or headless browsers. You send a URL, and we return the raw page content and optionally parsed data. ## Get Your API Key Sign in at [hasdata.com](http://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Make Your First Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrape/web' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"url":"https://example.com","outputFormat":["html","text","markdown"],"screenshot":true}' ``` ```bash HasData CLI theme={null} hasdata web-scraping \ --url 'https://example.com' \ --output-format 'html,text,markdown' \ --screenshot ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrape/web', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { url: 'https://example.com', outputFormat: ['html', 'text', 'markdown'], screenshot: true } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/web" payload = { "url": "https://example.com", "outputFormat": ["html", "text", "markdown"], "screenshot": True } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://example.com", "outputFormat" => ["html", "text", "markdown"], "screenshot" => true, ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/web", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "url": "https://example.com", "outputFormat": [ "html", "text", "markdown" ], "screenshot": true } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/web") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "url": "https://example.com", "outputFormat": [ "html", "text", "markdown" ], "screenshot": true } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrape/web") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrape/web") payload = { "url" => "https://example.com", "outputFormat" => ["html", "text", "markdown"], "screenshot" => true, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "url": "https://example.com", "outputFormat": [ "html", "text", "markdown" ], "screenshot": true }); let res = client .post("https://api.hasdata.com/scrape/web") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "url": "https://example.com", "outputFormat": [ "html", "text", "markdown" ], "screenshot": true }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrape/web", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` The `screenshot` and other `files.hasdata.com` links in the response are private to your workspace — fetch them with your API key in the `x-api-key` header, or browse them from the dashboard. ```json theme={null} { "requestMetadata": { "id": "e29e8506-143b-4872-a079-53b72e0edb10", "status": "ok" }, "headers": { "accept-ranges":"bytes", "alt-svc":"h3=\":443\"; ma=93600,h3-29=\":443\"; ma=93600,quic=\":443\"; ma=93600; v=\"43\"", "cache-control":"max-age=2589", "content-encoding":"gzip", "content-length":"648", "content-type":"text/html", "date":"Fri, 11 Apr 2025 23:41:30 GMT", "etag":"\"84238dfc8092e5d9c0dac8ef93371a07:1736799080.121134\"", "last-modified":"Mon, 13 Jan 2025 20:11:20 GMT", "vary":"Accept-Encoding" }, "screenshot": "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/e29e8506-143b-4872-a079-53b72e0edb10.jpeg", "content": "Example Domain ... ", "markdown": "# Example Domain\n\nThis domain is for use in ... [More information...](https://www.iana.org/domains/example)", "text": "Example Domain\n\nThis domain is for use in ... More information..." } ``` Maximum page load time is restricted to 300 seconds. In cases where a request fails after 300 seconds, you will not be charged for the unsuccessful request. ## Add Optional Parameters You can include additional parameters to control what data is returned: * `outputFormat` – Array of formats to return. Supports: html, text, markdown, json. * `screenshot` – Set to `true` to include a screenshot of the rendered page. * `extractLinks` – Set to `true` to extract all hyperlinks from the page. * `extractEmails` – Set to `true` to extract all email addresses found on the page. ## Proxy Configuration To scrape content with location-specific views or improve reliability on sites with strict traffic filtering, you can configure proxies: * `proxyType` – Choose proxy type. Options: `residential`, `datacenter`. * `proxyCountry` – Set a specific country for the proxy. Use [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format (e.g. `US`, `DE`, `IN`). That's it. You're ready to start scraping. For advanced usage and all parameters, see the [API Params](/apis/web-scraping-api/api-params) section. # Web Scraping API Request Cost Source: https://docs.hasdata.com/apis/web-scraping-api/request-cost Each request to the Web Scraping API consumes **API Credits** from your account balance. The number of credits charged depends on the request configuration. The cost per request is determined by the combination of `jsRendering` and `proxyType` parameters. | jsRendering | proxyType | Cost per Request | | ----------- | ----------- | ---------------- | | false | datacenter | 1 API Credit | | false | residential | 5 API Credits | | true | datacenter | 10 API Credits | | true | residential | 15 API Credits | Credits are deducted only for successful requests. Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). # YellowPages Place Scraper API Source: https://docs.hasdata.com/apis/yellowpages/place The YellowPages Place Scraper API allows users to retrieve detailed information about a specific place using its YellowPages URL. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Yellow Pages. Yellow Pages is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the YellowPages Place Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/yellowpages/place' \ --data-urlencode 'url=https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata yellowpages-place \ --url 'https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/yellowpages/place', params: { url: 'https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/yellowpages/place" querystring = {"url":"https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/yellowpages/place?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/yellowpages/place") .newBuilder() .addQueryParameter("url", "https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["url"] = "https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617"; var url = $"https://api.hasdata.com/scrape/yellowpages/place?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/yellowpages/place") params = { "url" => "https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/yellowpages/place") .query(&[("url", "https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("url", "https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617") u := "https://api.hasdata.com/scrape/yellowpages/place?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | --------------------------------- | | `url` | [https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617](https://www.yellowpages.com/kings-county-ny/mip/aladdin-plumbing-corp-548289617) | Yes | The YellowPages URL of the place. | # YellowPages Search Scraper API Source: https://docs.hasdata.com/apis/yellowpages/search The YellowPages Search Scraper API allows users to get results from the YellowPages search page. This API enables searching for businesses by keyword and location. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Yellow Pages. Yellow Pages is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the YellowPages Search Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/yellowpages/search' \ --data-urlencode 'keyword=Plumbers' \ --data-urlencode 'location=New York, NY' \ --data-urlencode 'sort=default' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata yellowpages-search \ --keyword Plumbers \ --location 'New York, NY' \ --sort default ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/yellowpages/search', params: {keyword: 'Plumbers', location: 'New York, NY', sort: 'default'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/yellowpages/search" querystring = {"keyword":"Plumbers","location":"New York, NY","sort":"default"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Plumbers", "location" => "New York, NY", "sort" => "default", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/yellowpages/search?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/yellowpages/search") .newBuilder() .addQueryParameter("keyword", "Plumbers") .addQueryParameter("location", "New York, NY") .addQueryParameter("sort", "default") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["keyword"] = "Plumbers"; query["location"] = "New York, NY"; query["sort"] = "default"; var url = $"https://api.hasdata.com/scrape/yellowpages/search?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/yellowpages/search") params = { "keyword" => "Plumbers", "location" => "New York, NY", "sort" => "default", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/yellowpages/search") .query(&[("keyword", "Plumbers")]) .query(&[("location", "New York, NY")]) .query(&[("sort", "default")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("keyword", "Plumbers") params.Set("location", "New York, NY") params.Set("sort", "default") u := "https://api.hasdata.com/scrape/yellowpages/search?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------- | ------------- | -------- | ------------------------------------------------------------------- | | `keyword` | Plumbers | Yes | The search term for which to get the search results. | | `location` | New York, NY | Yes | The location where to search for businesses with the given keyword. | | `sort` | default | No | The sorting option for the search results. | | `domain` | - | No | YellowPages domain to use. Default is `www.yellowpages.com`. | | `page` | - | No | The page number of the results to retrieve. | # Yelp Place Scraper API Source: https://docs.hasdata.com/apis/yelp/place The Yelp Place Scraper API allows users to retrieve detailed information about a specific place using its Yelp ID or Yelp Alias. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Yelp. Yelp is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Yelp Place Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/yelp/place' \ --data-urlencode 'placeId=mcdonalds-new-york-386' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata yelp-place \ --place-id mcdonalds-new-york-386 ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/yelp/place', params: {placeId: 'mcdonalds-new-york-386'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/yelp/place" querystring = {"placeId":"mcdonalds-new-york-386"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "mcdonalds-new-york-386", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/yelp/place?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/yelp/place") .newBuilder() .addQueryParameter("placeId", "mcdonalds-new-york-386") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["placeId"] = "mcdonalds-new-york-386"; var url = $"https://api.hasdata.com/scrape/yelp/place?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/yelp/place") params = { "placeId" => "mcdonalds-new-york-386", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/yelp/place") .query(&[("placeId", "mcdonalds-new-york-386")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("placeId", "mcdonalds-new-york-386") u := "https://api.hasdata.com/scrape/yelp/place?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | --------- | ---------------------- | -------- | ---------------------------------------------------------------------------------------------------------- | | `placeId` | mcdonalds-new-york-386 | Yes | The Yelp ID or Yelp Alias of the place. For example, 'jPIZ3FR5LNcwPuUHi2Fe4g' or 'mcdonalds-new-york-386'. | | `domain` | - | No | Yelp domain to use. Default is `www.yelp.com`. | # Yelp Reviews Scraper API Source: https://docs.hasdata.com/apis/yelp/reviews The Yelp Reviews Scraper API allows users to retrieve the review feed of a specific place on Yelp, with filtering by rating, language and keyword. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Yelp. Yelp is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Yelp Reviews Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/yelp/reviews' \ --data-urlencode 'placeId=-4ofMtrD7pSpZIX5pnDkig' \ --data-urlencode 'rating=5,4' \ --data-urlencode 'languageCode=en' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/yelp/reviews', params: {placeId: '-4ofMtrD7pSpZIX5pnDkig', rating: '5,4', languageCode: 'en'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/yelp/reviews" querystring = {"placeId":"-4ofMtrD7pSpZIX5pnDkig","rating":"5,4","languageCode":"en"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "-4ofMtrD7pSpZIX5pnDkig", "rating" => "5,4", "languageCode" => "en", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/yelp/reviews?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/yelp/reviews") .newBuilder() .addQueryParameter("placeId", "-4ofMtrD7pSpZIX5pnDkig") .addQueryParameter("rating", "5,4") .addQueryParameter("languageCode", "en") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["placeId"] = "-4ofMtrD7pSpZIX5pnDkig"; query["rating"] = "5,4"; query["languageCode"] = "en"; var url = $"https://api.hasdata.com/scrape/yelp/reviews?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/yelp/reviews") params = { "placeId" => "-4ofMtrD7pSpZIX5pnDkig", "rating" => "5,4", "languageCode" => "en", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/yelp/reviews") .query(&[("placeId", "-4ofMtrD7pSpZIX5pnDkig")]) .query(&[("rating", "5,4")]) .query(&[("languageCode", "en")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("placeId", "-4ofMtrD7pSpZIX5pnDkig") params.Set("rating", "5,4") params.Set("languageCode", "en") u := "https://api.hasdata.com/scrape/yelp/reviews?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------------- | ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `placeId` | -4ofMtrD7pSpZIX5pnDkig | Yes | The Yelp ID of the place. For example, '-4ofMtrD7pSpZIX5pnDkig'. Yelp IDs can be obtained from the Yelp Search Scraper API. | | `domain` | - | No | Yelp domain to use. Default is `www.yelp.com`. | | `query` | - | No | Note: Yelp ignores the `rating` filter while searching, so a query returns matching reviews of every star rating. Free-text query to search within the reviews of the place.
| | `sortBy` | - | No | The order in which the reviews are returned. Defaults to relevanceDesc. | | `rating` | 5,4 | No | Note: Yelp ignores this filter when `query` is set, so a search returns matching reviews of every star rating. Filters the reviews by star rating. Possible values are 5, 4, 3, 2 and 1. To return only five-star reviews, set it to `5`. To include several ratings, pass them comma-separated, for example `5,4,3`. When omitted, reviews with any rating are returned.
| | `languageCode` | en | No | Language of the reviews to return, as a two-letter code (e.g., 'en', 'es', 'fr'). Defaults to en. | | `notRecommended` | - | No | Returns the reviews Yelp does not currently recommend (filtered out of the main feed by its recommendation software) instead of the recommended ones. These reviews carry no photos, videos or reactions, and are paginated ten at a time. Defaults to false.
| | `start` | - | No | Result offset for pagination. It skips the given number of reviews, so the step matches `num` (e.g., 0, 49, 98 for the recommended feed, or 0, 10, 20 when `notRecommended` is set). The response echoes it back as `pagination.start`. Cannot be combined with `nextPageToken`.
| | `num` | - | No | Number of reviews to return per page. The maximum is 49. Defaults to 49 for the recommended feed and to 10 when `notRecommended` is set. The response echoes it back as `pagination.num`.
| | `nextPageToken` | - | No | Opaque cursor for the next page, taken verbatim from `pagination.nextPageToken` of the previous response. It carries both the offset and the page size, so passing it alone continues the feed where the last response ended. Keep the other filters (`sortBy`, `rating`, `languageCode`, `query`, `notRecommended`) identical across pages. Use either this or `start`, not both. Paginate until `pagination.hasNextPage` is false.
| # Yelp Search Scraper API Source: https://docs.hasdata.com/apis/yelp/search The Yelp Search Scraper API allows users to get results from the Yelp search page. This API enables searching for businesses by keyword and location. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Yelp. Yelp is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Yelp Search Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/yelp/search' \ --data-urlencode 'keyword=McDonald'\''s' \ --data-urlencode 'location=New York, NY' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata yelp-search \ --keyword 'McDonald'\''s' \ --location 'New York, NY' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/yelp/search', params: {keyword: 'McDonald\'s', location: 'New York, NY'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/yelp/search" querystring = {"keyword":"McDonald's","location":"New York, NY"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "McDonald's", "location" => "New York, NY", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/yelp/search?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/yelp/search") .newBuilder() .addQueryParameter("keyword", "McDonald's") .addQueryParameter("location", "New York, NY") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["keyword"] = "McDonald's"; query["location"] = "New York, NY"; var url = $"https://api.hasdata.com/scrape/yelp/search?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/yelp/search") params = { "keyword" => "McDonald's", "location" => "New York, NY", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/yelp/search") .query(&[("keyword", "McDonald's")]) .query(&[("location", "New York, NY")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("keyword", "McDonald's") params.Set("location", "New York, NY") u := "https://api.hasdata.com/scrape/yelp/search?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ---------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ | | `keyword` | McDonald's | Yes | The search term for which to get the search results. | | `location` | New York, NY | Yes | The location where to search for businesses with the given keyword. | | `l` | - | No | Parameter defines the distance or map radius for the search results. For example: `g:-95.2486,29.8496,-95.4277,29.6324`.
| | `domain` | - | No | Yelp domain to use. Default is `www.yelp.com`. | | `start` | - | No | Result offset for pagination (e.g., 0 for the first page, 10 for the 2nd page, etc.). | # YouTube Channel Scraper API Source: https://docs.hasdata.com/apis/youtube/channel The YouTube Channel Scraper API provides structured data from YouTube channel pages including channel info, videos, shorts, playlists, posts, streams, releases, podcasts, and more. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by YouTube. YouTube is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the YouTube Channel Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/youtube/channel' \ --data-urlencode 'channelId=@PewDiePie' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/youtube/channel', params: {channelId: '@PewDiePie'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/youtube/channel" querystring = {"channelId":"@PewDiePie"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "@PewDiePie", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/youtube/channel?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/youtube/channel") .newBuilder() .addQueryParameter("channelId", "@PewDiePie") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["channelId"] = "@PewDiePie"; var url = $"https://api.hasdata.com/scrape/youtube/channel?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/youtube/channel") params = { "channelId" => "@PewDiePie", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/youtube/channel") .query(&[("channelId", "@PewDiePie")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("channelId", "@PewDiePie") u := "https://api.hasdata.com/scrape/youtube/channel?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ----------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `channelId` | @PewDiePie | Yes | YouTube channel identifier — either the canonical channel ID (`UC…`, 24 chars) or the public handle starting with `@` (e.g. `@PewDiePie`). Legacy `/c/` and `/user/` URL slugs are also accepted. | | `tab` | - | No | Channel tab to scrape. Each tab returns a different content shape:
- `featured` (default) — channel Home page (channel trailer + curated rows)
- `videos` — uploaded long-form videos
- `shorts` — Shorts feed
- `streams` — past and upcoming live streams
- `playlists` — created and saved playlists
- `posts` / `community` — community posts
- `podcasts` — podcast episodes
- `releases` — music releases
- `about` — channel description, links, stats
- `store` — channel merch
| | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `deviceType` | - | No | Device type for the request. | | `paginationToken` | - | No | Token returned in the previous response to fetch the next page of results. | # YouTube Search Scraper API Source: https://docs.hasdata.com/apis/youtube/search The YouTube Search Scraper API provides real-time access to structured YouTube search results. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by YouTube. YouTube is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the YouTube Search Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/youtube/search' \ --data-urlencode 'q=BMW' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/youtube/search', params: {q: 'BMW'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/youtube/search" querystring = {"q":"BMW"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "BMW", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/youtube/search?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/youtube/search") .newBuilder() .addQueryParameter("q", "BMW") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "BMW"; var url = $"https://api.hasdata.com/scrape/youtube/search?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/youtube/search") params = { "q" => "BMW", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/youtube/search") .query(&[("q", "BMW")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "BMW") u := "https://api.hasdata.com/scrape/youtube/search?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ----------------- | ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `q` | BMW | Yes | Free-text search query, exactly as a user would type it into the YouTube search box. | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `deviceType` | - | No | Device type for the request. | | `sp` | - | No | Raw YouTube `sp` filter token, copied verbatim from a YouTube search URL (e.g. `EgIQAQ%253D%253D`). When provided, it overrides `sortBy`, `date`, `videoType`, `length`, and `filters[]`. Use only if you need a YouTube-side filter that this API does not expose as a structured parameter. | | `sortBy` | - | No | Sort order applied to the results page. `relevance` (default) — best match for the query; `date` — newest first; `views` — most viewed first; `rating` — highest rated first; `popularity` — trending/most popular. | | `date` | - | No | Limit results to videos uploaded within this time window relative to now. | | `videoType` | - | No | Restrict results to a single YouTube content type — regular videos, Shorts, channels, playlists, or movies. | | `length` | - | No | Filter by video duration bucket:
- `under4` — under 4 minutes
- `between420` — 4 to 20 minutes
- `plus20` — over 20 minutes
| | `filters[]` | - | No | Feature flags to require on results. Multiple values are combined with AND (every flag must apply).

- `hd` — HD quality
- `k4` — 4K quality
- `hdr` — HDR
- `subtitles` — has subtitles/closed captions
- `cc` — Creative Commons license
- `d3` — 3D video
- `d360` — 360° video
- `vr180` — VR180 video
- `live` — currently live
- `bought` — purchased/paid content
- `location` — has a geographic location tag
| | `paginationToken` | - | No | Token returned in the previous response to fetch the next page. | # YouTube Transcript Scraper API Source: https://docs.hasdata.com/apis/youtube/transcript The YouTube Transcript Scraper API extracts the full transcript (subtitles) from a YouTube video. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by YouTube. YouTube is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the YouTube Transcript Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/youtube/transcript' \ --data-urlencode 'v=dQw4w9WgXcQ' \ --data-urlencode 'languageCode=en' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/youtube/transcript', params: {v: 'dQw4w9WgXcQ', languageCode: 'en'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/youtube/transcript" querystring = {"v":"dQw4w9WgXcQ","languageCode":"en"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "dQw4w9WgXcQ", "languageCode" => "en", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/youtube/transcript?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/youtube/transcript") .newBuilder() .addQueryParameter("v", "dQw4w9WgXcQ") .addQueryParameter("languageCode", "en") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["v"] = "dQw4w9WgXcQ"; query["languageCode"] = "en"; var url = $"https://api.hasdata.com/scrape/youtube/transcript?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/youtube/transcript") params = { "v" => "dQw4w9WgXcQ", "languageCode" => "en", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/youtube/transcript") .query(&[("v", "dQw4w9WgXcQ")]) .query(&[("languageCode", "en")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("v", "dQw4w9WgXcQ") params.Set("languageCode", "en") u := "https://api.hasdata.com/scrape/youtube/transcript?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | -------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `v` | dQw4w9WgXcQ | Yes | 11-character YouTube video ID — the value of the `v=` query parameter in a watch URL (e.g. `dQw4w9WgXcQ` for `https://www.youtube.com/watch?v=dQw4w9WgXcQ`). | | `languageCode` | en | No | BCP-47 / YouTube language code of the transcript track to return (e.g. `en`, `de`, `en-US`, `pt-BR`). Must match a track that the video actually has. When omitted, the video's default language track is returned. | | `type` | - | No | Set to `asr` to fetch the YouTube auto-generated (speech-recognition) track. Omit to fetch the human-authored track for `languageCode` when one exists. | # YouTube Video Scraper API Source: https://docs.hasdata.com/apis/youtube/video The YouTube Video Scraper API provides structured data for a YouTube video page. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by YouTube. YouTube is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the YouTube Video Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 10 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/youtube/video' \ --data-urlencode 'v=dQw4w9WgXcQ' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/youtube/video', params: {v: 'dQw4w9WgXcQ'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/youtube/video" querystring = {"v":"dQw4w9WgXcQ"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "dQw4w9WgXcQ", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/youtube/video?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/youtube/video") .newBuilder() .addQueryParameter("v", "dQw4w9WgXcQ") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["v"] = "dQw4w9WgXcQ"; var url = $"https://api.hasdata.com/scrape/youtube/video?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/youtube/video") params = { "v" => "dQw4w9WgXcQ", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/youtube/video") .query(&[("v", "dQw4w9WgXcQ")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("v", "dQw4w9WgXcQ") u := "https://api.hasdata.com/scrape/youtube/video?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------ | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `v` | dQw4w9WgXcQ | Yes | 11-character YouTube video ID — the value of the `v=` query parameter in a watch URL (e.g. `dQw4w9WgXcQ` for `https://www.youtube.com/watch?v=dQw4w9WgXcQ`). | | `gl` | - | No | The two-letter country code for the country you want to limit the search to. | | `hl` | - | No | The two-letter language code for the language you want to use for the search. | | `deviceType` | - | No | Device type for the request. | # Zillow Listing Scraper API Source: https://docs.hasdata.com/apis/zillow/listing The Zillow Listing Scraper API lets you retrieve property listings from Zillow\.com based on various search parameters. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Zillow. Zillow is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Zillow Listing Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/zillow/listing' \ --data-urlencode 'keyword=New York, NY' \ --data-urlencode 'type=forSale' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata zillow-listing \ --keyword 'New York, NY' \ --type forSale ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/zillow/listing', params: {keyword: 'New York, NY', type: 'forSale'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/zillow/listing" querystring = {"keyword":"New York, NY","type":"forSale"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "New York, NY", "type" => "forSale", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/zillow/listing?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/zillow/listing") .newBuilder() .addQueryParameter("keyword", "New York, NY") .addQueryParameter("type", "forSale") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["keyword"] = "New York, NY"; query["type"] = "forSale"; var url = $"https://api.hasdata.com/scrape/zillow/listing?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/zillow/listing") params = { "keyword" => "New York, NY", "type" => "forSale", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/zillow/listing") .query(&[("keyword", "New York, NY")]) .query(&[("type", "forSale")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("keyword", "New York, NY") params.Set("type", "forSale") u := "https://api.hasdata.com/scrape/zillow/listing?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | ------------------------- | ------------- | -------- | -------------------------------------------------------------- | | `keyword` | New York, NY | Yes | The keyword used to search for listings. | | `type` | forSale | Yes | The type of listing. | | `sort` | - | No | The sorting option for the search results. | | `price[min]` | - | No | The minimum price of the listing. | | `price[max]` | - | No | The maximum price of the listing. | | `beds[min]` | - | No | The minimum number of bedrooms. | | `beds[max]` | - | No | The maximum number of bedrooms. | | `baths[min]` | - | No | The minimum number of bathrooms. | | `baths[max]` | - | No | The maximum number of bathrooms. | | `yearBuilt[min]` | - | No | The minimum year the property was built. | | `yearBuilt[max]` | - | No | The maximum year the property was built. | | `lotSize[min]` | - | No | The minimum lot size. | | `lotSize[max]` | - | No | The maximum lot size. | | `squareFeet[min]` | - | No | The minimum square footage. | | `squareFeet[max]` | - | No | The maximum square footage. | | `homeTypes[]` | - | No | An array of home types to filter the listings. | | `listingType` | - | No | The category of the listing. | | `listingPublishOptions[]` | - | No | An array of listing publish options. | | `hoa` | - | No | The Homeowners Association (HOA) fee. | | `propertyStatus[]` | - | No | An array of property statuses. | | `tours[]` | - | No | An array of tour options. | | `otherAmenities[]` | - | No | An array of other amenities. | | `views[]` | - | No | An array of views. | | `pets[]` | - | No | An array of pet options. | | `basement[]` | - | No | An array of basement options. | | `singleStoryOnly` | - | No | If set to true, only single-story properties will be included. | | `hide55plusCommunities` | - | No | If set to true, 55+ communities will be excluded. | | `daysOnZillow` | - | No | The number of days a listing has been on Zillow. | | `moveInDate` | - | No | The desired move-in date in `YYYY-MM-DD` format. | | `mustHaveGarage` | - | No | If set to true, only listings with a garage will be included. | | `parkingSpotsMin` | - | No | The minimum number of parking spots. | | `keywords` | - | No | Additional keywords to refine the search. | | `page` | - | No | The page number of the results to retrieve. | # Zillow Property Scraper API Source: https://docs.hasdata.com/apis/zillow/property The Zillow Property Scraper API lets you retrieve detailed information about a specific property on Zillow\.com using its URL. It provides details such as property features, price, and agent contacts. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Zillow. Zillow is a trademark of its respective owner. This API works with publicly available data only. ## Get Your API Key Sign in at [hasdata.com](https://app.hasdata.com/sign-in), go to your account settings, and copy your API key. All requests must include your key in the `x-api-key` header. ## Request Cost and API Credits Each request to the Zillow Property Scraper API consumes **API Credits** from your account balance. * **Cost per request:** 5 API Credits * Credits are deducted only for successful requests. * Your total available credits depend on your active plan. You can use your credits across all HasData APIs. The same credit balance is shared platform-wide. **Unused credits do not roll over.** Any remaining credits expire at the end of the current billing period. To monitor your credit usage and remaining balance, sign in to your account dashboard at [app.hasdata.com](https://app.hasdata.com/sign-in). ## Make Your First Request ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/zillow/property' \ --data-urlencode 'url=https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata zillow-property \ --url 'https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/zillow/property', params: { url: 'https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/' }, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/zillow/property" querystring = {"url":"https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/zillow/property?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/zillow/property") .newBuilder() .addQueryParameter("url", "https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["url"] = "https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/"; var url = $"https://api.hasdata.com/scrape/zillow/property?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/zillow/property") params = { "url" => "https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/zillow/property") .query(&[("url", "https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("url", "https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/") u := "https://api.hasdata.com/scrape/zillow/property?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## API Parameters | Parameter | Default Value | Required | Description | | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------- | | `url` | [https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731\_zpid/](https://www.zillow.com/homedetails/301-E-79th-St-APT-23S-New-York-NY-10075/31543731_zpid/) | Yes | The URL of the property on Zillow. Must be a valid Zillow property URL. | | `extractAgentEmails` | - | No | If enabled, attempts to extract agent email addresses from the property details. Increases the cost of the request. | # API vs Scraper Jobs Source: https://docs.hasdata.com/basics/api-vs-scraper-jobs HasData offers two ways to extract data: **APIs** and **Scraper Jobs**. Both are powered by the same backend, but differ in how they're triggered, what they’re best suited for, and how results are delivered. ```mermaid theme={null} sequenceDiagram autonumber participant Client participant HasData API participant Scraper Engine participant Webhook (Client) Note over Client,HasData API: API Request Flow Client->>HasData API: Send API Request HasData API->>Scraper Engine: Scrape Target Page Scraper Engine-->>HasData API: Return Extracted Data HasData API-->>Client: Return Response (HTML/JSON) Note over Client,HasData API: Scraper Job Flow Client->>HasData API: Submit Scraper Job HasData API-->>Client: Return Job ID + Status: queued HasData API->>Scraper Engine: Run Scraper Job (async) Scraper Engine-->>HasData API: Processed Result HasData API-->>Webhook (Client): Send Result via Webhook ``` ## When to Use APIs Use APIs when you need: * Fast, real-time responses * One-off requests with a known URL or query * Integration into apps, bots, dashboards, or workflows that expect immediate data APIs are synchronous — you send a request and get the result in the same HTTP response. **Example Use Cases** * Search Google SERP and get results back immediately * Fetch product data from Amazon or a listing from Zillow * Grab metadata from a specific page ## When to Use Scraper Jobs Use Scraper Jobs when you need to: * Scrape a large number of pages or listings * Crawl through paginated results * Extract data from complex platforms (e.g. Google Maps, Zillow) * Run structured scraping at scale Scraper Jobs are asynchronous — you submit a job with parameters like URLs, filters, or depth. The job runs in the background, and you can: * Receive the result via webhook * Or poll for status and download the result when it’s ready **Example Use Cases** * Crawl all listings for "restaurants in New York" from Google Maps * Scrape paginated product results from Amazon or Redfin * Extract 1,000+ real estate listings from Zillow with filters * Crawl all pages from a website and extract structured content (e.g. blog posts, articles) Jobs are designed for bulk extraction, crawling, or anything that can’t be done in a single API call. ## Summary | Feature | API | Scraper Job | | ---------------- | ---------------- | ---------------------------------- | | **Execution** | Real-time | Queued / background | | **Response** | Sync (immediate) | Async (webhook or polling) | | **Best for** | Single queries | Multi-page or high-volume scraping | | **Credit Model** | Per request | Per data row | # Pricing Source: https://docs.hasdata.com/basics/pricing HasData uses a credit-based pricing system. Each API request or scraper job consumes a specific number of credits. You’re only charged for successful results — failed or blocked requests won’t cost anything. ## API Pricing Each API has a fixed credit cost per request. Heavier endpoints (e.g. flights, serp, web scraping api) consume more credits due to their complexity and processing requirements. Lightweight APIs (e.g. Google SERP Light) are more cost-efficient. Use this table to compare the cost per request for each API. ### Web Scraping | API | CPM | Credits per Request | | ---------------------------------------------------- | ------ | ------------------- | | Web Scraping API *(no js rendering / basic proxy)* | \$0.08 | 1 | | Web Scraping API *(no js rendering / stealth proxy)* | \$0.42 | 5 | | Web Scraping API *(js rendering / basic proxy)* | \$0.83 | 10 | | Web Scraping API *(js rendering / stealth proxy)* | \$1.25 | 15 | ### Google | API | CPM | Credits per Request | | ----------------------------------- | ------ | ------------------- | | Google SERP API | \$0.83 | 10 | | Google News API | \$0.83 | 5 | | Google Events API | \$0.42 | 5 | | Google Product API | \$0.42 | 5 | | Google Flights API | \$1.25 | 5 | | Google Maps API | \$0.42 | 5 | | Google Maps Reviews API | \$0.42 | 5 | | Google Maps Contributor Reviews API | \$0.42 | 5 | | Google Images API | \$0.42 | 5 | | Google Trends API | \$1.25 | 5 | ### Amazon | API | CPM | Credits per Request | | ------------------ | ------ | ------------------- | | Amazon Search API | \$0.42 | 5 | | Amazon Product API | \$0.42 | 5 | | Amazon Reviews API | \$0.42 | 5 | ### Yelp | API | CPM | Credits per Request | | --------------- | ------ | ------------------- | | Yelp Search API | \$0.42 | 5 | | Yelp Place API | \$0.42 | 5 | ### Zillow | API | CPM | Credits per Request | | ------------------- | ------ | ------------------- | | Zillow Property API | \$0.42 | 5 | | Zillow Listing API | \$0.42 | 5 | ### Shopify | API | CPM | Credits per Request | | ----------------------- | ------ | ------------------- | | Shopify Products API | \$0.42 | 5 | | Shopify Collections API | \$0.42 | 5 | ### Redfin | API | CPM | Credits per Request | | ------------------- | ------ | ------------------- | | Redfin Property API | \$0.42 | 5 | | Redfin Listing API | \$0.42 | 5 | ### AirBnB | API | CPM | Credits per Request | | ------------------- | ------ | ------------------- | | AirBnB Property API | \$0.42 | 5 | | AirBnb Listing API | \$0.42 | 5 | ### Indeed | API | CPM | Credits per Request | | ------------------ | ------ | ------------------- | | Indeed Job API | \$0.42 | 5 | | Indeed Listing API | \$0.42 | 5 | ## Scraper Job Pricing Scraper Jobs are billed per data row returned. The more rows you extract, the more credits are used. Some jobs require more processing (pagination, rendering, retries), which affects cost per row. Use this table to see how many credits each scraper consumes per row of data. | Scraper | CPM | Credits per Data Row | | -------------------------------- | ------ | -------------------- | | Google Maps Scraper | \$0.25 | 3 | | Google Search Results Scraper | \$0.08 | 1 | | Phone, Email and Contact Scraper | \$0.42 | 5 | | Google Maps Reviews Scraper | \$0.08 | 1 | | Yelp Scraper | \$0.08 | 1 | | Yellow Pages Scraper | \$0.08 | 1 | | Amazon Best Sellers Scraper | \$0.08 | 1 | | Amazon Search Scraper | \$0.83 | 10 | | Amazon Product Scraper | \$0.83 | 10 | | Zillow Real Estate Scraper | \$0.83 | 10 | | Redfin Property Scraper | \$0.83 | 10 | | Indeed Jobs Scraper | \$0.83 | 10 | | Shopify Scraper | \$0.08 | 1 | | AirBnb Scraper | \$0.83 | 10 | | Google Trends Scraper | \$0.08 | 5 | # CLI Source: https://docs.hasdata.com/cli Single-binary CLI for the HasData APIs — wired for shell scripts, LLM agents, and RAG pipelines. The **HasData CLI** is a static Go binary that exposes every HasData API as a subcommand. Output is JSON on stdout — pipe it into `jq`, redirect it to a file, or call it from any language via `subprocess`. Source: [github.com/HasData/hasdata-cli](https://github.com/HasData/hasdata-cli). ## Install ```bash macOS / Linux theme={null} curl -sSL https://raw.githubusercontent.com/HasData/hasdata-cli/main/install.sh | sh ``` ```bash Go theme={null} go install github.com/HasData/hasdata-cli@latest ``` ```bash Windows theme={null} # Download the .zip from the Releases page, extract, then add hasdata.exe to %PATH%. # https://github.com/HasData/hasdata-cli/releases ``` The install script verifies SHA-256 checksums and detects OS/arch automatically. ## Authentication Get your API key from the [dashboard](https://app.hasdata.com), then save it once: ```bash theme={null} hasdata configure ``` This writes the key to `~/.hasdata/config.yaml`. Resolution order, highest precedence first: 1. `--api-key ` flag 2. `HASDATA_API_KEY` environment variable 3. `~/.hasdata/config.yaml` ## Usage ``` hasdata [flags] [--pretty|--raw] [--output FILE] ``` Each API endpoint is a subcommand. Flag names mirror the API parameters, kebab-cased: `outputFormat` → `--output-format`, `priceMin` → `--price-min`. Object/array params take a `---json` variant that accepts a JSON string, file path, or stdin. ### Examples ```bash Google SERP theme={null} hasdata google-serp --q "langchain vs llamaindex" --gl us --pretty ``` ```bash Web Scraping with AI extraction theme={null} hasdata web-scraping \ --url "https://news.ycombinator.com" \ --output-format markdown \ --ai-extract-rules-json '{"top_story":{"type":"string"}}' ``` ```bash Zillow listing search theme={null} hasdata zillow-listing \ --keyword "Austin, TX" --type forSale \ --price-min 400000 --price-max 900000 \ --beds-min 3 --sort priceLowToHigh ``` ### Output and exit codes Output auto-formats as pretty JSON when stdout is a TTY and as raw JSON when piped. Force either with `--pretty` / `--raw`. Exit codes: `0` success, `1` user error, `2` network, `3` API 4xx, `4` API 5xx. ### Common flags | Flag | Purpose | | ------------------------ | -------------------------------------------------- | | `--api-key` | Override the configured API key | | `--pretty` / `--raw` | Force output formatting | | `--output FILE` | Write the response to a file | | `--verbose` | Print request URL and rate-limit headers to stderr | | `--timeout`, `--retries` | Per-request controls | | `--help` | Per-command schema and examples | ## Supported commands The CLI ships a subcommand for every API documented under **Web Scraping API**, **Google SERP API**, **Google AI Mode API**, **Google Maps API**, and **Scraper APIs**. Run `hasdata --help` for the full list, or `hasdata --help` for parameter schemas. ## Updates ```bash theme={null} hasdata update --check # check for a new version hasdata update # install the latest release ``` The CLI auto-checks daily and notifies via stderr; it never updates without your consent. ## Billing Each subcommand consumes credits at the same rate as a direct API call. See [Credits and Concurrency](/credits-and-concurrency) for details. # Credits & Concurrency Source: https://docs.hasdata.com/credits-and-concurrency ## Credits System HasData uses a **credits-based pricing model** because the complexity and cost of scraping varies. Some APIs and scrapers require more resources and cost more credits. * **Successful Requests**: Only successful requests consume credits. Failed or invalid requests will not result in a charge. * **Credits per API Request**: Different APIs have different costs. For example, the Google Maps API consume 5 credits per request, while a more complex service, such as Google SERP API, might consume 10 credits per request. * **Credits per Scraper Job**: Scraper Jobs also follow the credit model. Each row of data returned by a scraper consumes a set amount of credits (e.g., 1 credit per row). You can track your credit consumption and remaining balance in the Dashboard. Credits are updated in real-time, so you can always see how many credits you've used and how much is left. ## Concurrency Concurrency refers to the number of simultaneous requests you can make to the API. * **Free Users**: Free accounts are limited to 1 concurrent request at a time. * **Paid Users**: Concurrency limits for paid users are defined by the plan you select. ### Exceeding Concurrency Limits If you exceed your concurrency limit, the API will return a `429 Too Many Requests` response, indicating that you've hit the maximum number of concurrent requests allowed. ### Scaling Concurrency To increase your concurrency limit, upgrade your plan. For custom limits, contact support to discuss your needs. ## Monitoring & Notifications You’ll receive real-time notifications when your credits are running low. To monitor credit consumption and concurrency usage programmatically, use the `/user/me/usage` endpoint. ```bash cURL theme={null} curl --request GET \ --url 'https://api.hasdata.com/user/me/usage' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/user/me/usage', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/user/me/usage" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/user/me/usage", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/user/me/usage") .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.hasdata.com/user/me/usage"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/user/me/usage") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/user/me/usage") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.hasdata.com/user/me/usage", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` Response: ```json theme={null} { "status": "ok", "data": { "totalCredits": 10000000, "availableCredits": 5473702, "concurrentRequests": 0, "availableConcurrency": 100 } } ``` ## FAQ You can track your remaining and used credits in the [dashboard](https://app.hasdata.com/dashboard). It updates in real time as you make requests. Your scraper jobs will be stopped, and you won’t be able to continue them once they stop. You also won’t be able to make any new requests. To avoid interruptions, you can enable auto-renew, which automatically renews your plan when you run out of credits. Yes. You can upgrade to a higher plan or reach out to support to discuss custom limits. No. You’re only charged for successful requests. # Introduction Source: https://docs.hasdata.com/introduction HasData extracts data quickly and reliably from any source. HasData HasData HasData is a cloud-based web scraping API that simplifies web-scraping tasks for businesses of all sizes. It eliminates the need to manage expensive infrastructure and handle proxy rotation, headless browsers, and other challenges when scraping complex websites. ## Key Features of HasData * **Reliable Data Extraction**: Consistently gather accurate data, even from difficult-to-scrape sources, with 99.9% uptime. * **Fast Response Times**: Median API latency under 2 seconds, ensuring real-time data delivery for your applications. * **Scalable Infrastructure**: Handle millions of requests per hour with optimized infrastructure that grows with your needs. * **Legal Compliance**: We only scrape public data, ensuring full compliance with GDPR, CCPA, and other legal frameworks. * **LLM-Ready Data**: Data structured and optimized for integration with Large Language Models (LLMs), ready for AI-powered applications. # MCP Server Source: https://docs.hasdata.com/mcp-server Connect LLM clients and AI agents to HasData via the Model Context Protocol. The **HasData MCP Server** exposes HasData's scraping and search capabilities to any client that speaks the [Model Context Protocol](https://modelcontextprotocol.io). Point your MCP-enabled client (Claude, Codex, Cursor, VS Code, Windsurf, custom agents, etc.) at the HasData endpoint and your model can scrape web pages, run Google searches, and pull structured data without writing API integration code. ## Endpoint ``` https://mcp.hasdata.com/mcp ``` The server uses the streamable HTTP transport. ## Authentication Two ways to connect: sign in with your HasData account, or send an API key. ### Sign in with your HasData account Clients that support OAuth connect without you handling a key: add the endpoint and follow the sign-in prompt. Each connection gets its own API key, named after the client — delete that key on the [API keys page](https://app.hasdata.com/api-keys) to disconnect it. ```bash Claude Code theme={null} claude mcp add --transport http hasdata https://mcp.hasdata.com/mcp # then run /mcp and authenticate ``` ```bash Codex theme={null} codex mcp add hasdata --url https://mcp.hasdata.com/mcp codex mcp login hasdata ``` ```bash VS Code theme={null} code --add-mcp '{"name":"hasdata","type":"http","url":"https://mcp.hasdata.com/mcp"}' ``` ```text Claude Desktop / claude.ai theme={null} Settings → Connectors → Add custom connector → https://mcp.hasdata.com/mcp ``` ```text Cursor theme={null} Settings → MCP → Add custom MCP → https://mcp.hasdata.com/mcp ``` ### API key Send your key from the [dashboard](https://app.hasdata.com/api-keys) in the `x-api-key` header. Use this for clients without OAuth support, and for unattended agents. ```bash Claude Code theme={null} claude mcp add --transport http hasdata https://mcp.hasdata.com/mcp \ --header "x-api-key: " ``` ```json Cursor theme={null} // ~/.cursor/mcp.json { "mcpServers": { "hasdata": { "url": "https://mcp.hasdata.com/mcp", "headers": { "x-api-key": "" } } } } ``` ```json Windsurf theme={null} // ~/.codeium/windsurf/mcp_config.json { "mcpServers": { "hasdata": { "serverUrl": "https://mcp.hasdata.com/mcp", "headers": { "x-api-key": "" } } } } ``` ```json Cline theme={null} // cline_mcp_settings.json { "mcpServers": { "hasdata": { "type": "streamableHttp", "url": "https://mcp.hasdata.com/mcp", "headers": { "x-api-key": "" } } } } ``` ```toml Codex theme={null} # ~/.codex/config.toml [mcp_servers.hasdata] url = "https://mcp.hasdata.com/mcp" env_http_headers = { "x-api-key" = "HASDATA_API_KEY" } ``` Any other client that speaks the streamable HTTP transport works the same way: point it at the endpoint and send `x-api-key`. Requests with no valid credential are rejected with `401 Unauthorized`. ## Choosing Which APIs to Expose By default the server exposes all 57 HasData APIs as tools, and your model re-reads all 57 tool definitions on every call. Add the `apis` parameter to expose only the ones you need: ``` https://mcp.hasdata.com/api/mcp?apis=amazon,shopify ``` That connection has 7 tools instead of 57. Authentication, billing and tool behaviour are unchanged. Name a provider to get all of its APIs, or name a single API — `?apis=google_maps_search,web_scraping` gives two tools. | Provider | Individual APIs | | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `airbnb` | `airbnb_listing`, `airbnb_property` | | `amazon` | `amazon_product`, `amazon_reviews`, `amazon_search`, `amazon_seller`, `amazon_seller_products` | | `bing` | `bing_serp` | | `booking` | `booking_place`, `booking_search` | | `duckduckgo` | `duckduckgo_serp` | | `glassdoor` | `glassdoor_job`, `glassdoor_listing` | | `google_images` | `google_images_images` | | `google_maps` | `google_maps_contributor_reviews`, `google_maps_photos`, `google_maps_place`, `google_maps_posts`, `google_maps_reviews`, `google_maps_search` | | `google_scholar` | `google_scholar_cite`, `google_scholar_scholar` | | `google_serp` | `google_serp_ai_mode`, `google_serp_ai_overview`, `google_serp_events`, `google_serp_immersive_product`, `google_serp_news`, `google_serp_product`, `google_serp_serp`, `google_serp_serp_light`, `google_serp_shopping`, `google_serp_short_videos` | | `google_travel` | `google_travel_flights`, `google_travel_hotels` | | `google_trends` | `google_trends_search` | | `indeed` | `indeed_job`, `indeed_listing` | | `instagram` | `instagram_posts`, `instagram_profile` | | `redfin` | `redfin_listing`, `redfin_property` | | `shopify` | `shopify_collections`, `shopify_products` | | `tiktok` | `tiktok_comments`, `tiktok_posts`, `tiktok_profile`, `tiktok_search` | | `walmart` | `walmart_product`, `walmart_reviews`, `walmart_search` | | `web_scraping` | `web_scraping_web_scraping` | | `yellowpages` | `yellowpages_place`, `yellowpages_search` | | `yelp` | `yelp_place`, `yelp_reviews`, `yelp_search` | | `youtube` | `youtube_channel`, `youtube_search`, `youtube_transcript`, `youtube_video` | | `zillow` | `zillow_listing`, `zillow_property` | A misspelled name is ignored and the rest still loads. If every name is misspelled the request fails with `400` and lists the valid providers. ## Billing Each tool call consumes HasData credits the same way a direct API request would, from the workspace the connection is attached to. See [Credits and Concurrency](/credits-and-concurrency) for details. # OpenClaw Skill Source: https://docs.hasdata.com/openclaw Drop the HasData skill into OpenClaw for real-time web data via the hasdata CLI. The **HasData skill** for [OpenClaw](https://clawhub.ai) wraps the [HasData CLI](/cli) so agents can fetch real-time web data: search, maps, e-commerce, real estate, jobs, social, and arbitrary scraping. Marketplace listing: [clawhub.ai/hasdata/hasdata-api](https://clawhub.ai/hasdata/hasdata-api). Source: [github.com/HasData/hasdata-cli](https://github.com/HasData/hasdata-cli). ## Install ```bash OpenClaw theme={null} openclaw skills install hasdata/hasdata-api ``` ```bash ClawHub theme={null} npx clawhub@latest install hasdata-api ``` The skill depends on the `hasdata` binary. Install it once: ```bash theme={null} curl -sSL https://raw.githubusercontent.com/HasData/hasdata-cli/main/install.sh | sh ``` See the [CLI page](/cli) for Go and Windows install paths. ## Configure The skill reads your API key from the standard CLI location. Run once: ```bash theme={null} hasdata configure ``` This writes the key to `~/.hasdata/config.yaml` (mode `0600`). You can also export `HASDATA_API_KEY` in your shell. Get the key from the [dashboard](https://app.hasdata.com). ## How the agent invokes it The skill maps natural-language intent to one of 30+ CLI subcommands. Action names match the [CLI](/cli) one-to-one: | Intent | Subcommand(s) | | ----------------- | ------------------------------------------------------ | | Web search | `google-serp`, `google-serp-light`, `bing-serp` | | News | `google-news` | | Shopping & prices | `google-shopping`, `amazon-search`, `shopify-products` | | Maps & reviews | `google-maps`, `google-maps-place`, `yelp-search` | | Real estate | `zillow-listing`, `redfin-property`, `airbnb-listing` | | Jobs | `indeed-job`, `glassdoor-job` | | Social | `instagram-profile` | | Arbitrary URLs | `web-scraping` (JS rendering, proxies, AI extraction) | ## Billing Each call costs the same as the equivalent direct API request, and every response includes the credit usage. See [Credits and Concurrency](/credits-and-concurrency). ## Security * API key lives in `~/.hasdata/config.yaml` at mode `0600`. Protect it like any other credential. # Quickstart Source: https://docs.hasdata.com/quickstart Start scraping data in under 5 minutes ## API Key HasData uses API keys to authenticate requests. To use the API you need to [sign up](https://app.hasdata.com/sign-up) for an account and include your unique API key in every request. ## Make Your First API Request Start by making a simple request to one of our APIs. Here’s an example for the Google SERP API: **Authentication**: Your API key must be passed in the request headers using `x-api-key`. If it’s missing or incorrect, the API will respond with 401 Unauthorized. ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrape/google/serp' \ --data-urlencode 'q=Coffee' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```bash HasData CLI theme={null} hasdata google-serp \ --q Coffee ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrape/google/serp', params: {q: 'Coffee'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/google/serp" querystring = {"q":"Coffee"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "Coffee", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/google/serp?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrape/google/serp") .newBuilder() .addQueryParameter("q", "Coffee") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["q"] = "Coffee"; var url = $"https://api.hasdata.com/scrape/google/serp?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrape/google/serp") params = { "q" => "Coffee", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrape/google/serp") .query(&[("q", "Coffee")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("q", "Coffee") u := "https://api.hasdata.com/scrape/google/serp?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` Stored artifacts — the `html`, `json` and `preview` links and result thumbnails under `files.hasdata.com` — are private to your workspace. Fetch them with your API key in the `x-api-key` header, or browse them from the dashboard. ```json theme={null} { "requestMetadata":{ "id":"cbf76761-d185-457f-978f-24ae53305572", "status":"ok", "html":"https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/cbf76761-d185-457f-978f-24ae53305572.html", "url":"https://www.google.com/search?q=Coffee&uule=w+CAIQICIaQXVzdGluLFRleGFzLFVuaXRlZCBTdGF0ZXM%3D&hl=en&gl=us&sourceid=chrome&ie=UTF-8" }, "searchInformation":{ "totalResults":"4230000000", "timeTaken":0.35 }, "organicResults":[ { "position":1, "title":"Coffee", "link":"https://en.wikipedia.org/wiki/Coffee", "displayedLink":"https://en.wikipedia.org › wiki › Coffee", "source":"Wikipedia", "snippet":"Coffee is a beverage brewed from roasted, ground coffee beans. Darkly colored, bitter, and slightly acidic, coffee has a stimulating effect on humans, ...", "snippetHighlitedWords":[ "Coffee" ], "images":[ "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/2eaf0e8f-937a-4350-80d5-9c97614e5d17.jpeg" ] }, { "position":2, "title":"Coffee ground collection : r/Austin", "link":"https://www.reddit.com/r/Austin/comments/1jwzyjm/coffee_ground_collection/", "displayedLink":"1 comment · 2 hours ago", "source":"Reddit · r/Austin", "snippet":"I'm looking for coffee grounds for my garden. Do y'all know any shops that will give out coffee grounds?", "snippetHighlitedWords":[ "coffee grounds" ], "sitelinks":{ "list":[ { "title":"r/Coffee - Reddit", "link":"https://www.reddit.com/r/Coffee/", "snippet":"Mar 6, 2014" }, { "title":"Coffee roasters or shops that sell coffee beans/quality ground ...", "link":"https://www.reddit.com/r/austinfood/comments/18mb2bn/coffee_roasters_or_shops_that_sell_coffee/", "snippet":"Dec 19, 2023" } ] } }, { "position":3, "title":"Starbucks rival coffee chain closes struggling location", "link":"https://www.thestreet.com/restaurants/popular-coffee-chain-closes-struggling-location", "displayedLink":"https://www.thestreet.com › restaurants › popular-coffe...", "source":"TheStreet", "snippet":"22 hours ago — Starbucks rival coffee chain closes struggling location. Economic problems force the popular coffeehouse chain to close an iconic location.", "snippetHighlitedWords":[ "Starbucks rival coffee chain closes struggling location" ] }, { "position":4, "title":"coffee brand coffee: premium fresh roasted coffee", "link":"https://coffeebrandcoffee.com/?srsltid=AfmBOoos2TjferbFWY-B23I-abFOVvGavhTYv8O-lMTHub6pttrj0vRk", "displayedLink":"https://coffeebrandcoffee.com", "source":"Coffee Brand Coffee", "snippet":"We work with the best, pick standout beans, and we're all about our community. Expect great coffee, new flavors, plus snacks and hot cocoa. That's it.", "snippetHighlitedWords":[ "great coffee, new flavors, plus snacks and hot cocoa" ], "sitelinks":{ "inline":[ { "title":"Coffee", "link":"https://coffeebrandcoffee.com/collections/coffee" }, { "title":"Medium Roast Coffee", "link":"https://coffeebrandcoffee.com/products/003" }, { "title":"Dark Roast Coffee", "link":"https://coffeebrandcoffee.com/products/004" }, { "title":"Premium fresh roasted coffee", "link":"https://coffeebrandcoffee.com/en-ca" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQfaEt7OD14iW3jB8OzSZviiXSrVg60SJ_bva03qKBmAo1OzmyDjtvM&usqp=CAE&s" ] }, { "position":5, "title":"Buy Coffee, Tea, Powders Online | The Coffee Bean & Tea ...", "link":"https://www.coffeebean.com/", "displayedLink":"https://www.coffeebean.com", "source":"The Coffee Bean & Tea Leaf", "snippet":"Buy exceptional coffee, tea, powders, equipment and drinkware at The Coffee Bean & Tea Leaf® online store to enjoy our globally sourced products at home.", "snippetHighlitedWords":[ "Buy exceptional coffee, tea, powders, equipment and drinkware" ], "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTsIOSeY1yNSUPrbAV20oIxM9MHxytyL5EZu5EuSAS-BQrihKnkqSBn&usqp=CAE&s" ] }, { "position":6, "title":"Peet's Coffee | The Original Craft Coffee Since 1966", "link":"https://www.peets.com/", "displayedLink":"https://www.peets.com", "source":"Peet's Coffee", "snippet":"Since 1966, Peet's Coffee has sourced and offered superior coffees and teas adhered to strict high-quality and taste standards. Shop online today.", "snippetHighlitedWords":[ "Peet's Coffee" ], "sitelinks":{ "inline":[ { "title":"Shop All Coffee", "link":"https://www.peets.com/collections/all-coffees" }, { "title":"Store Locator", "link":"https://www.peets.com/pages/store-locator" }, { "title":"Coffee for Coffee People", "link":"https://www.peets.com/pages/coffeepeople" }, { "title":"Peet's Coffeebar Menu", "link":"https://www.peets.com/pages/menu" } ] } }, { "position":7, "title":"Starbucks Coffee Company", "link":"https://www.starbucks.com/", "displayedLink":"https://www.starbucks.com", "source":"Starbucks", "snippet":"More than just great coffee. Explore the menu, sign up for Starbucks® Rewards, manage your gift card and more.", "snippetHighlitedWords":[ "coffee" ], "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRChKfiV87kDO6bYuYGocHw1k9ZVBDKAPM-1X8bMO8WKxH-3T83uMBr&usqp=CAE&s" ] }, { "position":8, "title":"Texas Coffee Traders", "link":"https://www.texascoffeetraders.com/", "displayedLink":"https://www.texascoffeetraders.com", "source":"Texas Coffee Traders", "snippet":"The original East Austin coffee roasters. Providing fresh beans and friendly service, with a commitment to sustainability, quality, and community.", "snippetHighlitedWords":[ "Providing fresh beans and friendly service" ], "sitelinks":{ "inline":[ { "title":"Coffee beans", "link":"https://www.texascoffeetraders.com/coffee" }, { "title":"Contact Us", "link":"https://www.texascoffeetraders.com/contact" }, { "title":"Coffee Traders Merch", "link":"https://www.texascoffeetraders.com/coffee-traders-merch" }, { "title":"Who We Are", "link":"https://www.texascoffeetraders.com/our-story" } ] }, "images":[ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTN6aXkI7SO5F3mw4RRsIeRST-bzq1BlCSwBLcJN3Q&usqp=CAE&s" ] }, { "position":9, "title":"Scooter's Coffee | Be Amazing", "link":"https://www.scooterscoffee.com/", "displayedLink":"https://www.scooterscoffee.com", "source":"Scooter's Coffee", "snippet":"Wake up to the ahhh-mazing aroma of quality. Subscribe to Scooter's Coffee® delivery and enjoy 100% Arabica beans, sourced directly from farmers who take pride ...", "snippetHighlitedWords":[ "100% Arabica beans" ], "richSnippet":{ "top":{ "extensions":[ "2–9 day delivery" ] } }, "sitelinks":{ "inline":[ { "title":"Locations", "link":"https://www.scooterscoffee.com/locations" }, { "title":"Menu", "link":"https://www.scooterscoffee.com/menu" }, { "title":"At-Home Coffee", "link":"https://www.scooterscoffee.com/shop/at-home-coffee" }, { "title":"Relationship Coffee", "link":"https://www.scooterscoffee.com/relationship-coffee" } ] } } ], "localResults":{ "places":[ { "position":1, "title":"The Hideout Coffee House", "rating":4.4, "reviews":613, "reviewsOriginal":"(613)", "address":"617 Congress Ave.", "hours":"\"Amazing fruity espresso with very knowledgeable batistas\"", "placeId":"15498522356495312950", "description":"\"Amazing fruity espresso with very knowledgeable batistas\"" }, { "position":2, "title":"Houndstooth Coffee", "rating":4.6, "reviews":1100, "reviewsOriginal":"(1.1K)", "address":"401 Congress Ave. #100c", "hours":"Closes soon ⋅ 7 PM", "placeId":"11265938073076301333", "description":"\"Good coffee, comfortable atmosphere, minimal wait, and very nice staff!\"" }, { "position":3, "title":"Halcyon", "rating":4.3, "reviews":2000, "reviewsOriginal":"(2K)", "address":"218 W 4th St", "hours":"\"The coffees were good, plenty of seating and fantastic ambiance.\"", "placeId":"34322981427933494", "description":"\"The coffees were good, plenty of seating and fantastic ambiance.\"" } ], "moreLocationsLink":"https://www.google.com/search?sca_esv=8d7859a9eab70d70&hl=en&gl=us&tbm=lcl&q=Coffee&rflfq=1&num=10&uule=w+CAIQICIaQXVzdGluLFRleGFzLFVuaXRlZCBTdGF0ZXM%3D&sa=X&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQjGp6BAg2EAE" }, "relatedSearches":[ { "query":"Coffee near me", "link":"https://www.google.com/search?sca_esv=8d7859a9eab70d70&hl=en&gl=us&q=Coffee+near+me&sa=X&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ1QJ6BQibARAB" }, { "query":"Coffee Bean menu", "link":"https://www.google.com/search?sca_esv=8d7859a9eab70d70&hl=en&gl=us&q=Coffee+Bean+menu&sa=X&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ1QJ6BQiXARAB" }, { "query":"Coffee menu", "link":"https://www.google.com/search?sca_esv=8d7859a9eab70d70&hl=en&gl=us&q=Coffee+menu&sa=X&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ1QJ6BQiUARAB" }, { "query":"Coffee png", "link":"https://www.google.com/search?sca_esv=8d7859a9eab70d70&hl=en&gl=us&q=Coffee+png&sa=X&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ1QJ6BQiRARAB" }, { "query":"Coffee emoji", "link":"https://www.google.com/search?sca_esv=8d7859a9eab70d70&hl=en&gl=us&q=Coffee+emoji&sa=X&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ1QJ6BQiOARAB" }, { "query":"Coffee recipe", "link":"https://www.google.com/search?sca_esv=8d7859a9eab70d70&hl=en&gl=us&q=Coffee+recipe&sa=X&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ1QJ6BQiLARAB" }, { "query":"Coffee Table", "link":"https://www.google.com/search?sca_esv=8d7859a9eab70d70&hl=en&gl=us&q=Coffee+Table&sa=X&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ1QJ6BQiKARAB" }, { "query":"Coffee brands", "link":"https://www.google.com/search?sca_esv=8d7859a9eab70d70&hl=en&gl=us&q=Coffee+brands&sa=X&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ1QJ6BQiHARAB" } ], "relatedQuestions":[ { "aiOverview":{ "textBlocks":[ { "type":"paragraph", "snippet":"In general, coffee is considered healthy when consumed in moderation, offering various potential benefits.", "snippetHighlightedWords":[ "coffee is considered healthy when consumed in moderation" ] }, { "type":"paragraph", "snippet":"Potential Benefits:" }, { "type":"list", "list":[ { "snippet":"Reduced Risk of Certain Diseases: Studies suggest coffee may lower the risk of Parkinson's disease, type 2 diabetes, and certain cancers." }, { "snippet":"Improved Brain Function: Coffee can enhance alertness, focus, and reaction time, potentially boosting cognitive performance." }, { "snippet":"Antioxidant Rich: Coffee is a significant source of antioxidants in the diet." }, { "snippet":"Other Potential Benefits: Coffee may improve mood, athletic performance, and even longevity." } ] }, { "type":"paragraph", "snippet":"Potential Risks:" }, { "type":"list", "list":[ { "title":"Caffeine Side Effects:", "snippet":"Excessive caffeine intake can lead to anxiety, insomnia, fast heart rate, and digestive issues." }, { "title":"Impact on Bone Density:", "snippet":"Some studies suggest a link between high coffee consumption (5+ cups daily) and lower bone density, particularly in women." }, { "title":"Interactions with Medications:", "snippet":"Caffeine can interact with certain medications, so it's important to be mindful of these interactions." } ] }, { "type":"paragraph", "snippet":"Moderation is Key:" }, { "type":"list", "list":[ { "snippet":"Most healthy adults can safely consume up to 400 milligrams of caffeine per day, which is roughly equivalent to four cups of brewed coffee." }, { "snippet":"Individuals with certain medical conditions, pregnant women, or those taking certain medications should consult with a healthcare professional about coffee consumption." } ] } ], "references":[ { "link":"https://www.mayoclinic.org/healthy-lifestyle/nutrition-and-healthy-eating/expert-answers/coffee-and-health/faq-20058339#:~:text=Drinking%20coffee%20with%20caffeine%20has,and%20it%20may%20have%20benefits.", "title":"Coffee and health: What does the research say? - Mayo Clinic", "snippet":"Drinking coffee with caffeine has been linked with improved mood and a lower risk of depression in some groups. Drinking 3 to 4 cu...", "source":"Mayo Clinic", "index":0 }, { "link":"https://www.hopkinsmedicine.org/health/wellness-and-prevention/9-reasons-why-the-right-amount-of-coffee-is-good-for-you", "title":"9 Reasons Why (the Right Amount of) Coffee Is Good for You", "snippet":" Here are the top ways coffee can positively impact your health: * You could live longer. ... * Your body may process glucose (or ...", "source":"Johns Hopkins Medicine", "index":1 }, { "link":"https://utswmed.org/medblog/is-coffee-good-for-you/", "title":"Is coffee good for you? | Diet and Nutrition | UT Southwestern Medical Center", "snippet":"", "source":"UT Southwestern Medical Center", "index":2 }, { "link":"https://www.healthline.com/nutrition/top-evidence-based-health-benefits-of-coffee#:~:text=Coffee%20is%20a%20major%20source%20of%20antioxidants,and%20a%20lower%20risk%20of%20several%20diseases.", "title":"9 Health Benefits of Coffee, Based on Science", "snippet":"Jan 11, 2022 — Coffee is a major source of antioxidants in the diet. It has many health benefits, such as improved brain function and...", "source":"Healthline", "index":3 }, { "link":"https://www.mayoclinic.org/healthy-lifestyle/nutrition-and-healthy-eating/in-depth/caffeine/art-20045678#:~:text=Up%20to%20400%20milligrams%20(mg,widely%2C%20especially%20among%20energy%20drinks.", "title":"Caffeine: How much is too much? - Mayo Clinic", "snippet":"Up to 400 milligrams (mg) of caffeine a day appears to be safe for most healthy adults. That's roughly the amount of caffeine in f...", "source":"Mayo Clinic", "index":4 } ] }, "question":"Is coffee good or bad for health?" }, { "aiOverview":{ "textBlocks":[ { "type":"paragraph", "snippet":"The \"80/20 rule\" for coffee, also known as the Pareto Principle, suggests that focusing on a small number of key factors (20%) can yield a significant portion (80%) of the desired results in coffee brewing, like achieving a delicious cup of coffee with minimal effort.", "snippetHighlightedWords":[ "focusing on a small number of key factors (20%) can yield a significant portion (80%) of the desired results in coffee brewing" ] }, { "type":"paragraph", "snippet":"Here's a breakdown of how the 80/20 rule applies to coffee:" }, { "type":"list", "list":[ { "title":"Focus on the Fundamentals:", "snippet":"Instead of getting bogged down in complex equipment or obscure brewing methods, concentrate on the core elements that have the biggest impact on the final cup." }, { "title":"Key Factors:", "snippet":"These core elements often include:" }, { "snippet":"Freshly Roasted Beans: Use high-quality, recently roasted beans for the best flavor." }, { "snippet":"Proper Grinding: Grind your beans to the appropriate consistency for your brewing method." }, { "snippet":"Water Quality: Use filtered water for a cleaner, more flavorful cup." }, { "snippet":"Brewing Time and Temperature: Adhere to the recommended brewing time and temperature for your chosen method." }, { "snippet":"Coffee-to-Water Ratio: Use a consistent and appropriate coffee-to-water ratio." }, { "title":"Optimizing for Sweetness:", "snippet":"The goal is to extract the coffee to a point just before it becomes dry or bitter, focusing on sweetness." }, { "title":"Lazy Barista Method:", "snippet":"This approach emphasizes finding the sweet spot for your coffee by focusing on the key factors and not getting overly concerned with every detail." }, { "title":"Example:", "snippet":"If you're struggling with consistently bad-tasting coffee, don't immediately invest in a new machine. Instead, start by ensuring you're using fresh beans, grinding them properly, and using filtered water." }, { "title":"Application to Espresso:", "snippet":"The 80/20 rule can also be applied to espresso, where focusing on the fundamentals like proper grind size, tamping, and extraction time can lead to a great shot of espresso." }, { "title":"Not Just for Brewing:", "snippet":"The 80/20 rule can also be applied to other aspects of coffee, such as choosing the right coffee shop or prioritizing which coffee drinks to order." } ] } ], "references":[ { "link":"https://www.youtube.com/watch?v=HE18U74W5XI&t=17", "title":"The 80/20 Rule: Espresso for Beginners - YouTube", "snippet":"Mar 26, 2024 — does that sound familiar. with so much noise going on in the online espresso. space it's enough to make you want to gi...", "source":"YouTube · The Coffee Chronicler", "index":0 }, { "link":"https://www.baristahustle.com/coffee-extraction-the-80-20-method/#:~:text=Here's%20how%20to%20use%20it%20for%20both%20Espresso%20and%20Filter%20Coffee:&text=Extract%20More%20=%20Grind%20finer%20AND,chart%20for%20you%20to%20follow.", "title":"Coffee Extraction - The 80:20 Method - Barista Hustle", "snippet":"Jan 30, 2017 — Here's how to use it for both Espresso and Filter Coffee: Extract More = Grind finer AND/OR brew for a longer time AND...", "source":"Barista Hustle", "index":1 }, { "link":"https://medium.com/barista-hustle/80-20-method-for-coffee-brewing-3e394c8b81b2#:~:text=So%20how%20do%20we%20get,coffee%20for%20the%20first%20time.", "title":"80/20 Method for Coffee Brewing - by Matthew Perger - Medium", "snippet":"Nov 9, 2015 — So how do we get there? It's super simple: If you remember, over extracted coffee is dry and bitter and under extracted...", "source":"Medium", "index":2 }, { "link":"https://grouptestwinner.com/the-80-20-rule-for-making-espresso/#:~:text=The%20sky's%20the%20limit%20when%20it%20comes,Fern%20Forest%20Cafe%20in%20Chiang%20Mai%20Thailand.", "title":"The 80/20 Rule for Making Espresso - Grouptest Winner", "snippet":"Jan 4, 2019 — The sky's the limit when it comes to home coffee making equipment. But by focusing on the essentials I say you can get ...", "source":"Grouptest Winner", "index":3 }, { "link":"https://zwarteroes.nl/en-int/blogs/koffie-zetten/wat-is-de-80-20-regel-voor-koffie#:~:text=The%2080%2D20%20Rule%20offers,of%20expert%2Dlevel%20coffee%20brewing.", "title":"What is the 80-20 rule for coffee? - Zwarte Roes", "snippet":"Apr 17, 2024 — The 80-20 Rule offers coffee lovers a simple, effective guide to improving their daily cup of coffee. By focusing on a...", "source":"Zwarte Roes", "index":4 }, { "link":"https://www.youtube.com/watch?v=iJS7o39Gkg0", "title":"The 80/20 Rule", "snippet":"Feb 6, 2025 — you open a coffee shop but begin to struggle what's going on you craft a dozen fancy drinks. but most customers just wa...", "source":"YouTube · Gohar Khan", "index":5 }, { "link":"https://fellowproducts.com/blogs/learn/the-golden-ratio-for-brewing-coffee#:~:text=SCAA%2C%20the%20Specialty%20Coffee%20Association,coffee%2C%20and%20personal%20taste%20preference.", "title":"The Golden Ratio For Brewing Coffee - Fellow", "snippet":"Feb 1, 2019 — SCAA, the Specialty Coffee Association of America, has come out with their golden ratio, which is approximately. 1:18. ", "source":"fellowproducts.com", "index":6 }, { "link":"https://www.rossstreetroasting.com/blogs/blog/making-the-perfect-cup-of-coffee-at-home-tips-from-the-experts#:~:text=There%20is%20something%20called%20the,should%20be%20served%20within%2015seconds.", "title":"Making the Perfect Cup of Coffee at Home: Tips from the Experts", "snippet":"Sep 14, 2021 — There is something called the 15/15/15/15 rule of thumb. Non-roasted beans will stale in 15 months. Roasted beans will...", "source":"Ross Street Roasting", "index":7 }, { "link":"https://www.haymakercoffeeco.com/press/The-Golden-Coffee-to-Water-Ratio-for-Each-Brew-Method1#:~:text=Thankfully%2C%20coffee%20experts%20around%20the,for%20more%20full%2Dbodied%20flavor.", "title":"The Golden Coffee to Water Ratio for Each Brew Method?", "snippet":"Thankfully, coffee experts around the world have figured out a tried-and-true, gold standard ratio: 1:17. It stands for 1 gram of ...", "source":"Haymaker Coffee Co.", "index":8 } ] }, "question":"What is the 80/20 rule for coffee?" }, { "snippet":"The top 10 coffee drinks often include espresso, americano, cappuccino, latte, macchiato, cortado, mocha, flat white, cold brew, and affogato. However, this list can vary depending on individual preferences and regional favourites.", "link":"https://balancecoffee.co.uk/blogs/blog/best-coffee-drinks-in-the-world", "title":"Best Coffee Drinks In The World (120 Days Drink Testing)", "displayedLink":"https://balancecoffee.co.uk › blogs › blog › best-coffee-...", "question":"What are the top 10 coffee drinks?" }, { "aiOverview":{ "textBlocks":[ { "type":"paragraph", "snippet":"Coffee, as a plant and beverage, is believed to have originated in the Kaffa region of Ethiopia, in the Ethiopian highlands, though its cultivation and development into the beverage we know today occurred in Yemen.", "snippetHighlightedWords":[ "believed to have originated in the Kaffa region of Ethiopia, in the Ethiopian highlands" ] }, { "type":"paragraph", "snippet":"Here's a more detailed look:" }, { "type":"list", "list":[ { "title":"Origin:", "snippet":"The coffee plant (Coffea arabica) is native to the Ethiopian highlands, specifically the Kaffa region." }, { "title":"Early Cultivation:", "snippet":"While coffee beans were likely used in Ethiopia for some time, it was in Yemen, particularly in the 15th century, that coffee was first cultivated and developed into the beverage we know today." }, { "title":"Spread of Coffee:", "snippet":"From Yemen, coffee spread throughout the Islamic world and eventually to Europe, where it gained immense popularity." }, { "title":"Coffee in the Americas:", "snippet":"Coffee cultivation also spread to the Americas, with Brazil becoming a major coffee-producing country." }, { "title":"Arabica vs. Robusta:", "snippet":"The two main species of coffee are Arabica (Coffea arabica) and Robusta (Coffea canephora), with Arabica being more prized for its flavor and aroma." }, { "title":"Coffee Belt:", "snippet":"Most coffee plants are grown in an area around the equator, known as the \"coffee belt,\" between the tropics of Capricorn and Cancer." } ] } ], "references":[ { "link":"https://en.wikipedia.org/wiki/History_of_coffee", "title":"History of coffee - Wikipedia", "snippet":" Americas * Gabriel de Clieu brought coffee seedlings to Martinique in the Caribbean in 1720. Those sprouts flourished and 50 year...", "source":"Wikipedia", "index":0 }, { "link":"https://www.nescafe.com/in/coffee-culture/knowledge/coffee-history#:~:text=European%20coffee%20history%20begins%20in,commodity%2C%20especially%20for%20wealthy%20people.", "title":"The History Of Coffee Origins and Cultural Significance | Nescafé IN", "snippet":"European coffee history begins in Italy, where it was imported from the Ottoman Empire. In particular, Venetian merchants contribu...", "source":"Nescafe", "index":1 }, { "link":"https://www.aboutcoffee.org/origins/history-of-coffee/#:~:text=Coffee%20arrived%20in%20Brazil%20thanks,billion%2Ddollar%20industry%20in%20Brazil.", "title":"History of coffee - NCA", "snippet":"Coffee arrived in Brazil thanks to the efforts (and charms) of Francisco de Mello Palheta, a Portuguese military officer sent by t...", "source":"About Coffee", "index":2 }, { "link":"https://usafacts.org/articles/where-does-americas-coffee-come-from/#:~:text=Aside%20from%20a%20small%20fraction,Colombia%2C%20Brazil%2C%20and%20Switzerland.&text=The%20United%20States%20drinks%20more,Colombia%2C%20Brazil%2C%20and%20Switzerland.", "title":"Where does America’s coffee come from? - USAFacts", "snippet":"Mar 14, 2024 — Aside from a small fraction grown in Hawaii, all of America's coffee comes imported from countries like Colombia, Braz...", "source":"USAFacts", "index":3 }, { "link":"https://en.wikipedia.org/wiki/Coffee", "title":"Coffee - Wikipedia", "snippet":" Cultivation and production * The traditional method of planting coffee is to place 20 seeds in each hole at the beginning of the ...", "source":"Wikipedia", "index":4 }, { "link":"https://www.britannica.com/topic/history-of-coffee#:~:text=Author%20of%20Les%20Caf%C3%A9iers%20et%20les%20caf%C3%A9s%20dans%20le%20monde.&text=coffee%20production%2C%20cultivation%20of%20coffee,cultivation%20further%20increase%20this%20diversity.", "title":"History of coffee | Origin, Facts, & Timeline - Britannica", "snippet":"Feb 28, 2025 — Author of Les Caféiers et les cafés dans le monde. ... coffee production, cultivation of coffee plants, usually done i...", "source":"Britannica", "index":5 }, { "link":"https://www.youtube.com/watch?v=voMC-eICDrg#:~:text=The%20coffee%20origin%20story%20of,takes%20a%20lot%20of%20time.&text=Afrimaxx%20Episode%203%20%2D%20YouTube,scenes%20of%20Europe's%20culinary%20culture.", "title":"and why good coffee takes a lot of time. | Afrimaxx Episode 3", "snippet":"Mar 4, 2023 — The coffee origin story of Ethopia – and why good coffee takes a lot of time. ... Afrimaxx Episode 3 - YouTube. This co...", "source":"YouTube · DW Food", "index":6 }, { "link":"https://www.britannica.com/topic/coffee#:~:text=By%20the%2020th%20century%20the,See%20also%20history%20of%20coffee.", "title":"Coffee | Origin, Types, Uses, History, & Facts - Britannica", "snippet":"By the 20th century the greatest concentration of production was centred in the Western Hemisphere—particularly Brazil. In the lat...", "source":"Britannica", "index":7 }, { "link":"https://www.espresso-international.com/where-does-coffee-come-from#:~:text=About%201000%20years%20after%20Christ,their%20first%20plantations%20in%20Yemen.", "title":"The discovery of the coffee bean | Origin & Legends", "snippet":"About 1000 years after Christ, it wasn´t Ethiopians or Italians, but the Arabs, who became the very first to start roasting and gr...", "source":"espresso-international.com", "index":8 }, { "link":"https://www.melitta.com/en/History-of-Coffee-629.html", "title":"Melitta® - History of Coffee", "snippet":"", "source":"Melitta", "index":9 }, { "link":"https://www.nescafe.com/gb/coffee-culture/knowledge/coffee-beans#:~:text=Where%20is%20coffee%20grown?,the%20coffee%20the%20beans%20produce.", "title":"Where Do Coffee Beans Come From? - Nescafe", "snippet":"Where is coffee grown? Most coffee plants are grown around what's known as 'the bean belt', an area around the equator between the...", "source":"Nescafe Global", "index":10 }, { "link":"https://varieties.worldcoffeeresearch.org/arabica-2/history-of-arabica#:~:text=From%20the%20Netherlands%2C%20plants%20were,the%20Dominican%20Republic%2C%20and%20Jamaica.", "title":"History of Arabica - World Coffee Research", "snippet":"From the Netherlands, plants were sent in 1719 on colonial trade routes to Dutch Guiana (now Suriname) and then on to Cayenne (Fre...", "source":"World Coffee Research", "index":11 }, { "link":"https://hanstrom.com/blog/where-does-coffee-come-from/#:~:text=Which%20countries%20grow%20the%20most,in%20the%20years%20to%20come.", "title":"Where Does Coffee Come From? A Guide to Countries & Beans", "snippet":"Aug 3, 2022 — Which countries grow the most coffee? Brazil was one of the top coffee growers in 2020 in the world, followed by Vietna...", "source":"Hanstrom", "index":12 }, { "link":"https://en.wikipedia.org/wiki/Coffee_bean#:~:text=Coffee%20plant,-The%20flower%20of&text=The%20coffee%20tree%20averages%20from,Coffea%20liberica%20and%20Coffea%20racemosa.", "title":"Coffee bean - Wikipedia", "snippet":"Coffee plant. ... The coffee tree averages from 5–10 m (16–33 ft) in height. As the tree gets older, it produces less fruit and sl...", "source":"Wikipedia", "index":13 }, { "link":"https://www.yemencoffeeonline.com/history-of-yemen-coffee/#:~:text=Most%20agree%20that%20the%20original,beverage%20that%20we%20know%20today.", "title":"History of Yemen Coffee - Al-Aqeeq Yemen Coffee Online", "snippet":"Most agree that the original coffee plants were native to the western regions of Ethiopia. Coffee was recorded as a beverage as ea...", "source":"yemencoffeeonline.com", "index":14 }, { "link":"https://iburucoffee.com/blogs/blog/where-did-coffee-come-from-originally#:~:text=What%20is%20the%20origin%20of,myths%2C%20legends%2C%20and%20facts.", "title":"Where did coffee come from originally?", "snippet":"Oct 21, 2021 — What is the origin of coffee beans? Many tales tell the story of discovering the first coffee bean and its very unique...", "source":"Iburu Coffee", "index":15 }, { "link":"https://stokescoffee.com/blogs/journal/where-does-coffee-come-from#:~:text=African%20Coffee:%20A%20Cradle%20of,that%20produce%20world%2Dclass%20coffee.", "title":"Where Does Coffee Come From?", "snippet":"Oct 27, 2023 — African Coffee: A Cradle of Diversity and Flavour Africa is the birthplace of coffee, and its coffee-producing countri...", "source":"Stokes Tea and Coffee - Lincoln", "index":16 }, { "link":"https://en.wikipedia.org/wiki/Coffee_in_Italy#:~:text=Caff%C3%A8%20(pronounced%20%5Bkaf%CB%88f%C9%9B%5D),the%20Europeans%20named%20it%20mokka.", "title":"Coffee in Italy - Wikipedia", "snippet":"Caffè (pronounced [kafˈfɛ]) is the Italian word for coffee and probably originates from Kaffa (Arabic: قهوة, romanized: Qahwa), th...", "source":"Wikipedia", "index":17 }, { "link":"https://colombiancoffee.us/blogs/news/the-history-of-the-coffee-bean-a-comprehensive-guide#:~:text=Where%20Does%20the%20Coffee%20Bean,drinkable%20and%20beneficial%20to%20locals.", "title":"The History of the Coffee Bean: A Comprehensive Guide", "snippet":"Where Does the Coffee Bean Come From? Depending on who you ask about the origin of coffee, some people will tell you the story of ...", "source":"Best Colombian Coffee Online", "index":18 }, { "link":"https://backyardbrew.com/blogs/coffee/where-does-coffee-come-from-its-history-origin#:~:text=Arabica%20coffee%20beans.-,Central%20American%20Coffee,producing%20countries%20of%20Central%20America:", "title":"Where does Coffee come from? Its History & Origin - Backyard Brew", "snippet":"Sep 13, 2024 — Central American Coffee Not just South America, but Central America also produces some great coffees. From chocolatey ...", "source":"backyardbrew.com", "index":19 }, { "link":"https://www.ictcoffee.com/news/coffee-origins-101-a-guide-to-south-american-coffee/#:~:text=A%20common%20misconception%20is%20that,was%20introduced%20to%20South%20America.", "title":"Coffee Origins 101: A Guide to South American Coffee", "snippet":"A common misconception is that coffee originated in South America. However, this is untrue. Coffee was first produced in Africa, a...", "source":"Intercontinental Coffee Trading", "index":20 }, { "link":"https://www.cafedumonde.co.uk/academie/guides/where-is-coffee-from/#:~:text=It%20is%20traditionally%20grown%20along,third%20of%20the%20world's%20coffee.", "title":"Where Is Coffee Grown? - Find Out More | Cafe Du Monde", "snippet":"It is traditionally grown along the “coffee belt” which sits in between the tropics of Cancer and Capricorn, this includes Central...", "source":"Cafedumonde.co.uk", "index":21 }, { "link":"https://www.quora.com/What-is-the-origin-of-coffee-in-the-world#:~:text=According%20to%20most%20researchers%2C%20the,Yemen%20and%20spread%20from%20there.&text=Coffee%20grown%20worldwide%20can%20trace,forests%20on%20the%20Ethiopian%20plateau.", "title":"What is the origin of coffee in the world? - Quora", "snippet":"Aug 16, 2023 — According to most researchers, the coffee bean originated in Ethiopia, however, evidence of drinking coffee dates back...", "source":"Quora", "index":22 }, { "link":"https://www.folger.edu/blogs/shakespeare-and-beyond/islamic-history-of-coffee/#:~:text=Historically%2C%20coffee%20as%20a%20hot,(Ralph%20Hattox%2C%201985).", "title":"Early modern coffee culture and history in the Islamic world", "snippet":"May 14, 2021 — Historically, coffee as a hot beverage was introduced to the world by the Sufi saints in 15th-century Yemen. They dran...", "source":"Folger Shakespeare Library", "index":23 }, { "link":"https://stonestreetcoffee.com/blogs/brooklyn-coffee-academy/ethiopia-the-birthplace-of-coffee#:~:text=Ethiopia%20is%20the%20birthplace%20of,beans%20knows%20that%20it's%20special.", "title":"Ethiopia, the Birthplace of Coffee | Stone Street Coffee", "snippet":"Ethiopia is the birthplace of coffee, so if you're a coffee-lover, you must experience the original to fully appreciate every othe...", "source":"Stone Street Coffee", "index":24 } ] }, "question":"Where does coffee originate?" } ], "knowledgeGraph":{ "title":"Coffee", "type":"Beverages" }, "perspectives":[ { "index":1, "author":"denny_dure", "source":"Instagram", "duration":"1:21", "extensions":[ "1.7K+ likes" ], "thumbnail":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQd1ZaZoT9iDBwd33JcmCvVsphQmJu1vkM1QiD4Zy9KN3RHzaZSKljLS3V1EQ&usqp=CAI&s", "title":"Not all coffee is created equal.\nCheap beans = cheap health\n\nGo for high-quality coffee:\n-Organic, single-origin, and fair-trade\n-Freshly roasted + properly stored\n-Whole beans you grind yourself\n-Brands with legit sourcing and testing\n\nPro tips: \n-Drink it after food (ideally not on an empty stomach)\n-Go dark roast if you’re sensitive to the acid, it’s easier on digestion\n-Skip the milk and sugar if you want to avoid bloating and acid reflux\n-Pairing black coffee with high-purity dark cocoa (70 percent or higher) may enhance blood sugar and blood pressure regulation. The polyphenols in coffee can help lower triglycerides and total cholesterol, while dark chocolate helps stabilize blood sugar levels, thus reducing the risk of Type 2 diabetes.\n\nCheers ☕️", "link":"https://www.instagram.com/reel/DIUXj28SWXy/", "date":"4 hours ago" }, { "index":2, "author":"Ethan Rode", "source":"TikTok", "duration":"0:35", "extensions":[ "7K+ views" ], "thumbnail":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAo-rki7nBcHHo_okJjG11tRLkRmXA803x-UpH423NUCrYHkUT2HFM6XtSOw&usqp=CAI&s", "title":"the coffee alphabet - irish coffee", "link":"https://www.tiktok.com/@ethanrodecoffee/video/7492091840892521774", "date":"7 hours ago" }, { "index":3, "author":"An0malyMusic", "source":"Facebook", "extensions":[ "9.8K+ reactions" ], "thumbnail":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR-9mOUsEPR17gzYT0A0ARXPGUhy-0hKX5N5TSGaXYxdJ4hP6y3twSAJ-ya&usqp=CAI&s", "title":"Coffee at home! Looool.", "link":"https://www.facebook.com/story.php?story_fbid=1229759848518715&id=100044541335084", "date":"23 hours ago" } ], "immersiveProducts":[ { "position":1, "category":"Popular products", "title":"Black Rifle Coffee Company Freedom Fuel Coffee", "productId":"18134019833504388210", "productLink":"https://www.google.com/shopping/product/18134019833504388210", "price":"$15.99", "extractedPrice":15.99, "source":"Black Rifle Coffee Company", "reviews":737, "rating":4.8, "delivery":"Free delivery on $75+", "extensions":[ "Also nearby" ], "thumbnail":"https://encrypted-tbn1.gstatic.com/shopping?q=tbn:ANd9GcQN_CC0gH6MlQF0lxouaL9ffMwqGDzOLJx7nMgSUegEGJtEHDqeDozUhk_QbccwjLxuQSWFUN61cOBtjBsKbZB4B_4Tbr_pOV_6HadyDwDBWg3Izexr5Ymo" }, { "position":2, "category":"Popular products", "title":"Ground Bones Coffee 5 Bag Sample Pack", "productId":"7733553032036677584", "productLink":"https://www.google.com/shopping/product/7733553032036677584", "price":"$33.00", "extractedPrice":33, "source":"Bones Coffee Company", "reviews":11000, "rating":4.8, "delivery":"Free delivery on $75+", "thumbnail":"https://encrypted-tbn1.gstatic.com/shopping?q=tbn:ANd9GcSraT7OVtMhg6QutGI2A2KdWz-jCFqQp4esNHj27_GSCG_HqLrJvA4NiW14IYiQ__nSpbevLv3Z46RG5zuaCARh2Zt_btlKX1AqK4MJILm6InwPLe1LNoRd1w" }, { "position":3, "category":"Popular products", "title":"Dunkin Donuts Ground Coffee Original Blend", "productId":"13144439343082777610", "productLink":"https://www.google.com/shopping/product/13144439343082777610", "price":"$6.99", "extractedPrice":6.99, "source":"Amazon.com", "reviews":8200, "rating":4.7, "extensions":[ "Also nearby" ], "thumbnail":"https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcTu-SWewPjVledda5FflGrBJ7kUjn2ruIEC7ioXgUs5OsUjPhgBC75UTPdt8lJ7LZGuuTV66dcKeaQtbty3Ep-h-BIyHSVXtNApEKQcQUNimwpfQK7U2-kQ7g" }, { "position":4, "category":"Popular products", "title":"Folgers Coffee Ground Classic Roast", "productId":"16914877625280977865", "productLink":"https://www.google.com/shopping/product/16914877625280977865", "price":"$5.78", "extractedPrice":5.78, "source":"Walmart", "reviews":15000, "rating":4.6, "extensions":[ "Nearby, 12 mi" ], "thumbnail":"https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcTyiImkxm7BL7GGtNo3eTT3YchvlhF9N6A5fg92bH1gXOoc4Ge2JumU5jzDDB5Df0Z-7bIz-Yi3DfDymwcdOyYdRkUGhln0dtjQDjQdP_caCgiSqkMLD-iX" }, { "position":5, "category":"Popular products", "title":"Death Wish Coffee Coffee", "productId":"984394624832565634", "productLink":"https://www.google.com/shopping/product/984394624832565634", "price":"$19.99", "extractedPrice":19.99, "source":"Death Wish Coffee Company", "reviews":6600, "rating":4.8, "delivery":"Free delivery on $50+", "extensions":[ "Also nearby" ], "thumbnail":"https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcSyM-1NVboEEP1dIg6_TmtRyNCDIR4mPv1T8q9G3o4HHHtSFWFQXm31KoYCUUGpw_-DPu7rIyYI_YBoTI2YY4GzZMPEWjDicaaIPYSxuiLbOSACCURhD8Oi" }, { "position":6, "category":"Popular products", "title":"Donut Shop Keurig K-Cups", "productId":"5750877340217241243", "productLink":"https://www.google.com/shopping/product/5750877340217241243", "price":"$25.99", "extractedPrice":25.99, "source":"Best Buy", "reviews":11000, "rating":4.6, "extensions":[ "Nearby, 15 mi" ], "thumbnail":"https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcRkwxyaYKyJNWJyKbrX-8p2yXZTh9KBE4BspLPpoOc9w5XJ_OjJgQoWK3ABDJ1LoPLnOgTaJPEQ63Wwe3Mn6N5QyomPGucSN9BHvSbgAA" }, { "position":7, "category":"Popular products", "title":"Maxwell House Wake Up Roast Ground Coffee", "productId":"10822717519905177294", "productLink":"https://www.google.com/shopping/product/10822717519905177294", "price":"$9.99", "extractedPrice":9.99, "source":"Walgreens.com", "reviews":134, "rating":4.6, "extensions":[ "Nearby, 13 mi" ], "thumbnail":"https://encrypted-tbn2.gstatic.com/shopping?q=tbn:ANd9GcTYjrQDUdIzTfvF0Ih7in3ZCvD7x0X2waWUa6Cfivz7WxKpOAgxyF_iBvsL5INGKhctELsiO3qPMJ8mVuMOnNAgF7ft9EXArDvnKsEXu4ZFJ-zM5inL4RYc" }, { "position":8, "category":"Popular products", "title":"Lavazza Caffe Espresso Whole Bean Coffee Blend", "productId":"8157153556221040021", "productLink":"https://www.google.com/shopping/product/8157153556221040021", "price":"$13.42", "extractedPrice":13.42, "source":"Amazon.com", "reviews":251, "rating":4.5, "extensions":[ "Also nearby" ], "thumbnail":"https://encrypted-tbn3.gstatic.com/shopping?q=tbn:ANd9GcTvD4eo-BfQtyQ8Fc1i0nFp66UKGhDXI51miW0yrqKpHxtu8c4g9n-f8lEMh27iH1Gs-i49OWNrudkHtii1YmKkWgtTlv8CcxyoLBlo5eZfK1WvgvzZ3QKMyA" } ], "pagination":{ "next":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=10&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8NMDegQIGBAW", "pages":[ { "2":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=10&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8tMDegQIGBAE" }, { "3":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=20&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8tMDegQIGBAG" }, { "4":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=30&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8tMDegQIGBAI" }, { "5":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=40&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8tMDegQIGBAK" }, { "6":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=50&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8tMDegQIGBAM" }, { "7":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=60&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8tMDegQIGBAO" }, { "8":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=70&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8tMDegQIGBAQ" }, { "9":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=80&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8tMDegQIGBAS" }, { "10":"https://www.google.com/search?q=Coffee&sca_esv=8d7859a9eab70d70&hl=en&gl=us&ei=Iab5Z_DgMPeNxc8Pnrmp4Ak&start=90&sa=N&sstk=Af40H4WrrNH32HivYNYYmgU1YCExb7yj43OG2xAVP0wmShkYZEmzJ4bEyIlWntbYOBCU6C-27JUs9vfqQbmYaQ1ddoDlqLX22TOusw&ved=2ahUKEwiw9eS5kdGMAxX3RvEDHZ5cCpwQ8tMDegQIGBAU" } ] } } ``` ## Web Scraping API Request Web Scraping API allows you to scrape web pages without the hassle of managing proxies, headless browsers, or retry logic. Simply send the URL and get the HTML response in return. ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrape/web' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"url":"https://example.com","outputFormat":["html","text","markdown"],"screenshot":true}' ``` ```bash HasData CLI theme={null} hasdata web-scraping \ --url 'https://example.com' \ --output-format 'html,text,markdown' \ --screenshot ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrape/web', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { url: 'https://example.com', outputFormat: ['html', 'text', 'markdown'], screenshot: true } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrape/web" payload = { "url": "https://example.com", "outputFormat": ["html", "text", "markdown"], "screenshot": True } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://example.com", "outputFormat" => ["html", "text", "markdown"], "screenshot" => true, ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrape/web", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "url": "https://example.com", "outputFormat": [ "html", "text", "markdown" ], "screenshot": true } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrape/web") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "url": "https://example.com", "outputFormat": [ "html", "text", "markdown" ], "screenshot": true } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrape/web") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrape/web") payload = { "url" => "https://example.com", "outputFormat" => ["html", "text", "markdown"], "screenshot" => true, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "url": "https://example.com", "outputFormat": [ "html", "text", "markdown" ], "screenshot": true }); let res = client .post("https://api.hasdata.com/scrape/web") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "url": "https://example.com", "outputFormat": [ "html", "text", "markdown" ], "screenshot": true }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrape/web", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ```json theme={null} { "requestMetadata": { "id": "e29e8506-143b-4872-a079-53b72e0edb10", "status": "ok" }, "headers": { "accept-ranges":"bytes", "alt-svc":"h3=\":443\"; ma=93600,h3-29=\":443\"; ma=93600,quic=\":443\"; ma=93600; v=\"43\"", "cache-control":"max-age=2589", "content-encoding":"gzip", "content-length":"648", "content-type":"text/html", "date":"Fri, 11 Apr 2025 23:41:30 GMT", "etag":"\"84238dfc8092e5d9c0dac8ef93371a07:1736799080.121134\"", "last-modified":"Mon, 13 Jan 2025 20:11:20 GMT", "vary":"Accept-Encoding" }, "screenshot": "https://files.hasdata.com/7c9e6679-7425-40de-944b-e07fc1f90ae7/e29e8506-143b-4872-a079-53b72e0edb10.jpeg", "content": "Example Domain ... ", "markdown": "# Example Domain\n\nThis domain is for use in ... [More information...](https://www.iana.org/domains/example)", "text": "Example Domain\n\nThis domain is for use in ... More information..." } ``` ## Submit Scraper Job Scraper Jobs are used for more complex tasks like crawling websites or extracting large datasets from platforms like Google Maps, Amazon, or Zillow. Unlike single-request APIs, Scraper Jobs run in the background and return results via webhook or polling once the data is ready. ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/crawler/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":25,"urls":["https://hasdata.com","https://example.com"],"maxDepth":5,"includePaths":"(blog/.+|articles/.+)","webhook":{"url":"https://example.com/webhook","events":["scraper.job.started","scraper.job.finished","scraper.data.scraped"]}}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/crawler/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { limit: 25, urls: ['https://hasdata.com', 'https://example.com'], maxDepth: 5, includePaths: '(blog/.+|articles/.+)', webhook: { url: 'https://example.com/webhook', events: ['scraper.job.started', 'scraper.job.finished', 'scraper.data.scraped'] } } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/crawler/jobs" payload = { "limit": 25, "urls": ["https://hasdata.com", "https://example.com"], "maxDepth": 5, "includePaths": "(blog/.+|articles/.+)", "webhook": { "url": "https://example.com/webhook", "events": ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"] } } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 25, "urls" => ["https://hasdata.com", "https://example.com"], "maxDepth" => 5, "includePaths" => "(blog/.+|articles/.+)", "webhook" => ["url" => "https://example.com/webhook", "events" => ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"]], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/crawler/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 25, "urls": [ "https://hasdata.com", "https://example.com" ], "maxDepth": 5, "includePaths": "(blog/.+|articles/.+)", "webhook": { "url": "https://example.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ] } } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/crawler/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 25, "urls": [ "https://hasdata.com", "https://example.com" ], "maxDepth": 5, "includePaths": "(blog/.+|articles/.+)", "webhook": { "url": "https://example.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ] } } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/crawler/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/crawler/jobs") payload = { "limit" => 25, "urls" => ["https://hasdata.com", "https://example.com"], "maxDepth" => 5, "includePaths" => "(blog/.+|articles/.+)", "webhook" => {"url" => "https://example.com/webhook", "events" => ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"]}, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 25, "urls": [ "https://hasdata.com", "https://example.com" ], "maxDepth": 5, "includePaths": "(blog/.+|articles/.+)", "webhook": { "url": "https://example.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ] } }); let res = client .post("https://api.hasdata.com/scrapers/crawler/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 25, "urls": [ "https://hasdata.com", "https://example.com" ], "maxDepth": 5, "includePaths": "(blog/.+|articles/.+)", "webhook": { "url": "https://example.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ] } }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/crawler/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ```json theme={null} { "id": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "status": "pending", "creditsSpent": 0, "dataRowsCount": 0, "input": { "limit": 25, "urls": ["https://hasdata.com", "https://example.com"], "maxDepth": 5, "includePaths": "(blog/.+|articles/.+)", "webhook": { "url": "https://example.com/webhook", "events": ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"] } } } ``` ### Get Scraper Job Status To get the status of an existing scraper job, make a GET request to the endpoint `/scrapers/jobs/:jobId`: ```bash cURL theme={null} curl --request GET \ --url 'https://api.hasdata.com/scrapers/jobs/:jobId' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrapers/jobs/:jobId', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/jobs/:jobId" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrapers/jobs/:jobId", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/jobs/:jobId") .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.hasdata.com/scrapers/jobs/:jobId"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrapers/jobs/:jobId") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrapers/jobs/:jobId") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.hasdata.com/scrapers/jobs/:jobId", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ```json theme={null} { "id": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "status": "finished", "creditsSpent": 250, "dataRowsCount": 25, "data": { "csv": "https://api.hasdata.com/scrapers/jobs/dd1a8c53-2d47-4444-977d-8d653a6a3c82/results/b6cc6733-6d0e-4e44-9e94-38688aad3884.csv", "json": "https://api.hasdata.com/scrapers/jobs/dd1a8c53-2d47-4444-977d-8d653a6a3c82/results/9cb592e3-6700-42ff-b58c-e7da3f478f28.json", "xlsx": "https://api.hasdata.com/scrapers/jobs/dd1a8c53-2d47-4444-977d-8d653a6a3c82/results/ecea853c-e0ca-4a23-ae74-eea0588e54b6.xlsx" }, "input": { "limit": 25, "urls": ["https://hasdata.com", "https://example.com"], "maxDepth": 5, "includePaths": "(blog/.+|articles/.+)", "webhook": { "url": "https://example.com/webhook", "events": ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"] } } } ``` ### Webhook The webhook will notify you of events related to the scraper job. Here is an example webhook payload for the `scraper.data.scraped` event: ```javascript theme={null} { "event": "scraper.data.scraped", "timestamp": "2025-04-11T14:30:00Z", "jobId": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "jobStatus": "in_progress", "dataRows": [ { "text": "Extracted text here...", "statusCode": 200, "statusText": "OK", "url": "https://hasdata.com/blog", "depth": 1, "title": "Blog | HasData" } ] } ``` # Airbnb Scraper Source: https://docs.hasdata.com/scrapers/airbnb Run vacancy and pricing analysis, track competitor listings, and source short-term rental investment leads. Returns listing id, url, title, address + coordinates, rating, reviews, room type, guest capacity, host profile (name, rating, reviews, years hosting, verification, host status), cohosts, total/original/discounted price with full breakdown, description, and photo gallery. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Airbnb. Airbnb is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **10 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/airbnb/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":100,"location":"New York","checkIn":"","checkOut":""}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/airbnb/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: {limit: 100, location: 'New York', checkIn: '', checkOut: ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/airbnb/jobs" payload = { "limit": 100, "location": "New York", "checkIn": "", "checkOut": "" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 100, "location" => "New York", "checkIn" => "", "checkOut" => "", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/airbnb/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 100, "location": "New York", "checkIn": "", "checkOut": "" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/airbnb/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 100, "location": "New York", "checkIn": "", "checkOut": "" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/airbnb/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/airbnb/jobs") payload = { "limit" => 100, "location" => "New York", "checkIn" => "", "checkOut" => "", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 100, "location": "New York", "checkIn": "", "checkOut": "" }); let res = client .post("https://api.hasdata.com/scrapers/airbnb/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 100, "location": "New York", "checkIn": "", "checkOut": "" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/airbnb/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Result rows limit Destination Check-in date (yyyy-mm-dd) Check-out date (yyyy-mm-dd) Adults Children Infants Pets ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | -------------------------- | ---------------- | | `email` | Email Address | Host email address | 5 credits | | `phone` | Phone Number | Host phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Host LinkedIn profile URL | 5 credits | | `facebookUrl` | Facebook Profile | Host Facebook profile URL | 5 credits | | `instagramUrl` | Instagram Profile | Host Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Host X profile URL | 5 credits | | `githubUrl` | GitHub Profile | Host GitHub profile URL | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Amazon Best Sellers Scraper Source: https://docs.hasdata.com/scrapers/amazon-bestsellers Spot trending products, find dropshipping candidates, and benchmark category leaders. Returns rank, ASIN, title, brand, current + before price, discount, rating, total reviews, feature bullets, "bought in past month", badges, variants, delivery dates, seller, shipper, primary + all images, specification, and customer-aspect summaries. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Amazon. Amazon is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **1 credit** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/amazon-bestsellers/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"urls":["https://www.amazon.com/gp/bestsellers/electronics/1292115011","https://www.amazon.com/best-sellers-books-Amazon/zgbs/books"]}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/amazon-bestsellers/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { urls: [ 'https://www.amazon.com/gp/bestsellers/electronics/1292115011', 'https://www.amazon.com/best-sellers-books-Amazon/zgbs/books' ] } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/amazon-bestsellers/jobs" payload = { "urls": ["https://www.amazon.com/gp/bestsellers/electronics/1292115011", "https://www.amazon.com/best-sellers-books-Amazon/zgbs/books"] } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} ["https://www.amazon.com/gp/bestsellers/electronics/1292115011", "https://www.amazon.com/best-sellers-books-Amazon/zgbs/books"], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/amazon-bestsellers/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "urls": [ "https://www.amazon.com/gp/bestsellers/electronics/1292115011", "https://www.amazon.com/best-sellers-books-Amazon/zgbs/books" ] } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/amazon-bestsellers/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "urls": [ "https://www.amazon.com/gp/bestsellers/electronics/1292115011", "https://www.amazon.com/best-sellers-books-Amazon/zgbs/books" ] } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/amazon-bestsellers/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/amazon-bestsellers/jobs") payload = { "urls" => ["https://www.amazon.com/gp/bestsellers/electronics/1292115011", "https://www.amazon.com/best-sellers-books-Amazon/zgbs/books"], } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "urls": [ "https://www.amazon.com/gp/bestsellers/electronics/1292115011", "https://www.amazon.com/best-sellers-books-Amazon/zgbs/books" ] }); let res = client .post("https://api.hasdata.com/scrapers/amazon-bestsellers/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "urls": [ "https://www.amazon.com/gp/bestsellers/electronics/1292115011", "https://www.amazon.com/best-sellers-books-Amazon/zgbs/books" ] }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/amazon-bestsellers/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Enter URLs of categories you want to scrape. Each URL must be on a different line. ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | ----------------------------------- | ---------------- | | `email` | Email Address | Amazon seller email address | 5 credits | | `website` | Website URL | Amazon seller website URL | 5 credits | | `phone` | Phone Number | Amazon seller phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Amazon seller LinkedIn page URL | 5 credits | | `facebookUrl` | Facebook Profile | Amazon seller Facebook page URL | 5 credits | | `instagramUrl` | Instagram Profile | Amazon seller Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Amazon seller X profile URL | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Amazon Product Scraper Source: https://docs.hasdata.com/scrapers/amazon-product Run catalog research, build price monitoring, and hydrate your own marketplace datasets. Returns ASIN, title, brand, price + before/used price, rating, reviews, availability, shipping-eligibility/recommendation/best-seller flags, description, full image and video galleries, feature bullets, specifications, and variants. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Amazon. Amazon is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **10 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/amazon-products/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"asins":["B0CRJ13WM7","https://www.amazon.com/dp/B0CMZ86H9D"],"domain":"www.amazon.com"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/amazon-products/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { asins: ['B0CRJ13WM7', 'https://www.amazon.com/dp/B0CMZ86H9D'], domain: 'www.amazon.com' } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/amazon-products/jobs" payload = { "asins": ["B0CRJ13WM7", "https://www.amazon.com/dp/B0CMZ86H9D"], "domain": "www.amazon.com" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} ["B0CRJ13WM7", "https://www.amazon.com/dp/B0CMZ86H9D"], "domain" => "www.amazon.com", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/amazon-products/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "asins": [ "B0CRJ13WM7", "https://www.amazon.com/dp/B0CMZ86H9D" ], "domain": "www.amazon.com" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/amazon-products/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "asins": [ "B0CRJ13WM7", "https://www.amazon.com/dp/B0CMZ86H9D" ], "domain": "www.amazon.com" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/amazon-products/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/amazon-products/jobs") payload = { "asins" => ["B0CRJ13WM7", "https://www.amazon.com/dp/B0CMZ86H9D"], "domain" => "www.amazon.com", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "asins": [ "B0CRJ13WM7", "https://www.amazon.com/dp/B0CMZ86H9D" ], "domain": "www.amazon.com" }); let res = client .post("https://api.hasdata.com/scrapers/amazon-products/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "asins": [ "B0CRJ13WM7", "https://www.amazon.com/dp/B0CMZ86H9D" ], "domain": "www.amazon.com" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/amazon-products/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Enter ASINs or URLs of products you want to scrape. Each ASIN or URL must be on a different line. Amazon domain to use. Default is [www.amazon.com](http://www.amazon.com). ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | ----------------------------------- | ---------------- | | `email` | Email Address | Amazon seller email address | 5 credits | | `website` | Website URL | Amazon seller website URL | 5 credits | | `phone` | Phone Number | Amazon seller phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Amazon seller LinkedIn page URL | 5 credits | | `facebookUrl` | Facebook Profile | Amazon seller Facebook page URL | 5 credits | | `instagramUrl` | Instagram Profile | Amazon seller Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Amazon seller X profile URL | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Amazon Reviews Scraper Source: https://docs.hasdata.com/scrapers/amazon-product-reviews Feed sentiment analysis, surface product issues, and mine customer language for marketing copy. Returns review id, ASIN, product title, review text, date, rating, likes, username, avatar, attached images and video, plus the associated product details. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Amazon. Amazon is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **10 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/amazon-product-reviews/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":100,"asins":["B096NP4QWH","https://www.amazon.com/Semwiss-Womens-Comfortable-Pointed-Leopard/dp/B0B11MFHKX"],"domain":"www.amazon.com"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/amazon-product-reviews/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { limit: 100, asins: [ 'B096NP4QWH', 'https://www.amazon.com/Semwiss-Womens-Comfortable-Pointed-Leopard/dp/B0B11MFHKX' ], domain: 'www.amazon.com' } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/amazon-product-reviews/jobs" payload = { "limit": 100, "asins": ["B096NP4QWH", "https://www.amazon.com/Semwiss-Womens-Comfortable-Pointed-Leopard/dp/B0B11MFHKX"], "domain": "www.amazon.com" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 100, "asins" => ["B096NP4QWH", "https://www.amazon.com/Semwiss-Womens-Comfortable-Pointed-Leopard/dp/B0B11MFHKX"], "domain" => "www.amazon.com", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/amazon-product-reviews/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 100, "asins": [ "B096NP4QWH", "https://www.amazon.com/Semwiss-Womens-Comfortable-Pointed-Leopard/dp/B0B11MFHKX" ], "domain": "www.amazon.com" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/amazon-product-reviews/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 100, "asins": [ "B096NP4QWH", "https://www.amazon.com/Semwiss-Womens-Comfortable-Pointed-Leopard/dp/B0B11MFHKX" ], "domain": "www.amazon.com" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/amazon-product-reviews/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/amazon-product-reviews/jobs") payload = { "limit" => 100, "asins" => ["B096NP4QWH", "https://www.amazon.com/Semwiss-Womens-Comfortable-Pointed-Leopard/dp/B0B11MFHKX"], "domain" => "www.amazon.com", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 100, "asins": [ "B096NP4QWH", "https://www.amazon.com/Semwiss-Womens-Comfortable-Pointed-Leopard/dp/B0B11MFHKX" ], "domain": "www.amazon.com" }); let res = client .post("https://api.hasdata.com/scrapers/amazon-product-reviews/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 100, "asins": [ "B096NP4QWH", "https://www.amazon.com/Semwiss-Womens-Comfortable-Pointed-Leopard/dp/B0B11MFHKX" ], "domain": "www.amazon.com" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/amazon-product-reviews/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Reviews per product Enter ASINs or URLs of products you want to get reviews from. Each ASIN/URL must be on a different line. Amazon domain to use. Default is [www.amazon.com](http://www.amazon.com). ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Amazon Search Scraper Source: https://docs.hasdata.com/scrapers/amazon-search Monitor pricing, track SEO-relevant search placement, and discover new competitor SKUs. Returns ASIN, title, URL, price + before price, rating, reviews, shipping-eligibility/recommendation/best-seller flags, brand, position, and thumbnails — with optional extended product detail (description, image/video galleries, variants, features, overview). HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Amazon. Amazon is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **10 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/amazon-search/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":100,"keywords":["laptop","tablet"],"domain":"www.amazon.com","detailedInformation":false}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/amazon-search/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { limit: 100, keywords: ['laptop', 'tablet'], domain: 'www.amazon.com', detailedInformation: false } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/amazon-search/jobs" payload = { "limit": 100, "keywords": ["laptop", "tablet"], "domain": "www.amazon.com", "detailedInformation": False } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 100, "keywords" => ["laptop", "tablet"], "domain" => "www.amazon.com", "detailedInformation" => false, ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/amazon-search/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 100, "keywords": [ "laptop", "tablet" ], "domain": "www.amazon.com", "detailedInformation": false } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/amazon-search/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 100, "keywords": [ "laptop", "tablet" ], "domain": "www.amazon.com", "detailedInformation": false } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/amazon-search/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/amazon-search/jobs") payload = { "limit" => 100, "keywords" => ["laptop", "tablet"], "domain" => "www.amazon.com", "detailedInformation" => false, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 100, "keywords": [ "laptop", "tablet" ], "domain": "www.amazon.com", "detailedInformation": false }); let res = client .post("https://api.hasdata.com/scrapers/amazon-search/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 100, "keywords": [ "laptop", "tablet" ], "domain": "www.amazon.com", "detailedInformation": false }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/amazon-search/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Results per keyword A list of keywords or URLs you want to scrape. Each URL or keyword must be on a different line. Amazon domain to use. Default is [www.amazon.com](http://www.amazon.com). Products Detailed Information ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | ----------------------------------- | ---------------- | | `email` | Email Address | Amazon seller email address | 5 credits | | `website` | Website URL | Amazon seller website URL | 5 credits | | `phone` | Phone Number | Amazon seller phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Amazon seller LinkedIn page URL | 5 credits | | `facebookUrl` | Facebook Profile | Amazon seller Facebook page URL | 5 credits | | `instagramUrl` | Instagram Profile | Amazon seller Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Amazon seller X profile URL | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Amazon Seller Products Scraper Source: https://docs.hasdata.com/scrapers/amazon-seller-products Track competitor catalogs, audit resellers, and detect counterfeit listings. Returns ASIN, title, URL, price + before price, rating, reviews, shipping-eligibility/recommendation/best-seller flags, brand, and position — with optional extended product detail (description, image/video galleries, variants, features, overview). HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Amazon. Amazon is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **10 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/amazon-seller-products/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":100,"sellerId":"A5XZLIYI1M8Y0","domain":"www.amazon.com","detailedInformation":false}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/amazon-seller-products/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { limit: 100, sellerId: 'A5XZLIYI1M8Y0', domain: 'www.amazon.com', detailedInformation: false } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/amazon-seller-products/jobs" payload = { "limit": 100, "sellerId": "A5XZLIYI1M8Y0", "domain": "www.amazon.com", "detailedInformation": False } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 100, "sellerId" => "A5XZLIYI1M8Y0", "domain" => "www.amazon.com", "detailedInformation" => false, ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/amazon-seller-products/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 100, "sellerId": "A5XZLIYI1M8Y0", "domain": "www.amazon.com", "detailedInformation": false } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/amazon-seller-products/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 100, "sellerId": "A5XZLIYI1M8Y0", "domain": "www.amazon.com", "detailedInformation": false } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/amazon-seller-products/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/amazon-seller-products/jobs") payload = { "limit" => 100, "sellerId" => "A5XZLIYI1M8Y0", "domain" => "www.amazon.com", "detailedInformation" => false, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 100, "sellerId": "A5XZLIYI1M8Y0", "domain": "www.amazon.com", "detailedInformation": false }); let res = client .post("https://api.hasdata.com/scrapers/amazon-seller-products/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 100, "sellerId": "A5XZLIYI1M8Y0", "domain": "www.amazon.com", "detailedInformation": false }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/amazon-seller-products/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Results limit Amazon seller ID whose storefront listing should be scraped. Amazon domain to use. Default is [www.amazon.com](http://www.amazon.com). Products Detailed Information ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Phone, Email and Contact Scraper Source: https://docs.hasdata.com/scrapers/contacts Enrich lead lists, verify business contacts, and build outbound sales databases. Returns the URL, emails, phone numbers, and social profile URLs (LinkedIn, X/Twitter, Facebook, Instagram, Dribbble, Clutch). This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **5 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/contacts/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"urls":["https://hasdata.com/about-us","https://example.com/"]}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/contacts/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: {urls: ['https://hasdata.com/about-us', 'https://example.com/']} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/contacts/jobs" payload = { "urls": ["https://hasdata.com/about-us", "https://example.com/"] } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} ["https://hasdata.com/about-us", "https://example.com/"], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/contacts/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "urls": [ "https://hasdata.com/about-us", "https://example.com/" ] } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/contacts/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "urls": [ "https://hasdata.com/about-us", "https://example.com/" ] } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/contacts/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/contacts/jobs") payload = { "urls" => ["https://hasdata.com/about-us", "https://example.com/"], } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "urls": [ "https://hasdata.com/about-us", "https://example.com/" ] }); let res = client .post("https://api.hasdata.com/scrapers/contacts/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "urls": [ "https://hasdata.com/about-us", "https://example.com/" ] }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/contacts/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Enter URLs of websites you want to scrape and extract data from. Each URL must be on a different line. ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Getting Results Source: https://docs.hasdata.com/scrapers/getting-results You can check the status of a scraper job and fetch results manually using the job ID. This is useful if you’re not using webhooks or need to monitor job progress in your system. ## Check Job Status To check whether a job is still running or finished: ```bash cURL theme={null} curl --request GET \ --url 'https://api.hasdata.com/scrapers/jobs/:jobId' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrapers/jobs/:jobId', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/jobs/:jobId" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrapers/jobs/:jobId", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/jobs/:jobId") .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.hasdata.com/scrapers/jobs/:jobId"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrapers/jobs/:jobId") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrapers/jobs/:jobId") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.hasdata.com/scrapers/jobs/:jobId", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ### Example Response ```javascript theme={null} { "id": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "status": "in_progress", "creditsSpent": 200, "dataRowsCount": 20, "input": { /* job parameters */ } } ``` ### Job Statuses * `pending` — Waiting to be processed * `in_progress` — Currently running * `finished` — Completed ## Fetch Results Once the job status is `finished`, you can retrieve results: ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrapers/jobs/:jobId/results' \ --data-urlencode 'page=1' \ --data-urlencode 'limit=100' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrapers/jobs/:jobId/results', params: {page: '1', limit: '100'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/jobs/:jobId/results" querystring = {"page":"1","limit":"100"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "1", "limit" => "100", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/jobs/:jobId/results?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrapers/jobs/:jobId/results") .newBuilder() .addQueryParameter("page", "1") .addQueryParameter("limit", "100") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["page"] = "1"; query["limit"] = "100"; var url = $"https://api.hasdata.com/scrapers/jobs/:jobId/results?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrapers/jobs/:jobId/results") params = { "page" => "1", "limit" => "100", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrapers/jobs/:jobId/results") .query(&[("page", "1")]) .query(&[("limit", "100")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("page", "1") params.Set("limit", "100") u := "https://api.hasdata.com/scrapers/jobs/:jobId/results?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` Maximum limit is 100 per request. ### Response Example ```javascript theme={null} { "meta": { "total": 122, "perPage": 100, "currentPage": 1, "lastPage": 2, "firstPage": 1, "firstPageUrl": "/?page=1", "lastPageUrl": "/?page=2", "nextPageUrl": "/?page=2", "previousPageUrl": null }, "data": [ { "id": "8e705f7b-c542-403d-8acc-3e3d5c2f1271", "data": { /* scraped data */ }, "createdAt": "2025-05-02T17:26:28.603+03:00", "updatedAt": "2025-05-02T17:26:28.603+03:00" }, { "id": "01d1f7d2-43b4-4752-a114-b5e6601c5722", "data": { /* scraped data */ }, "createdAt": "2025-05-02T17:26:25.740+03:00", "updatedAt": "2025-05-02T17:26:25.740+03:00" } ] } ``` # Glassdoor Scraper Source: https://docs.hasdata.com/scrapers/glassdoor Benchmark compensation, track hiring demand, and source employer intelligence. Returns job URL, title, salary range + currency + period, employer name/URL, industry, location (city, region, country, coordinates), education and experience requirements, benefits, description, post date, and valid-through date. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Glassdoor. Glassdoor is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **10 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/glassdoor/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"keywords":["Software Engineer","Software Developer"],"locations":["New York, NY"],"limit":100,"sort":"relevant","domain":"www.glassdoor.com"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/glassdoor/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { keywords: ['Software Engineer', 'Software Developer'], locations: ['New York, NY'], limit: 100, sort: 'relevant', domain: 'www.glassdoor.com' } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/glassdoor/jobs" payload = { "keywords": ["Software Engineer", "Software Developer"], "locations": ["New York, NY"], "limit": 100, "sort": "relevant", "domain": "www.glassdoor.com" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} ["Software Engineer", "Software Developer"], "locations" => ["New York, NY"], "limit" => 100, "sort" => "relevant", "domain" => "www.glassdoor.com", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/glassdoor/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "keywords": [ "Software Engineer", "Software Developer" ], "locations": [ "New York, NY" ], "limit": 100, "sort": "relevant", "domain": "www.glassdoor.com" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/glassdoor/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "keywords": [ "Software Engineer", "Software Developer" ], "locations": [ "New York, NY" ], "limit": 100, "sort": "relevant", "domain": "www.glassdoor.com" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/glassdoor/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/glassdoor/jobs") payload = { "keywords" => ["Software Engineer", "Software Developer"], "locations" => ["New York, NY"], "limit" => 100, "sort" => "relevant", "domain" => "www.glassdoor.com", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "keywords": [ "Software Engineer", "Software Developer" ], "locations": [ "New York, NY" ], "limit": 100, "sort": "relevant", "domain": "www.glassdoor.com" }); let res = client .post("https://api.hasdata.com/scrapers/glassdoor/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "keywords": [ "Software Engineer", "Software Developer" ], "locations": [ "New York, NY" ], "limit": 100, "sort": "relevant", "domain": "www.glassdoor.com" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/glassdoor/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Enter the keywords of the job positions. Each keyword must be on a different line. Enter the locations where you want to search for and extract job listings. Each location must be on a different line. Results per each keyword Sort By Glassdoor Domain ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | -------------------------------------- | ---------------- | | `email` | Email Address | Employer company email address | 5 credits | | `website` | Website URL | Employer company website URL | 5 credits | | `phone` | Phone Number | Employer company phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Employer company LinkedIn page URL | 5 credits | | `facebookUrl` | Facebook Profile | Employer company Facebook page URL | 5 credits | | `instagramUrl` | Instagram Profile | Employer company Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Employer company X profile URL | 5 credits | | `githubUrl` | GitHub Profile | Employer company GitHub profile URL | 5 credits | | `revenue` | Revenue | Employer company revenue | 5 credits | | `traffic` | Website Traffic | Employer company website traffic | 5 credits | | `funding` | Funding Info | Employer company funding information | 5 credits | | `founded` | Founded Year | Employer company founded year | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Google Maps Scraper Source: https://docs.hasdata.com/scrapers/google-maps Build lead lists, run local SEO audits, and power competitor intelligence for any industry. Returns title, type, address, latitude/longitude, website, phone, working hours, rating, reviews count, description, price level, service options, place/data IDs, and extractable email addresses. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **3 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/google-maps/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":100,"categories":["doctor","dentist","physical therapist","psychologist","pediatrician"],"locations":[],"extractEmails":false}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/google-maps/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { limit: 100, categories: ['doctor', 'dentist', 'physical therapist', 'psychologist', 'pediatrician'], locations: [], extractEmails: false } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/google-maps/jobs" payload = { "limit": 100, "categories": ["doctor", "dentist", "physical therapist", "psychologist", "pediatrician"], "locations": [], "extractEmails": False } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 100, "categories" => ["doctor", "dentist", "physical therapist", "psychologist", "pediatrician"], "locations" => [], "extractEmails" => false, ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/google-maps/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 100, "categories": [ "doctor", "dentist", "physical therapist", "psychologist", "pediatrician" ], "locations": [], "extractEmails": false } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/google-maps/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 100, "categories": [ "doctor", "dentist", "physical therapist", "psychologist", "pediatrician" ], "locations": [], "extractEmails": false } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/google-maps/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/google-maps/jobs") payload = { "limit" => 100, "categories" => ["doctor", "dentist", "physical therapist", "psychologist", "pediatrician"], "locations" => [], "extractEmails" => false, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 100, "categories": [ "doctor", "dentist", "physical therapist", "psychologist", "pediatrician" ], "locations": [], "extractEmails": false }); let res = client .post("https://api.hasdata.com/scrapers/google-maps/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 100, "categories": [ "doctor", "dentist", "physical therapist", "psychologist", "pediatrician" ], "locations": [], "extractEmails": false }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/google-maps/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Data limit (0 - unlimited) Choose your own keywords or pick from our ready-made categories. If you use our categories, we'll only gather information from the places in those categories. Locations Extract emails (10 credits per row) ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | ------------------------------ | ---------------- | | `email` | Email Address | Business email address | 5 credits | | `linkedinUrl` | LinkedIn Profile | Business LinkedIn page URL | 5 credits | | `facebookUrl` | Facebook Profile | Business Facebook page URL | 5 credits | | `instagramUrl` | Instagram Profile | Business Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Business X profile URL | 5 credits | | `revenue` | Revenue | Business revenue | 5 credits | | `traffic` | Website Traffic | Business website traffic | 5 credits | | `funding` | Funding Info | Business funding information | 5 credits | | `founded` | Founded Year | Business founded year | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Google Maps Reviews Scraper Source: https://docs.hasdata.com/scrapers/google-maps-reviews Analyze customer sentiment, benchmark against competitors, and surface response-rate gaps for your business. Returns review date, rating, snippet, owner response, likes, review URL, reviewer name/photo/reviews count/reviewer status, place URL, and attached images. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **1 credit** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/google-maps-reviews/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":100,"urls":["https://www.google.com/maps/place/?q=place_id:ChIJFU2bda4SM4cRKSCRyb6pOB8"],"sortBy":"mostRelevant"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/google-maps-reviews/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { limit: 100, urls: ['https://www.google.com/maps/place/?q=place_id:ChIJFU2bda4SM4cRKSCRyb6pOB8'], sortBy: 'mostRelevant' } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/google-maps-reviews/jobs" payload = { "limit": 100, "urls": ["https://www.google.com/maps/place/?q=place_id:ChIJFU2bda4SM4cRKSCRyb6pOB8"], "sortBy": "mostRelevant" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 100, "urls" => ["https://www.google.com/maps/place/?q=place_id:ChIJFU2bda4SM4cRKSCRyb6pOB8"], "sortBy" => "mostRelevant", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/google-maps-reviews/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 100, "urls": [ "https://www.google.com/maps/place/?q=place_id:ChIJFU2bda4SM4cRKSCRyb6pOB8" ], "sortBy": "mostRelevant" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/google-maps-reviews/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 100, "urls": [ "https://www.google.com/maps/place/?q=place_id:ChIJFU2bda4SM4cRKSCRyb6pOB8" ], "sortBy": "mostRelevant" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/google-maps-reviews/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/google-maps-reviews/jobs") payload = { "limit" => 100, "urls" => ["https://www.google.com/maps/place/?q=place_id:ChIJFU2bda4SM4cRKSCRyb6pOB8"], "sortBy" => "mostRelevant", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 100, "urls": [ "https://www.google.com/maps/place/?q=place_id:ChIJFU2bda4SM4cRKSCRyb6pOB8" ], "sortBy": "mostRelevant" }); let res = client .post("https://api.hasdata.com/scrapers/google-maps-reviews/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 100, "urls": [ "https://www.google.com/maps/place/?q=place_id:ChIJFU2bda4SM4cRKSCRyb6pOB8" ], "sortBy": "mostRelevant" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/google-maps-reviews/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Number of reviews Enter Google Maps Place URLs. Each URL must be on a different line. Sort By ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | ----------------------------------- | ---------------- | | `email` | Email Address | Review author email address | 5 credits | | `website` | Website URL | Review author website URL | 5 credits | | `phone` | Phone Number | Review author phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Review author LinkedIn profile URL | 5 credits | | `facebookUrl` | Facebook Profile | Review author Facebook profile URL | 5 credits | | `instagramUrl` | Instagram Profile | Review author Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Review author X profile URL | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Google Search Results Scraper Source: https://docs.hasdata.com/scrapers/google-serp Track SERP rankings, monitor competitors, research keywords, and audit SEO presence at scale. Returns position, keyword, title, link, displayedLink, snippet, highlighted words, source, rich snippet blocks, and sitelinks for every query × location combination. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **2 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/google-serp/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"keywords":["pizza in new york","beef in new york"],"location":"Austin,Texas,United States","limit":0}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/google-serp/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { keywords: ['pizza in new york', 'beef in new york'], location: 'Austin,Texas,United States', limit: 0 } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/google-serp/jobs" payload = { "keywords": ["pizza in new york", "beef in new york"], "location": "Austin,Texas,United States", "limit": 0 } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} ["pizza in new york", "beef in new york"], "location" => "Austin,Texas,United States", "limit" => 0, ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/google-serp/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "keywords": [ "pizza in new york", "beef in new york" ], "location": "Austin,Texas,United States", "limit": 0 } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/google-serp/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "keywords": [ "pizza in new york", "beef in new york" ], "location": "Austin,Texas,United States", "limit": 0 } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/google-serp/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/google-serp/jobs") payload = { "keywords" => ["pizza in new york", "beef in new york"], "location" => "Austin,Texas,United States", "limit" => 0, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "keywords": [ "pizza in new york", "beef in new york" ], "location": "Austin,Texas,United States", "limit": 0 }); let res = client .post("https://api.hasdata.com/scrapers/google-serp/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "keywords": [ "pizza in new york", "beef in new york" ], "location": "Austin,Texas,United States", "limit": 0 }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/google-serp/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Put each keyword on the different line Google canonical location for the search. Results per each keyword (min. 10). The default value of 0 means no limit. ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | --------- | --------------- | -------------------------------- | ---------------- | | `email` | Email Address | Website-associated email address | 5 credits | | `phone` | Phone Number | Website-associated phone number | 5 credits | | `revenue` | Revenue | Company revenue | 5 credits | | `traffic` | Website Traffic | Website traffic | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Google Trends Scraper Source: https://docs.hasdata.com/scrapers/google-trends Spot emerging topics, track seasonal demand, and compare keyword momentum across markets. Returns a time series of data points: timestamp, formatted time, value, formatted value. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **1 credit** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/google-trends/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"keywords":["coffee","green tea"],"location":"US","date":"today 12-m"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/google-trends/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: {keywords: ['coffee', 'green tea'], location: 'US', date: 'today 12-m'} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/google-trends/jobs" payload = { "keywords": ["coffee", "green tea"], "location": "US", "date": "today 12-m" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} ["coffee", "green tea"], "location" => "US", "date" => "today 12-m", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/google-trends/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "keywords": [ "coffee", "green tea" ], "location": "US", "date": "today 12-m" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/google-trends/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "keywords": [ "coffee", "green tea" ], "location": "US", "date": "today 12-m" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/google-trends/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/google-trends/jobs") payload = { "keywords" => ["coffee", "green tea"], "location" => "US", "date" => "today 12-m", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "keywords": [ "coffee", "green tea" ], "location": "US", "date": "today 12-m" }); let res = client .post("https://api.hasdata.com/scrapers/google-trends/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "keywords": [ "coffee", "green tea" ], "location": "US", "date": "today 12-m" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/google-trends/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters When passing multiple queries you need to use a comma (,) to separate them (e.g. coffee,pizza,green tea). The maximum number of queries per search is 5. Specifies the location for the search. Timeframe ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Indeed Scraper Source: https://docs.hasdata.com/scrapers/indeed Monitor hiring trends, benchmark pay bands, and power candidate-facing job boards. Returns job title, company, location, posted date, salary min/max + period, benefits, full description (HTML and text), details, and apply URL. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Indeed. Indeed is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **10 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/indeed/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":0,"keywords":["senior software engineer","staff engineer"],"locations":["new york, ny"],"sort":"date","domain":"www.indeed.com"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/indeed/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { limit: 0, keywords: ['senior software engineer', 'staff engineer'], locations: ['new york, ny'], sort: 'date', domain: 'www.indeed.com' } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/indeed/jobs" payload = { "limit": 0, "keywords": ["senior software engineer", "staff engineer"], "locations": ["new york, ny"], "sort": "date", "domain": "www.indeed.com" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 0, "keywords" => ["senior software engineer", "staff engineer"], "locations" => ["new york, ny"], "sort" => "date", "domain" => "www.indeed.com", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/indeed/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 0, "keywords": [ "senior software engineer", "staff engineer" ], "locations": [ "new york, ny" ], "sort": "date", "domain": "www.indeed.com" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/indeed/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 0, "keywords": [ "senior software engineer", "staff engineer" ], "locations": [ "new york, ny" ], "sort": "date", "domain": "www.indeed.com" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/indeed/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/indeed/jobs") payload = { "limit" => 0, "keywords" => ["senior software engineer", "staff engineer"], "locations" => ["new york, ny"], "sort" => "date", "domain" => "www.indeed.com", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 0, "keywords": [ "senior software engineer", "staff engineer" ], "locations": [ "new york, ny" ], "sort": "date", "domain": "www.indeed.com" }); let res = client .post("https://api.hasdata.com/scrapers/indeed/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 0, "keywords": [ "senior software engineer", "staff engineer" ], "locations": [ "new york, ny" ], "sort": "date", "domain": "www.indeed.com" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/indeed/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Results Limit (0 - Unlimited) Enter the keywords of the job positions. Each keyword must be on a different line. Enter the locations where you want to search for and extract job listings. Each location must be on a different line. Sort By Indeed Domain ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | ------------------------------------ | ---------------- | | `email` | Email Address | Hiring company email address | 5 credits | | `website` | Website URL | Hiring company website URL | 5 credits | | `phone` | Phone Number | Hiring company phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Hiring company LinkedIn page URL | 5 credits | | `facebookUrl` | Facebook Profile | Hiring company Facebook page URL | 5 credits | | `instagramUrl` | Instagram Profile | Hiring company Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Hiring company X profile URL | 5 credits | | `githubUrl` | GitHub Profile | Hiring company GitHub profile URL | 5 credits | | `revenue` | Revenue | Hiring company revenue | 5 credits | | `traffic` | Website Traffic | Hiring company website traffic | 5 credits | | `funding` | Funding Info | Hiring company funding information | 5 credits | | `founded` | Founded Year | Hiring company founded year | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Redfin Property Scraper Source: https://docs.hasdata.com/scrapers/redfin Track housing prices, scout investment properties, and analyze neighborhood trends without writing code. Returns property URL, address, price, beds, baths, living area, listing status, photos, and key listing metadata. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Redfin. Redfin is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **10 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/redfin/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":120,"locations":["33321","33068"],"type":"forSale"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/redfin/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: {limit: 120, locations: ['33321', '33068'], type: 'forSale'} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/redfin/jobs" payload = { "limit": 120, "locations": ["33321", "33068"], "type": "forSale" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 120, "locations" => ["33321", "33068"], "type" => "forSale", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/redfin/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 120, "locations": [ "33321", "33068" ], "type": "forSale" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/redfin/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 120, "locations": [ "33321", "33068" ], "type": "forSale" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/redfin/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/redfin/jobs") payload = { "limit" => 120, "locations" => ["33321", "33068"], "type" => "forSale", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 120, "locations": [ "33321", "33068" ], "type": "forSale" }); let res = client .post("https://api.hasdata.com/scrapers/redfin/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 120, "locations": [ "33321", "33068" ], "type": "forSale" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/redfin/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Result rows limit Specify the Zip Codes you want to extract data from. Type ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | --------------------------------------- | ---------------- | | `email` | Email Address | Listing agent email address | 5 credits | | `website` | Website URL | Listing agent or brokerage website URL | 5 credits | | `phone` | Phone Number | Listing agent or brokerage phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Listing agent LinkedIn profile URL | 5 credits | | `facebookUrl` | Facebook Profile | Listing agent Facebook profile URL | 5 credits | | `instagramUrl` | Instagram Profile | Listing agent Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Listing agent X profile URL | 5 credits | | `githubUrl` | GitHub Profile | Listing agent GitHub profile URL | 5 credits | | `revenue` | Revenue | Brokerage revenue | 5 credits | | `traffic` | Website Traffic | Brokerage website traffic | 5 credits | | `funding` | Funding Info | Brokerage funding information | 5 credits | | `founded` | Founded Year | Brokerage founded year | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # SEC EDGAR Scraper Source: https://docs.hasdata.com/scrapers/sec Monitor 10-K, 10-Q, 8-K, and other filings, track insider activity, and build financial research pipelines. Returns filing records from the SEC EDGAR system with document links and filing metadata for each match. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **1 credit** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/sec-edgar/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":100,"ciks":["AAPL","789019","Alphabet Inc."],"filingTypes":"1-K, 10-K, 10-Q, 8-K"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/sec-edgar/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { limit: 100, ciks: ['AAPL', '789019', 'Alphabet Inc.'], filingTypes: '1-K, 10-K, 10-Q, 8-K' } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/sec-edgar/jobs" payload = { "limit": 100, "ciks": ["AAPL", "789019", "Alphabet Inc."], "filingTypes": "1-K, 10-K, 10-Q, 8-K" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 100, "ciks" => ["AAPL", "789019", "Alphabet Inc."], "filingTypes" => "1-K, 10-K, 10-Q, 8-K", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/sec-edgar/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 100, "ciks": [ "AAPL", "789019", "Alphabet Inc." ], "filingTypes": "1-K, 10-K, 10-Q, 8-K" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/sec-edgar/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 100, "ciks": [ "AAPL", "789019", "Alphabet Inc." ], "filingTypes": "1-K, 10-K, 10-Q, 8-K" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/sec-edgar/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/sec-edgar/jobs") payload = { "limit" => 100, "ciks" => ["AAPL", "789019", "Alphabet Inc."], "filingTypes" => "1-K, 10-K, 10-Q, 8-K", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 100, "ciks": [ "AAPL", "789019", "Alphabet Inc." ], "filingTypes": "1-K, 10-K, 10-Q, 8-K" }); let res = client .post("https://api.hasdata.com/scrapers/sec-edgar/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 100, "ciks": [ "AAPL", "789019", "Alphabet Inc." ], "filingTypes": "1-K, 10-K, 10-Q, 8-K" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/sec-edgar/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Results Limit List of CIKs, Tickers, or Company Names Filing Types Filed From (YYYY-MM-DD) Filed To (YYYY-MM-DD) ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Shopify Scraper Source: https://docs.hasdata.com/scrapers/shopify Research competitor catalogs, track price changes over time, and build product comparison feeds. Returns product id, name, handle, description, vendor, product type, min/max price, variants with full variant data, images, options, bestseller flag, and create/publish/update timestamps. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Shopify. Shopify is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **1 credit** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/shopify/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"url":"https://b2bdemoexperience.myshopify.com/","currency":"USD"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/shopify/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: {url: 'https://b2bdemoexperience.myshopify.com/', currency: 'USD'} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/shopify/jobs" payload = { "url": "https://b2bdemoexperience.myshopify.com/", "currency": "USD" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://b2bdemoexperience.myshopify.com/", "currency" => "USD", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/shopify/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "url": "https://b2bdemoexperience.myshopify.com/", "currency": "USD" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/shopify/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "url": "https://b2bdemoexperience.myshopify.com/", "currency": "USD" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/shopify/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/shopify/jobs") payload = { "url" => "https://b2bdemoexperience.myshopify.com/", "currency" => "USD", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "url": "https://b2bdemoexperience.myshopify.com/", "currency": "USD" }); let res = client .post("https://api.hasdata.com/scrapers/shopify/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "url": "https://b2bdemoexperience.myshopify.com/", "currency": "USD" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/shopify/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Shopify Store URL Currency (3 letter code) ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | ------------------------------------ | ---------------- | | `email` | Email Address | Vendor company email address | 5 credits | | `website` | Website URL | Vendor company website URL | 5 credits | | `phone` | Phone Number | Vendor company phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Vendor company LinkedIn page URL | 5 credits | | `facebookUrl` | Facebook Profile | Vendor company Facebook page URL | 5 credits | | `instagramUrl` | Instagram Profile | Vendor company Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Vendor company X profile URL | 5 credits | | `githubUrl` | GitHub Profile | Vendor company GitHub profile URL | 5 credits | | `revenue` | Revenue | Vendor company revenue | 5 credits | | `traffic` | Website Traffic | Vendor company website traffic | 5 credits | | `funding` | Funding Info | Vendor company funding information | 5 credits | | `founded` | Founded Year | Vendor company founded year | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Stopping a Job Source: https://docs.hasdata.com/scrapers/stopping-job You can stop a running scraper job at any time using its `jobId`. This is useful if you submitted a job with wrong parameters or no longer need the data. ## Stop Request Only active jobs (`in_progress`) ```bash cURL theme={null} curl --request DELETE \ --url 'https://api.hasdata.com/scrapers/jobs/:jobId' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'DELETE', url: 'https://api.hasdata.com/scrapers/jobs/:jobId', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/jobs/:jobId" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.delete(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrapers/jobs/:jobId", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "DELETE", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/jobs/:jobId") .delete() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api.hasdata.com/scrapers/jobs/:jobId"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrapers/jobs/:jobId") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Delete.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .delete("https://api.hasdata.com/scrapers/jobs/:jobId") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("DELETE", "https://api.hasdata.com/scrapers/jobs/:jobId", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## Behavior If the job is still running, all in-progress pages will finish scraping, but no new pages will be started. * Any data collected up to that point is preserved and can still be fetched. * Credits are only charged for successfully scraped pages, even if the job was stopped early. * If the job has already finished or failed, the stop request has no effect. ## Response Example ```javascript theme={null} { "jobId": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "status": "stopped", "creditsSpent": 200, "dataRowsCount": 20, "input": { /* job parameters */ } } ``` # Webhooks Source: https://docs.hasdata.com/scrapers/webhooks You can configure a webhook to receive real-time updates when a scraper job runs. To enable it, pass a `webhook` object in your job request. Webhook delivery is async and retries automatically on failure (3 attempts) ### Example ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/google-maps/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"keywords":["coffee shops"],"locations":["CUSTOM>New York, NY"],"extractEmails":true,"webhook":{"url":"https://yourdomain.com/webhook","events":["scraper.job.started","scraper.job.finished","scraper.data.scraped"],"headers":{"x-custom-header":"custom header value"}}}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/google-maps/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { keywords: ['coffee shops'], locations: ['CUSTOM>New York, NY'], extractEmails: true, webhook: { url: 'https://yourdomain.com/webhook', events: ['scraper.job.started', 'scraper.job.finished', 'scraper.data.scraped'], headers: {'x-custom-header': 'custom header value'} } } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/google-maps/jobs" payload = { "keywords": ["coffee shops"], "locations": ["CUSTOM>New York, NY"], "extractEmails": True, "webhook": { "url": "https://yourdomain.com/webhook", "events": ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"], "headers": { "x-custom-header": "custom header value" } } } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} ["coffee shops"], "locations" => ["CUSTOM>New York, NY"], "extractEmails" => true, "webhook" => ["url" => "https://yourdomain.com/webhook", "events" => ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"], "headers" => ["x-custom-header" => "custom header value"]], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/google-maps/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "keywords": [ "coffee shops" ], "locations": [ "CUSTOM>New York, NY" ], "extractEmails": true, "webhook": { "url": "https://yourdomain.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ], "headers": { "x-custom-header": "custom header value" } } } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/google-maps/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "keywords": [ "coffee shops" ], "locations": [ "CUSTOM>New York, NY" ], "extractEmails": true, "webhook": { "url": "https://yourdomain.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ], "headers": { "x-custom-header": "custom header value" } } } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/google-maps/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/google-maps/jobs") payload = { "keywords" => ["coffee shops"], "locations" => ["CUSTOM>New York, NY"], "extractEmails" => true, "webhook" => {"url" => "https://yourdomain.com/webhook", "events" => ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"], "headers" => {"x-custom-header" => "custom header value"}}, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "keywords": [ "coffee shops" ], "locations": [ "CUSTOM>New York, NY" ], "extractEmails": true, "webhook": { "url": "https://yourdomain.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ], "headers": { "x-custom-header": "custom header value" } } }); let res = client .post("https://api.hasdata.com/scrapers/google-maps/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "keywords": [ "coffee shops" ], "locations": [ "CUSTOM>New York, NY" ], "extractEmails": true, "webhook": { "url": "https://yourdomain.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ], "headers": { "x-custom-header": "custom header value" } } }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/google-maps/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ### Supported Events * `scraper.job.started` — Sent when the job starts processing * `scraper.data.scraped` — Sent as data is collected (may trigger multiple times) * `scraper.job.finished` — Sent when the job is complete # Job Parameters Source: https://docs.hasdata.com/scrapers/websites-crawler/job-params These parameters control how the crawler behaves and which pages it visits. List of starting URLs. The crawler will begin from these. Maximum number of pages to scrape. `0` means no limit. How many link levels to follow from each starting URL. `1` means only direct links. `2` means follow links from those pages, and so on. Only follow URLs that match this regex. Example: `(blog/.+|about/.+)` matches `/blog/post-1`, `/about/company`, etc. Skip URLs that match this regex. Example: `(admin/.+|private/.+)` skips `/admin/login`, `/private/settings`, etc. You can also use any [Web Scraping API Params](/apis/web-scraping-api/api-params). They apply to every page the crawler visits — including `outputFormat`, `extractRules`, `headers`, `proxyType`, and others. # Polling for Status Source: https://docs.hasdata.com/scrapers/websites-crawler/polling-for-status You can check the status of a scraper job and fetch results manually using the job ID. This is useful if you're not using webhooks or need to monitor job progress in your system. ## Check Job Status To check whether a job is still running or finished: ```bash cURL theme={null} curl --request GET \ --url 'https://api.hasdata.com/scrapers/jobs/:jobId' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrapers/jobs/:jobId', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/jobs/:jobId" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrapers/jobs/:jobId", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/jobs/:jobId") .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.hasdata.com/scrapers/jobs/:jobId"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrapers/jobs/:jobId") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrapers/jobs/:jobId") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.hasdata.com/scrapers/jobs/:jobId", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ### Example Response ```javascript theme={null} { "id": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "status": "in_progress", "creditsSpent": 200, "dataRowsCount": 20, "input": { /* job parameters */ } } ``` ```json theme={null} { "id": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "status": "finished", "creditsSpent": 200, "dataRowsCount": 20, "data": { "csv": "https://api.hasdata.com/scrapers/jobs/dd1a8c53-2d47-4444-977d-8d653a6a3c82/results/b6cc6733-6d0e-4e44-9e94-38688aad3884.csv", "json": "https://api.hasdata.com/scrapers/jobs/dd1a8c53-2d47-4444-977d-8d653a6a3c82/results/9cb592e3-6700-42ff-b58c-e7da3f478f28.json", "xlsx": "https://api.hasdata.com/scrapers/jobs/dd1a8c53-2d47-4444-977d-8d653a6a3c82/results/ecea853c-e0ca-4a23-ae74-eea0588e54b6.xlsx" }, "input": { "limit": 25, "urls": ["https://hasdata.com", "https://example.com"], "maxDepth": 5, "includePaths": "(blog/.+|articles/.+)", "webhook": { "url": "https://example.com/webhook", "events": ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"] } } } ``` ### Job Statuses * `pending` — Waiting to be processed * `in_progress` — Currently running * `finished` — Completed ## Fetch Results Once the job status is `finished`, you can retrieve results: ```bash cURL theme={null} curl --request GET -G \ --url 'https://api.hasdata.com/scrapers/jobs/:jobId/results' \ --data-urlencode 'page=1' \ --data-urlencode 'limit=100' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrapers/jobs/:jobId/results', params: {page: '1', limit: '100'}, headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/jobs/:jobId/results" querystring = {"page":"1","limit":"100"} headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers, params=querystring) print(response.json()) ``` ```php PHP theme={null} "1", "limit" => "100", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/jobs/:jobId/results?" . http_build_query($params), CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); HttpUrl url = HttpUrl.parse("https://api.hasdata.com/scrapers/jobs/:jobId/results") .newBuilder() .addQueryParameter("page", "1") .addQueryParameter("limit", "100") .build(); Request request = new Request.Builder() .url(url) .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Web; var client = new HttpClient(); var query = HttpUtility.ParseQueryString(string.Empty); query["page"] = "1"; query["limit"] = "100"; var url = $"https://api.hasdata.com/scrapers/jobs/:jobId/results?{query}"; var request = new HttpRequestMessage(new HttpMethod("GET"), url); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrapers/jobs/:jobId/results") params = { "page" => "1", "limit" => "100", } uri.query = URI.encode_www_form(params) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrapers/jobs/:jobId/results") .query(&[("page", "1")]) .query(&[("limit", "100")]) .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" "net/url" ) func main() { params := url.Values{} params.Set("page", "1") params.Set("limit", "100") u := "https://api.hasdata.com/scrapers/jobs/:jobId/results?" + params.Encode() req, _ := http.NewRequest("GET", u, nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` Maximum limit is 100 per request. ### Response Example ```json theme={null} { "meta": { "total": 122, "perPage": 100, "currentPage": 1, "lastPage": 2, "firstPage": 1, "firstPageUrl": "/?page=1", "lastPageUrl": "/?page=2", "nextPageUrl": "/?page=2", "previousPageUrl": null }, "data": [ { "id": "8e705f7b-c542-403d-8acc-3e3d5c2f1271", "data": { "url": "https://example.com/page1", "statusCode": 200, "text": "Extracted content...", "title": "Example Page", "depth": 1 }, "createdAt": "2025-05-02T17:26:28.603+03:00", "updatedAt": "2025-05-02T17:26:28.603+03:00" }, { "id": "01d1f7d2-43b4-4752-a114-b5e6601c5722", "data": { "url": "https://example.com/page2", "statusCode": 404, "error": "Page not found", "depth": 1 }, "createdAt": "2025-05-02T17:26:25.740+03:00", "updatedAt": "2025-05-02T17:26:25.740+03:00" } ] } ``` # Quickstart - Websites Crawler Source: https://docs.hasdata.com/scrapers/websites-crawler/quickstart The **Websites Crawler** lets you crawl and extract content from multiple pages of a website by following internal links. You submit one or more starting URLs and define how deep the crawler should go using `maxDepth`. You can also limit which paths should be followed using regex with `includePaths`. This scraper job is asynchronous. You’ll receive a `jobId`, and results can be fetched via polling or delivered to a webhook. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/crawler/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"urls":["https://example.com"],"maxDepth":3,"includePaths":"(blog/.+|articles/.+)","outputFormat":["text","json"],"webhook":{"url":"https://yourdomain.com/webhook","events":["scraper.job.started","scraper.job.finished","scraper.data.scraped"]}}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/crawler/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { urls: ['https://example.com'], maxDepth: 3, includePaths: '(blog/.+|articles/.+)', outputFormat: ['text', 'json'], webhook: { url: 'https://yourdomain.com/webhook', events: ['scraper.job.started', 'scraper.job.finished', 'scraper.data.scraped'] } } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/crawler/jobs" payload = { "urls": ["https://example.com"], "maxDepth": 3, "includePaths": "(blog/.+|articles/.+)", "outputFormat": ["text", "json"], "webhook": { "url": "https://yourdomain.com/webhook", "events": ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"] } } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} ["https://example.com"], "maxDepth" => 3, "includePaths" => "(blog/.+|articles/.+)", "outputFormat" => ["text", "json"], "webhook" => ["url" => "https://yourdomain.com/webhook", "events" => ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"]], ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/crawler/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "urls": [ "https://example.com" ], "maxDepth": 3, "includePaths": "(blog/.+|articles/.+)", "outputFormat": [ "text", "json" ], "webhook": { "url": "https://yourdomain.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ] } } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/crawler/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "urls": [ "https://example.com" ], "maxDepth": 3, "includePaths": "(blog/.+|articles/.+)", "outputFormat": [ "text", "json" ], "webhook": { "url": "https://yourdomain.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ] } } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/crawler/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/crawler/jobs") payload = { "urls" => ["https://example.com"], "maxDepth" => 3, "includePaths" => "(blog/.+|articles/.+)", "outputFormat" => ["text", "json"], "webhook" => {"url" => "https://yourdomain.com/webhook", "events" => ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"]}, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "urls": [ "https://example.com" ], "maxDepth": 3, "includePaths": "(blog/.+|articles/.+)", "outputFormat": [ "text", "json" ], "webhook": { "url": "https://yourdomain.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ] } }); let res = client .post("https://api.hasdata.com/scrapers/crawler/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "urls": [ "https://example.com" ], "maxDepth": 3, "includePaths": "(blog/.+|articles/.+)", "outputFormat": [ "text", "json" ], "webhook": { "url": "https://yourdomain.com/webhook", "events": [ "scraper.job.started", "scraper.job.finished", "scraper.data.scraped" ] } }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/crawler/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Use Web Scraping API Params You can use **any parameters from the Web Scraping API** inside a Websites Crawler job — including: * `extractRules` * `aiExtractRules` * `headers` * `proxyType` / `proxyCountry` * `blockResources`, `jsScenario`, `outputFormat`, and [more](/apis/web-scraping-api/api-params) All parameters are applied to each crawled page individually. ## Get Scraper Job Status To get the status of an existing scraper job, make a GET request to the endpoint `/scrapers/jobs/:jobId`: ```bash cURL theme={null} curl --request GET \ --url 'https://api.hasdata.com/scrapers/jobs/:jobId' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'GET', url: 'https://api.hasdata.com/scrapers/jobs/:jobId', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/jobs/:jobId" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.get(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrapers/jobs/:jobId", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "GET", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/jobs/:jobId") .get() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.hasdata.com/scrapers/jobs/:jobId"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrapers/jobs/:jobId") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Get.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .get("https://api.hasdata.com/scrapers/jobs/:jobId") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("GET", "https://api.hasdata.com/scrapers/jobs/:jobId", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ```json theme={null} { "id": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "status": "finished", "creditsSpent": 200, "dataRowsCount": 20, "data": { "csv": "https://api.hasdata.com/scrapers/jobs/dd1a8c53-2d47-4444-977d-8d653a6a3c82/results/b6cc6733-6d0e-4e44-9e94-38688aad3884.csv", "json": "https://api.hasdata.com/scrapers/jobs/dd1a8c53-2d47-4444-977d-8d653a6a3c82/results/9cb592e3-6700-42ff-b58c-e7da3f478f28.json", "xlsx": "https://api.hasdata.com/scrapers/jobs/dd1a8c53-2d47-4444-977d-8d653a6a3c82/results/ecea853c-e0ca-4a23-ae74-eea0588e54b6.xlsx" }, "input": { "limit": 25, "urls": ["https://hasdata.com", "https://example.com"], "maxDepth": 5, "includePaths": "(blog/.+|articles/.+)", "webhook": { "url": "https://example.com/webhook", "events": ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"] } } } ``` ## Webhook The webhook will notify you of events related to the scraper job. Here is an example webhook payload for the `scraper.data.scraped` event: ```javascript theme={null} { "event": "scraper.data.scraped", "timestamp": "2025-04-11T14:30:00Z", "jobId": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "jobStatus": "in_progress", "data": [ { "text": "Extracted text here...", "statusCode": 200, "statusText": "OK", "url": "https://hasdata.com/blog", "depth": 1, "title": "Blog | HasData" } ] } ``` # Stopping a Job Source: https://docs.hasdata.com/scrapers/websites-crawler/stopping-job You can stop a running scraper job at any time using its `jobId`. This is useful if you submitted a job with wrong parameters or no longer need the data. ## Stop Request Only active jobs (`in_progress`) ```bash cURL theme={null} curl --request DELETE \ --url 'https://api.hasdata.com/scrapers/jobs/:jobId' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'DELETE', url: 'https://api.hasdata.com/scrapers/jobs/:jobId', headers: {'Content-Type': 'application/json', 'x-api-key': ''} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/jobs/:jobId" headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.delete(url, headers=headers) print(response.json()) ``` ```php PHP theme={null} "https://api.hasdata.com/scrapers/jobs/:jobId", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "DELETE", CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/jobs/:jobId") .delete() .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; var client = new HttpClient(); var request = new HttpRequestMessage(new HttpMethod("DELETE"), "https://api.hasdata.com/scrapers/jobs/:jobId"); request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var content = await response.Content.ReadAsStringAsync(); Console.WriteLine(content); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' uri = URI("https://api.hasdata.com/scrapers/jobs/:jobId") http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Delete.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; fn main() -> Result<(), Box> { let client = Client::new(); let res = client .delete("https://api.hasdata.com/scrapers/jobs/:jobId") .header("Content-Type", "application/json") .header("x-api-key", "") .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "fmt" "io" "net/http" ) func main() { req, _ := http.NewRequest("DELETE", "https://api.hasdata.com/scrapers/jobs/:jobId", nil) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() body, _ := io.ReadAll(res.Body) fmt.Println(string(body)) } ``` ## Behavior If the job is still running, all in-progress pages will finish scraping, but no new pages will be started. * Any data collected up to that point is preserved and can still be fetched. * Credits are only charged for successfully scraped pages, even if the job was stopped early. * If the job has already finished or failed, the stop request has no effect. ## Response Example ```javascript theme={null} { "jobId": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "status": "stopped", "creditsSpent": 200, "dataRowsCount": 20, "input": { /* job parameters */ } } ``` # Webhooks Source: https://docs.hasdata.com/scrapers/websites-crawler/webhooks You can configure a webhook to receive real-time updates when a scraper job runs. To enable it, pass a `webhook` object in your job request. Webhook delivery is async and retries automatically on failure (3 attempts) ## Example ```json theme={null} { "webhook": { "url": "https://yourdomain.com/webhook", "events": ["scraper.job.finished", "scraper.data.scraped"], "headers": { "x-custom-header": "custom header value" } } } ``` ## Supported Events * `scraper.job.started` — Sent when the job starts processing * `scraper.data.scraped` — Sent as data is collected (may trigger multiple times) * `scraper.job.finished` — Sent when the job is complete ## Custom Headers You can pass custom HTTP headers in the `headers` field. These headers will be included in every webhook request. Use it to include auth tokens or signatures. ## Payload Each webhook event will include: * `event` — Event name * `jobId` — ID of the related job * `timestamp` — ISO timestamp of the event * `data` — Job Results Example payload: ```json theme={null} { "event": "scraper.job.finished", "jobId": "abc123", "jobStatus": "finished", "timestamp": "2025-04-14T12:00:00Z" } ``` ```javascript theme={null} { "event": "scraper.data.scraped", "timestamp": "2025-04-11T14:30:00Z", "jobId": "dd1a8c53-2d47-4444-977d-8d653a6a3c82", "jobStatus": "in_progress", "data": [ { "text": "Extracted text here...", "statusCode": 200, "statusText": "OK", "url": "https://hasdata.com/blog", "depth": 1, "title": "Blog | HasData" }, /*...*/ { "text": "Extracted text here...", "statusCode": 200, "statusText": "OK", "url": "https://hasdata.com/datasets/", "depth": 1, "title": "Ready-to-use datasets | HasData" } ] } ``` # Yellow Pages Scraper Source: https://docs.hasdata.com/scrapers/yellow-pages Power lead generation, local SEO research, and territory market mapping. Returns business title, URL, full address (country, region, city, zipcode, coordinates), phone, email, categories, working hours, payment options, amenities, website, menu link, rating + reviews, Tripadvisor rating + reviews, images, and breadcrumbs. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Yellow Pages. Yellow Pages is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **3 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/yellow-pages/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":100,"keyword":"Pizza","locations":[],"sort":"name"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/yellow-pages/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: {limit: 100, keyword: 'Pizza', locations: [], sort: 'name'} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/yellow-pages/jobs" payload = { "limit": 100, "keyword": "Pizza", "locations": [], "sort": "name" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 100, "keyword" => "Pizza", "locations" => [], "sort" => "name", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/yellow-pages/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 100, "keyword": "Pizza", "locations": [], "sort": "name" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/yellow-pages/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 100, "keyword": "Pizza", "locations": [], "sort": "name" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/yellow-pages/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/yellow-pages/jobs") payload = { "limit" => 100, "keyword" => "Pizza", "locations" => [], "sort" => "name", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 100, "keyword": "Pizza", "locations": [], "sort": "name" }); let res = client .post("https://api.hasdata.com/scrapers/yellow-pages/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 100, "keyword": "Pizza", "locations": [], "sort": "name" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/yellow-pages/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Data limit (0 - unlimited) Search query for YellowPages businesses to scrape Location to search for businesses using a specific keyword. Use predefined Country–State pairs, or enter your own locations — one per line (supported by YellowPages). Sort By ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | ------------------------------ | ---------------- | | `email` | Email Address | Business email address | 5 credits | | `website` | Website URL | Business website URL | 5 credits | | `phone` | Phone Number | Business phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Business LinkedIn page URL | 5 credits | | `facebookUrl` | Facebook Profile | Business Facebook page URL | 5 credits | | `instagramUrl` | Instagram Profile | Business Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Business X profile URL | 5 credits | | `revenue` | Revenue | Business revenue | 5 credits | | `traffic` | Website Traffic | Business website traffic | 5 credits | | `funding` | Funding Info | Business funding information | 5 credits | | `founded` | Founded Year | Business founded year | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Yelp Scraper Source: https://docs.hasdata.com/scrapers/yelp Build local lead lists, compare competitor offerings, and aggregate review data. Returns business name, URL, place id/alias, phone, website, menu, price level, rating, reviews count, full address and location, categories, services, features, highlights, operation hours, thumbnail, and full image gallery. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Yelp. Yelp is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **3 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/yelp/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":100,"keyword":"Pizza","locations":[],"domain":"www.yelp.com"}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/yelp/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: {limit: 100, keyword: 'Pizza', locations: [], domain: 'www.yelp.com'} }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/yelp/jobs" payload = { "limit": 100, "keyword": "Pizza", "locations": [], "domain": "www.yelp.com" } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 100, "keyword" => "Pizza", "locations" => [], "domain" => "www.yelp.com", ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/yelp/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 100, "keyword": "Pizza", "locations": [], "domain": "www.yelp.com" } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/yelp/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 100, "keyword": "Pizza", "locations": [], "domain": "www.yelp.com" } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/yelp/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/yelp/jobs") payload = { "limit" => 100, "keyword" => "Pizza", "locations" => [], "domain" => "www.yelp.com", } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 100, "keyword": "Pizza", "locations": [], "domain": "www.yelp.com" }); let res = client .post("https://api.hasdata.com/scrapers/yelp/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 100, "keyword": "Pizza", "locations": [], "domain": "www.yelp.com" }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/yelp/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Data limit (0 - unlimited) Search query for Yelp businesses to scrape Location to search for businesses using a specific keyword. Use predefined Country–State pairs, or enter your own locations — one per line (supported by Yelp). Yelp Domain ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | ------------------------------ | ---------------- | | `email` | Email Address | Business email address | 5 credits | | `website` | Website URL | Business website URL | 5 credits | | `phone` | Phone Number | Business phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Business LinkedIn page URL | 5 credits | | `facebookUrl` | Facebook Profile | Business Facebook page URL | 5 credits | | `instagramUrl` | Instagram Profile | Business Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Business X profile URL | 5 credits | | `revenue` | Revenue | Business revenue | 5 credits | | `traffic` | Website Traffic | Business website traffic | 5 credits | | `funding` | Funding Info | Business funding information | 5 credits | | `founded` | Founded Year | Business founded year | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits. # Zillow Real Estate Scraper Source: https://docs.hasdata.com/scrapers/zillow Power real estate market research, lead generation, and investment analysis. Returns full address, city/state/zip, coordinates, price, home type, area, beds/baths, year built, listing details, photos, broker/agent info (with optional emails), price and tax history, schools, floor plans, and nearby data. HasData is an independent service and is not affiliated with, endorsed by, or sponsored by Zillow. Zillow is a trademark of its respective owner. This scraper works with publicly available data only. This scraper job is asynchronous. You'll receive a `jobId`, and can fetch results via polling or webhook delivery. ## Request Cost Each row of data returned consumes **10 credits** from your balance. Credits are deducted only for successful rows. ## Example Request ```bash cURL theme={null} curl --request POST \ --url 'https://api.hasdata.com/scrapers/zillow/jobs' \ --header 'Content-Type: application/json' \ --header 'x-api-key: ' \ --data '{"limit":120,"keyword":"New York","type":"forSale","homeTypes":"all","daysOnZillow":"all","detailedInformation":false,"extractEmails":false}' ``` ```javascript Node.js theme={null} const axios = require('axios').default; const options = { method: 'POST', url: 'https://api.hasdata.com/scrapers/zillow/jobs', headers: {'Content-Type': 'application/json', 'x-api-key': ''}, data: { limit: 120, keyword: 'New York', type: 'forSale', homeTypes: 'all', daysOnZillow: 'all', detailedInformation: false, extractEmails: false } }; try { const { data } = await axios.request(options); console.log(data); } catch (error) { console.error(error); } ``` ```python Python theme={null} import requests url = "https://api.hasdata.com/scrapers/zillow/jobs" payload = { "limit": 120, "keyword": "New York", "type": "forSale", "homeTypes": "all", "daysOnZillow": "all", "detailedInformation": False, "extractEmails": False } headers = { "Content-Type": "application/json", "x-api-key": "" } response = requests.post(url, json=payload, headers=headers) print(response.json()) ``` ```php PHP theme={null} 120, "keyword" => "New York", "type" => "forSale", "homeTypes" => "all", "daysOnZillow" => "all", "detailedInformation" => false, "extractEmails" => false, ]; $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://api.hasdata.com/scrapers/zillow/jobs", CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_HTTPHEADER => [ "Content-Type: application/json", "x-api-key: ", ], ]); $response = curl_exec($curl); curl_close($curl); echo $response; ``` ```java Java theme={null} OkHttpClient client = new OkHttpClient(); MediaType mediaType = MediaType.parse("application/json"); String json = """ { "limit": 120, "keyword": "New York", "type": "forSale", "homeTypes": "all", "daysOnZillow": "all", "detailedInformation": false, "extractEmails": false } """; RequestBody requestBody = RequestBody.create(json, mediaType); Request request = new Request.Builder() .url("https://api.hasdata.com/scrapers/zillow/jobs") .post(requestBody) .addHeader("Content-Type", "application/json") .addHeader("x-api-key", "") .build(); Response response = client.newCall(request).execute(); ``` ```csharp C# theme={null} using System.Net.Http; using System.Text; var client = new HttpClient(); var json = """ { "limit": 120, "keyword": "New York", "type": "forSale", "homeTypes": "all", "daysOnZillow": "all", "detailedInformation": false, "extractEmails": false } """; var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/zillow/jobs") { Content = content, }; request.Headers.Add("x-api-key", ""); using var response = await client.SendAsync(request); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadAsStringAsync(); Console.WriteLine(body); ``` ```ruby Ruby theme={null} require 'net/http' require 'uri' require 'json' uri = URI("https://api.hasdata.com/scrapers/zillow/jobs") payload = { "limit" => 120, "keyword" => "New York", "type" => "forSale", "homeTypes" => "all", "daysOnZillow" => "all", "detailedInformation" => false, "extractEmails" => false, } http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true request = Net::HTTP::Post.new(uri) request["Content-Type"] = 'application/json' request["x-api-key"] = '' request.body = payload.to_json response = http.request(request) puts response.read_body ``` ```rust Rust theme={null} use reqwest::blocking::Client; use serde_json::json; fn main() -> Result<(), Box> { let client = Client::new(); let payload = json!({ "limit": 120, "keyword": "New York", "type": "forSale", "homeTypes": "all", "daysOnZillow": "all", "detailedInformation": false, "extractEmails": false }); let res = client .post("https://api.hasdata.com/scrapers/zillow/jobs") .header("Content-Type", "application/json") .header("x-api-key", "") .json(&payload) .send()? .text()?; println!("{}", res); Ok(()) } ``` ```go Go theme={null} package main import ( "bytes" "fmt" "io" "net/http" ) func main() { payload := []byte(`{ "limit": 120, "keyword": "New York", "type": "forSale", "homeTypes": "all", "daysOnZillow": "all", "detailedInformation": false, "extractEmails": false }`) req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/zillow/jobs", bytes.NewBuffer(payload)) req.Header.Add("Content-Type", "application/json") req.Header.Add("x-api-key", "") res, _ := http.DefaultClient.Do(req) defer res.Body.Close() responseBody, _ := io.ReadAll(res.Body) fmt.Println(string(responseBody)) } ``` ## Job Parameters Result rows limit Location of properties to scrape MLS #, yard, etc. Type Home Type Price Beds Baths Year Built Lot Size Square Feet Days On Zillow (Sold In Last) Listings Detailed Information Extract agents emails (+5 credits per row) ## Supported Enrichments Request any of the fields below via the `enrichments` array in your job payload. | ID | Title | Description | Cost per Request | | -------------- | ------------------- | --------------------------------------- | ---------------- | | `email` | Email Address | Listing agent email address | 5 credits | | `website` | Website URL | Listing agent or brokerage website URL | 5 credits | | `phone` | Phone Number | Listing agent or brokerage phone number | 5 credits | | `linkedinUrl` | LinkedIn Profile | Listing agent LinkedIn profile URL | 5 credits | | `facebookUrl` | Facebook Profile | Listing agent Facebook profile URL | 5 credits | | `instagramUrl` | Instagram Profile | Listing agent Instagram profile URL | 5 credits | | `xUrl` | X (Twitter) Profile | Listing agent X profile URL | 5 credits | | `revenue` | Revenue | Brokerage revenue | 5 credits | | `traffic` | Website Traffic | Brokerage website traffic | 5 credits | | `funding` | Funding Info | Brokerage funding information | 5 credits | | `founded` | Founded Year | Brokerage founded year | 5 credits | ## Getting Results Receive real-time updates when your scraper job starts, completes, or collects data. Use the Results API to fetch your data using the `jobId`, with support for polling and pagination. Cancel an active scraper job early if it's no longer needed or you want to save credits.