Copy-paste examples in cURL, Node.js, and Python. Replace credentials and the host as needed. All examples assume https://api.kwery.co and query Idealo — swap source and country for any other source.
curl -s https://api.kwery.co/job \
-H "Authorization: Bearer $KWERY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"source":"idealo","country":"de","key":"gtin","values":["4006381333962"]}'const res = await fetch('https://api.kwery.co/job', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.KWERY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ source: 'idealo', country: 'de', key: 'gtin', values: ['4006381333962'] }),
});
const data = await res.json();
if (data.error) throw new Error(data.message);
console.log('job id:', data.job._id);import os, requests
res = requests.post(
"https://api.kwery.co/job",
headers={"Authorization": f"Bearer {os.environ['KWERY_API_KEY']}"},
json={"source": "idealo", "country": "de", "key": "gtin", "values": ["4006381333962"]},
)
data = res.json()
if data.get("error"):
raise RuntimeError(data["message"])
print("job id:", data["job"]["_id"])JOB=64f1c2d3e4b5a6c7d8e9f0a1
curl -s "https://api.kwery.co/job/$JOB" -H "Authorization: Bearer $KWERY_API_KEY" # status
curl -s "https://api.kwery.co/job/$JOB/download" -H "Authorization: Bearer $KWERY_API_KEY" # resultsasync function waitAndDownload(jobId) {
const headers = { 'Authorization': `Bearer ${process.env.KWERY_API_KEY}` };
for (;;) {
const job = await (await fetch(`https://api.kwery.co/job/${jobId}`, { headers })).json();
if (job.status === 'finished') break;
await new Promise(r => setTimeout(r, 3000));
}
return (await fetch(`https://api.kwery.co/job/${jobId}/download`, { headers })).json();
}import time
HEADERS = {"Authorization": f"Bearer {os.environ['KWERY_API_KEY']}"}
def wait_and_download(job_id):
while True:
job = requests.get(f"https://api.kwery.co/job/{job_id}", headers=HEADERS).json()
if job.get("status") == "finished":
break
time.sleep(3)
return requests.get(f"https://api.kwery.co/job/{job_id}/download", headers=HEADERS).json()curl -s https://api.kwery.co/stream \
-H "Authorization: Bearer $KWERY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source":"idealo","country":"de","key":"gtin",
"values":["4006381333962","4719512101148"],
"callback_url":"https://your-app.example.com/kwery/webhook"
}'
# → { "error": false, "job_id": "...", "webhook_secret": "..." }Store the returned webhook_secret — you need it to verify deliveries.
The signature is v1= followed by the HMAC-SHA256 of "{timestamp}.{raw_body}", keyed with your webhook_secret. Verify against the raw body, before JSON parsing.
const express = require('express');
const crypto = require('crypto');
const SECRET = process.env.KWERY_WEBHOOK_SECRET; // from the POST /stream response
const app = express();
// Capture the raw body for signature verification.
app.use('/kwery/webhook', express.raw({ type: 'application/json' }));
app.post('/kwery/webhook', (req, res) => {
const rawBody = req.body; // Buffer
const sig = req.get('X-Kwery-Signature') || '';
const ts = req.get('X-Kwery-Timestamp') || '';
// 1. Reject stale deliveries (replay protection).
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) {
return res.status(401).end('stale timestamp');
}
// 2. Recompute and compare in constant time.
const expected = 'v1=' + crypto.createHmac('sha256', SECRET)
.update(`${ts}.${rawBody.toString('utf8')}`)
.digest('hex');
const ok = sig.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
if (!ok) return res.status(401).end('bad signature');
// 3. Acknowledge fast, then process asynchronously.
res.status(202).end('ok');
const payload = JSON.parse(rawBody.toString('utf8'));
for (const item of payload.results || []) {
// handle item.result.content ...
}
});
app.listen(9000);import hmac, hashlib, time, os
from flask import Flask, request
SECRET = os.environ["KWERY_WEBHOOK_SECRET"].encode()
app = Flask(__name__)
@app.post("/kwery/webhook")
def webhook():
raw = request.get_data() # raw bytes
sig = request.headers.get("X-Kwery-Signature", "")
ts = request.headers.get("X-Kwery-Timestamp", "")
# 1. Replay protection.
if abs(time.time() - float(ts or 0)) > 300:
return "stale timestamp", 401
# 2. Constant-time signature check.
expected = "v1=" + hmac.new(
SECRET, f"{ts}.{raw.decode()}".encode(), hashlib.sha256
).hexdigest()
if not hmac.compare_digest(sig, expected):
return "bad signature", 401
# 3. Acknowledge, then process.
payload = request.get_json()
for item in payload.get("results", []):
pass # handle item["result"]["content"] ...
return "ok", 202- Webhooks — payload shape, retries, replay, and polling fallback.
- Authentication — API keys, and the legacy options.