How to Convert JSON to PDF with cURL
This tutorial shows how to convert JSON to PDF with cURL and the pdfRest Convert to PDF API Tool. The request creates tagged output, presents nested JSON as a reader-oriented hierarchy, and applies consistent page and typography settings without requiring a local PDF renderer.
Why Convert JSON to PDF with cURL?
JSON is designed for APIs and application state, not for people who need a paginated record. A raw payload may be difficult for support staff, project managers, or auditors to scan, and its appearance depends on whichever editor or browser opens it.
A deployment pipeline provides a practical example. After promoting a service, a shell job may save a JSON manifest containing component versions, environment values, and feature flags. The same job can convert that manifest into a hierarchy-formatted PDF and store it with the release evidence, giving reviewers an accessible snapshot without replacing the machine-readable original.
When exact syntax is more useful than a nested outline, the request can use source presentation instead. That mode validates and pretty-prints the JSON, making cURL suitable for both human-oriented operational records and code-oriented diagnostic artifacts.
cURL Code Example for Converting JSON 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 JSON input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.json"
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}}},"data_presentation":"hierarchy"}'
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_json"
Source: View the sample on GitHub
Breaking Down the Code
The JSON 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 JSON input to a tagged PDF through multipart /pdf. INPUT_PATH="/path/to/sample.json"
For this JSON 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 .json 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 JSON input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.json"
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}}},"data_presentation":"hierarchy"}'
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.
{
"data_presentation": "hierarchy"
}
source is the default. It validates and parses the input, then pretty-prints normalized JSON syntax in a code-style block; original indentation and insignificant whitespace are not preserved. hierarchy removes the syntax and creates a nested list in which property names are bold and primitive values appear as key-value items.
Scalar arrays become ordinary nested values. Arrays containing objects or other arrays label their members Item 1, Item 2, and so on. The converter preserves JSON structure but intentionally does not infer application-specific report meaning. Malformed JSON is rejected in either presentation mode.
The sample’s shared style.table object does not affect JSON source or hierarchy output. It can be omitted when the profile is used only for JSON conversion.
For JSON 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_json"
The JSON 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 JSON input to a tagged PDF through multipart /pdf.
INPUT_PATH="/path/to/sample.json"
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}}},"data_presentation":"hierarchy"}'
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_json"
Beyond the Tutorial
This pattern can support configuration snapshots, API response archives, processing manifests, and automated evidence packages. Hierarchy mode emphasizes relationships and values, while source mode retains normalized braces, brackets, and property syntax for technical inspection.
Tagged output contributes logical structure for compatible assistive and downstream tools but does not independently establish accessibility conformance. Test representative payloads in API Lab and use the Convert to PDF documentation for the authoritative option contract.