Download a rendered PDF in Node with fetch
The download url is not a shareable link. It answers to the key that made the render, and this recipe is the contract: who gets bytes, who gets 401, who gets 404.
Every other recipe on this site ends with an authenticated GET. This one is that GET, spelled out: the receipt's download url fetched with the key, the same url fetched without it, and the facts a file server or a background worker needs before it treats the url as a link.
The recipe
import { writeFile } from "node:fs/promises";
const ORIGIN = "https://webcapture.io";
// 1. render: the POST answers with the receipt, not the bytes
const res = await fetch(`${ORIGIN}/v1/convert`, {
method: "POST",
headers: {
"Authorization": "Bearer wc_your_key",
"Content-Type": "application/json",
},
body: JSON.stringify({"url": "https://example.com/"}),
});
const receipt = await res.json();
// receipt.download: ${ORIGIN}/v1/conversions/cnv_9f2c01ab.pdf
// 2. download: the same header goes on the GET
const file = await fetch(receipt.download, {
headers: { "Authorization": "Bearer wc_your_key" },
});
// 200, application/pdf
console.log(file.status, file.headers.get("content-type"));
await writeFile("page.pdf", Buffer.from(await file.arrayBuffer()));
// 3. what a downloader without the key gets: 401
const stranger = await fetch(receipt.download);
console.log(stranger.status);
Three outcomes, all by design: your key fetches the bytes (200); no key or a revoked key gets 401; a different valid key gets 404, because the id is looked up per key and another key's renders are invisible. The url is therefore a short-lived pointer, not storage: fetch the bytes and keep them yourself.
Same-key GET: 401 without it; 404 for another key.
The fields this recipe uses
url: the page address to render; the download half of the pattern needs no body field, only the same header.
Related
- Next: Get a free key to run this Node recipe, or read the API docs.
- More recipes: Node: convert from a URL, Python: save to a file, curl: convert from a URL.
- The webcapture API reference: every field the convert endpoint admits, with the response shapes and the error table.
- The recipes hub: the same endpoint in the other languages.
- Going deeper: the security page spells out how keys, artifacts, and access controls are handled server-side. Scheduling the download from an automation stack? The n8n, Zapier, and Make guides wire the same fetch into each platform's steps.
- The free URL to PDF tool: try the render in a browser before you wire the call.
Method
Source: convert field reference, checked 2026-10-05. Corrections.