Node.js SDK

Official JavaScript / TypeScript SDK for the Enconvert API. Targets Node.js 18+ with zero runtime dependencies — built on native fetch, FormData, and node:stream. Ships dual ESM + CJS builds and full TypeScript declarations.

npm: @enconvert/node-sdk · Source: enconvert/enconvert-js · Node: 18+

Install

npm install @enconvert/node-sdk
pnpm add @enconvert/node-sdk
yarn add @enconvert/node-sdk

Quick Start

import { Enconvert } from "@enconvert/node-sdk";

const client = new Enconvert({ apiKey: process.env.ENCONVERT_API_KEY! });

const result = await client.convertUrlToPdf("https://example.com", {
    saveTo: "page.pdf",
});

console.log(result.presignedUrl);

The SDK works in every modern Node runtime (Node 18+, Bun, Deno via the npm specifier). It is server-side only — do not bundle your private API key into a browser app.


Methods

The client exposes six methods that map 1:1 to the REST API:

Method Endpoint Returns
convertUrlToPdf(url, options?) POST /v1/convert/url-to-pdf ConversionResult
convertUrlToScreenshot(url, options?) POST /v1/convert/url-to-screenshot ConversionResult
convertUrlToMarkdown(url, options?) POST /v1/convert/url-to-markdown ConversionResult
convertImage(file, options) POST /v1/convert/{from}-to-{to} ConversionResult
convertDocument(file, options?) POST /v1/convert/{from}-to-{to} ConversionResult
getJobStatus(jobId) GET /v1/convert/status/{jobId} JobStatus

Every method returns a typed promise. All option fields are optional unless marked otherwise.


convertUrlToPdf

Render any public URL to a PDF.

const result = await client.convertUrlToPdf("https://example.com", {
    pdfOptions: { pageSize: "A4", orientation: "landscape" },
    singlePage: false,
    viewportWidth: 1440,
    saveTo: "report.pdf",
});
Option Type Default Description
saveTo string -- Local path to stream the PDF to. Parent directories are created automatically.
singlePage boolean true true produces one continuous page. false paginates using pdfOptions.pageSize.
pdfOptions PdfOptions -- Page size, orientation, margins, scale, grayscale, header/footer. See PDF options.
viewportWidth number 1920 Browser viewport width in pixels.
viewportHeight number 1080 Browser viewport height in pixels.
loadMedia boolean true Wait for images and videos before capture.
enableScroll boolean true Scroll top-to-bottom to trigger lazy loaders.
outputFilename string auto Override the generated filename. .pdf is appended if missing.

convertUrlToScreenshot

Capture a full-page PNG of any URL.

const result = await client.convertUrlToScreenshot("https://example.com", {
    viewportWidth: 1440,
    saveTo: "screenshot.png",
});

Accepts the same viewport, media, scroll, and filename options as convertUrlToPdf (minus singlePage and pdfOptions).


convertUrlToMarkdown

Extract clean GitHub-Flavored Markdown from any URL. The converter strips navigation, footers, ads, and scripts, keeps the main article body, and prepends YAML frontmatter (title, description, url, links, images).

const result = await client.convertUrlToMarkdown("https://example.com/article", {
    saveTo: "article.md",
});

Useful for building RAG pipelines, importing third-party content into a CMS, or generating training data.


convertImage

Convert between jpeg, png, svg, heic, and webp.

// From a path
await client.convertImage("photo.heic", {
    outputFormat: "webp",
    saveTo: "photo.webp",
});

// From bytes
import { readFile } from "node:fs/promises";
const buf = await readFile("photo.heic");

await client.convertImage(
    { data: buf, filename: "photo.heic" },
    { outputFormat: "webp", saveTo: "photo.webp" },
);

The input format is detected from the path / filename extension. The output format is required.

Option Type Required Description
outputFormat "jpeg" \| "png" \| "svg" \| "heic" \| "webp" Yes Target format.
saveTo string -- Local path to stream the result to.
outputFilename string -- Override the generated filename.

convertDocument

Convert documents and data formats. The default outputFormat is "pdf".

// docx -> pdf
await client.convertDocument("report.docx", { saveTo: "report.pdf" });

// json -> yaml
await client.convertDocument("data.json", {
    outputFormat: "yaml",
    saveTo: "data.yaml",
});

// markdown -> pdf with custom page setup
await client.convertDocument("README.md", {
    outputFormat: "pdf",
    pdfOptions: { pageSize: "A4", margins: { top: 20, bottom: 20, left: 25, right: 25 } },
    saveTo: "readme.pdf",
});

Supported inputs: doc, docx, xls, xlsx, ppt, pptx, html, htm, odt, ods, odp, ots, pages, numbers, epub, markdown (.md, .markdown), csv, json, xml, yaml (.yaml, .yml), toml.

Option Type Default Description
outputFormat string "pdf" Target format.
saveTo string -- Local path to stream the result to.
outputFilename string -- Override the generated filename.
pdfOptions PdfOptions -- Page setup. Only honored when output is PDF.

getJobStatus

Poll the status of an async or recovered job.

const status = await client.getJobStatus("job_abc123");

if (status.status === "success") {
    console.log(status.presignedUrl);
} else if (status.status === "failed") {
    console.error(status.error);
}

Returns { status: "processing" | "success" | "failed", presignedUrl?, objectKey?, error? }.

You usually do not need to call this directly. The SDK polls automatically when a sync request returns 5xx — see Timeout recovery below.

PDF Options

Passed via the pdfOptions field on convertUrlToPdf and convertDocument.

const result = await client.convertUrlToPdf("https://example.com", {
    pdfOptions: {
        pageSize: "A4",
        orientation: "landscape",
        margins: { top: 10, bottom: 10, left: 15, right: 15 },
        scale: 0.9,
        grayscale: false,
    },
    saveTo: "report.pdf",
});
Field Type Description
pageSize string "A4", "A3", "Letter", "Legal", etc.
orientation "portrait" \| "landscape" Defaults to portrait.
margins { top, bottom, left, right } (mm) All four are optional.
scale number Render scale, e.g. 0.9 for 90%.
grayscale boolean Post-process the PDF through Ghostscript to grayscale.
header Record<string, string> Header text per page region.
footer Record<string, string> Footer text per page region.

Error handling

Errors are typed exception classes that you can match with instanceof.

import {
    Enconvert,
    APIError,
    AuthenticationError,
    RateLimitError,
} from "@enconvert/node-sdk";

try {
    await client.convertUrlToPdf("https://example.com");
} catch (e) {
    if (e instanceof AuthenticationError) {
        console.error("Invalid API key — check ENCONVERT_API_KEY.");
    } else if (e instanceof RateLimitError) {
        console.error("Hit your monthly quota or per-second rate limit.");
    } else if (e instanceof APIError) {
        console.error(`API error [${e.statusCode}]: ${e.message}`);
    } else {
        throw e;
    }
}
Class Thrown on Status code
AuthenticationError Invalid, missing, or revoked key 401, 403
RateLimitError Quota or rate limit exceeded 429
APIError Any other 4xx / 5xx the actual code
EnconvertError Base class for all of the above --

The full error message map is in the Error Codes reference.


Timeout recovery

Long URL-to-PDF or large document conversions can exceed the 60–120 second reverse-proxy timeout limit, even when the conversion eventually succeeds on the server. The SDK handles this transparently:

  1. Before each request, the SDK generates a UUID and sends it as job_id in the request body.
  2. If the original request returns 5xx, the SDK silently switches to polling GET /v1/convert/status/{job_id} every 3 seconds.
  3. As soon as the job is recorded as success, the SDK returns the result. As soon as it is recorded as failed, the SDK throws APIError.
  4. Polling deadline is 5 minutes. If exceeded, the SDK throws APIError(504, "Conversion timed out").

You don't need to write any code for this — it just works. Set timeout on the constructor if you want to bound the initial request.


Configuration

const client = new Enconvert({
    apiKey: process.env.ENCONVERT_API_KEY!,
    timeout: 300_000, // ms — 5 min default
    baseUrl: "https://api.enconvert.com", // override for self-hosted gateways
});
Option Type Default Description
apiKey string -- (required) Private API key (sk_live_...).
timeout number 300_000 Request timeout in ms. Aborts the underlying fetch via AbortController.
baseUrl string https://api.enconvert.com API base URL. Trailing slashes are stripped.
Never hardcode the API key. Read it from an environment variable or your secret manager. Anyone who gets your private key can run conversions against your project's quota.

Result shape

Every conversion method returns a ConversionResult:

interface ConversionResult {
    presignedUrl: string;          // signed URL to download the output (1 hour)
    objectKey: string;             // storage object key
    filename: string;              // server-side filename
    fileSize?: number;             // bytes
    conversionTimeSeconds?: number;
    jobId?: string;                // present when timeout recovery polled
}

The presigned URL is valid for one hour. If you need permanent access, download the file (use saveTo, or fetch the URL yourself) and store it in your own bucket.


TypeScript

Type definitions ship with the package — no @types/... install needed. The package is dual-published (ESM + CJS) with proper exports, types, and .d.ts / .d.cts so it works under any Node module resolution mode.

import type {
    ClientOptions,
    ConversionResult,
    ConvertDocumentOptions,
    ConvertImageOptions,
    FileInput,
    JobStatus,
    PdfOptions,
    UrlToMarkdownOptions,
    UrlToPdfOptions,
    UrlToScreenshotOptions,
} from "@enconvert/node-sdk";

Source and issues