EmbedPDF

Metadata

doc.metadata reads and rewrites the document’s Info dictionary — title, author, dates, and custom keys.

interface MetadataService {
  read(): AbortablePromise<DocumentMetadata>;
  update(patch: MetadataPatch): AbortablePromise<MetadataUpdateResult>;
}

Reading metadata#

const meta = await doc.metadata.read();
 
meta.title;    // string | null
meta.author;   // string | null
meta.created;  // ISO 8601 string | null (from /CreationDate)
meta.modified; // ISO 8601 string | null (from /ModDate)
meta.trapped;  // 'true' | 'false' | 'unknown'
meta.custom;   // Record<string, string> of non-standard Info entries

The full shape:

interface DocumentMetadata {
  title: string | null;
  author: string | null;
  subject: string | null;
  keywords: string | null;
  producer: string | null;
  creator: string | null;
  created: string | null;   // ISO 8601
  modified: string | null;  // ISO 8601
  trapped: 'true' | 'false' | 'unknown';
  custom: Record<string, string>;
}

Dates come back as ISO 8601 strings. Parsing them into Dates is the caller’s job — the engine doesn’t assume a timezone for you.

Updating metadata#

update() takes a three-state patch, the same convention used by annotation patches:

  • undefined — leave the field untouched
  • null — clear the field
  • a value — set the field
const result = await doc.metadata.update({
  title: 'Q2 Proposal (final)',
  subject: null,            // clear /Subject
  created: '2026-01-04T09:00:00Z', // engine formats to PDF date syntax
  custom: {
    reviewedBy: 'dana',     // set a custom key
    draftOwner: null,       // remove a custom key
  },
});
 
console.log(result.metadata.title); // re-read result

Notes:

  • created/modified accept ISO 8601 strings; the engine formats them into PDF date syntax (D:YYYYMMDD…) on write.
  • trapped has no clear form (it’s a tri-valued enum) — omit it to leave it untouched.
  • custom is a per-key three-state map. Reserved standard keys are rejected.
  • The result includes the re-read metadata plus cloud coherence pins so subsequent reads stay consistent.

Writing metadata is gated by doc.metadata.modify on the cloud. Without it, update() rejects with Forbidden.

Was this page helpful?

Your feedback goes directly to the documentation team.