Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To download a PDF from a REST API, send the documented HTTP request, verify the response status and media type, then write the response body as binary bytes. Do not decode a raw PDF as text or assume that a .pdf URL guarantees a PDF. For large documents, stream the response in chunks instead of buffering the entire file.

What a PDF API response looks like

A REST endpoint may return the PDF directly as the HTTP response body. A successful raw-PDF response normally has a 2xx status and Content-Type: application/pdf. The HTTP specification defines Content-Type as the media type of the enclosed representation. The response may also include Content-Disposition, usually with attachment and a suggested filename such as report.pdf.

Headers describe the response; the PDF itself is binary data. An authentication failure, validation error, rate-limit response, or login page can also have a body, so always check the status before saving anything.

Response shape What your client should do
Raw PDF bytes Check status and media type, then write bytes to a binary file.
JSON error object Read it as JSON, report the error, and do not save it as a PDF.
HTML login or error page Inspect authentication, redirects, and the final URL.
JSON containing base64 Read the API contract, decode the designated field, and write the decoded bytes.

Choose the right download method

Direct browser navigation

If the endpoint works without a custom authorization header, opening its URL or linking to it may be sufficient. A server response with Content-Disposition: attachment generally asks the browser to save the file, while inline indicates normal in-browser processing. Browser behavior can vary with headers, redirects, extensions, and the endpoint’s authentication scheme.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Epson Workforce ES-50 Compact & Lightweight Mobile Document Scanner
  • PORTABLE SCANNER FOR USE ON-THE-GO — The fastest and lightest mobile single-sheet-fed compact document scanner in its class¹
  • QUICK DOCUMENT SCANNING ― This Epson ultra-fast scanner scans a single page as quickly as 5.5 seconds²; Windows and Mac compatible
  • VERSATILE PAPER HANDLING ― Portable scanner scans documents up to 8.5 x 72 in; Also easily digitizes receipts and ID cards to make accounting, bookkeeping, and organizing simpler
  • INTUITIVE, HIGH-SPEED SOFTWARE — Epson ScanSmart Software³ is a smart tool allowing you to easily scan, review, and save; Stay organized easily with the help of this Epson scanner
  • EASY SETUP — USB-powered connect to your computer for quick and simple scanning; No batteries or external power supply required to operate portable document scanner; Standard Connectivity: USB 2.0

Browser Fetch

Use Fetch when the page must add an authorization header, send a POST body, or choose a filename in JavaScript. Fetch the response, reject unsuccessful statuses, consume it as a Blob, create an object URL, click a temporary download link, and revoke the URL after use.

async function downloadPdf() {
  const response = await fetch('https://api.example.com/reports/123.pdf', {
    headers: { Authorization: 'Bearer TOKEN' }
  });
  if (!response.ok) {
    const detail = await response.text();
    throw new Error(`HTTP ${response.status}: ${detail}`);
  }
  const type = response.headers.get('content-type') || '';
  if (!type.toLowerCase().includes('application/pdf')) {
    throw new Error(`Expected PDF, received ${type || 'unknown media type'}`);
  }
  const blob = await response.blob();
  const objectUrl = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = objectUrl;
  link.download = 'report.pdf';
  document.body.appendChild(link);
  link.click();
  link.remove();
  URL.revokeObjectURL(objectUrl);
}

Do not expose a long-lived secret API key in browser JavaScript. Put privileged requests behind your own server or use a short-lived token designed for browser use.

Backend or script

A server-side client is usually better when the endpoint requires a secret, the file is large, retries are needed, or the downloaded document must be stored in controlled infrastructure. Python Requests, cURL, and Node.js all let you inspect status and headers before writing the body.

Python: stream the PDF safely

For a small response, response.content can be written directly. For reports that may be large, Requests recommends a streamed response, chunk iteration, and binary output.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import requests

url = "https://api.example.com/reports/123.pdf"
headers = {"Authorization": "Bearer TOKEN"}

with requests.get(url, headers=headers, stream=True, timeout=(5, 60)) as response:
    response.raise_for_status()
    content_type = response.headers.get("Content-Type", "")
    if "application/pdf" not in content_type.lower():
        preview = next(response.iter_content(chunk_size=512), b"")
        raise RuntimeError(
            f"Expected application/pdf, received {content_type!r}; "
            f"body starts with {preview[:120]!r}"
        )

    with open("report.pdf", "wb") as output:
        for chunk in response.iter_content(chunk_size=64 * 1024):
            if chunk:
                output.write(chunk)

stream=True delays body retrieval. iter_content yields chunks so memory use does not grow with the complete file. The with blocks close the response and file even when an exception occurs. Consume or close a streamed response so the connection can be reused.

Small-file variant

import requests

response = requests.get(
    "https://api.example.com/reports/123.pdf",
    headers={"Authorization": "Bearer TOKEN"},
    timeout=(5, 60),
)
response.raise_for_status()
if "application/pdf" not in response.headers.get("Content-Type", "").lower():
    raise RuntimeError("The server did not return a PDF")
with open("report.pdf", "wb") as output:
    output.write(response.content)

cURL: save the response body

Use -o (or --output) to write bytes without printing them to the terminal. Keep headers visible while diagnosing with -D -.

Rank #2
Sale
Brother DS-640 Compact Mobile Document Scanner, (Model: DS640)
  • FAST SPEEDS - Scans color and black and white documents a blazing speed up to 16ppm (1). Color scanning won’t slow you down as the color scan speed is the same as the black and white scan speed.
  • ULTRA COMPACT – At less than 1 foot in length and only about 1. 5lbs in weight you can fit this device virtually anywhere (a bag, a purse, even a pocket).
  • READY WHENEVER YOU ARE – The DS-640 mobile scanner is powered via an included micro USB 3. 0 cable allowing you to use it even where there is no outlet available. Plug it into you PC or laptop and you are ready to scan.
  • WORKS YOUR WAY – Use the Brother free iPrint&Scan desktop app for scanning to multiple “Scan-to” destinations like PC, Network, cloud services, Email and OCR. (2) Supports Windows, Mac and Linux and TWAIN/WIA for PC/ICA for Mac/SANE drivers. (3)
  • OPTIMIZE IMAGES AND TEXT – Automatic color detection/adjustment, image rotation (PC only), bleed through prevention/background removal, text enhancement, color drop to enhance scans. Software suite includes document management and OCR software. (4)
curl --fail --location 
  -H "Authorization: Bearer TOKEN" 
  -H "Accept: application/pdf" 
  "https://api.example.com/reports/123.pdf" 
  --output report.pdf

--fail makes HTTP errors fail rather than quietly creating an error file, and --location follows redirects. To inspect status and headers without mixing them into the PDF, use:

curl --include --location 
  -H "Authorization: Bearer TOKEN" 
  "https://api.example.com/reports/123.pdf" 
  --output report.pdf

For an endpoint that creates a document with POST, send the request body and still save the response with --output. Follow the API’s documented content type and authentication requirements; do not change GET to POST merely because the result is a file.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Node.js: write a streamed response

In modern Node.js, Fetch returns a Web ReadableStream. Convert it to a Node stream and pipe it to a file so a large PDF is not held in memory.

import { createWriteStream } from 'node:fs';
import { Readable } from 'node:stream';
import { once } from 'node:events';

const response = await fetch('https://api.example.com/reports/123.pdf', {
  headers: { Authorization: 'Bearer TOKEN' }
});

if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
const type = response.headers.get('content-type') || '';
if (!type.toLowerCase().includes('application/pdf') || !response.body) {
  throw new Error(`Expected a PDF body, received ${type || 'nothing'}`);
}

const file = createWriteStream('report.pdf');
Readable.fromWeb(response.body).pipe(file);
await once(file, 'finish');

If your Node version or runtime does not provide Readable.fromWeb, use its documented stream adapter or read chunks from the response body and call file.write, respecting backpressure. Always handle the stream’s error event in production.

Filenames and Content-Disposition

Content-Disposition: attachment; filename="report.pdf" suggests both download behavior and a name. RFC 6266 also defines filename* for encoded characters; when both parameters are present, recipients should prefer filename*. Treat either value as untrusted input.

  • Remove directory components such as ../, backslashes, and drive prefixes.
  • Replace control characters and filesystem-reserved names.
  • Choose an extension that matches the verified media type.
  • Constrain the output to a directory your application is allowed to write.
  • Use your own fallback name when the header is missing or malformed.

Never let a server-supplied path decide where your process writes. A filename is metadata, not permission.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Canon imageFORMULA R10 - Portable Document Scanner, USB Powered, Duplex Scanning, Document Feeder, Easy Setup, Convenient, Perfect for Mobile Users, White
  • STAY ORGANIZED – Easily convert your paper documents into digital formats like searchable PDF files, JPEGs, and more.Power Consumption : 2.5W or less (Energy Saving Mode: 0.7W). Suggested Daily Volume : 500 scans..Does it contain liquid: no
  • CONVENIENT AND PORTABLE –lightweight and small in size, you can take the scanner anywhere from home offices, classrooms, remote offices, and anywhere in between
  • HANDLES VARIOUS MEDIA TYPES – Digitize receipts, business cards, plastic or embossed cards, reports, legal documents, and more
  • FAST AND EFFICIENT – No technical hurdles or complicated setups here; easily scan both sides of a document at the same time, in color or black-and-white, at up to 12 pages-per-minute, and with a 20 sheet automatic feeder
  • BROAD COMPATIBILITY – Works with both Windows and Mac devices, be it laptop or computer

Validate that the file is really a PDF

Status and headers are necessary but not infallible. A URL ending in .pdf is not proof of the representation. For higher assurance, inspect the first bytes for the PDF signature %PDF- and, where appropriate, use a PDF parser to verify the document structure. Keep a bounded preview for diagnostics; do not log an entire response that might contain sensitive data.

Authentication, redirects, and timeouts

Authentication

Use the scheme documented by the API: commonly a bearer token, API-key header, cookie, or signed URL. A 401 or 403 response should be handled as an authentication or authorization problem, not saved as .pdf.

Redirects

Inspect the final URL and redirect history when troubleshooting. A redirect can lead to a login page, a different host, or a signed object-storage URL. Do not automatically forward confidential headers to an untrusted host.

Timeouts and retries

Set a connection timeout and a read timeout appropriate to document generation and transfer size. Retry only failures that are safe to retry, such as transient network errors or documented 5xx responses. Avoid blindly retrying a non-idempotent generation request unless the API supplies an idempotency key or job identifier.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Large files, partial downloads, and reliability

Chunked writing limits memory use, but it does not by itself make a download resumable. If a transfer is interrupted, remove or quarantine the partial file unless you have implemented HTTP range requests and the server documents support for them. Write to a temporary filename, flush and close it, then rename it into place so readers never see a truncated document.

Record status, final URL, selected headers, byte count, elapsed time, and a request or job ID when supplied. Do not record access tokens or PDF contents. For asynchronous APIs, poll the documented job endpoint until it provides a download URL, then apply the same status, header, streaming, and validation checks.

Rank #4
IRIScan Express 4 Black Compact Portable USB Simplex Document Scanner, 8 PPM for Contracts, Invoices and Business Cards, Compatible with Windows, Readiris PDF Included
  • IRIScan Express, portable scanner : scans color and black and white documents a blazing speed up to 8ppm simplex. Color scanning won’t slow you down as the color scan speed is the same as the black and white scan speed.
  • IRIScan Express mobile scanner is powered via an included micro USB 2. 0 cable allowing you to use it even where there is no outlet available. Plug it into you PC or laptop and you are ready to scan. USB cable provided. AC Adapter not provided and not needed.
  • IRIScan flatbed scanner uses a simplex scanning mode allows for quick and straightforward scanning of single-sided documents. IRIScan with its full portable features is the ideal document scanners for computers.
  • IRIScan document scanner : Versatile scanning capabilities, including scanning to Word, PDF, and Excel formats with companion software provided Readiris OCR
  • Receipt scanner and card scanner with Additional features include scanning business cards directly to Outlook, photo scanning, and receipt scanning for efficient document management

Troubleshooting checklist

The saved file contains JSON

Open the response metadata, not just the extension. Check the status code and Content-Type; inspect a short body preview for fields such as error, message, or validation details. Fix the request, credentials, parameters, or rate limit before saving again.

The saved file is an HTML page

Follow the redirect chain and inspect the final URL. An expired session commonly redirects to a login page. Send the required authorization in the way the API expects, and do not assume browser cookies are available to a backend process.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The file is empty or truncated

Confirm that the stream was fully consumed and closed, increase the read timeout for slow generation, and check proxy or server termination. Use a temporary file and compare the written byte count with any trustworthy Content-Length value; chunked responses may not provide one.

The browser uses the wrong filename

Inspect Content-Disposition, including filename*. If you control the client, choose a safe local name instead of trusting path segments or unsafe extensions.

The API returns JSON with base64

This is a different contract from a raw PDF response. Parse JSON, validate the designated field, base64-decode it, and write the resulting bytes in binary mode. Do not decode arbitrary error text as base64.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your task is generating a PDF or image capture of a web page rather than downloading a PDF that your existing REST service already produces, ScreenshotNeo provides a website screenshot API and MCP server. One GET request can return a clean PNG, JPEG, WebP, or PDF. Its cleanup step accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing result in headers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For the complete parameter list and PDF options, see the ScreenshotNeo documentation. The supplied request pattern is:

Best Value
Canon Canoscan Lide 300 Scanner (PDF, AUTOSCAN, Copy, Send)
  • Scanner type: Document
  • Connectivity technology: USB
  • With Auto Scan Mode, the scanner automatically detects what you're scanning
  • Digitize documents and images
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. It includes full-page capture, device and viewport controls, lazy-image loading, selectors, custom CSS and JavaScript, waiting and blocking rules, authentication headers and cookies, geolocation, PDF page settings, caching, signed links, asynchronous jobs, bulk capture, usage reporting, and an OpenAPI specification.

The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots, and every feature is available on every plan. Create a free ScreenshotNeo account.

Practical decision guide

Situation Recommended approach Reason
Public endpoint, small document Direct browser link or cURL Minimal setup and no application memory concern.
Secret header or POST body Backend client Keeps credentials out of browser code and gives reliable error handling.
Large report Streaming Python, cURL output, or Node stream Writes chunks instead of buffering the complete body.
Untrusted or inconsistent endpoint Validate status, media type, signature, and bounded preview Prevents HTML or JSON errors being mistaken for PDFs.
Web-page capture rather than an existing PDF API ScreenshotNeo Clean capture, no billing for failed or blocked pages, and an MCP workflow.

Frequently Asked Questions

Can I save a PDF response with a .txt extension first?

You can technically write the bytes under any name, but use a .pdf extension only after verifying that the response is a PDF. The extension does not convert text or JSON into a PDF.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I trust Content-Length when checking a download?

Use it as a diagnostic when present, not as the sole validity check. Proxies and chunked transfer can omit or alter it; status, media type, complete stream consumption, and PDF validation are more useful together.

Is a PDF returned by a REST API always downloadable in a browser?

No. A browser may need credentials that cannot be placed in a normal link, or the API may require POST. In those cases use Fetch with an appropriate short-lived credential or a server-side client.

How do I handle a PDF endpoint that takes minutes to generate?

Follow the service’s asynchronous-job contract when available: submit the job, poll its status, then download the resulting URL with the same validation and streaming safeguards.

The Bottom Line

Send the documented request, check the status before touching the body, verify that the representation is a PDF, and write the bytes in binary mode. Stream large responses, treat filenames and redirects as untrusted input, and preserve partial-file and retry safeguards in production code.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

Bestseller No. 3
Canon imageFORMULA R10 - Portable Document Scanner, USB Powered, Duplex Scanning, Document Feeder, Easy Setup, Convenient, Perfect for Mobile Users, White
Canon imageFORMULA R10 - Portable Document Scanner, USB Powered, Duplex Scanning, Document Feeder, Easy Setup, Convenient, Perfect for Mobile Users, White
BROAD COMPATIBILITY – Works with both Windows and Mac devices, be it laptop or computer; This product is not intended for scanning photographs on photo paper / photographic media
$184.00
Bestseller No. 4
IRIScan Express 4 Black Compact Portable USB Simplex Document Scanner, 8 PPM for Contracts, Invoices and Business Cards, Compatible with Windows, Readiris PDF Included
IRIScan Express 4 Black Compact Portable USB Simplex Document Scanner, 8 PPM for Contracts, Invoices and Business Cards, Compatible with Windows, Readiris PDF Included
Find our Software here : irislink.com/start; IRIScan Express is only compatible Windows platform and not macintosh
$129.00
Bestseller No. 5
Canon Canoscan Lide 300 Scanner (PDF, AUTOSCAN, Copy, Send)
Canon Canoscan Lide 300 Scanner (PDF, AUTOSCAN, Copy, Send)
Scanner type: Document; Connectivity technology: USB; With Auto Scan Mode, the scanner automatically detects what you're scanning
$75.00

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.