webhook object in your job request.
Webhook delivery is async and retries automatically on failure (3 attempts)
Example
curl --request POST \
--url 'https://api.hasdata.com/scrapers/google-maps/jobs' \
--header 'Content-Type: application/json' \
--header 'x-api-key: <your-api-key>' \
--data '{"keywords":["coffee shops"],"locations":["CUSTOM>New York, NY"],"extractEmails":true,"webhook":{"url":"https://yourdomain.com/webhook","events":["scraper.job.started","scraper.job.finished","scraper.data.scraped"],"headers":{"x-custom-header":"custom header value"}}}'
const axios = require('axios').default;
const options = {
method: 'POST',
url: 'https://api.hasdata.com/scrapers/google-maps/jobs',
headers: {'Content-Type': 'application/json', 'x-api-key': '<your-api-key>'},
data: {
keywords: ['coffee shops'],
locations: ['CUSTOM>New York, NY'],
extractEmails: true,
webhook: {
url: 'https://yourdomain.com/webhook',
events: ['scraper.job.started', 'scraper.job.finished', 'scraper.data.scraped'],
headers: {'x-custom-header': 'custom header value'}
}
}
};
try {
const { data } = await axios.request(options);
console.log(data);
} catch (error) {
console.error(error);
}
import requests
url = "https://api.hasdata.com/scrapers/google-maps/jobs"
payload = {
"keywords": ["coffee shops"],
"locations": ["CUSTOM>New York, NY"],
"extractEmails": True,
"webhook": {
"url": "https://yourdomain.com/webhook",
"events": ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"],
"headers": { "x-custom-header": "custom header value" }
}
}
headers = {
"Content-Type": "application/json",
"x-api-key": "<your-api-key>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
<?php
$payload = [
"keywords" => ["coffee shops"],
"locations" => ["CUSTOM>New York, NY"],
"extractEmails" => true,
"webhook" => ["url" => "https://yourdomain.com/webhook", "events" => ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"], "headers" => ["x-custom-header" => "custom header value"]],
];
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.hasdata.com/scrapers/google-maps/jobs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <your-api-key>",
],
]);
$response = curl_exec($curl);
curl_close($curl);
echo $response;
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
String json = """
{
"keywords": [
"coffee shops"
],
"locations": [
"CUSTOM>New York, NY"
],
"extractEmails": true,
"webhook": {
"url": "https://yourdomain.com/webhook",
"events": [
"scraper.job.started",
"scraper.job.finished",
"scraper.data.scraped"
],
"headers": {
"x-custom-header": "custom header value"
}
}
}
""";
RequestBody requestBody = RequestBody.create(json, mediaType);
Request request = new Request.Builder()
.url("https://api.hasdata.com/scrapers/google-maps/jobs")
.post(requestBody)
.addHeader("Content-Type", "application/json")
.addHeader("x-api-key", "<your-api-key>")
.build();
Response response = client.newCall(request).execute();
using System.Net.Http;
using System.Text;
var client = new HttpClient();
var json = """
{
"keywords": [
"coffee shops"
],
"locations": [
"CUSTOM>New York, NY"
],
"extractEmails": true,
"webhook": {
"url": "https://yourdomain.com/webhook",
"events": [
"scraper.job.started",
"scraper.job.finished",
"scraper.data.scraped"
],
"headers": {
"x-custom-header": "custom header value"
}
}
}
""";
var content = new StringContent(json, Encoding.UTF8, "application/json");
var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.hasdata.com/scrapers/google-maps/jobs")
{
Content = content,
};
request.Headers.Add("x-api-key", "<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/scrapers/google-maps/jobs")
payload = {
"keywords" => ["coffee shops"],
"locations" => ["CUSTOM>New York, NY"],
"extractEmails" => true,
"webhook" => {"url" => "https://yourdomain.com/webhook", "events" => ["scraper.job.started", "scraper.job.finished", "scraper.data.scraped"], "headers" => {"x-custom-header" => "custom header value"}},
}
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request["Content-Type"] = 'application/json'
request["x-api-key"] = '<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!({
"keywords": [
"coffee shops"
],
"locations": [
"CUSTOM>New York, NY"
],
"extractEmails": true,
"webhook": {
"url": "https://yourdomain.com/webhook",
"events": [
"scraper.job.started",
"scraper.job.finished",
"scraper.data.scraped"
],
"headers": {
"x-custom-header": "custom header value"
}
}
});
let res = client
.post("https://api.hasdata.com/scrapers/google-maps/jobs")
.header("Content-Type", "application/json")
.header("x-api-key", "<your-api-key>")
.json(&payload)
.send()?
.text()?;
println!("{}", res);
Ok(())
}
package main
import (
"bytes"
"fmt"
"io"
"net/http"
)
func main() {
payload := []byte(`{
"keywords": [
"coffee shops"
],
"locations": [
"CUSTOM>New York, NY"
],
"extractEmails": true,
"webhook": {
"url": "https://yourdomain.com/webhook",
"events": [
"scraper.job.started",
"scraper.job.finished",
"scraper.data.scraped"
],
"headers": {
"x-custom-header": "custom header value"
}
}
}`)
req, _ := http.NewRequest("POST", "https://api.hasdata.com/scrapers/google-maps/jobs", bytes.NewBuffer(payload))
req.Header.Add("Content-Type", "application/json")
req.Header.Add("x-api-key", "<your-api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
responseBody, _ := io.ReadAll(res.Body)
fmt.Println(string(responseBody))
}
Supported Events
scraper.job.started— Sent when the job starts processingscraper.data.scraped— Sent as data is collected (may trigger multiple times)scraper.job.finished— Sent when the job is complete