# Document Metadata

> Write, update and read the title, author, subject and keywords of PDFs with SaveSettings, LoadSettings and DocumentSettings, and custom properties in DOCX.

- **Product:** TX Text Control .NET Server
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET Server > PDF Processing > Document Metadata
- **4118 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/metadata/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/metadata/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/metadata/llms-full.txt

---

Title, author, subject and keywords describe a document without opening it. PDF readers show them in the document properties, search tools index them and archives sort by them. TX Text Control writes this metadata when it saves a PDF and reads it from the PDF documents it loads. Read on for how the three settings objects work together, how to update the metadata of an existing PDF, build a keyword index, store custom properties and give an accessible PDF its title.

Setting the metadata of a new PDF with `SaveSettings` is shown in [Create a PDF](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/pdf/create/#set-document-properties), and reading it after loading in [Load and Modify a PDF](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/pdf/load-modify/#read-metadata-and-attachments).

### Where Metadata Lives

Three objects carry the metadata of a document:

| Object | Role |
|---|---|
| [SaveSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/llms-full.txt) | The values `Save` writes to the file you save now |
| [LoadSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/llms-full.txt) | The values of the document that `Load` read; read only |
| [ServerTextControl.DocumentSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/documentsettings-property/llms-full.txt) | The values of the current document: filled when a document is loaded and stored automatically when it's saved |

When you save, a value set in `SaveSettings` overrides the value of the same name in `DocumentSettings`. A property you leave empty in `SaveSettings` is taken from `DocumentSettings`, so a loaded document keeps its metadata when you save it again. The properties are:

| Metadata | `SaveSettings` | `LoadSettings` | `DocumentSettings` | Empty value |
|---|---|---|---|---|
| Title | [DocumentTitle](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/documenttitle-property/llms-full.txt) | [DocumentTitle](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/documenttitle-property/llms-full.txt) | [DocumentTitle](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/documentsettings/documenttitle-property/llms-full.txt) | Empty string |
| Author | [Author](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/author-property/llms-full.txt) | [Author](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/author-property/llms-full.txt) | [Author](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/documentsettings/author-property/llms-full.txt) | Empty string |
| Subject | [DocumentSubject](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/documentsubject-property/llms-full.txt) | [DocumentSubject](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/documentsubject-property/llms-full.txt) | [DocumentSubject](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/documentsettings/documentsubject-property/llms-full.txt) | Empty string |
| Keywords | [DocumentKeywords](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/documentkeywords-property/llms-full.txt) | [DocumentKeywords](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/documentkeywords-property/llms-full.txt) | [DocumentKeywords](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/documentsettings/documentkeywords-property/llms-full.txt) | `null` |
| Creating application | [CreatorApplication](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/creatorapplication-property/llms-full.txt) | [CreatorApplication](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/creatorapplication-property/llms-full.txt) | [CreatorApplication](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/documentsettings/creatorapplication-property/llms-full.txt) | Empty string |
| Creation date | [CreationDate](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/creationdate-property/llms-full.txt) | [CreationDate](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/creationdate-property/llms-full.txt) | [CreationDate](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/documentsettings/creationdate-property/llms-full.txt) | January 1, 0001 |
| Modification date | [LastModificationDate](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/lastmodificationdate-property/llms-full.txt) | [LastModificationDate](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/lastmodificationdate-property/llms-full.txt) | — | January 1, 0001 |
| Custom properties | [UserDefinedDocumentProperties](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/savesettings/userdefineddocumentproperties-property/llms-full.txt) | [UserDefinedDocumentProperties](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/userdefineddocumentproperties-property/llms-full.txt) | [UserDefinedDocumentProperties](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/documentsettings/userdefineddocumentproperties-property/llms-full.txt) | `null` |

A PDF stores the title, author, subject, keywords, creating application and both dates. The standard properties are also saved with DOCX and the other formats, and the three objects work the same way for them.

### Update the Metadata of an Existing PDF

To change a few values of a PDF, load it, change what you need and save it again. The following program adds keywords to a loaded PDF and records your application as the creator, while the title, author and subject of the original document stay:

```csharp
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Load("Documents/input.pdf", StreamType.AdobePDF);

    // Filled from the loaded PDF
    DocumentSettings documentSettings = tx.DocumentSettings;
    Console.WriteLine($"Title: {documentSettings.DocumentTitle}");
    Console.WriteLine($"Created with: {documentSettings.CreatorApplication}");

    // Stays with the document for every later save
    documentSettings.DocumentKeywords = new string[] { "invoice", "INV-2025-001", "Acme Corporation" };

    // Overrides the document settings for this file only
    SaveSettings saveSettings = new SaveSettings()
    {
        CreatorApplication = "Invoice Service",
        LastModificationDate = DateTime.Now
    };

    tx.Save("output.pdf", StreamType.AdobePDF, saveSettings);
}
```

The code works as follows:

- After `Load`, [DocumentSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/documentsettings/llms-full.txt) contains the metadata of the PDF. Values you change there are written by every later `Save` of this instance.
- `SaveSettings` sets only `CreatorApplication` and `LastModificationDate`. All other metadata of the saved PDF comes from `DocumentSettings`, so the original title, author and subject are kept.
- Without the new `CreatorApplication`, the saved PDF would still name the application that created the original file.

The saved PDF is a new document built from the loaded content, as [Load and Modify a PDF](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/pdf/load-modify/#what-happens-when-you-load-a-pdf) explains.

### Build a Keyword Index of Many PDFs

Search tools often rank metadata higher than body text, so keywords help users find PDF documents in large repositories. The following program reads the metadata of all PDF files in a folder and writes a JSON index:

```csharp
using System.Text.Json;
using TXTextControl;

List<object> index = new List<object>();

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();

    foreach (string file in Directory.GetFiles("Documents", "*.pdf"))
    {
        // Text only: the metadata doesn't need the layout of the pages
        LoadSettings loadSettings = new LoadSettings()
        {
            PDFImportSettings = PDFImportSettings.GenerateLines
        };

        tx.Load(file, StreamType.AdobePDF, loadSettings);

        index.Add(new
        {
            File = Path.GetFileName(file),
            Title = loadSettings.DocumentTitle,
            Author = loadSettings.Author,
            Subject = loadSettings.DocumentSubject,
            Keywords = (loadSettings.DocumentKeywords ?? Array.Empty<string>()).Select(keyword => keyword.Trim()).ToArray(),
            Created = loadSettings.CreationDate == DateTime.MinValue ? (DateTime?)null : loadSettings.CreationDate
        });
    }
}

string json = JsonSerializer.Serialize(index, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText("index.json", json);
Console.WriteLine(json);
```

The code works as follows:

- One `ServerTextControl` instance loads the files one after the other; each `Load` replaces the previous document.
- `DocumentKeywords` is `null` when a PDF has no keywords, which the index stores as an empty array. `Trim` removes the spaces around each keyword.
- A missing date is `DateTime.MinValue`, which the index stores as `null`.

The blog article [Enhancing PDF Searchability in Large Repositories by Adding and Reading Keywords Using C# .NET](https://www.textcontrol.com/blog/2025/06/24/enhancing-pdf-searchability-in-large-repositories-by-adding-and-reading-keywords-using-csharp-dotnet/) recommends consistent tagging and 5 to 10 keywords per document.

### Store Custom Properties

Besides the standard metadata, a document can carry properties of your own, such as an invoice number or the name of the data source a template uses. A [UserDefinedPropertyDictionary](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/userdefinedpropertydictionary/llms-full.txt) holds them: each name is a string of up to 255 characters, and each value a string, a Boolean value, an integer or a double value. User-defined properties are saved and loaded with DOCX, RTF and the TX Text Control format, and with DOC on the Classic engine.

The following program updates the invoice number of a DOCX template and keeps all other properties it already has:

```csharp
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Load("Documents/template.docx", StreamType.WordprocessingML);

    UserDefinedPropertyDictionary properties =
        tx.DocumentSettings.UserDefinedDocumentProperties ?? new UserDefinedPropertyDictionary();

    // Replace the value of an existing property
    if (properties.Contains("InvoiceNumber"))
    {
        properties.Remove("InvoiceNumber");
    }

    properties.Add("InvoiceNumber", "INV-2025-001");
    tx.DocumentSettings.UserDefinedDocumentProperties = properties;

    foreach (string name in properties.Names)
    {
        Console.WriteLine($"{name}: {properties[name]}");
    }

    tx.Save("Documents/template.docx", StreamType.WordprocessingML);
}
```

[Contains](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/userdefinedpropertydictionary/contains-method/llms-full.txt) checks for a name, [Remove](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/userdefinedpropertydictionary/remove-method/llms-full.txt) and [Add](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/userdefinedpropertydictionary/add-method/llms-full.txt) change the entries, and the indexer [Item](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/userdefinedpropertydictionary/item-property/llms-full.txt) returns the value of a name. Because the loaded properties are in `DocumentSettings`, `Save` keeps them without further code. MS Word users see the properties in the document's properties.

### Give an Accessible PDF Its Title

PDF/UA, the standard for accessible PDF documents, requires a document title in `DocumentSettings.DocumentTitle`, as [What Your Document Must Provide](https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/pdf-ua/#what-your-document-must-provide) describes, and [Check a Document Before Saving](https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/pdf-ua/#check-a-document-before-saving) finds documents without one. A PDF created with TX Text Control contains its metadata in XMP format as well, together with the declaration that the document conforms to PDF/UA, and to PDF/A when it's saved with `StreamType.AdobePDFA`. To add XMP metadata of your own, such as the extension schema of an electronic invoice, pass it to the constructor of an embedded file, as [Attachments](https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/attachments/#create-an-electronic-invoice) shows.

### Read the Raw Metadata of a PDF

With [PDFImportSettings](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/pdfimportsettings/enumeration/llms-full.txt) `LoadEmbeddedData`, `Load` also provides additional data of a PDF in [LoadSettings.EmbeddedData](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/loadsettings/embeddeddata-property/llms-full.txt), a dictionary whose keys are values of [EmbeddedDataFormat](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/embeddeddataformat/enumeration/llms-full.txt) and whose values are strings. The key `MetaData` returns the metadata of the PDF document:

```csharp
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();

    LoadSettings loadSettings = new LoadSettings()
    {
        PDFImportSettings = PDFImportSettings.GenerateLines | PDFImportSettings.LoadEmbeddedData
    };

    tx.Load("Documents/input.pdf", StreamType.AdobePDF, loadSettings);

    if (loadSettings.EmbeddedData != null &&
        loadSettings.EmbeddedData.TryGetValue(EmbeddedDataFormat.MetaData, out object? metaData))
    {
        Console.WriteLine(metaData);
    }
}
```

The dictionary is filled only when `LoadEmbeddedData` is set, and it contains only the formats the PDF provides. The other keys, `TextCoordinates` and `FormFields`, are used in [Text Extraction](https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/text-extraction/llms-full.txt) and for PDF forms.

### Next Steps

- [PDF/UA](https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/pdf-ua/llms-full.txt): meet the other requirements of accessible PDF documents.
- [Attachments](https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/attachments/llms-full.txt): embed files with their own metadata.
- [PDF Validation](https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/validation/llms-full.txt): check the title and metadata of the PDF documents you create.
- [Document Properties](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/properties/llms-full.txt) in the Document Editor: set the properties in the browser.

---

## Nearby

- **Previous:** [Text Extraction](https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/text-extraction/llms-full.txt)
- **Next:** [Watermarks](https://docs.textcontrol.com/tx-text-control-dotnet-server/pdf/watermarks/llms-full.txt)
