webcapture Get a free key

Extract markdown in TypeScript with fetch

The same endpoint extracts: format: markdown skips the print step and hands back the page's text as markdown, through the same receipt and the same download.

format is pdf by default and markdown is one of its alternatives. The response is still the receipt with a download url; fetching it serves the extracted markdown as text/markdown, and the download's Content-Disposition names the file with an .md extension even though the url itself keeps its .pdf suffix.

The recipe

import { writeFile } from "node:fs/promises";

const ORIGIN = "https://webcapture.io";

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/", "format": "markdown"}),
});
const receipt = await res.json();

// receipt.download: ${ORIGIN}/v1/conversions/cnv_ec487efd8c301fc8.pdf
// the url keeps its .pdf suffix, but the bytes are markdown:
const file = await fetch(receipt.download, {
  headers: { "Authorization": "Bearer wc_your_key" },
});
// text/markdown; charset=utf-8
console.log(file.headers.get("content-type"));
await writeFile("page.md", await file.text(), "utf8");

Markdown extraction runs in the same quota and behind the same key as pdf: one extraction is one document against the month's count. Extraction reads the rendered page, so JavaScript already ran and the receipt's bytes field counts the markdown, which is usually a few kilobytes.

Same-key GET: 401 without it; 404 for another key.

The fields this recipe uses

Related

Method

Source: convert field reference, checked 2026-10-05. Corrections.