Skip to content

Print-ready output

A PDF that is going to a printer, an archive or a customer’s inbox needs more than the right pixels. Compose PDF splits those concerns in two: what belongs to the template, and what is decided at the moment you export.

These live in the Output panel and are saved with the template, so a PDF rendered through the API carries the same values as one exported from the browser.

Document info — Title, Author, Subject, Keywords, and a Document ID. The title falls back to the template’s name if you leave it empty.

Encryption policy — turn on Encrypt this document and choose what a reader is allowed to do: Print, Print at high quality, Change the content, Copy text and images, Add annotations, Fill in forms, Reorder pages, and Read aloud with assistive technology. Everything not ticked is forbidden.

The password is not part of the template. A template is stored, shared and versioned; a password stored beside it would be a password anyone with access to the template already knows. The template holds the policy, the render call holds the secret:

Terminal window
curl -X POST https://composepdf.com/v1/canvases/{canvasId}/pdf \
-H "x-api-key: $COMPOSEPDF_API_KEY" \
-H "content-type: application/json" \
-d '{ "data": { … }, "options": { "password": "…" } }' \
--output invoice.pdf

The two halves are checked against each other. Asking for an encrypted template without a password is refused, and so is sending a password to a template that does not declare encryption — the first would hand out a readable file, the second an unprotected one.

Attach an Underlay PDF to a page and the template is drawn on top of it. Pre-printed letterhead, a statutory form, a certificate with a border — the underlay stays exactly as it is, and you place your content in the spaces it leaves. You choose which page of the attached file to use.

Spot colours and bleed are supported for work that goes to a commercial printer: a spot colour is written as a real separation rather than being approximated in process inks, and a bleed area extends artwork past the trim.

What a file is when it is finished belongs to the template (the “Output” section of the left pane). That is what makes an export from the studio and a call to the published URL answer with the same kind of file.

  • Profile — Standard, PDF/X-4, or PDF/A-3b. The conformance profiles need an ICC profile (.icc) and an output-intent identifier, which you supply, because the correct profile is the one your printer or archive specifies. The ICC lives in the workspace and the template refers to it by id.
  • Factur-X (ZUGFeRD) metadata, with the invoice XML attached (PDF/A-3b). The invoice XML is derived from each render’s payload, so besides attaching a fixed one you can send it with the call (same filename, the call wins).
  • Attachments — files embedded in the PDF.
  • Fast Web View — reorders the file so the first page arrives first.
  • Signature field — a named, empty field for whoever receives the document to sign. It can instead be emitted prepared for a signing tool, which is an intermediate file rather than a document to hand out: until that tool writes the CMS into it, a viewer reads the reserved space as a broken signature and says so.
  • Verify — drop any PDF onto the studio’s export dialog to check it against a conformance profile and read the report.

Only what cannot belong to a template is a parameter of the call.

  • Creation dateoptions.createdAt, ISO 8601 in UTC ("2026-08-13T09:30:00Z"). A fact about one render, not about the template.
  • Password — whether to encrypt, and what the reader may do, is the template’s; the secret is the call’s.

A given template, payload, font set and engine version produce a byte-identical PDF. There is no clock reading, no random identifier and nothing left to iteration order — so a checksum is a meaningful cache key, and a diff between two renders means something actually changed.

  • Without a creation date, files are dated 2000-01-01T00:00:00Z. The engine never reads a clock — that is what “the same input gives the same file” rests on — so pass options.createdAt when the date matters.
  • Studio-only: verifying an existing PDF, and the low-memory (streaming) export. The first only reads a file; the second is a delivery method rather than a property of one.
  • PDF/X-4 and PDF/A-3b forbid encryption, so a template that declares an encryption policy cannot be exported under those profiles.
  • An encrypted PDF cannot also be linearized or take a signature placeholder.
  • Passwords are never stored. For the same reason they cannot be used with asynchronous rendering, which would have to keep the secret while the job waits.