pageflock, meet HTML + your backend.
A complete local example pairs a plain HTML button with a small Node.js server. The browser never receives your pageflock key.
Your first connection.
- 01
Save both files below in one folder: index.html and server.mjs. Use Node.js 22 or newer and set WAGGLE_API_KEY in your terminal.
- 02
Run node server.mjs, then open http://127.0.0.1:3001. Click Extract example.com to send one real request; successful extraction uses one credit.
- 03
This sample listens only on your computer and accepts only example.com. For a hosted application, add your own sign-in, CSRF protection and user quotas before exposing an endpoint.
Tool reference: HTML + your backend documentation ↗
Build the request.
Set the environment variables in your terminal for these code examples. In automation tools, enter the URL and credentials in the tool’s own fields.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>pageflock extraction demo</title>
</head>
<body>
<h1>Your first pageflock result</h1>
<p>Each successful request uses one credit.</p>
<button id="run">Extract example.com</button>
<pre id="result" aria-live="polite"></pre>
<script type="module">
const button = document.querySelector("#run");
const output = document.querySelector("#result");
button.addEventListener("click", async () => {
button.disabled = true;
output.textContent = "Extracting…";
try {
const response = await fetch("/api/pageflock-request", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: "{}",
signal: AbortSignal.timeout(50000),
});
const result = await response.json();
if (!response.ok) throw new Error(JSON.stringify(result));
output.textContent = JSON.stringify(result, null, 2);
} catch (error) {
output.textContent = String(error);
} finally {
button.disabled = false;
}
});
</script>
</body>
</html>import { createServer } from "node:http";
import { readFile } from "node:fs/promises";
const apiKey = process.env.WAGGLE_API_KEY;
if (!apiKey) throw new Error("Set WAGGLE_API_KEY");
const origin = "http://127.0.0.1:3001";
const html = await readFile(new URL("./index.html", import.meta.url));
let busy = false;
const server = createServer(async (request, response) => {
const json = (status, data) => {
response.writeHead(status, {
"Content-Type": "application/json",
"Cache-Control": "no-store",
"X-Content-Type-Options": "nosniff",
});
response.end(JSON.stringify(data));
};
if (request.headers.host !== "127.0.0.1:3001") {
return json(403, { error: "Open the local demo URL" });
}
if (request.method === "GET" && request.url === "/") {
response.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
return response.end(html);
}
if (request.method !== "POST" || request.url !== "/api/pageflock-request") {
return json(404, { error: "Not found" });
}
if (request.headers.origin !== origin) {
return json(403, { error: "This demo accepts same-origin requests only" });
}
if (busy) return json(429, { error: "Wait for the current request" });
busy = true;
request.resume(); // The demo ignores input and uses a fixed public URL.
try {
const upstream = await fetch("https://pageflock.hyvelabs.tech/api/pageflock/v1/scrape", {
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://example.com" }),
signal: AbortSignal.timeout(45000),
});
json(upstream.status, await upstream.json());
} catch {
json(502, { error: "pageflock request failed. Check Activity before retrying." });
} finally {
busy = false;
}
});
server.listen(3001, "127.0.0.1", () => console.log(origin));Reading or copying this example does not send a request or use credits.