How to Refry a PDF with JavaScript in NodeJS
This NodeJS walkthrough uses JavaScript, Axios, and multipart form data. It completes a PDF -> PostScript -> PDF roundtrip by passing a resource ID from /postscript into /pdf. The complete sample is included below so JavaScript in NodeJS developers can see the file handling, request construction, and response path together.
Why Refry a PDF with JavaScript in NodeJS?
PDF refrying converts a PDF to PostScript and then converts that PostScript into a new PDF. It can be useful in a print or prepress delivery flow when a downstream stage expects page content rebuilt through a PostScript-based path.
JavaScript in NodeJS expresses that process as two awaited requests: the first result’s outputId becomes a data dependency for the second call instead of a temporary local file that has to be managed separately. A worker can apply a chosen .joboptions configuration on the return conversion, then upload or download the final PDF only after both calls complete.
The workflow is intentionally lossy. Retain the original PDF when tags, forms, annotations, transparency, layers, or other PDF-specific content remain important.
JavaScript in NodeJS Code Example for PDF Refrying
/** * Refry a PDF by converting it to PostScript and back to PDF. * * PDF refrying is the common name for a PDF -> PostScript -> PDF roundtrip. * Some print, prepress, and legacy production workflows use it to rebuild or * normalize page content, flatten certain PDF constructs, or prepare a file * for downstream systems. The process is intentionally lossy and may remove * tags, forms, layers, annotations, transparency, metadata, and editability. * Use this workflow when a downstream system requires rebuilt page content or * a PostScript-based interchange file. * * The PostScript-to-PDF step uses a custom .joboptions profile in this sample. * A .joboptions file contains Adobe Distiller-compatible conversion settings; * it is optional, and default settings are used when omitted. pdfRest applies * the profile with Datalogics PDF Converter SDK. Datalogics maintains the SDK * in partnership with Adobe, using the same Adobe technology that powers * Distiller. * * Run: node refry-pdf.js[outputPdf] */ const axios = require("axios"); const FormData = require("form-data"); const fs = require("fs"); const path = require("path"); const apiUrl = (process.env.PDFREST_URL || "https://api.pdfrest.com").replace(/\/$/, ""); const apiKey = process.env.PDFREST_API_KEY || "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; const inputPath = process.argv[2] || "/path/to/sample.pdf"; const jobOptionsPath = process.argv[3] || "/path/to/custom.joboptions"; const outputPath = process.argv[4] || path.join(__dirname, "refried.pdf"); async function postMultipart(endpoint, fields) { const form = new FormData(); for (const field of fields) { if (field.path) { form.append(field.name, fs.createReadStream(field.path), { filename: path.basename(field.path), contentType: field.contentType, }); } else { form.append(field.name, field.value); } } const response = await axios.post(`${apiUrl}/${endpoint}`, form, { headers: { Accept: "application/json", "Api-Key": apiKey, ...form.getHeaders() }, maxBodyLength: Infinity, }); console.log(`${endpoint}: ${response.status}`); return response.data; } async function main() { const postscript = await postMultipart("postscript", [ { name: "file", path: inputPath, contentType: "application/pdf" }, { name: "ps_level", value: "3" }, { name: "page_range", value: "all" }, { name: "binary_output", value: "true" }, { name: "scale", value: "1" }, { name: "rotate", value: "false" }, { name: "shrink_to_fit", value: "true" }, { name: "print_annotations", value: "true" }, { name: "output", value: "refry_intermediate" }, ]); const finalPdf = await postMultipart("pdf", [ { name: "id", value: postscript.outputId }, { name: "job_options", path: jobOptionsPath, contentType: "application/octet-stream" }, { name: "output", value: "refried" }, ]); const download = await axios.get(`${apiUrl}/resource/${finalPdf.outputId}?format=file`, { headers: { "Api-Key": apiKey }, responseType: "arraybuffer", }); fs.writeFileSync(outputPath, download.data); console.log(JSON.stringify(finalPdf, null, 2)); console.log(`Created ${outputPath}`); } main().catch((error) => { console.error(error.response ? error.response.data : error.message); process.exitCode = 1; });
Source: View the sample on GitHub
Breaking Down the Code
Configure the service and input
const apiUrl = (process.env.PDFREST_URL || "https://api.pdfrest.com").replace(/\/$/, ""); const apiKey = process.env.PDFREST_API_KEY || "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; const inputPath = process.argv[2] || "/path/to/sample.pdf"; const jobOptionsPath = process.argv[3] || "/path/to/custom.joboptions"; const outputPath = process.argv[4] || path.join(__dirname, "refried.pdf");
For this PDF Refrying example, JavaScript in NodeJS coordinates the two dependent API calls. The NodeJS samples use axios for HTTP, form-data for multipart encoding, and Node’s file-system module for local inputs. Install the packages listed in the repository’s JavaScript package manifest when adapting the example. The sample’s placeholder path and API key make the moving pieces visible; replace them with a real local path and protected runtime credential before using the request.
Pass the Intermediate Resource to the Next Step
{ name: "output", value: "refry_intermediate" },
]);
const finalPdf = await postMultipart("pdf", [
{ name: "id", value: postscript.outputId },
{ name: "job_options", path: jobOptionsPath, contentType: "application/octet-stream" },
{ name: "output", value: "refried" },
]);
const download = await axios.get(`${apiUrl}/resource/${finalPdf.outputId}?format=file`, {
headers: { "Api-Key": apiKey },
responseType: "arraybuffer",
});
In the JavaScript in NodeJS workflow, outputId from /postscript becomes the id passed to /pdf. The second request also supplies a custom .joboptions file so the return conversion has an explicit Adobe Distiller-compatible profile, even though default settings are available when the profile is omitted.
Build the multipart request
*/
const axios = require("axios");
const FormData = require("form-data");
const fs = require("fs");
const path = require("path");
const apiUrl = (process.env.PDFREST_URL || "https://api.pdfrest.com").replace(/\/$/, "");
const apiKey = process.env.PDFREST_API_KEY || "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
const inputPath = process.argv[2] || "/path/to/sample.pdf";
const jobOptionsPath = process.argv[3] || "/path/to/custom.joboptions";
const outputPath = process.argv[4] || path.join(__dirname, "refried.pdf");
For the PDF Refrying form, FormData appends a readable file stream and the text options. Its generated headers include the multipart boundary, so the request combines form.getHeaders() with the Api-Key header rather than setting a boundary by hand.
Read the output resource
* * Run: node refry-pdf.js[outputPdf] */ const axios = require("axios"); const FormData = require("form-data"); const fs = require("fs"); const path = require("path"); const apiUrl = (process.env.PDFREST_URL || "https://api.pdfrest.com").replace(/\/$/, ""); const apiKey = process.env.PDFREST_API_KEY || "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; const inputPath = process.argv[2] || "/path/to/sample.pdf"; const jobOptionsPath = process.argv[3] || "/path/to/custom.joboptions";
After the PDF Refrying call, axios resolves successful responses to a JSON object and sends API failures to the catch block. The sample prints either the output-resource details or the returned error payload, which is a useful starting point for production logging.
Beyond the Tutorial
You completed the two-stage refry process in JavaScript in NodeJS and saved the final PDF after both calls succeeded. The intermediate response ID is the important handoff between conversion stages, not merely a status value to print and discard.
Try representative pdf refrying inputs in API Lab. For the authoritative request fields, accepted values, and response contract, consult the pdfRest API Reference Guide. The same request pattern can then be adapted to your JavaScript in NodeJS application’s error handling, retention policy, and delivery workflow.