1.15 release notes

RSS

Before attempting to upgrade to Document Engine 1.15, make sure your application runs as expected on your current version. If you’re on version 1.6.1 or later, you can upgrade directly to 1.15. If you’re on an earlier version, follow the step-by-step upgrade path outlined in our upgrade guide.

Highlights

This release includes GdPicture improvements, a new accessibility API, Office template image substitution, performance optimizations for large PDFs, and smarter OCR handling for mixed documents. For the complete list of changes, see the changelog.

GdPicture update

This release ships with GdPicture 14.3.26(opens in a new tab). Across these updates, the changelog includes Office conversion improvements, faster XLSX-to-PDF conversion, Office templating fixes, and the image substitution support used by Document Engine’s Office templating API.

Accessibility API

A new /api/accessibility/autotag endpoint simplifies converting PDFs to PDF/UA-1 compliant, screen reader-ready documents. Instead of constructing Build API instructions, you can now upload a PDF directly and receive a tagged document:

Terminal window
curl -X POST http://localhost:5000/api/accessibility/autotag \
-H "Authorization: Token token=<API_AUTH_TOKEN>" \
-H "Content-Type: application/pdf" \
--data-binary @input.pdf \
-o tagged.pdf

Office template image substitution

POST /api/process_office_template now supports image substitution. You can populate _type: "image" markers from Base64 data, data URLs, or remote HTTP(S) URLs, making it possible to inject dynamic assets such as logos, signatures, and product images into DOCX templates.

Performance improvements for large PDFs

This release improves document load time, page-tile rendering, and measurement metadata reads for large PDFs. In our large-file benchmarks, these changes reduced first-page render time substantially and made subsequent tile requests much faster.

Smarter OCR for mixed documents

Build instructions now support the skipOcrForSearchableDocuments flag for OCR actions. This lets you skip OCR on pages that already contain text while still OCRing image-only pages, which helps reduce OCR artifacts on mixed documents.

Breaking changes

This release includes one breaking change that may require updates to your integration.

Embedded credentials in remote URLs are now rejected

Document Engine now rejects remote URLs that include embedded credentials — for example, https://user:password@example.com/file.pdf.

This affects server-side remote fetching protected by SSRF validation, including Office template image substitution and Chromium-based HTML-to-PDF asset loading.

If you currently rely on embedded credentials in URLs, switch to a different authentication mechanism before upgrading.

Deprecations

This release doesn’t include any deprecations.

Performance

This release includes several performance improvements for large PDFs, covering document loading, page rendering, and metadata handling.

Faster rendering for PDFs with many pages

We improved the document-load path to reduce time to first-page render and speed up page-tile rendering, especially for PDFs with many pages.

The optimization focuses on avoiding expensive full metadata extraction during initial load:

  • Optimizes various SQL queries by selecting data more carefully.
  • Reuses already-available document data in request assigns when possible.
  • Reads metadata like page count and page dimensions more efficiently.

This improves initial document load and makes page-tile requests complete faster, resulting in smoother and more responsive scrolling.

Faster measurement metadata reads for large PDFs

We improved measurement metadata reads by caching measurement_content_formats and secondary_measurement_unit more efficiently and lazily backfilling missing entries for older documents on first access.

This reduces the need to read measurement metadata from the source PDF file on disk and improves response times for large PDFs.

Measured improvements

These optimizations build on each other. The figures below should be read per scenario.

All benchmarks used synthetic files in a development environment. Production results will vary depending on hardware, concurrent load, and document characteristics.

Initial render and tile requests (50,000-page PDF)

Performance was measured using a PDF with 50,000 pages.

For first-page render, which relies on several HTTP requests:

  • secondary_measurement_unit — 670 ms > 90 ms (87 percent faster)
  • measurement_content_formats — 15,480 ms > 1,680 ms (89 percent faster)
  • render_annotations — 2,950 ms > 2,140 ms (28 percent faster)

In total: 19,100 ms > 3,910 ms (80 percent faster)

Subsequent tile requests: 930 ms > 304 ms (67 percent faster)

Metadata request benchmarks (multiple large-file profiles)

These measurements cover the combined metadata requests for secondary_measurement_unit, measurement_content_formats, and embedded-files.

  • 50,000-page file — about 1,330 ms > 220 ms (83 percent faster)
  • 100,000-annotation file — about 2,060 ms > 110 ms (95 percent faster)
  • 3 GB file — about 460 ms > 390 ms (15 percent faster)

Worker handling improvements

We’ve identified an issue with how we handle worker errors. It led to a situation where the worker was restarted unnecessarily, and the pool of workers might have been depleted, causing slow processing. This was mainly visible when documents were malformed and Document Engine was under heavy load.

Accessibility API

A new /api/accessibility/autotag endpoint provides a simplified interface for converting PDFs to PDF/UA-1 compliant documents. This endpoint wraps the Build API’s PDF/UA auto-tagging capability with a streamlined API.

The endpoint accepts PDF input via raw binary upload, multipart form-data, or JSON with a URL reference, and it returns a tagged PDF with proper structure for screen readers and assistive technologies.

Key capabilities of PDF/UA auto-tagging include heading detection (H1–H6), list semantics, table structure with scope attributes, logical reading order, annotation handling, and artifact cleanup for decorative elements.

Configuration options

New environment variables are exposed.

  • PSPDFKITD_READ_TIMEOUT — Overrides the worker daemon socket read timeout, in milliseconds. Increase this for long-running operations that legitimately take longer to return a response. By default, it’s set to 120000 (120 seconds).
  • PSPDFKITD_WRITE_TIMEOUT — Overrides the worker daemon socket write timeout, in milliseconds. Increase this if you’re sending very large requests to the core (e.g. large Instant JSON payloads). By default, it’s set to 10000 (10 seconds).

Document upload and creation improvements

POST /api/documents now has improved and more consistent behavior for document creation from uploaded files and remote URLs.

Remote URL download failures now return 422

For document creation via remote URL, permanent upstream download failures such as 403 Forbidden and 404 Not Found now return 422 with reason: "remote_download_failed" instead of 500.

Other request failures can also return 422 with the same stable reason when the request cannot be completed from the provided URL.

When available, the response includes an upstream_status field.

Example response:

{
"error": {
"status": 422,
"upstream_status": 404,
"reason": "remote_download_failed",
"description": "Fetching the specified document from URL failed: remote server returned 404 Not Found. This is a permanent upstream availability error for the provided URL, so the request was not retried."
}
}

Improved S3-aware diagnostics in logs

When a remote URL failure is detected as an Amazon S3 XML error, logs now include structured metadata with:

  • s3_error_code
  • s3_error_message
  • x_amz_request_id
  • x_amz_id_2

Safer URL and error logging

  • Remote URLs are sanitized for logging (userinfo, query, and fragment are removed).
  • Remote-controlled S3 error text is normalized and truncated before being logged.

Null-byte protection

For properties extracted from PDF metadata that are stored in PostgreSQL, we now sanitize null bytes before persistence:

  • Null bytes at the beginning or end of a value are stripped.
  • Inner null bytes are replaced with spaces.
  • One or more consecutive inner null bytes are collapsed to a single space.

Requests are still rejected with 422 when null bytes are present in restricted fields such as document_id, url, or storage (including nested storage fields).

Forms API

This release improves the form field creation workflow.

Creating form fields now also creates default form field values

When you create form fields with POST /api/documents/{documentId}/form-fields, Document Engine now also creates the corresponding form field value records automatically.

This makes newly created fields immediately usable through the form field values API, without requiring a separate initialization request.

Auto-created values follow the form field type:

  • Text fields get an empty default value.
  • List boxes get an empty list value.
  • The created value inherits the form field’s group.

Smarter OCR for mixed documents

Build instructions now support the skipOcrForSearchableDocuments flag for OCR actions. When enabled, OCR is skipped for pages that already contain text (born-digital pages), while image-only pages are still OCRed. This helps reduce OCR artifacts on mixed documents.

Usage

{
"actions": [
{ "type": "ocr", "language": "english", "skipOcrForSearchableDocuments": true }
]
}

Affected endpoints

All endpoints that work with Build instructions are affected, including:

  • /api/documents/{documentId}/apply_instructions
  • /api/documents/{documentId}/layers/{layerName}/apply_instructions
  • /api/build

Office template image substitution

Document Engine now supports image substitution in POST /api/process_office_template. You can populate _type: "image" markers in Office templates from Base64 data, data URLs, or remote HTTP(S) URLs.

This makes it possible to inject dynamic images such as logos, signatures, profile photos, and product images alongside the existing text templating support.

Supported image formats are PNG, JPEG, GIF, BMP, and TIFF. SVG isn’t supported.

Image sources

Each image marker requires a source field:

  • "base64" — Raw Base64 string in data. Requires an explicit format field (e.g. "png", "jpg").
  • "dataUrl" — A data:image/...;base64,... string in data. Format is inferred from the MIME type.
  • "url" — A remote HTTP(S) URL in url (or path). Format is usually inferred automatically; if it cannot be inferred, an explicit format is required.

Image options

Image markers support the following optional fields:

  • sizing — Controls how the image fills the placeholder: "original" (default), "fixed", "fit-width", "fit-height", or "fit-max". The "fixed" and "fit-max" modes require both width and height; "fit-width" requires width; "fit-height" requires height.
  • width, height — Dimensions in points, required by certain sizing modes.
  • borderWidth — Border thickness in points.
  • caption, captionPosition — Optional caption text and placement ("above" or "below").
  • rotation — Rotation angle in degrees.
  • pageNumber — Selects a specific frame from multipage images (e.g. animated GIFs).

Example

Terminal window
curl -X POST http://localhost:5000/api/process_office_template \
-H "Authorization: Token token=<API_AUTH_TOKEN>" \
-F document=@template.docx \
-F 'model={
"config": {
"delimiter": { "start": "{{", "end": "}}" }
},
"model": {
"signature": {
"_type": "image",
"source": "dataUrl",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJ..."
},
"logo": {
"_type": "image",
"source": "url",
"url": "https://example.com/logo.png",
"sizing": "fit-width",
"width": 200
}
}
}'

The endpoint continues to accept both the preferred { config?, model } payload and the legacy bare-model payload.

Remote image fetching

When source: "url" is used, Document Engine fetches the image server-side and applies SSRF protection, timeout, and size limits. The following environment variables control this behavior:

VariableDefaultDescription
OFFICE_TEMPLATE_IMAGE_TIMEOUT_MS10000Timeout per remote image fetch (ms).
OFFICE_TEMPLATE_MAX_IMAGE_BYTES20971520 (20 MB)Maximum size per image.
OFFICE_TEMPLATE_MAX_TOTAL_IMAGE_BYTES52428800 (50 MB)Total image budget per request.
OFFICE_TEMPLATE_MAX_MODEL_BYTES92274688 (88 MiB)Maximum serialized model size.
OFFICE_TEMPLATE_IMAGE_FETCH_CONCURRENCY8Parallel remote fetches.

Database migrations

There are no database migrations in this release.