PDF Documents
Converting and merging already return PDF when you ask for it. For a PDF that has to meet more requirements, such as PDF/A for an archive, a title and keywords for a document management system, passwords and permissions, a digital signature or attached files, the DocumentProcessing Web API has the pdf/create endpoint. Two more endpoints read an existing PDF: its XMP metadata and the files embedded in it. The sections below show all three with curl and with the .NET package.
How Creating a PDF Works
The endpoint is POST /documentprocessing/pdf/create:
| Part of the request | Content |
|---|---|
| Body | A JSON object, the PDFCreationSettings, with the content type application/json. Its property documentData holds the source document as a Base64 string and is required; all other properties are optional |
returnFormat | PDF or PDFA. The default is PDF |
| Response | The PDF document as a Base64 string in a JSON string |
The source can be any document that DS Server loads, for example a DOCX file or a document in the TX format that the merge endpoint created. When DS Server runs on Linux, the Core build supports DOCX, HTML, PDF and XLSX only, as Limits on Linux lists.
Every request needs an access token, as Authentication describes.
PDF or PDF/A
PDF/A is the PDF format for long-term archiving. DS Server creates one PDF/A conformance level: PDFA creates PDF/A-3b, as the .NET API reference describes the value PDFA of the PDFFormat enumeration. There is no parameter for another level.
| You need | Use |
|---|---|
| A PDF or PDF/A with default settings | The returnFormat PDF or PDFA of Converting Documents, Merging Templates or Appending Documents |
| Document properties, passwords, permissions, a signature, attached files or JavaScript | pdf/create |
| A merged document with any of these | Merge with returnFormat=TX, then send the result to pdf/create |
The last row is the workflow the Text Control blog describes for a digitally signed PDF in DS Server 1.1 Released: PDF and Barcodes: the merge endpoint returns the document in the TX Text Control format, and pdf/create turns it into the final PDF with all settings. On Linux, the Core build doesn't support the TX format; merge with returnFormat=DOCX there instead.
Create a PDF/A Document With curl
The following commands create a PDF/A document with a title, an author and keywords from document.docx:
DS=http://localhost:5000
TOKEN="<access_token>"
# Build the PDFCreationSettings object around the Base64 string of the document
base64 0 document.docx | jq '{
documentData: .,
documentTitle: "Invoice 4711",
author: "Accounting",
documentKeywords: ["invoice", "2026"]
}' > pdf-settings.json
curl POST "$DS/documentprocessing/pdf/create?returnFormat=PDFA" \
"Authorization: Bearer $TOKEN" \
"Content-Type: application/json" \
@pdf-settings.json \
pdf.json
# Decode the Base64 string of the response
jq . pdf.json | base64 > invoice.pdf
The commands work as follows:
jq -Rsreads the Base64 text as one string,., and builds the JSON object around it. Writing the body to a file keeps large documents out of the command line.returnFormat=PDFAcreates PDF/A-3b. Leave it out, or setPDF, for a plain PDF.- The response is a JSON string.
jq -r .removes its quotes, andbase64 -ddecodes it into the PDF file.
Create a PDF/A Document With .NET
The package TXTextControl.DocumentServices.DocumentProcessing has the PDF methods in its PDF property. The settings are a PDFSettings object, in the namespace TXTextControl.DocumentServices.DocumentProcessing.PDF:
using TXTextControl.DocumentServices.DocumentProcessing;
using TXTextControl.DocumentServices.DocumentProcessing.OAuth;
using TXTextControl.DocumentServices.DocumentProcessing.PDF;
var oauthSettings = new OAuthSettings("<client ID>", "<client secret>");
var documentProcessing = new DocumentProcessing("http://localhost:5000", oauthSettings);
byte[] document = File.ReadAllBytes("document.docx");
var settings = new PDFSettings
{
DocumentTitle = "Invoice 4711",
Author = "Accounting",
DocumentKeywords = new[] { "invoice", "2026" }
};
byte[] pdfA = await documentProcessing.PDF.Create(document, settings, PDFFormat.PDFA);
File.WriteAllBytes("invoice.pdf", pdfA);
The code works as follows:
- The
DocumentProcessingconstructor takes the service URL and the credentials of a security profile, and requests an access token. PDFSettingsholds the settings of the PDF. It inherits the document propertiesDocumentTitle,DocumentSubject,Author,CreatorApplication,CreationDate,LastModificationDateandUserPasswordfromDocumentSettings.PDF.Createtakes the document as a byte array, the settings and aPDFFormatvalue,PDForPDFA, and returns the PDF as a byte array.
The classes are listed in the DocumentProcessing namespace of the .NET API.
Set the PDF Options
The properties of the JSON body and of PDFSettings correspond:
| JSON property | PDFSettings | Content |
|---|---|---|
documentTitle, documentSubject | DocumentTitle, DocumentSubject | The title and the subject, each up to 2,000 characters in a PDF |
documentKeywords | DocumentKeywords | The keywords, as an array of strings |
author, creatorApplication | Author, CreatorApplication | The author and the application that created the document |
creationDate, lastModificationDate | CreationDate, LastModificationDate | The dates saved in the document, in JSON as date-time strings such as "2026-09-29T10:00:00Z" |
userPassword | UserPassword | The password a reader needs to open the document |
masterPassword | MasterPassword | The password that protects the access permissions |
documentAccessPermissions | DocumentAccessPermissions | What a reader may do with the document, see Protect a PDF With Passwords |
imageCompressionQuality | ImageCompressionQuality | The compression quality of images, from 1 to 100 |
documentLevelJavaScriptActions | DocumentLevelJavaScriptActions | JavaScript actions embedded in the PDF, as an array of strings |
embeddedFiles | EmbeddedFiles | Files attached to the PDF, see Read the Embedded Files for their properties |
digitalSignature | DigitalSignature | The certificate to sign the PDF with, see Sign the PDF |
The attached files go in embeddedFiles, an array, and their dates are date-time strings. DS Server ignores a property it doesn't know without an error, so a misspelled name such as embeddedFile leaves the PDF without attachments.
Protect a PDF With Passwords
A reader needs the user password to open the document. The master password protects the access permissions, which only have an effect when a master password is set. The permissions and their values are:
| Value | Number | Allows |
|---|---|---|
None | 0 | None of the permissions |
AllowAuthoring | 1 | Adding comments and filling in form fields, including signature fields |
AllowAuthoringFields | 2 | Filling in existing form fields, including signature fields |
AllowContentAccessibility | 4 | Extracting content for the visually impaired only |
AllowDocumentAssembly | 8 | Inserting, rotating and deleting pages and creating bookmarks and thumbnails |
AllowExtractContents | 16 | Copying or otherwise extracting text and graphics |
AllowGeneralEditing | 32 | Changing the content of the document |
AllowHighLevelPrinting | 64 | Printing, fully allowed |
AllowLowLevelPrinting | 128 | Printing, low-level |
AllowAll | 255 | All of the permissions |
In JSON, documentAccessPermissions is a number: add the numbers of the permissions you allow. A name such as "AllowAll" is refused with 400 and the error "The JSON value could not be converted". The following body creates a PDF that everyone can open and print, but not change:
base64 0 document.docx | jq '{
documentData: .,
masterPassword: "<owner password>",
documentAccessPermissions: 68
}' > pdf-settings.json
68 is AllowHighLevelPrinting (64) plus AllowContentAccessibility (4). Send the file to pdf/create as in Create a PDF/A Document With curl. In C#, combine the values of the DocumentAccessPermissions enumeration, which is in the PDF namespace, with the | operator:
var settings = new PDFSettings
{
MasterPassword = "<owner password>",
DocumentAccessPermissions = DocumentAccessPermissions.AllowHighLevelPrinting |
DocumentAccessPermissions.AllowContentAccessibility
};
byte[] pdf = await documentProcessing.PDF.Create(document, settings, PDFFormat.PDF);
Add a userPassword or UserPassword to require a password for opening the document as well.
Sign the PDF
pdf/create signs the PDF with an X.509 certificate that you send with the request:
- JSON.
digitalSignatureis an object withx509Certificate2, the certificate as a string,password, the password of the certificate, and the optionaltimeServerURL, the URL of a time server. - .NET.
PDFSettings.DigitalSignaturetakes aDigitalSignatureobject with the propertiesCertificate, anX509Certificate2,PasswordandTimeServerURL.
The certificate and its password travel to DS Server with every request, so send them over HTTPS only, as HTTPS sets it up.
Read the Metadata of a PDF
POST /documentprocessing/pdf/metadata returns the metadata of a PDF document as a JSON string. In the example of the endpoint reference, the string is an XMP packet, the XML format of PDF metadata:
base64 0 invoice.pdf | jq . > invoice.json
curl POST "$DS/documentprocessing/pdf/metadata" \
"Authorization: Bearer $TOKEN" \
"Content-Type: application/json" \
@invoice.json \
| jq . > metadata.xml
The body is the PDF as a Base64 string in a JSON string. jq -r . turns the JSON string into the XML text. A PDF without metadata is answered with 400 Bad Request. In C#, PDF.GetMetaData returns the same string:
string metadata = await documentProcessing.PDF.GetMetaData(File.ReadAllBytes("invoice.pdf"));
Read the Embedded Files
POST /documentprocessing/pdf/embeddedfiles returns the files attached to a PDF, such as the XML invoice data of an electronic invoice. The body is the PDF as a Base64 string, and the response an array of EmbeddedFile objects:
| Property | Content |
|---|---|
fileName | The file name of the attachment |
data | The content of the file. In the example of the endpoint reference, it is a Base64 string and dataType is BASE64BINARY |
dataType | The type of data |
mimeType | The MIME type, such as application/pdf |
description | The description of the attachment |
relationship | The relationship of the file to the PDF |
creationDate, lastModificationDate | The dates of the file |
metadata | The metadata of the file |
The following commands save each attachment of invoice.pdf under its file name:
curl POST "$DS/documentprocessing/pdf/embeddedfiles" \
"Authorization: Bearer $TOKEN" \
"Content-Type: application/json" \
@invoice.json \
attachments.json
count=$(jq length attachments.json)
for i in $(seq 0 $((count - 1))); do
name=$(jq ".[$i].fileName" attachments.json)
jq ".[$i].data" attachments.json | base64 > "$(basename "$name")"
done
In C#, PDF.GetEmbeddedFiles returns an array of EmbeddedFile objects, in the PDF namespace:
byte[] pdf = File.ReadAllBytes("invoice.pdf");
EmbeddedFile[] files = await documentProcessing.PDF.GetEmbeddedFiles(pdf);
foreach (EmbeddedFile file in files)
{
Console.WriteLine($"{file.FileName} ({file.MIMEType})");
File.WriteAllBytes(Path.GetFileName(file.FileName), Convert.FromBase64String(file.Data));
}
Path.GetFileName and basename keep a file name from the PDF from writing outside the current folder. A PDF whose attachments your application doesn't know is outside input; check the names and types before you use the files.
Next Steps
- PDF Form Fields: read the AcroForm fields of a PDF and flatten form fields.
- Converting Documents: create PDF and PDF/A with default settings.
- Merging Templates: create the document that pdf/create turns into the final PDF.
- Errors and Status Codes: what a refused request means.