When you configure a webhook URL in your Outscraper integration settings, our system will automatically send a POST
request with the scraped results to that URL whenever a task/reuqest is finished.
For security, every webhook payload is signed using your Outscraper API key. This allows you to verify that the webhook truly comes from Outscraper and has not been altered.
Step 1. Signature Header
Every webhook request includes an additional header:
X-Hub-Signature-256: sha256=
-
<signature>
is an HMAC-SHA256 digest of the raw JSON payload. -
It is generated using your Outscraper API key.
-
To verify authenticity, you need to compute the same digest locally and compare it with the header.
Step 2. Example Webhook Request
Here’s what a real webhook request looks like:
POST /webhooks HTTP/1.1
Host: your-domain.com
Content-Type: application/json
X-Hub-Signature-256: sha256=7b6b9d07b1c0d7ff3b4b3fcecbf9c08a5f6c2a248ef12c7a37a7269d3a5b1b93
{
"id": "your-request-id",
"user_id": "your-user-id",
"status": "SUCCESS",
"api_task": true,
"results_location": "https://api.outscraper.cloud/requests/your-request-id",
"quota_usage": [
{
"product_name": "Google Maps Data",
"quantity": 1
}
]
}
Step 3. Verifying
To verify a webhook request, you must:
-
Read the raw JSON payload (not the parsed object).
-
Compute an HMAC-SHA256 digest of this payload using your API key.
-
Prepend it with
"sha256="
and compare to the value in theX-Hub-Signature-256
header. -
Reject the request if the signatures don’t match.
Python Example
import hmac
import hashlib
import json
from flask import Flask, request, abort
app = Flask(__name__)
API_KEY = "your_api_key_here" # your Outscraper API key
def generate_hmac_sha256(secret: str, data: str) -> str:
return hmac.new(secret.encode("utf-8"), data.encode("utf-8"), hashlib.sha256).hexdigest()
@app.route("/webhooks", methods=["POST"])
def webhook():
# Raw JSON payload as text
payload = request.get_data(as_text=True)
# Signature header from Outscraper
signature_header = request.headers.get("X-Hub-Signature-256", "")
# Compute expected signature
expected_signature = "sha256=" + generate_hmac_sha256(API_KEY, payload)
# Secure comparison
if not hmac.compare_digest(signature_header, expected_signature):
abort(401, "Invalid signature")
data = json.loads(payload)
print("Verified payload:", data)
return "ok", 200
Node.js Example
const crypto = require("crypto");
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json({ verify: (req, res, buf) => { req.rawBody = buf.toString() } }));
const API_KEY = "your_api_key_here"; // your Outscraper API key
function generateHmacSha256(secret, data) {
return crypto.createHmac("sha256", secret).update(data, "utf8").digest("hex");
}
app.post("/webhooks", (req, res) => {
const signature = req.headers["x-hub-signature-256"];
const expected = "sha256=" + generateHmacSha256(API_KEY, req.rawBody);
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).send("Invalid signature");
}
console.log("Verified payload:", req.body);
res.send("ok");
});
app.listen(3000, () => console.log("Webhook listener running on port 3000"));
PHP Example
Step 4. What to Do if Verification Fails
If the computed signature does not match the header:
Reject the request (
401 Unauthorized
).Log the attempt for debugging/audit.
Do not process the payload.
Step 5. Testing
You can test your verification logic by triggering a webhook from Outscraper.
The signature will always validate correctly as long as you use your API key.
Summary
All Outscraper webhooks are signed using your API key.
Verify requests by computing:
sha256(HMAC(api_key, raw_payload))
Compare the computed digest with the
X-Hub-Signature-256
header.Only process verified requests to keep your system secure.
References
The method Outscraper uses is the same approach trusted by major platforms for verifying webhook authenticity:
GitHub Webhooks: Securing your webhooks – GitHub uses the same
X-Hub-Signature-256
header with HMAC-SHA256.Twilio: Validating Requests – Twilio validates all webhook requests via HMAC signatures.
Slack: Verifying requests from Slack – Slack signs requests with a shared secret and requires HMAC validation.
These examples show that verifying webhook signatures with HMAC-SHA256 is the standard way to confirm authenticity and prevent tampering.