requests field.
When to Use Batch Scraping
- Extracting titles, authors, and publish dates from a list of blog or news article URLs
- Running
aiExtractRulesacross 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
curl --request POST \
--url 'https://api.hasdata.com/scrape/batch/web' \
--header 'Content-Type: application/json' \
--header 'x-api-key: <your-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"}}}]}'
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': '<your-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);
}
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": "<your-api-key>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
<?php
$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"]]]],
];
$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: <your-api-key>",
],
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
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", "<your-api-key>")
.build();
Response response = client.newCall(request).execute();
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", "<your-api-key>");
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
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"] = '<your-api-key>'
request.body = payload.to_json
response = http.request(request)
puts response.read_body
use reqwest::blocking::Client;
use serde_json::json;
fn main() -> Result<(), Box<dyn std::error::Error>> {
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", "<your-api-key>")
.json(&payload)
.send()?
.text()?;
println!("{}", res);
Ok(())
}
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", "<your-api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
responseBody, _ := io.ReadAll(res.Body)
fmt.Println(string(responseBody))
}
Response
{
"jobId": "9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0",
"status": "ok"
}
Get Job Status & Results
To check the status of your batch job: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: <your-api-key>'
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': '<your-api-key>'}
};
try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}
import requests
url = "https://api.hasdata.com/scrape/batch/web/9a35f32e-4f9c-4d49-9c6e-7c4de4a091e0"
headers = {
"Content-Type": "application/json",
"x-api-key": "<your-api-key>"
}
response = requests.get(url, headers=headers)
print(response.json())
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "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: <your-api-key>",
],
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
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", "<your-api-key>")
.build();
Response response = client.newCall(request).execute();
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", "<your-api-key>");
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
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"] = '<your-api-key>'
response = http.request(request)
puts response.read_body
use reqwest::blocking::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
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", "<your-api-key>")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
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", "<your-api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}
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: <your-api-key>'
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': '<your-api-key>'}
};
try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}
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": "<your-api-key>"
}
response = requests.get(url, headers=headers, params=querystring)
print(response.json())
<?php
$params = [
"page" => "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: <your-api-key>",
],
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
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", "<your-api-key>")
.build();
Response response = client.newCall(request).execute();
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", "<your-api-key>");
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(content);
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"] = '<your-api-key>'
response = http.request(request)
puts response.read_body
use reqwest::blocking::Client;
fn main() -> Result<(), Box<dyn std::error::Error>> {
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", "<your-api-key>")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
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", "<your-api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}
Example Result
{
"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