How to Convert Plain Text to PDF with cURL

Use cURL to convert plain text into a styled, tagged PDF while preserving source lines or reflowing paragraphs.
Share this page

This tutorial uses cURL and the pdfRest Convert to PDF API Tool to turn a plain text file into a styled, tagged PDF. The request preserves the source line breaks and applies page, margin, font, color, title, and language settings in one command.

Why Convert Plain Text to PDF with cURL?

Plain text is the common output of command-line tools, monitoring jobs, and legacy systems, but it lacks page boundaries and a consistent presentation for sharing. PDF makes that content easier to review, attach to a record, and open without depending on a particular text editor.

An operations script might collect the relevant portion of a service log after an outage and add it to an incident-management case. By calling pdfRest with line_handling: "preserve", the script can retain timestamps, line breaks, and intentional spacing in a paginated PDF. The response becomes a portable diagnostic artifact that support and engineering can reference together.

For narrative notes rather than logs, the same workflow can use reflow so source lines combine into readable paragraphs. This choice allows a small cURL integration to serve both format-sensitive technical output and ordinary prose while applying consistent metadata and optional tagging.

cURL Code Example for Converting Plain Text to PDF

#!/bin/sh

# By default, we use the US-based API service. This is the primary endpoint for global use.
API_URL="https://api.pdfrest.com"

# For GDPR compliance and enhanced performance for European users, you can switch to the EU-based service by uncommenting the URL below.
# For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
# API_URL="https://eu-api.pdfrest.com"

# This sample converts plain text input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.txt"
OPTIONS='{"title":"Structured Content Sample","language":"en-US","enable_tagging":true,"page_setup":{"size":"Letter","orientation":"portrait","margin":{"top":36,"right":42,"bottom":36,"left":42}},"style":{"font":"Arial","heading_font":"Arial","code_font":"Courier","text_size":11,"text_color_rgb":[34,34,34],"heading_scale":1.35,"table":{"column_width_weights":[2,3,2],"keep_header_with_first_row":true,"repeat_headers_on_overflow":true,"show_borders":true,"border_width":0.75,"border_color_rgb":[180,188,200],"header_fill_color_rgb":[33,64,98],"header_text_color_rgb":[255,255,255],"row_fill_color_rgb":[250,250,252],"alternate_row_fill_color_rgb":[235,240,246],"cell_padding":{"top":6,"right":8,"bottom":6,"left":8}}},"plain_text":{"line_handling":"preserve"}}'

curl --location "$API_URL/pdf" \
  --header "Accept: application/json" \
  --header "Content-Type: multipart/form-data" \
  --header "Api-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
  --form "file=@$INPUT_PATH" \
  --form "structured_text_options=$OPTIONS" \
  --form "output=pdf_from_text"

Source: View the sample on GitHub

Breaking Down the Code

The Plain Text shell example calls cURL directly, so no language package is required. API_URL keeps regional routing visible: the active value uses the US service, and the commented alternative selects the EU service.

#!/bin/sh

# By default, we use the US-based API service. This is the primary endpoint for global use.
API_URL="https://api.pdfrest.com"

# For GDPR compliance and enhanced performance for European users, you can switch to the EU-based service by uncommenting the URL below.
# For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
# API_URL="https://eu-api.pdfrest.com"

# This sample converts plain text input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.txt"

For this Plain Text request, the endpoint excerpt makes the regional service choice explicit:

# By default, we use the US-based API service. This is the primary endpoint for global use.
API_URL="https://api.pdfrest.com"

# For GDPR compliance and enhanced performance for European users, you can switch to the EU-based service by uncommenting the URL below.
# For more information visit https://pdfrest.com/pricing#how-do-eu-gdpr-api-calls-work
# API_URL="https://eu-api.pdfrest.com"

INPUT_PATH identifies the local .txt source. The @ prefix in the later --form argument instructs cURL to upload that file’s contents instead of sending its path as text.

# This sample converts plain text input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.txt"
OPTIONS='{"title":"Structured Content Sample","language":"en-US","enable_tagging":true,"page_setup":{"size":"Letter","orientation":"portrait","margin":{"top":36,"right":42,"bottom":36,"left":42}},"style":{"font":"Arial","heading_font":"Arial","code_font":"Courier","text_size":11,"text_color_rgb":[34,34,34],"heading_scale":1.35,"table":{"column_width_weights":[2,3,2],"keep_header_with_first_row":true,"repeat_headers_on_overflow":true,"show_borders":true,"border_width":0.75,"border_color_rgb":[180,188,200],"header_fill_color_rgb":[33,64,98],"header_text_color_rgb":[255,255,255],"row_fill_color_rgb":[250,250,252],"alternate_row_fill_color_rgb":[235,240,246],"cell_padding":{"top":6,"right":8,"bottom":6,"left":8}}},"plain_text":{"line_handling":"preserve"}}'

The JSON assigned to OPTIONS is pdfRest-specific rather than shell syntax. title becomes document metadata, language identifies the document language, and enable_tagging explicitly requests logical structure. page_setup selects Letter portrait pages with 36-point margins, while style supplies fonts, text size, color, and format-specific presentation.

{
  "plain_text": {
    "line_handling": "preserve"
  }
}

preserve keeps every normalized source line and its spacing in a preformatted block. Windows and legacy carriage-return line endings are normalized consistently. The alternative reflow joins consecutive nonblank lines into paragraphs, using blank lines as paragraph boundaries; reflow is the default when the field is omitted. Only those two values are accepted. When horizontal alignment matters, select a monospaced body font because preserve mode retains characters and spacing but does not force a particular font.

The sample also carries style.table because the repository uses one broad structured-text profile. Plain Text does not create a table, so those table colors, borders, widths, and padding have no effect and may be omitted from a text-only integration.

For Plain Text conversion, the --form arguments create the multipart fields: file carries the structured source, structured_text_options carries serialized settings, and output names the requested PDF.

  --header "Content-Type: multipart/form-data" \
  --header "Api-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
  --form "file=@$INPUT_PATH" \
  --form "structured_text_options=$OPTIONS" \
  --form "output=pdf_from_text"

The Plain Text request asks for JSON with Accept, declares multipart form data with Content-Type, and authenticates through Api-Key. Success returns the generated PDF resource and download URL; failure returns API error information.

# This sample converts plain text input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.txt"
OPTIONS='{"title":"Structured Content Sample","language":"en-US","enable_tagging":true,"page_setup":{"size":"Letter","orientation":"portrait","margin":{"top":36,"right":42,"bottom":36,"left":42}},"style":{"font":"Arial","heading_font":"Arial","code_font":"Courier","text_size":11,"text_color_rgb":[34,34,34],"heading_scale":1.35,"table":{"column_width_weights":[2,3,2],"keep_header_with_first_row":true,"repeat_headers_on_overflow":true,"show_borders":true,"border_width":0.75,"border_color_rgb":[180,188,200],"header_fill_color_rgb":[33,64,98],"header_text_color_rgb":[255,255,255],"row_fill_color_rgb":[250,250,252],"alternate_row_fill_color_rgb":[235,240,246],"cell_padding":{"top":6,"right":8,"bottom":6,"left":8}}},"plain_text":{"line_handling":"preserve"}}'

curl --location "$API_URL/pdf" \
  --header "Accept: application/json" \
  --header "Content-Type: multipart/form-data" \
  --header "Api-Key: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" \
  --form "file=@$INPUT_PATH" \
  --form "structured_text_options=$OPTIONS" \
  --form "output=pdf_from_text"

Beyond the Tutorial

This example shows how to create a tagged PDF from plain text while retaining intentional line breaks and spacing from the source file. Tagged output adds logical document structure that can support accessibility and downstream processing, but it does not by itself guarantee conformance with a specific accessibility standard.

For simpler workflows, you can submit a plain text file without every styling option. Explore the API Lab to test requests in your browser, and see the Convert to PDF documentation for the complete parameter reference.

Generate a self-service API Key now!
Create your FREE API Key to start processing PDFs in seconds, only possible with pdfRest.