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.
@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? }.
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:
- Before each request, the SDK generates a UUID and sends it as
job_idin the request body. - If the original request returns 5xx, the SDK silently switches to polling
GET /v1/convert/status/{job_id}every 3 seconds. - As soon as the job is recorded as
success, the SDK returns the result. As soon as it is recorded asfailed, the SDK throwsAPIError. - 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. |
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
- npm: @enconvert/node-sdk
- GitHub: enconvert/enconvert-js
- License: MIT