Skip to main content
Version: 9.x

Sign a PDF

Signs a PDF with your certificate, so readers can check who signed it and that nothing changed since.

POST/forms/pdf/sign
filesfile[]required

The PDFs, and the files the options name.

archivesfile[]

ZIP files Gotenberg unpacks: each entry counts as a file uploaded under files.

URLs Gotenberg downloads first, as if you had uploaded the files. Each entry takes a url, and optionally extraHttpHeaders.

certificatefilerequired

An uploaded PKCS#12 file, or a PEM certificate with key.

keyfile

The PEM private key that goes with a PEM certificate.

The password that opens a PKCS#12 certificate.

reasonstring

Why the PDF is signed.

locationstring

Where it is signed.

How to reach the signer.

namestring

The signer's name.

padesboolean

Makes a PAdES signature, the format eIDAS recognizes.

Default: false

An RFC 3161 timestamp authority to timestamp the signature with.

The PDF, or a ZIP of the PDFs when you send several.

The route also takes the headers. An error answers a status and a message: see Errors.

Upload the PDF, a PEM certificate and its private key:

curl \
--request POST http://localhost:3000/forms/pdf/sign \
--form files=@report.pdf \
--form files=@cert.pem \
--form files=@key.pem \
--form certificate=cert.pem \
--form key=key.pem \
--form reason=Approved \
--form location=Paris \
-o report.pdf

reason, location, contactInfo and name show in the viewer's signature panel. cert.pem is a self-signed test certificate, so viewers flag the signature as untrusted: sign with a certificate from an authority they trust.

Sign with a PKCS#12 file​

A .p12 or .pfx file holds the certificate and its key. certificatePassword opens it:

curl \
--request POST http://localhost:3000/forms/pdf/sign \
--form files=@report.pdf \
--form files=@cert.p12 \
--form certificate=cert.p12 \
--form certificatePassword=secret \
-o report.pdf

Make it PAdES​

pades: true makes a PAdES signature, the format the EU's eIDAS regulation recognizes for electronic signatures. Set it for documents signed in or for the EU:

curl \
--request POST http://localhost:3000/forms/pdf/sign \
--form files=@report.pdf \
--form files=@cert.pem \
--form files=@key.pem \
--form certificate=cert.pem \
--form key=key.pem \
--form pades=true \
-o report.pdf

Timestamp the signature​

timestampUrl asks an RFC 3161 timestamp authority to vouch for the signing time:

curl \
--request POST http://localhost:3000/forms/pdf/sign \
--form files=@report.pdf \
--form files=@cert.pem \
--form files=@key.pem \
--form certificate=cert.pem \
--form key=key.pem \
--form pades=true \
--form timestampUrl=http://timestamp.digicert.com \
-o report.pdf

Operators decide which authorities Gotenberg may call: see timestamp.

Sign last​

A change after a signature breaks it, so only a timestamp or a render may follow the sign stage, and a list signs once. Process before you sign: a stage that rewrites the file, such as select, merge, remediate or optimize, refuses a signed PDF, since its rewrite would drop the signature. Stamps, rotations, metadata, bookmarks, attachments and tags append to the file and keep it: see what each stage does to the file. An encrypted PDF signs in two requests: decrypt it, then sign the result.

curl \
--request POST http://localhost:3000/forms/pdf/pipe \
--form files=@report.pdf \
--form files=@cert.pem \
--form files=@key.pem \
--form 'stages=[
{ "op": "optimize" },
{ "op": "sign", "certificate": "cert.pem", "key": "key.pem", "pades": true }
]' \
-o report.pdf

In a list of stages​

The stage also runs in a list on /forms/pdf/pipe, and on the PDFs a Chromium or LibreOffice conversion makes, in its stages field:

curl \
--request POST http://localhost:3000/forms/pdf/pipe \
--form files=@report.pdf \
--form files=@cert.pem \
--form files=@key.pem \
--form 'stages=[
{ "op": "sign", "certificate": "cert.pem", "key": "key.pem", "reason": "Approved", "pades": true }
]' \
-o report.pdf