Documentation

Choose your language below

Overview

Learn how to take advantage of GridPanel's APIs

GridPanel has one API you can use:

  • The Mobile Proxy API
  • The Scraping API

Below you will find information on how to use and make the most out of these APIs yourself.


Authentication

api_key [string] (default = "") required

All requests, except when explicitly mentioned, to both GridPanel APIs are authenticated using your private API key.

To get access to your API key, create an account and confirm your email address. You can do this here


User Information

GET /api/user

Description

Get information about the user this API key belongs to.

Example

curl 'https://gridpanel.net/api/user?api_key=API_KEY'
import requests

params = {
    'api_key': 'API_KEY',
}

response = requests.get('https://gridpanel.net/api/user', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/user')
params = {
  :api_key => 'API_KEY',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/user?api_key=API_KEY", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/user?api_key=API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/user?api_key=API_KEY"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/user?api_key=API_KEY');

Response

{
  "user": {
    "first_name": "Bob",
    "last_name": "Marley",
    "email": "[email protected]",
    "gbp_balance_in_pence": 10000
  }
}

Proxy API Overview

Our mobile proxy API enables you to: rotate your proxies, get information regarding your usage and your orders in general.

Please note, in order to use the proxy endpoints below, you will need to have an active proxy order on your account.

You can order your GridPanel mobile proxies here.


Rotate your IP address

GET /api/reboot

Description

This endpoint allows you to rotate the IP of your mobile proxy.

Please note that this endpoint does not require your api_key as a parameter.

When you call this endpoint, it will take your proxy down for 20-40 seconds in order for us to get you a new IP address. This is because rotation involves taking the device offline then online again in quick succession. If you have a 5G proxy, it will take your proxy down for around 5-10 seconds as the process is much faster here.

name [type] (default_value) Description
token [string] (required)
This is your rotation token, you will be given one per order and can find it on your manage order page.

Example

curl 'https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi'
import requests

params = {
    'token': 'MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi',
}

response = requests.get('https://gridpanel.net/api/reboot', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/reboot')
params = {
  :token => 'MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/reboot?token=MsIzNSwwIWE1YjnmMC03Yzk2LTRlY2QtOTVhOC1iNDI1ZWo3MTbzOGi');

Response

In the case of a successful rotation you will receive the following response.

{
    "success": true
}

If you attempt to rotate to frequently, in that you rotate faster than you orders minimum rotation time, you will receive the following response.

{
    "success": false,
    "reason": "too_frequent"
}

Proxy Information

GET /api/proxies

Description

Get all proxy orders in your account

Example

curl 'https://gridpanel.net/api/proxies?api_key=API_KEY'
import requests

params = {
    'api_key': 'API_KEY',
}

response = requests.get('https://gridpanel.net/api/proxies', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/proxies')
params = {
  :api_key => 'API_KEY',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/proxies?api_key=API_KEY", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/proxies?api_key=API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/proxies?api_key=API_KEY"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/proxies?api_key=API_KEY');

Response

{
  "orders": {
    "10123": {
      "port": 10123,
      "status": "active",
      "expiry_date": "2023-03-30T00:00:00Z",
      "plan": "5G Mobile Proxies",
      "duration": "Monthly",
      "auto_renew": true,
      "auto_rotate": false,
      "auto_rotate_seconds": null,
      "last_reboot": "2023-03-04T12:34:56Z",
      "minimum_rotation_time_seconds": 300,
      "gateway_ip": "192.168.1.1",
      "username": "username",
      "password": "password",
      "reboot_url": "https://gridpanel.net/api/reboot?token=1234",
      "reboot_token": "1234",
      "connection_string": "username:[email protected]:10123",
      "network": "THREE",
      "location": "LONDON",
    },
    "10124": {
      "port": 10124,
      "status": "active",
      "expiry_date": "2023-03-30T00:00:00Z",
      "plan": "4G Mobile Proxies",
      "duration": "Monthly",
      "auto_renew": true,
      "auto_rotate": false,
      "auto_rotate_seconds": null,
      "last_reboot": "2023-03-06T12:00:00Z",
      "minimum_rotation_time_seconds": 300,
      "gateway_ip": "192.168.1.1",
      "username": "username",
      "password": "password",
      "reboot_url": "https://gridpanel.net/api/reboot?token=1235",
      "reboot_token": "1235",
      "connection_string": "username:[email protected]:10124",
      "network": "EE",
      "location": "LONDON",
    }
  }
}

Proxy Statistics

GET /api/statistics

Description

Returns daily statistics (such as bandwidth usage) for one or more proxies, across a date range.

name [type] (default_value) Description
ports [string] (required)
Proxy port(s) to query for (comma-separated) e.g. 10123,10124
start [string] (required)
Date to query from in YYYY-MM-DD format e.g. 2023-01-01
end [string] (required)
Date to query to in YYYY-MM-DD format e.g. 2023-01-01. Must be within 31 days of start but more than 48 hours before the time of request.

Example

curl 'https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04' 
import requests

response = requests.get(
    'https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04',
)
require 'net/http'

uri = URI('https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04')
res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/statistics?api_key=API_KEY&ports=10123,10124&start=2023-03-01&end=2023-03-04');

Response

{
  "results": {
    "10123": [
      {
        "date": "2023-03-04",
        "used_bytes": 11111111111
      },
      {
        "date": "2023-03-03",
        "used_bytes": 22222222222
      },
      {
        "date": "2023-03-02",
        "used_bytes": 33333333333
      },
      {
        "date": "2023-03-01",
        "used_bytes": 44444444444
      }
    ],
    "10124": [
      {
        "date": "2023-03-04",
        "used_bytes": 55555555555
      },
      {
        "date": "2023-03-03",
        "used_bytes": 66666666666
      },
      {
        "date": "2023-03-02",
        "used_bytes": 77777777777
      },
      {
        "date": "2023-03-01",
        "used_bytes": 88888888888
      }
    ]
  }
}

Anti-detect API Overview

Our anti-detect API enables you to automatically manage your browser profiles from custom sotware. This means you can create, start, stop and manage profiles entirely automatically. You can then connect to them using your favourite browser automation framework.


Browser automation

In order to connect to favourite automation software, you will need to get the automation endpoint from inside the running profiles. This is available via the Settings button from within a running browser session.


Selenium

We encourage using a patched chromedriver (e.g. this one). This makes detection more difficult, but not impossible.
chrome_options = Options()
chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:53018")
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get('http://iphey.com')

Remember to replace 127.0.0.1:53018 with your endpoint.


Puppeteer

const puppeteer = require('puppeteer-core');
 
(async () => {
	const browser = await puppeteer.connect({
		browserURL: `http://127.0.0.1:53018`
	});
	 
	const page = await browser.newPage();
	await page.goto('http://iphey.com');
})();

Remember to replace 127.0.0.1:53018 with your endpoint.


Playwright

const { chromium } = require('playwright');
 
(async () => {
	const browser = await chromium.connectOverCDP(`http://127.0.0.1:53018`);
	 
	const page = await browser.contexts()[0].newPage();
	await page.goto('https://iphey.com');
})();

Remember to replace 127.0.0.1:53018 with your endpoint.


CDP (Chrome Devtools Protocol)

For the ultimate control, we highly recommend connecting directly via CDP (the Chrome Devtools Protocol). This provides the lowest risk of being caught with an automation framework, but provides the most raw access and the least number of in-built features.

To use CDP, you can begin by opening http://127.0.0.1:53018/json to see your tabs. Explore the https://chromedevtools.github.io/devtools-protocol/ to see how to control each part of the browser, much like how you would with Selenium, Playwright or Puppeteer.

Remember to replace 127.0.0.1:53018 with your endpoint.


Scraping API Overview

GET /api/scrape

GridPanel's scraping API is the easiest scraping API available to use on the web.

To scrape any web page, you need two things:

  • Your API key, available here
  • The encoded web page URL you want to scrape

The following is an example snippet of a simple GET API call to scrape the URL defined in the query string variable YOUR-URL :

curl 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL'
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL');

The API will then respond with the raw HTML content of the target URL:

<html>

    <head>
        ...
    </head>

    <body>
        ...
    </body>

</html>

Be aware of the maximum 30-second timeout when your code calls the API

Headers and cookies returned by the target website are prefixed with Spb- (for Scraping browser)


Parameters

Here is the list of the different parameters you can use with GridPanel's HTML API.

name [type] (default_value) Description
api_key [string] (required)
Your API key Get your API key
url [string] (required)
The URL of the page you want to scrape
render_js [boolean] (true)
Render javascript on the page
block_ads [boolean] (false)
Block ads on the page you want to scrape
block_resources [boolean] (true)
Block images and CSS on the page you want to scrape
cookies [string] ("")
Pass custom cookies to the webpage you want to scrape
country_code [string] ("")
Premium proxy geolocation
device [string] ("desktop")
Control the device the request will be sent from
extract_rules [[stringified JSON]] ("")
Data extraction from CSS selectors
forward_headers [boolean] (false)
Forward particular headers to the webpage, as well as any other headers generated by GridPanel
forward_headers_pure [boolean] (false)
Forward only particular headers to webpage, no other headers
js_scenario [[stringified JSON]] ({})
JavaScript scenario to execute
json_response [bool] (false)
Wrap the response in JSON
own_proxy [string] ("")
The details of your own proxy, if you want to use your own.
return_page_source [boolean] (false)
Return the original HTML before JavaScript rendering
screenshot [boolean] (false)
Return a screenshot of the page you want to scrape
screenshot_selector [string] ("")
Return a screenshot of a certain area of the page, based on a CSS selector
create_session [boolean] (false)
Create a session that lasts 5 minutes
session_id [string] ("")
Route multiple API requests through the same session (IP address and browser context)
stealth_proxy [boolean] (false)
Use special stealth proxy pool
timeout [integer] (14000)
Timeout for your requests
transparent_status_code [boolean] (false)
Transparently return the same HTTP code of the page requested
wait [integer] (0)
Additional time in ms for JavaScript to render
wait_browser [string] (domcontentloaded)
Wait until certain browser conditions are met before returning the response
wait_for [string] ("")
CSS/XPath selector to wait for in the DOM
window_height [integer] (1080)
Pixel height of the viewport used to render the page you want to scrape
window_width [integer] (1920)
Pixel width of the viewport used to render the page you want to scrape

URL

url [string] (default = "") required

This parameter is the full URL including the protocol (with http/https ) of the page to extract data from.

You must encode your URL. For example, the + character is encoded to %20 . Consult your programming language documentation for functions that encode URLs.

Alternatively you can encode/decode urls using this tool: https://meyerweb.com/eric/tools/dencoder/

We have provided a number of examples for some languages below:

p = URI::Parser.new
p.escape("YOUR-URL")
sudo apt-get install gridsite-clients
urlencode "YOUR URL"
import urllib.parse
encoded_url = urllib.parse.quote("YOUR URL")
<?php

$url_encoded = urlencode("YOUR URL");

?>
String encoded_url = URLEncoder.encode("YOUR URL", "UTF-8");
package main

import (
"net/url"
)

func main() {
encoded_url := url.QueryEscape("YOUR URL")
}
encoded_url = encodeURIComponent("YOUR URL")

JavaScript Rendering

render_js [boolean] (default = true)

By default, GridPanel will fetch the URL you want to scrape on a real device and execute the websites JavaScript code on the page.

However, there may be scenarios where you want to disable JS rendering entirely, this can be done by setting render_js=false, like we are doing below:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'render_js': 'false',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :render_js => 'false',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&render_js=false');

Block Ads

block_ads [boolean] (default = false)

To block ads when scraping pass block_ads=true, this can also help you speed up your requests as all ad loading will be prevented.

Note, that this parameter is unnecessary if JavaScript rendering has been disabled.

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'block_ads': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :block_ads => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_ads=true');

Block Resources

block_ads [boolean] (default = false)

To block resources (images & CSS) when scraping pass block_resources=true, this can also help you speed up your requests as all resource loading will be prevented.

Note, that this parameter is unnecessary if JavaScript rendering has been disabled.

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'block_resources': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :block_resources => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&block_resources=true');

Wait a fixed amount of time

wait [integer] (default = 0)

Most websites take some time to fully render their full content. Using the wait parameter you can tell GridPanel to wait before it returns the fully rendered HTML.

The wait parameter can be a value in milliseconds between 0 and 35000.

Below you can see an example where we are waiting 10000ms (10 seconds) for the page to load before we return the HTML.

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'wait': '10000',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :wait => '10000',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait=10000');

Wait for selector

wait_for [string] (default = "")

Instead of waiting a fixed amount of time, you might just want to wait for a particular element to appear in the DOM before returning the HTML.

You can utilise the wait_for parameter to pass a CSS/XPath selector to wait for before returning any HTML.

Below you can see an example of us waiting for the div element with a class value of a-loading-div, therefore we can use wait_for=.a-loading-div

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'wait_for': '.a-loading-div',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :wait_for => '.a-loading-div',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_for=.a-loading-div');

Wait for the browser

wait_browser [string] (default = load)

Instead of waiting for a specific time period, or for an element to appear, you can wait until specific network conditions have been met.

This parameter can take one of 4 different values:

  • domcontentloaded: Wait until the DOM is loaded
  • load (default): Wait until the page is fully loaded
  • networkidle0: Wait until there are no more than 0 network connections for at least 500ms
  • networkidle2: Wait until there are no more than 2 network connections for at least 500ms

Below you can see an example where we are waiting for the DOM to load by passing wait_browser=domcontentloaded.

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'wait_browser': 'domcontentloaded',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :wait_browser => 'domcontentloaded',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&wait_browser=domcontentloaded');

Data Extraction

extract_rules [stringified JSON] (default = "")

If you need to extract any data from the pages you scrape, and don't want to process any HTML on your side, you can take advantage of our extraction rules.

These rules are passed through the extract_rules parameter and use the following syntax:

{ "key_name": "css_or_xpath_selector" }

For example, if you are looking to extract the title, and subtitle of a blog post you will need to use rules that look like the following:

{
    "title": "h1",
    "subtitle": "#subtitle"
}

This will then return the following JSON response:

{
    "title": "Your blog title",
    "subtitle": "Your blog subtitle"
}

It's important to note that these rules are JSON formatted and therefore need to be stringified when you pass them with your requests. You can see an example request here:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'extract_rules': '{"title": "h1", "subtitle": "#subtitle"}',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :extract_rules => '{"title": "h1", "subtitle": "#subtitle"}',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&extract_rules=%7B%22title%22%3A+%22h1%22%2C+%22subtitle%22%3A+%22%23subtitle%22%7D');

Running JavaScript

js_scenario [stringified JSON] (default = {})

To interact with pages you want to scrape before we return the HTML you can add a JavaScript scenario to your API calls.

For example, to click a button, you can use the following scenario:

{
    "instructions": [
        { "click": "#buttonId"}
    ]
}

This will result with the following API call:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'js_scenario': '{"instructions": [{"click": "#buttonId"}]}',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :js_scenario => '{"instructions": [{"click": "#buttonId"}]}',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&js_scenario=%7B%22instructions%22%3A+%5B%7B%22click%22%3A+%22%23buttonId%22%7D%5D%7D');

Again please note that the JavaScript scenario parameter is JSON formatted, which means you need to stringify it when you pass it to your API requests.

Each scenario can have multiple instructions, and they will be executed in the order you send them before returning the HTML of the page.

The supported instructions are as follows:

{
    "instructions": [
        {"click": "#buttonId"}, // Click a button
        {"wait": 1000}, // Wait a fixed duration in ms
        {"wait_for": #a_div}, // Wait for a specific element
        {"wait_for_and_click": #a_div}, // Wait for an element and click it
        {"scroll_x": 1000}, // Scroll the screen in the horizontal axis, in px
        {"scroll_y": 1000}, // Scroll the screen in the vertical axis, in px
        {"fill": ["#input_1", "value_1"]}, // Fill in some input
        {"evaluate": "console.log(123)", // Evaluate custom javascript code
        {"infinite_scroll": // Scroll the page until end
            {
                "max_count": 0, // Max number to scroll, 0 is forever
                "delay": 1000, // Delay between every scroll in ms
                "end_click": { "selector": "#button_id" } // Click a button when the end of the page is reached
            }
        }
    ]
}

If an instruction you need is not supported, you can use the evaluate instruction to run any JavaScript code that you need.


Returning JSON

json_response [boolean] (default = false)

If you want your response format to be in JSON and you want to intercept the responses of XHR/Ajax requests you can use the json_response parameter.

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'json_response': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :json_response => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&json_response=true');

You will receive a response that looks like the following:


{
  # Headers sent by the server
  "headers": {
    "Date": "Fri, 16 Apr 2021 15:03:54 GMT",
    ...
    "Access-Control-Allow-Credentials": "true"
  },
  # Credit cost of your request
  "cost": 1,
  # Initial status code of the server
  "initial-status-code": 200,
  # Resolved URL (following redirection)
  "resolved-url": "https://httpbin.org/",
  # Type of the response "html" or "json" or "b64_bytes" for file, image, pdf,...
  "type": "html",
  # Content of the answer. Content will be base 64 encoded if is a file, image, pdf,...
  "body": "<html>... </body>"
  # base 64 encoded screenshot of the page, if screenshot=true is used
  "screenshot": "b0918...aef",
  # Cookies sent back by the server
  "cookies": [
    {
        "name": "cookie_name",
        "value": "cookie_value",
        "domain": "test.com",
        ...
    },
    ...
  ],
  # Results of the JS scenario "evaluate" instructions
  "evaluate_results": [...]
  # Content and source of iframes in the page
  "iframes": [
    {
      "content": "<html>... </body>",
      "src": "https://site.com/iframe"
    },
    ...
  ],
  # XHR / Ajax requests sent by the browser
  "xhr": [
    {
      # URL
      "url": "https://",
      # status code of the server
      "status_code": 200,
      # Method of the request
      "method": "POST",
      # Headers of the XHR / Ajax request
      "headers": {
        "pragma": "no-cache",
        ...
      },
      # Response of the XHR / Ajax request
      "body": "2d,x"
    },
    ...
  ],
  # js_scenario detailed report ( only useful if using render_js=True and js_scenario=...)
  "js_scenario_report": {
    "task_executed": 1,
    "task_failure": 0,
    "task_success": 1,
    "tasks": [
        {
            "duration": 3.042,
            "params": 3000,
            "success": true,
            "task": "wait"
        }
    ],
    "total_duration": 3.042
  }, 
  # Metada / Schema data
  "metadata": {
    "microdata": ...,
    "json-ld": ..., 
  }
} 

Return page source

return_page_source [boolean] (default = false)

If you need the HTML returned by the server, unchanged by the browser (before any JavaScript has been executed), you can pass return_page_source=true

If you have disabled JavaScript rendering, this parameter will do nothing and is unnecessary.

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'return_page_source': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :return_page_source => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&return_page_source=true');

Creating a session

create_session [boolean] (default = false)

In some instances you need to re-use the same browser context and IP address across multiple requests. For example, if you need to preserve cookies across requests.

You can achieve this by creating a session which will last 30 seconds from the last request made, for a maximum of 20 minutes. To create a session, pass create_session=true to your API calls and it will return to you the html of the page as well as a session_id which you can then use in later requests.

Below you can see how we can create a session:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'create_session': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :create_session => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&create_session=true');

This will return a session_id uuid like below:

{
    ...
    "session_id": "717094a8-f324-451f-8cc3-81c6e3f1205d",
    ...
}

Read on to understand how to use the session_id parameter


Using a session

session_id [string] (default = "")

Once you have obtained your session_id using create_session=true you can route your requests through the same browser context.

To do this, you need to pass the session_id to all your API calls as follows:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'session_id': '717094a8-f324-451f-8cc3-81c6e3f1205d',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :session_id => '717094a8-f324-451f-8cc3-81c6e3f1205d',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&session_id=717094a8-f324-451f-8cc3-81c6e3f1205d');

Every request you make with the session_id parameter will extend the session for 30 seconds. Your session cannot be longer than 20 minutes total.


Screenshot

screenshot [boolean] (default = false)

If you require a screenshot of the page that you want to scrape, you can use the screenshot parameter.

Your response will then contain a screenshot key where the value is the screenshot data in base64.

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true" > ./screenshot.png
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'screenshot': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :screenshot => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&screenshot=true');

Screenshot a selector

screenshot_selector [string] (default = "")

Instead of taking a screenshot of the whole page, you can screenshot a specific CSS/XPath selector.

To achieve this, pass screenshot_selector=CSS_selector where CSS_selector is the the selector you want to capture.


Premium Proxy

premium_proxy [boolean] (default = false)

To scrape some websites, you may need to use a premium proxy to ensure you do not get blocked.

We recommend trying premium proxies when you receive error codes or are scraping harder sites.

To gain access to our premium proxy pool pass premium_proxy=true

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&premium_proxy=true"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'premium_proxy': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :premium_proxy => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&premium_proxy=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&premium_proxy=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&premium_proxy=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&premium_proxy=true');

Stealth Proxy

stealth_proxy [boolean] (default = false)

For the hardest to scrape websites using premium_proxy=true is not enough. You can take advantage of our stealth api pool to scrape the hardest websites.

To use this proxy pool, pass stealth_proxy=true to your API calls.

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'stealth_proxy': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :stealth_proxy => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&stealth_proxy=true');

Own Proxy

stealth_proxy [string] (default = "")

If you want to use our scraping infrastructure but provide your own proxy you can use the own_proxy parameter. You can then take advantage of all GridPanel's features with your own proxy.

The syntax for suppling proxy information is as follows: {protocol}{username}:{password}@{host}:{port}

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'own_proxy': 'https://johndoe:password@my_proxy.com:1234',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :own_proxy => 'https://johndoe:password@my_proxy.com:1234',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&own_proxy=https%3A%2F%2Fjohndoe%3Apassword%40my_proxy.com%3A1234');

Geolocation

country_code [string] (default = "")

As well as using premium proxies, you are also able to chose the proxy location using the country_code parameter.

For example to use proxies from the United Kingdom you need to set premium_proxy=true

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'country_code': 'de',
    'premium_proxy': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :country_code => 'de',
  :premium_proxy => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&country_code=de&premium_proxy=true');

Device

device [string] (default = 'desktop')

Choose the device that will send the request.

We currently support two device types: desktop (default) and mobile.

Below you can see an example where we are setting the device to desktop:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'device': 'desktop',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :device => 'desktop',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=desktop');

Here we are setting the device to mobile:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'device': 'mobile',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :device => 'mobile',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&device=mobile');

Window width

window_width [integer] (default = 1920)

If you need to change the dimensions of the browser's viewport, when scraping you can use the window_width and window_height parameters.

Below you can see an example of setting window_width

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'window_width': '1500',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :window_width => '1500',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_width=1500');

Window height

window_height [integer] (default = 1080)

If you need to change the dimensions of the browser's viewport, when scraping you can use the window_width and window_height parameters.

Below you can see an example of setting window_height

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'window_height': '500',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :window_height => '500',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&window_height=500');

Cookies

cookies [string] (default = "")

If you need to pass any custom cookies to the page you are trying to scrape, you can pass a cookie string through the cookie parameter.

If you need to pass multiple cookies, you need to separate them with a ;.

Every cookie can have the following attributes:

  • name (required)
  • value (required)
  • domain (optional)
  • path (optional)
  • expires (optional)

Every attribute needs to be separated with a ,.

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&cookies=cookie_name_1%3Dcookie_value1%3Bcookie_name_2%3Dcookie_value_2"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'cookies': 'cookie_name_1=cookie_value1;cookie_name_2=cookie_value_2',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :cookies => 'cookie_name_1=cookie_value1;cookie_name_2=cookie_value_2',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&cookies=cookie_name_1%3Dcookie_value1%3Bcookie_name_2%3Dcookie_value_2", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&cookies=cookie_name_1%3Dcookie_value1%3Bcookie_name_2%3Dcookie_value_2');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&cookies=cookie_name_1%3Dcookie_value1%3Bcookie_name_2%3Dcookie_value_2"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&cookies=cookie_name_1%3Dcookie_value1%3Bcookie_name_2%3Dcookie_value_2');

Transparent status codes

transparent_status_code [boolean] (default = false)

GridPanel's default behaviour is to return a HTTP 500 if the scraped URL returns something other than a 20x or a 404.

To get the same status code as the requested URL use the transparent_status_code parameter.

You can see an example of this below:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true"
import requests

params = {
    'api_key': 'API_KEY',
    'url': 'YOUR-URL',
    'transparent_status_code': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'YOUR-URL',
  :transparent_status_code => 'true',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=YOUR-URL&transparent_status_code=true');

Forward headers

forward_headers [boolean] (default = false)

In some circumstances you might need to forward certain headers to the website that you want to scrape.

To achieve this, you need to set forward_headers to true and then pass your custom headers.

To forward headers, you must ensure that you prefix each header with "Spb-" for "Scraping Browser". We will trim the prefix and send the headers to the target website.

Below you can see an example of how to forward the Accept-Language header to the target site:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true"   -H "Spb-Accept-Language:En-US"
import requests

headers = {
    'Spb-Accept-Language': 'En-US',
}

params = {
    'api_key': 'API_KEY',
    'url': 'http://httpbin.org/headers?json',
    'forward_headers': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params, headers=headers)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'http://httpbin.org/headers?json',
  :forward_headers => 'true',
}
uri.query = URI.encode_www_form(params)

req = Net::HTTP::Get.new(uri)
req['Spb-Accept-Language'] = 'En-US'

req_options = {
  use_ssl: uri.scheme == 'https'
}
res = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(req)
end
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("Spb-Accept-Language", "En-US")
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Spb-Accept-Language: En-US',
]);

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true"))
    .GET()
    .setHeader("Spb-Accept-Language", "En-US")
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers=true', {
  headers: {
    'Spb-Accept-Language': 'En-US'
  }
});

Forward headers pure

forward_headers_pure [boolean] (default = false)

If you want to forward headers, but you want to ensure those are the only headers that get sent with your requests, you can use forward_headers_pure.

To achieve this, you need to set forward_headers_pure to true and then pass your custom headers.

To forward headers, you must ensure that you prefix each header with "Spb-" for "Scraping Browser". We will trim the prefix and send the headers to the target website.

Below you can see an example of how to forward the Accept-Language header to the target site:

curl "https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true"   -H "Spb-Accept-Language:En-US"
import requests

headers = {
    'Spb-Accept-Language': 'En-US',
}

params = {
    'api_key': 'API_KEY',
    'url': 'http://httpbin.org/headers?json',
    'forward_headers_pure': 'true',
}

response = requests.get('https://gridpanel.net/api/scrape', params=params, headers=headers)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape')
params = {
  :api_key => 'API_KEY',
  :url => 'http://httpbin.org/headers?json',
  :forward_headers_pure => 'true',
}
uri.query = URI.encode_www_form(params)

req = Net::HTTP::Get.new(uri)
req['Spb-Accept-Language'] = 'En-US'

req_options = {
  use_ssl: uri.scheme == 'https'
}
res = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
  http.request(req)
end
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true", nil)
	if err != nil {
		log.Fatal(err)
	}
	req.Header.Set("Spb-Accept-Language", "En-US")
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Spb-Accept-Language: En-US',
]);

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true"))
    .GET()
    .setHeader("Spb-Accept-Language", "En-US")
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape?api_key=API_KEY&url=http%3A%2F%2Fhttpbin.org%2Fheaders%3Fjson&forward_headers_pure=true', {
  headers: {
    'Spb-Accept-Language': 'En-US'
  }
});

Track your usage

GET /api/scrape/usage

Description

Allows you to programmatically monitor credit consumption and currency usage.

Results are available in real time, and will not increase your request concurrency and will not cost credits.

Example

curl 'https://gridpanel.net/api/scrape/usage?api_key=API_KEY'
import requests

params = {
    'api_key': 'API_KEY',
}

response = requests.get('https://gridpanel.net/api/scrape/usage', params=params)
require 'net/http'

uri = URI('https://gridpanel.net/api/scrape/usage')
params = {
  :api_key => 'API_KEY',
}
uri.query = URI.encode_www_form(params)

res = Net::HTTP.get_response(uri)
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
)

func main() {
	client := &http.Client{}
	req, err := http.NewRequest("GET", "https://gridpanel.net/api/scrape/usage?api_key=API_KEY", nil)
	if err != nil {
		log.Fatal(err)
	}
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer resp.Body.Close()
	bodyText, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s
", bodyText)
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gridpanel.net/api/scrape/usage?api_key=API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$response = curl_exec($ch);

curl_close($ch);
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://gridpanel.net/api/scrape/usage?api_key=API_KEY"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
fetch('https://gridpanel.net/api/scrape/usage?api_key=API_KEY');

Response

{
  "result": {
    "max_api_credit": 100000,
    "used_api_credit": 301,
    "max_concurrency": 5,
    "used_concurrency": 1,
    "renewal_date": "Free Trial"
}

Credit costs

Every GridPanel plan will provide you a certain number of API credits per month.

Each request costs a different amount of credits based on the parameters you pass with your API calls.

Below is a breakdown of these costs:

Feature used Credit cost
Rotating Proxy without javascript rendering 1
Rotating Proxy with javascript rendering (default) 5
Premium Proxy without javascript rendering 10
Premium Proxy with javascript rendering 25
Stealth Proxy without javascript rendering 75
Stealth Proxy with javascript rendering 75
Creating a session 50