PDF to Text in Node.js
Overview
Extract text from PDF documents with the PDFCrowd Node.js client. The client handles communication with the API, while conversions run on PDFCrowd's servers.
Installation
Install the Node.js client with npm, or see other installation options.
npm install pdfcrowd
Quick Start
You can run the examples below with the displayed API credentials. Update the input URLs and filenames as needed.
Convert a PDF URL
Extract text from a PDF URL and save it locally as invoice.txt:
const pdfcrowd = require('pdfcrowd'); const client = new pdfcrowd.PdfToTextClient("demo", "demo"); client.convertUrlToFile( "https://your-server.com/invoice.pdf", "invoice.txt", (error, filePath) => { if (error) { console.error(error.toString()); return; } console.log("Saved:", filePath); } );
The URL must return a PDF and be reachable from PDFCrowd's servers.
The output file is ready when the callback runs without an error.
Put code that uses the file inside that callback.
The callback receives a pdfcrowd.Pdfcrowd.Error on failure.
Validation can also throw an exception.
See Handle Errors.
Convert a PDF File
Extract text from invoice.pdf and save the result locally as invoice.txt:
const pdfcrowd = require('pdfcrowd'); const client = new pdfcrowd.PdfToTextClient("demo", "demo"); client.convertFileToFile("invoice.pdf", "invoice.txt", (error, filePath) => { if (error) { console.error(error.toString()); return; } console.log("Saved:", filePath); });
Configure a Conversion
Authentication
Pass your PDFCrowd username and API key to
PdfToTextClient.
Find your credentials on the API Keys page.
Choose an Input
Send a PDF URL, upload a local file, or pass PDF bytes or a readable binary stream.
| Input | Method |
|---|---|
| URL | convertUrlToFile() |
| Local file | convertFileToFile() |
| Bytes in memory | convertRawDataToFile() |
| Readable binary stream | convertStreamToFile() |
Add Conversion Settings
Set conversion options on the client before calling a conversion method.
For example, client.setNoLayout(true); extracts text without preserving the PDF layout.
Common settings are listed below. See the method reference for all available options or browse Node.js examples.
| Purpose | Methods |
|---|---|
| Pages to convert | setPrintPageRange() |
| Password-protected input | setPdfPassword() |
| Layout and paragraphs | setNoLayout(), setParagraphMode(), setLineSpacingThreshold() |
| Line endings and page breaks | setEol(), setPageBreakMode(), setCustomPageBreak() |
| Text cleanup | setRemoveHyphenation(), setRemoveEmptyLines() |
| Extract from a page area | setCropArea() |
By default, extraction preserves the PDF's layout with spacing. Enable setNoLayout() to extract text without preserving columns and positioning.
The PDF password unlocks the input document; it is separate from your PDFCrowd API key.
Handle the Result
Choose an Output
The result is UTF-8 plain text. A PDF must contain a text layer for extraction; recognizing text in a scanned document requires a separate OCR step.
The methods below use URL input; local files, bytes, and input streams have corresponding methods.
| Output | Method |
|---|---|
| Local file | convertUrlToFile() |
| Readable stream | convertUrl(), with a data(stream) callback |
For stream output, pass a callbacks object with these functions:
| Callback | When it runs |
|---|---|
data(readStream) |
Called when the output stream is available. Read its chunks into a Buffer
or pipe it to a writable stream. |
error(message, statusCode) |
Called if the request or conversion fails. message describes the error;
statusCode contains the error status code when available. |
end() |
Called when all output data has been received. |
If you pipe the response to a file, writing may still be in progress when end runs.
Use the pipeline callback, after checking for errors, for code that uses the saved file.
This example extracts text from a PDF, collects the result in a
Buffer, decodes it as UTF-8,
and saves it locally as invoice.txt:
const fs = require("node:fs"); const pdfcrowd = require("pdfcrowd"); const client = new pdfcrowd.PdfToTextClient("demo", "demo"); const chunks = []; client.convertUrl("https://your-server.com/invoice.pdf", { data: (stream) => stream.on("data", (chunk) => chunks.push(chunk)), error: (message, statusCode) => { console.error(new pdfcrowd.Pdfcrowd.Error(message, statusCode).toString()); }, end: () => { const text = Buffer.concat(chunks).toString("utf8"); fs.writeFileSync("invoice.txt", text); } });
When serving the result from a web application, use Content-Type: text/plain; charset=utf-8.
Handle Errors
File-output methods pass a pdfcrowd.Pdfcrowd.Error to their callback
on failure and null on success. Validation can also throw an exception.
This example extracts text from a PDF and handles both paths,
logging the HTTP status and reason code when available:
const pdfcrowd = require("pdfcrowd"); const client = new pdfcrowd.PdfToTextClient("demo", "demo"); function handleError(error) { if (error instanceof pdfcrowd.Pdfcrowd.Error) { console.error("PDFCrowd error:", error.getStatusCode(), error.getReasonCode(), error.getMessage()); } else { console.error(error); } } try { client.convertUrlToFile( "https://your-server.com/invoice.pdf", "invoice.txt", (error) => { if (error) { handleError(error); return; } } ); } catch (error) { handleError(error); }
Stream-output methods call error(message, statusCode) on failure.
Local file and stream errors may need separate handling.
pdfcrowd.Pdfcrowd.Error provides these methods:
| Method | Returns |
|---|---|
getStatusCode() | The HTTP status code, when available. |
getReasonCode() | The reason code identifying the specific error, or -1 if unavailable. |
getMessage() | The error message. |
getDocumentationLink() | A link to relevant documentation, when available. |
error.toString() returns the complete error, including available status and reason codes.
Common Status Codes
| Status | What it means | What to do |
|---|---|---|
400 | Invalid input, settings, or conversion failure | Read the reason code and correct the input or settings. |
401 | Missing credentials or an inactive license | Check your username, API key, and license status. |
403 | Suspended service or no credits remaining | Check your account and available credits. |
413 | Upload exceeds the 300 MB limit | Reduce the upload size. |
429 | Request rate limit reached | Wait and reduce the rate of new requests. |
430 | Concurrent request limit reached | Allow active requests to finish before starting more. |
503 | Temporary network issue | Check your retry policy before submitting another request. |
See all status and reason codes for specific explanations and Limits and Retries for retry behavior.
Read Conversion Information
This information is available after a conversion and describes the client's last conversion. Read it in the completion or error callback.
| Method | Use |
|---|---|
getJobId() | Identify the conversion in logs and support requests. |
getDebugLogUrl() | The URL of the conversion debug log when logging is enabled. |
getPageCount() | Read the page count reported for the conversion. |
getOutputSize() | Read the text size in bytes. |
getConsumedCreditCount() | Read the credits consumed by the conversion. |
getRemainingCreditCount() | Read the remaining credit count reported with the conversion. |
Limits and Retries
Request rate and concurrency limits depend on your license. Control how quickly
your application submits conversions and how many it runs at once. A
429 response concerns request rate; a 430 response
concerns requests already in progress. The maximum upload size is 300 MB.
The Node.js client automatically retries a request once when it receives HTTP
502 or 503. Use
setRetryCount()
to change that count, or set it to 0 to disable automatic retries.
Account for these retries when adding an application-level retry policy.
Troubleshooting
Inspect a Conversion
This example extracts text from a PDF with debug logging enabled and logs the debug log URL when available. Use the input and settings from the conversion you are investigating.
const pdfcrowd = require("pdfcrowd"); const client = new pdfcrowd.PdfToTextClient("demo", "demo"); function finish(error) { if (error) { console.error(error.toString()); } const debugLogUrl = client.getDebugLogUrl(); if (debugLogUrl) console.info("Debug log:", debugLogUrl); } try { client.setDebugLog(true); client.convertUrlToFile( "https://your-server.com/invoice.pdf", "invoice.txt", finish ); } catch (error) { finish(error); }
The debug log contains conversion settings and processing details. You can also find logs in your conversion history. A local or connection failure may occur before a conversion log is available.
Common Problems
| Problem | Check |
|---|---|
| The PDF cannot be loaded | Check that the URL returns a PDF, rather than HTML or a login page, and is reachable from PDFCrowd's servers. For local files, check the path and read permissions. |
| The PDF requires a password | Set the input document's password with setPdfPassword(). |
| Text is missing | A scanned PDF may contain images without a text layer. Extracting text from scans requires a separate OCR step. |
| Spacing or reading order is unexpected | Try setNoLayout() and the paragraph settings. PDF text placement does not always encode a natural reading order. |
For help, contact support and include any available diagnostics, the client version, and enough detail to reproduce the problem.