ScreenshotNeo

BlogHow-to

How to convert HTML emails to PDF with PDFCrowd

Convert an HTML email to PDF with PDFCrowd: prepare the email HTML, choose an online or API workflow, bundle resources, and control page layout.

By the ScreenshotNeo team4 October 202610 min read

To convert an HTML email to PDF with PDFCrowd, first obtain the email’s HTML, then submit it to PDFCrowd’s online converter for a one-off conversion or its HTTP API for a repeatable workflow. PDFCrowd’s documented inputs are HTML text, an HTML file, or a URL; the documentation does not describe direct mailbox access. If the email relies on local images or stylesheets, include those resources with the HTML.

1. Get the email’s HTML

PDFCrowd converts web content you provide; it does not, according to the documented workflow, sign in to an email account and retrieve a message for you. Export or otherwise obtain the message’s HTML using the tools available in your email environment, then provide it as text, a file, or a URL. The exact method depends on the mail client, and this guide does not assume a particular client’s export menu.

Before conversion, inspect the HTML and identify its dependencies:

  • Images: Are they embedded, hosted at reachable URLs, or stored as local files?
  • Stylesheets and fonts: Are they inline, remote, or local?
  • Print styling: Does the markup include @page rules that specify paper size or margins?
  • Sensitive content: Does the message contain personal, financial, or confidential information that your organization does not allow you to submit to a third-party conversion service?

PDFCrowd documents URL input and loading resources from accessible internet URLs. Remote resources still need to be reachable by the converter. For local dependencies, package the HTML and resource files together as described below. PDFCrowd’s API guide describes the supported input methods.

2. Choose an online conversion or the HTTP API

Route Use it when What you provide
Online converter You have an occasional, manual conversion. The HTML or a URL through PDFCrowd’s online converter.
HTTP API Conversion is part of an application, script, or repeatable process. An authenticated POST request containing HTML, a file, or a URL.

PDFCrowd lists the online converter for one-time work and its API for application PDF generation. The API endpoint shown in its guide is version 24.04; check the current vendor documentation before deploying an integration, since endpoint details can change. For a manual job, open the PDFCrowd online converter and provide the HTML or URL there.

3. Convert HTML with the PDFCrowd HTTP API

The documented HTTP API uses POST to https://api.pdfcrowd.com/convert/24.04/, HTTP Basic authentication with your PDFCrowd username and API key, and form fields. A successful response is 200 OK with PDF bytes in the response body. Keep credentials private and do not put a real key in source control.

For an HTML string, the documented field is text. This runnable cURL example reads credentials from environment variables and writes the response to email.pdf:

export PDFCrowd_USERNAME='your-pdfcrowd-username'
export PDFCrowd_API_KEY='your-api-key'

curl --fail --silent --show-error \
  -u "$PDFCrowd_USERNAME:$PDFCrowd_API_KEY" \
  -F 'text=<!doctype html><html><body><h1>Monthly update</h1><p>Email content goes here.</p></body></html>' \
  'https://api.pdfcrowd.com/convert/24.04/' \
  -o email.pdf

The example uses short sample HTML. For a real message, pass the complete HTML in the form field or use a file or URL input as appropriate. The API guide documents HTML text, file upload, and URL inputs. Use the input field names and options from the current PDFCrowd API documentation when adapting a request.

Python: submit an HTML string and save the PDF

This example uses only the Python standard library. It sends a form-encoded POST with Basic authentication and saves the returned bytes. Set the two environment variables before running it.

import base64
import os
import urllib.parse
import urllib.request

username = os.environ["PDFCrowd_USERNAME"]
api_key = os.environ["PDFCrowd_API_KEY"]
html = """<!doctype html>
<html>
  <body>
    <h1>Monthly update</h1>
    <p>Email content goes here.</p>
  </body>
</html>"""

endpoint = "https://api.pdfcrowd.com/convert/24.04/"
form = urllib.parse.urlencode({"text": html}).encode("utf-8")
request = urllib.request.Request(endpoint, data=form, method="POST")
credentials = base64.b64encode(f"{username}:{api_key}".encode()).decode()
request.add_header("Authorization", f"Basic {credentials}")
request.add_header("Content-Type", "application/x-www-form-urlencoded")

with urllib.request.urlopen(request, timeout=120) as response:
    if response.status != 200:
        raise RuntimeError(f"PDFCrowd returned HTTP {response.status}")
    pdf_bytes = response.read()

if not pdf_bytes.startswith(b"%PDF-"):
    raise RuntimeError("Response did not look like a PDF; check API errors and credentials")

with open("email.pdf", "wb") as output:
    output.write(pdf_bytes)

For large HTML bodies, an uploaded HTML file or archive may be more convenient than embedding the full document in a form field. Consult the API reference for the current upload parameter names and conversion options.

Node.js: submit an HTML string and save the PDF

This example uses built-in Node.js modules. It sends form data with Basic authentication and writes the returned bytes to disk.

import { writeFile } from 'node:fs/promises';

const username = process.env.PDFCROWD_USERNAME;
const apiKey = process.env.PDFCROWD_API_KEY;
if (!username || !apiKey) {
  throw new Error('Set PDFCROWD_USERNAME and PDFCROWD_API_KEY first');
}

const html = `<!doctype html>
<html><body>
  <h1>Monthly update</h1>
  <p>Email content goes here.</p>
</body></html>`;

const form = new URLSearchParams({ text: html });
const credentials = Buffer.from(`${username}:${apiKey}`).toString('base64');
const response = await fetch('https://api.pdfcrowd.com/convert/24.04/', {
  method: 'POST',
  headers: {
    Authorization: `Basic ${credentials}`,
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: form,
  signal: AbortSignal.timeout(120_000),
});

if (!response.ok) {
  const detail = await response.text();
  throw new Error(`PDFCrowd HTTP ${response.status}: ${detail}`);
}

const pdf = Buffer.from(await response.arrayBuffer());
if (!pdf.subarray(0, 5).equals(Buffer.from('%PDF-'))) {
  throw new Error('Response did not look like a PDF; check the API response');
}
await writeFile('email.pdf', pdf);

These examples cover HTML text. For a file or URL, follow the corresponding input method and parameter names in PDFCrowd’s current API documentation rather than assuming that the HTML-string field accepts a path or URL.

4. Include images, stylesheets, and other resources

If the email HTML references local files, send those files alongside the HTML in a supported archive: .zip, .tar.gz, or .tar.bz2. PDFCrowd converts the first HTML file it finds in the archive unless the request specifies another using zip_main_filename. Keep relative paths in the HTML consistent with the archive’s folder structure.

Alternatively, resources hosted at accessible internet URLs can be loaded remotely. Check that each resource URL works without an interactive login or a browser-only session. If a remote image is missing in the PDF, verify its URL and accessibility, and consider bundling it with the HTML.

  1. Put the message HTML and its local assets in one directory.
  2. Keep the HTML’s resource references valid relative to the archive layout.
  3. Archive the directory in one of the documented formats.
  4. Upload the archive using PDFCrowd’s documented file input. If it contains multiple HTML files, select the intended entry with zip_main_filename.

For a URL-based conversion, make sure the page and dependent resources are reachable to the converter. A URL is useful when the HTML is already hosted, but it is not a substitute for packaging files that are only available on your local machine.

5. Set paper size, orientation, margins, and print CSS

PDFCrowd’s API reference lists A4 as the default page size and supports standard sizes including Letter. It also exposes controls for orientation, margins, headers, footers, and custom styling. Use those options to make long messages readable and avoid clipping important content.

Layout concern What to check
Paper size Choose the intended standard size, such as A4 or Letter; A4 is the documented default.
Orientation Use portrait for most email content. Consider landscape only when the message contains wide tables.
Margins Leave enough room for readable text and printing; inspect the result for clipped edges.
Custom CSS Use it to adjust typography, spacing, or elements that do not belong on paper.
Headers and footers Enable only if the document needs page context such as page numbers.
Existing @page CSS Choose how CSS page rules interact with API layout settings.

The API reference documents css_page_rule_mode: default gives priority to API settings, while mode2 gives priority to CSS @page rules. If the PDF ignores your chosen paper size or margins, check whether the source email’s print CSS is taking precedence and set the mode to match the intended authority.

When adding custom CSS, keep the original email styling intact unless you have a reason to change it. Review the generated PDF for line wrapping, image sizing, page breaks, and content that may be hidden or clipped. Conversion quality can vary with the specific markup and resources.

6. Review the PDF before using it

After conversion, open the PDF and confirm that it contains the intended message and is readable at the chosen paper size. In particular, review:

  • Whether all expected text and links are present.
  • Whether images loaded and have sensible dimensions.
  • Whether text wraps cleanly and tables fit the page.
  • Whether page breaks split a heading, table, or important block awkwardly.
  • Whether the page count and margins suit the intended use.

This review matters because the documentation describes conversion inputs and settings, not guaranteed rendering for every email template. Do not assume that a responsive email layout, remote font, or third-party image will look identical in every PDF.

7. Troubleshooting common problems

Symptom Likely cause What to do
Authentication fails The username or API key is missing, incorrect, or malformed in the Basic auth value. Check the account credentials and environment variables. Keep the key private and ensure the header is Basic authentication over the documented HTTPS endpoint.
The response is an error instead of a PDF The request has invalid fields, an unsupported input combination, or an API issue. Inspect the HTTP status and response body. Compare the request fields with the current API reference before saving the body as a PDF.
The output file is not a valid PDF An error response or HTML message was saved as if it were PDF bytes. Check the status first and inspect the response. Confirm the file begins with a PDF signature before passing it to downstream tools.
Images or styles are missing Local paths were not included, relative paths do not match the archive, or remote resources are inaccessible. Bundle local assets in a supported archive, fix relative paths, or make remote resources reachable to the converter.
The wrong HTML file in an archive is converted The archive contains more than one HTML file and the desired file is not the first one found. Set zip_main_filename to the intended HTML entry.
Paper size or margins seem ignored CSS @page rules may be taking precedence over API settings, or the reverse. Set css_page_rule_mode to default for API setting priority or mode2 for CSS page-rule priority.
The request times out The HTML or its remote resources take too long to process, or the client timeout is too short. Use a suitable client timeout, reduce unnecessary dependencies, and verify remote resources respond. Retry only after considering whether the first request may have completed.
Long content is cut off or difficult to read The page layout, margins, orientation, or source print styling does not suit the message. Try the appropriate paper size and orientation, adjust margins or custom CSS, then inspect page breaks in the resulting PDF.

8. Performance, reliability, and cost considerations

For one-off work, the online converter avoids writing an integration. For recurring conversions, the API makes the request repeatable and can fit into an application workflow. Conversion time depends on the HTML and any resources that must load; the cited documentation does not provide a universal conversion-time benchmark.

For reliability, keep credentials outside source code, set a client timeout, check the HTTP status before treating a response as a PDF, and preserve error details for diagnosis. If retrying a failed request, account for the possibility that a timeout occurred after the remote service completed processing. Verify your account’s current pricing and usage terms directly with PDFCrowd; no rate or cost figure is assumed here.

Or skip the browser setup

For a screenshot of an email or a rendered message page, ScreenshotNeo offers a one-request website capture. It is a website screenshot API and MCP server by ScreenshotNeo; its API documentation covers the request options. This captures a rendered web page as an image or PDF; it does not retrieve an email from a mailbox or replace the HTML-to-PDF workflow when you specifically need PDFCrowd.

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 removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for 1,000 free screenshots a month with no card.

FAQ

Can PDFCrowd convert an email directly from my mailbox?

The documented workflow accepts HTML text, an HTML file, or a URL. Obtain the email’s HTML first; the cited documentation does not establish direct mailbox access.

Can I use a URL instead of sending HTML?

Yes. PDFCrowd documents URL input. The page and any resources it needs must be accessible to the converter.

Which page-rule mode should I use?

Use default when API page settings should take priority. Use mode2 when the document’s CSS @page rules should take priority.

Does this workflow guarantee that every email renders perfectly?

No such guarantee is established by the cited documentation. Review the output for missing assets, wrapping, and page breaks.