# Types

Shapes returned by, or accepted by, the SDK API. All are exported from the package for your own signatures.

## SDKInitOptions

```ts
interface SDKInitOptions {
  license?: string; // Your license token — see Licensing
  engineUrl?: string; // A self-hosted copy of pdf-engine.bin — self-hosting licenses only; see Engine Binary Setup
  shaperUrl?: string; // A self-hosted copy of pdf-shaper.bin — likewise
  subsetterUrl?: string; // A self-hosted copy of pdf-subset.bin — likewise
  workerUrl?: string; // URL to render.worker.js — see Web Worker Rendering
  styleNonce?: string; // The page's CSP nonce, carried by every stylesheet the SDK injects — see Content security policy
  licensePopup?: LicensePopupOptions; // The "License required" popup in your own words — see Licensing
}

interface LicensePopupOptions {
  title?: string; // Default: "License required"
  text?: string; // The body, in place of the SDK's sentence naming the reason
  closeLabel?: string; // Default: "Close"
}
```

The options of [`Kernstra.init()`](https://kernstra.com/docs/web-sdk/api/kernstra/init) — see [Initialization](https://kernstra.com/docs/web-sdk/config/init). `engineUrl`, `shaperUrl` and `subsetterUrl` need a license that includes self-hosting (`FEATURE_NOT_LICENSED` otherwise); a `styleNonce` that is not base64 or base64url rejects with `INVALID_ARGUMENT`.

## PDFViewerConfig

```ts
interface PDFViewerConfig {
  mode?: SDKMode; // Default: SDKMode.FULL
  tools?: ToolsConfig; // Per-tool visibility
  defaultTool?: 'selectText' | 'pan' | null; // The resting tool. Default: 'selectText'
  forms?: FormsConfig; // Form field behavior
  export?: ExportConfig; // Export defaults
  confirmations?: boolean | ConfirmationsConfig; // Ask before deleting, discarding or replacing. Default: true
  fonts?: FontsConfig; // Font loading & custom fonts
  toolbar?: ToolbarConfig; // Top toolbar
  navigation?: NavigationBarConfig; // Bottom navigation bar
  sidebar?: SidebarConfig; // The side panels: pages, outline, attachments, signatures, comments
  links?: LinksConfig; // The document's links: clickable, confirmed, named
  print?: PrintConfig; // Whether Print asks first
  theme?: ThemeConfig; // Visual theme
  locale?: LocaleConfig; // Language and translations
  callbacks?: CallbacksConfig; // Lifecycle callbacks
  performance?: PerformanceConfig; // Rendering performance
  accessibility?: AccessibilityConfig; // Accessible text layer
  loader?: LoaderConfig; // Loading indicator branding
  annotations?: AnnotationsConfig; // Comment author, review rule, colors and weights
  layout?: LayoutConfig; // Responsive layout & bar placement
}
```

The third argument of `new PDFViewer(container, doc, config?)`: every section is documented under Configuration, one page per section. `viewer.config` reads it back as a [ResolvedPDFViewerConfig](https://kernstra.com/docs/web-sdk/api/types#ty-resolvedpdfviewerconfig), every default filled in.

## ResolvedPDFViewerConfig

`PDFViewerConfig` as the viewer holds it after the defaults are applied: what `viewer.config` reads and what `DEFAULT_CONFIG` is — your options over the defaults, with what the license does not cover switched off (its tools, and `toolbar.print` / `download`). Its `tools` names every tool: `false` for one you, the mode or the license switched off, otherwise your options for it or `true`. Read it; do not construct it: each option added to `PDFViewerConfig` adds a required field here. Its parts are the `Resolved*Config` family, each a section with its defaults filled in: `ResolvedToolbarConfig`, `ResolvedNavigationBarConfig`, `ResolvedSidebarConfig` (with `ResolvedPagesPanelConfig`, `ResolvedEditablePanelConfig` and `ResolvedPanelSwitch` for its panels), `ResolvedLinksConfig`, `ResolvedPrintConfig`, `ResolvedThemeConfig`, `ResolvedLocaleConfig`, `ResolvedPerformanceConfig`, `ResolvedFormsConfig`, `ResolvedExportConfig`, `ResolvedConfirmationsConfig`, `ResolvedAccessibilityConfig`, `ResolvedLoaderConfig`, `ResolvedAnnotationsConfig`, `ResolvedLayoutConfig` and `ResolvedLayoutBreakpoints` — all exported, so a host can type its own configuration.

## ResolvedToolbarConfig

`toolbar` as the viewer holds it after the defaults are applied. See [Toolbar](https://kernstra.com/docs/web-sdk/config/toolbar).

## ResolvedNavigationBarConfig

`navigation` as the viewer holds it after the defaults are applied. See [Navigation bar](https://kernstra.com/docs/web-sdk/config/navigation).

## ResolvedSidebarConfig

`sidebar` as the viewer holds it after the defaults are applied: `rail`, and one entry per panel. See [Sidebar](https://kernstra.com/docs/web-sdk/config/sidebar).

## ResolvedPagesPanelConfig

The Pages panel's entry of `ResolvedSidebarConfig`.

## ResolvedEditablePanelConfig

A panel that can be edited (outline, attachments, comments) in `ResolvedSidebarConfig`: whether it is offered, and whether editing is.

## ResolvedPanelSwitch

A panel that is only on or off (signatures) in `ResolvedSidebarConfig`.

## ResolvedLinksConfig

`links` as the viewer holds it after the defaults are applied. See [Links](https://kernstra.com/docs/web-sdk/config/links).

## ResolvedPrintConfig

`print` as the viewer holds it after the defaults are applied. See [Print](https://kernstra.com/docs/web-sdk/config/print).

## ResolvedThemeConfig

`theme` as the viewer holds it after the defaults are applied. See [Theme](https://kernstra.com/docs/web-sdk/config/theme).

## ResolvedLocaleConfig

`locale` as the viewer holds it after the defaults are applied. See [Locale](https://kernstra.com/docs/web-sdk/config/locale).

## ResolvedPerformanceConfig

`performance` as the viewer holds it after the defaults are applied. See [Performance](https://kernstra.com/docs/web-sdk/config/performance).

## ResolvedFormsConfig

`forms` as the viewer holds it after the defaults are applied. See [Forms](https://kernstra.com/docs/web-sdk/config/forms).

## ResolvedExportConfig

`export` as the viewer holds it after the defaults are applied. See [Export](https://kernstra.com/docs/web-sdk/config/export).

## ResolvedConfirmationsConfig

`confirmations` with every switch decided. See [Confirmations](https://kernstra.com/docs/web-sdk/config/confirmations).

## ResolvedAccessibilityConfig

`accessibility` as the viewer holds it after the defaults are applied. See [Accessibility](https://kernstra.com/docs/web-sdk/config/accessibility).

## ResolvedLoaderConfig

`loader` as the viewer holds it: `html` or `text`, whichever was given. See [Loader](https://kernstra.com/docs/web-sdk/config/loader).

## ResolvedAnnotationsConfig

`annotations` as the viewer holds it after the defaults are applied. See [Annotations](https://kernstra.com/docs/web-sdk/config/annotations).

## ResolvedLayoutConfig

`layout` with the defaults applied. See [Layout](https://kernstra.com/docs/web-sdk/config/layout).

## ResolvedLayoutBreakpoints

`layout.breakpoints` with the defaults applied.

## ErrorCodeValue

```ts
type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode]
```

The union of the `ErrorCode` values: the type of `SDKError.code` and of the `error` event's `code`. See [Errors](https://kernstra.com/docs/web-sdk/api/errors).

## ToolsApi

The type of `viewer.tools`. See [ToolsApi](https://kernstra.com/docs/web-sdk/api/tools-api).

## GlobalEventMap

```ts
type GlobalEventMap = {
  initialized: { version: string };
  licenseChanged: LicenseState;
  documentLoaded: { document: PDFDocument; pageCount: number; hasPassword: boolean };
  documentClosed: { document: PDFDocument };
}
```

The events of `Kernstra.events`: the SDK and the document, which outlive any one viewer. A handler for one of these registered on a viewer would never run, so `viewer.on` does not accept them. See [Events](https://kernstra.com/docs/web-sdk/api/events).

## ViewerEventMap

```ts
type ViewerEventMap = {
  pageChanged: { pageIndex: number };
  zoomChanged: { scale: number };
  toolChanged: { tool: ToolName | null; previous: ToolName | null };
  panelChanged: { panel: SidebarTab | null; previous: SidebarTab | null };
  pagesChanged: { pageCount: number };
  formFieldChanged: { field: FormFieldInfo };
  formFieldFocused: { field: FormFieldInfo };
  formFieldBlurred: { field: FormFieldInfo };
  signatureCaptured: { fieldName: string; pageIndex: number; method: 'draw' | 'type' | 'upload' | 'host'; dataUrl: string };
  textChanged: { changes: TextChange[] };
  documentChanged: { source: DocumentChangeSource; tool?: ToolName; hasUnsavedChanges: boolean; canUndo: boolean; canRedo: boolean };
  contentPlaced: { tool: ToolName; pageIndex: number };
  annotationsChanged: { pageIndex: number; changes: AnnotationChange[] };
  commentsChanged: { pageIndex: number; changes: CommentChange[] };
  error: { code: ErrorCodeValue; message: string; fatal: boolean };
  savedSignaturesChanged: { signatures: SavedSignature[] };
  userStampsChanged: { stamps: SavedStamp[] };
  exportStarted: Record<string, never>;
  exportCompleted: { sizeBytes: number; partial: boolean; pdfA?: 'kept' | 'dropped' };
}
```

The events of `viewer.on(...)`: what happens in one viewer. A handler for one of these registered on `Kernstra.events` would never run, so it does not accept them. See [Events](https://kernstra.com/docs/web-sdk/api/events).

## SDKEventMap

```ts
type SDKEventMap = GlobalEventMap & ViewerEventMap
```

Every event the SDK fires, on either emitter — `GlobalEventMap` and `ViewerEventMap` together — for a payload typed by name (`SDKEventMap['pageChanged']`). Subscribe through the emitter's own map; the other is a compile error rather than a handler that never runs.

## EventHandler

```ts
type EventHandler<T> = (data: T) => void
```

A handler for `on(event, handler)`: called with the event's payload.

## SubscribeOptions

```ts
interface SubscribeOptions {
  once?: boolean; // Call the handler once, for the next emit, then unsubscribe it
  signal?: AbortSignal; // Unsubscribe when this signal aborts; a signal already aborted subscribes nothing
}
```

The third argument of `viewer.on()` and `Kernstra.events.on()`: how a subscription ends on its own. `signal` is the DOM's idiom, so one `AbortController` can end every subscription a component made.

## GlobalEvents

```ts
type GlobalEvents = Pick<EventEmitter<GlobalEventMap>, 'on' | 'off'>
```

The type of `Kernstra.events`: what a host gets of the global emitter, subscribing and unsubscribing only. Only the SDK emits on it.

## LicenseState

```ts
type LicenseState = LicenseStateValid | LicenseStateInvalid;

interface LicenseStateValid {
  valid: true;
  watermark: boolean; // true while output is marked: a development token
  env: 'development' | 'production';
  plan: string;
  features: LicenseFeature[]; // the features this SDK version enforces that the license names, in a fixed order
  expiresAt?: Date; // only on a license with an expiry date
  offline: boolean; // air-gapped: no status check, no network calls
  reason?: undefined;
  pauseReason?: undefined;
}

interface LicenseStateInvalid {
  valid: false;
  watermark: true; // unlicensed output is marked
  reason: LicenseInvalidReason; // why the license is not valid
  pauseReason?: LicensePauseReason; // why, when reason is 'paused'
  env?: undefined;
  plan?: undefined;
  features?: undefined;
  expiresAt?: undefined;
  offline?: undefined;
}
```

What `Kernstra.setLicense()`, `Kernstra.getLicense()`, `Kernstra.onLicenseChange()` and the `licenseChanged` event all hand you: a union narrowed on `valid`, so `if (state.valid) state.features.includes('export')` type-checks. A valid license fills `env`, `plan`, `features` and `offline`, and `expiresAt` when the license has an expiry date (an offline license always does, an online one normally does not); an invalid one fills `reason`. `LicenseStateValid` and `LicenseStateInvalid` are exported too. See [Licensing](https://kernstra.com/docs/web-sdk/guides/licensing).

## LicenseFeature

```ts
type LicenseFeature = 'edit-text' | 'add-text' | 'edit-pages' | 'annotations' | 'forms' | 'export' | 'print' | 'extract'
```

A feature the license may grant, listed in the license's `features` and enforced at every entry point: `edit-text` (Edit Text: retyping the document's own text), `add-text` (Add Text: writing new text into the page), `edit-pages` (changing the document's structure: pages, bookmarks and attachments), `annotations` (every drawing, mark-up, note, link, stamp, image, signature and erase tool, and `doc.annotations`), `forms` (filling fields, `doc.forms.setValues`), `export` (download, blob, buffer, base64, upload, `doc.save()`, page extraction and password protection), `print`, and `extract` (reading the document's content out through the API). Tools outside the license never appear in the toolbar; `activateTool` and the APIs refuse them with `FEATURE_NOT_LICENSED`. See [Licensing](https://kernstra.com/docs/web-sdk/guides/licensing).

## LicenseInvalidReason

```ts
type LicenseInvalidReason =
  | 'no-license'
  | 'insecure-context' // plain HTTP: the SDK runs only over HTTPS or on localhost
  | 'malformed'
  | 'unsupported-algorithm'
  | 'invalid-signature'
  | 'not-yet-valid'
  | 'expired'
  | 'origin-mismatch'
  | 'wrong-holder' // the token was issued to another browser and copied to this one
  | 'revoked'
  | 'paused' // see LicensePauseReason
  | 'stale'; // not confirmed by the licensing API for more than 48 hours, or never on this browser
```

Why a license is not valid, as `reason` in `LicenseStateInvalid`. `wrong-holder`: the token was issued to another browser and copied to this one (a copied token may also be reported as `revoked`). `stale`: the licensing API has not confirmed the license for more than 48 hours, or never on this browser and the check could not get through; the SDK loads, watermarked and without `extract`, and asks again whenever a document is opened, so a page recovers without a reload once the API answers.

## LicensePauseReason

```ts
type LicensePauseReason = 'payment' | 'suspended' | 'term_ended' | 'trial_ended' | 'other'
```

Why the licensing API paused a license, as `pauseReason` when `reason` is `'paused'`: a missing payment, a suspension by Kernstra, a license term that ended, a trial that ended. `other` stands for any reason this SDK version does not know, so a newer licensing API never breaks an older SDK. A pause is not permanent: the same key loads cleanly again once the license is back in force.

## OpenOptions

```ts
interface OpenOptions {
  password?: string; // The password of an encrypted file
}
```

The options of [`PDFDocument.fromFile()`](https://kernstra.com/docs/web-sdk/api/pdfdocument/fromfile) and [`fromBytes()`](https://kernstra.com/docs/web-sdk/api/pdfdocument/frombytes).

## OpenUrlOptions

```ts
interface OpenUrlOptions extends OpenOptions {
  signal?: AbortSignal; // Aborting it rejects the load with ABORTED
  headers?: Record<string, string>; // Request headers, as fetch() takes them — an Authorization header, say
  credentials?: RequestCredentials; // fetch()'s credentials: 'omit', 'same-origin' or 'include'
}
```

The options of [`PDFDocument.fromUrl()`](https://kernstra.com/docs/web-sdk/api/pdfdocument/fromurl). `signal`, `headers` and `credentials` go to `fetch()` as given, so a document behind authentication opens without the host downloading it first. The headers are read once, at the call: a token that expires during a long progressive load is not refreshed. With `credentials: 'include'` a cross-origin server must answer the page's exact origin and `Access-Control-Allow-Credentials: true`, or the request fails as `CORS_ERROR`; a `401` or `403` rejects with `NETWORK_ERROR`. See [Loading from protected URLs](https://kernstra.com/docs/web-sdk/guides/document-features).

## OpenProgressiveOptions

```ts
interface OpenProgressiveOptions extends OpenUrlOptions {
  chunkSize?: number; // Range-request size in bytes. Default: 256 KiB
  onProgress?: (downloaded: number, total: number) => void; // Download progress
}
```

The options of [`PDFDocument.fromUrlProgressive()`](https://kernstra.com/docs/web-sdk/api/pdfdocument/fromurlprogressive): what `fromUrl` takes (every range request carries `headers`, `credentials` and `signal`) plus the chunk size and a progress callback. See [Progressive loading](https://kernstra.com/docs/web-sdk/guides/document-features).

## DocumentMetadata

```ts
interface DocumentMetadata {
  title: string;
  author: string;
  subject: string;
  keywords: string; // as the file lists them, one string
  creator: string; // the application that produced the document
  producer: string; // the application that wrote the file
  creationDate: Date | null; // null when the file does not say, which is often
  modifiedDate: Date | null; // null when the file does not say. A save sets it
}
```

The type of `doc.metadata`. `modifiedDate` is the saved copy's once a save sets it; the open document's stays what the file said. Without the `extract` feature the six strings are `''`.

## PDFAClaim

The type of `doc.pdfA`: what a file says of itself in its XMP metadata — that it conforms to a part of PDF/A, the archival profile of PDF. `{ part, conformance? }`: `part` is the part of PDF/A claimed (1, 2, 3 or 4), `conformance` the level as written (`'A'`, `'B'`, `'U'`, or for PDF/A-4 `'E'` or `'F'`), absent when the file names none. A claim, not a check — the SDK does not validate it.

## FormFieldInfo

```ts
interface FormFieldInfo {
  name: string;
  type: FormFieldType; // 'text' | 'checkbox' | 'radio' | 'dropdown' | 'listbox' | 'signature'
  value: string;
  pageIndex: number;
  rect: Rect; // the widget's box, in page space — see Coordinates
  options?: { label: string; value: string; selected: boolean }[];
  readOnly: boolean;
  required: boolean;
  noExport: boolean; // left out of a form submission
  multiline: boolean; // a text field of several lines
  password: boolean; // a text field shown as dots
  comb: boolean; // a text field spread over maxLength equal cells
  multiSelect: boolean; // a list box that takes several choices
  hidden: boolean; // Hidden/NoView: no editor is drawn; still filled, read and exported
  maxLength?: number;
  exportValue?: string; // AcroForm export value ("on state") of checkbox/radio widgets
  dateFormat?: string; // a date field's format ('mm/dd/yyyy', 'd-mmm-yy' …), from its AFDate_* script
  signature?: 'digital' | 'appearance'; // a signature field that holds a digital signature, or only shows one (signed earlier, or in this viewer this session)
  format?: FieldFormat; // how it shows its value: number, percent, date, time, special, mask
  range?: FieldRange; // the values it accepts, { min?, max? }
  calculation?: FieldCalculation; // what it computes from other fields
  look?: FieldLook; // the box its widget draws: { background?, border?, borderWidth, borderStyle }
  rotation?: number; // 90 | 180 | 270: its widget's content turned counterclockwise on the page
}
```

One form field as `doc.forms.fields()` lists it and as the `formFieldChanged`, `formFieldFocused` and `formFieldBlurred` events carry it: every widget with its name, type, options, the booleans its flags set and its value (a check box's or radio button's export value when on, `'Off'` when off). Without the `extract` feature `value`, `exportValue` and every option's `label` and `value` are `''`; how the field behaves — `format`, `range`, `calculation`, `look` — is there either way.

## FormType

```ts
type FormType = 'none' | 'acroform' | 'xfa' | 'xfa-foreground'
```

The kind of form the document carries, from `doc.forms.type()`. Only AcroForm fields are interactive; `'xfa-foreground'` is XFA laid over an AcroForm, whose AcroForm part fills.

## FormValue

```ts
type FormValue = string | string[]; // an array: a multi-select list box's choices
```

A field's value as `doc.forms.getValues()` reads it and `doc.forms.setValues()` takes it: a string, or an array of strings for a multi-select list box. `setValues()` also takes a boolean for a check box or radio group (`true` is its export value, `false` is `'Off'`).

## SetFieldResult

```ts
interface SetFieldResult {
  applied: string[]; // field names successfully set
  rejected: { name: string; reason: SetFieldRejectionReason }[];
}
```

What `doc.forms.setValues()` resolves to. Rejections are reported here — never thrown — so a partial autofill mapping is applied safely; compare `reason` against [`SetFieldRejection`](https://kernstra.com/docs/web-sdk/api/enums#s-setfieldrejection).

## SetFieldRejectionReason

```ts
type SetFieldRejectionReason = 'unknown_field' | 'read_only' | 'invalid_value' | 'unsupported_type'
```

Why a field write was rejected. The constants are exported as `SetFieldRejection.UNKNOWN_FIELD`, `.READ_ONLY`, `.INVALID_VALUE`, `.UNSUPPORTED_TYPE`.

## FieldFormat

```ts
type FieldFormat =
  | {
      kind: 'number';
      decimals: number;
      separator: number; // 0 1,234.56 · 1 1234.56 · 2 1.234,56 · 3 1234,56 · 4 1'234.56
      negative: number; // 0 -1,234.56 · 1 red · 2 (1,234.56) · 3 red in parentheses
      currency: string;
      currencyPrepend: boolean; // the currency before the number, else after
    }
  | { kind: 'percent'; decimals: number; separator: number; percentPrepend: boolean } // the value × 100
  | { kind: 'date'; format: string } // 'mm/dd/yyyy' …; the value is stored in this format
  | { kind: 'time'; format: string } // 'h:MM tt' …
  | { kind: 'special'; special: 'zip' | 'zip4' | 'phone' | 'ssn' } // stored as its digits
  | { kind: 'mask'; mask: string }; // 9 a digit, A a letter, O either, X anything
```

How a field shows its value, as Acrobat's form functions define it: `FormFieldInfo.format`.

## FieldRange

```ts
interface FieldRange { min?: number; max?: number } // both included; either may be absent
```

The values a numeric field accepts: `FormFieldInfo.range`.

## FieldCalculation

```ts
type FieldCalculation =
  | { kind: 'simple'; operation: 'SUM' | 'PRD' | 'AVG' | 'MIN' | 'MAX'; fields: string[] } // a group's name takes every field in it
  | { kind: 'expression'; expression: string }; // field names, numbers, + - * / and parentheses
```

What a field computes from other fields: `FormFieldInfo.calculation`. Calculated fields are recalculated when `doc.forms.setValues()` writes without a viewer.

## FieldLook

```ts
interface FieldLook {
  background?: string; // '#rrggbb', absent when the widget draws none
  border?: string; // likewise
  borderWidth: number; // points
  borderStyle: 'solid' | 'dashed' | 'beveled' | 'inset' | 'underline';
}
```

The box a field's widget draws: `FormFieldInfo.look`.

## AnnotationInfo

```ts
interface AnnotationInfo {
  pageIndex: number;
  id: string; // its name when the file names it, else derived from its object in the file; never ''
  type: AnnotationType;
  rect: Rect | null;
  contents: string; // '' without the extract feature
  author: string; // '' without the extract feature
  color: string | null; // '#rrggbb': a shape's stroke, a mark's or note's own color; null for none
  opacity: number; // 0–1
  fillColor: string | null; // a shape's fill, '#rrggbb'
  created: Date | null;
  modified: Date | null;
  quads: Quad[];
  inkList: Point[][];
  vertices: Point[]; // a polygon's or polyline's corners; empty for other kinds
  line: { start: Point; end: Point } | null;
  lineEndings: { start: LineEnding; end: LineEnding } | null; // a line's caps; null for other kinds
  strokeWidth: number | null; // a square's, circle's, line's, drawing's, polygon's or polyline's (pt); null for other kinds or none stated
  uri: string | null; // a web link's address; '' without the extract feature
  targetPage: number | null;
  flags: AnnotationFlags; // its flags as booleans
  inReplyTo: string | null; // a reply's or status's comment, by id
  status: ReviewStatus | null; // the status a status entry records
}
```

One annotation as `doc.annotations.list()`, `get()` and `comments()` report it. An `id` is the annotation's name — a UUID for one the SDK created — or `obj:<number>` for one the file carries without a name; it is what `update()`, `delete()`, `get()`, `reply()` and `setStatus()` take. Form fields appear as `type: 'widget'`; read and fill those through `doc.forms`. `color` is the color and `opacity` how opaque, each its own member: `null` means the annotation carries no color entry. Colors come out as lower-case `#rrggbb`.

## AnnotationType

```ts
type AnnotationType =
  // text marks — the selection bar's Highlight, Underline, Squiggly underline and Strikethrough; create() takes these
  | 'highlight' | 'underline' | 'squiggly' | 'strikeout'
  | 'note' | 'link' | 'square' | 'circle' | 'line' | 'ink' | 'polygon' | 'polyline' // and these
  | 'freeText' | 'stamp' | 'widget' | 'other'; // list() also reports these
```

The kinds `doc.annotations` names. `create()` takes the first twelve; `'freeText'`, `'stamp'`, `'widget'` (a form field) and `'other'` (a pop-up, among others) are reported by `list()` only — a stamp's or text box's picture is its appearance, which only its tool draws.

## NewAnnotation

```ts
interface NewAnnotation {
  type:
    | 'highlight' | 'underline' | 'squiggly' | 'strikeout'
    | 'note' | 'link' | 'square' | 'circle' | 'line' | 'ink' | 'polygon' | 'polyline';
  rect: Rect;
  contents?: string;
  author?: string;
  color?: string | null; // any CSS color string the API takes; its alpha is the opacity unless opacity is given
  opacity?: number; // 0–1
  fillColor?: string | null; // a square's, circle's or polygon's fill; drawn at opacity
  quads?: Quad[]; // a text mark's lines; omitted, it covers rect
  line?: { start: Point; end: Point };
  inkList?: Point[][];
  vertices?: Point[]; // a polygon's corners, three or more; a polyline's, two or more
  strokeWidth?: number | null; // up to 14 400 pt; 0: no outline on a square, circle or polygon; omitted: 1
  lineEndings?: { start?: LineEnding; end?: LineEnding } | null; // a line's; omitted: 'none'
  borderStyle?: BorderStyle | null; // a shape's outline; omitted: 'solid'; 'cloudy' on a square, circle or polygon only
  uri?: string;
  targetPage?: number;
  id?: string; // your own, written as its name and saved for every reader; at most 256 chars, no control chars, unused in the document
  flags?: Partial<AnnotationFlags>; // a flag left out is off; it prints unless noPrint
  created?: Date; // omitted: now
  modified?: Date; // omitted: the same as created
}
```

What `doc.annotations.create(pageIndex, annotation, options?)` takes. A text mark covers `quads` (omitted or empty: its `rect`); a `line` needs `line`, an `ink` needs `inkList`, a `polygon` needs `vertices` (three or more corners), a `polyline` too (two or more). A shape with no `color` is drawn in `#18181B`. A link goes to `uri` — `http:`, `https:`, `mailto:` or `tel:`; a bare address gets `https://` — or to `targetPage`. What `list()` reports, `create()` takes back, so text marks, notes, links and shapes copy between documents.

## AnnotationUpdate

```ts
interface AnnotationUpdate { rect?: Rect; contents?: string; author?: string; color?: string; fillColor?: string; opacity?: number }
```

What `doc.annotations.update(id, changes, options?)` changes. `fillColor` is a square's, circle's or polygon's, refused on anything else; `color` is refused on a `freeText`, whose color is its words' and is set when it is written; a `color` with no alpha changes the color alone, one with an alpha, or an `opacity` beside it, sets the opacity too; `null` is refused, a color entry cannot be removed. A new `rect` moves and scales what the annotation draws with it; a stamp's or text box's own picture is fitted to it.

## AnnotationFlags

An annotation's flags, each a boolean: `hidden` (not shown and not printed), `noView` (not shown on screen; may still print), `noPrint` (left out when the page is printed — off by default: the SDK writes new annotations printable), `locked` (cannot be moved, resized or deleted by a reader's tools; its contents may still change), `lockedContents` (its contents cannot be changed by a reader's tools; it may still be moved), `readOnly` (takes no interaction at all), `noRotate` (keeps its orientation when the page is turned), `noZoom` (keeps its size when the page is zoomed). What `AnnotationInfo.flags` holds, and what `NewAnnotation.flags` takes in part. The tools honor an annotation's flags; the API does not.

## CommentThread

```ts
interface CommentThread {
  comment: AnnotationInfo; // the note, highlight, shape or stamp commented on
  replies: AnnotationInfo[]; // replies to replies included, oldest first
  statuses: AnnotationInfo[]; // each reviewer's latest status entry, oldest first
  status: ReviewStatus | null; // the latest any reviewer set
}
```

One comment with its thread, as `doc.annotations.comments(pageIndex?)` reports it: each markup annotation with its replies, its reviewers' latest statuses and the latest status. Links, form fields, pop-ups and hidden comments are left out. Contents and authors are blank as `list()` blanks them.

## NewReply

```ts
interface NewReply { contents: string; author?: string }
```

What `doc.annotations.reply(id, reply, options?)` writes under a comment. `contents` must not be empty (`INVALID_ARGUMENT`).

## StatusOptions

What `doc.annotations.setStatus(id, status, options?)` takes beside the status: `author` (the reviewer, written as the status's author; omitted, `''`) and `invalidateSignatures` from [SignedDocumentOptions](https://kernstra.com/docs/web-sdk/api/types#ty-signeddocumentoptions), to go ahead on a certified document whose certification forbids it.

## ReviewStatus

```ts
type ReviewStatus = 'accepted' | 'rejected' | 'cancelled' | 'completed' | 'none'
```

A reviewer's status on a comment: what `doc.annotations.setStatus()` takes (`'none'` clears theirs) and what `CommentThread.status` and a status entry's `AnnotationInfo.status` hold. The exported `REVIEW_STATUSES` lists them in the order the panel's menu offers them.

## CommentPermissions

```ts
interface CommentPermissions {
  reply: boolean; // Write a reply under it
  setStatus: boolean; // Set their review status on it
  edit: boolean; // Change its words
  delete: boolean; // Delete it, with its thread
}
```

What the user may do to one comment by the panel's rules (Acrobat's), as `viewer.commentPermissions(id)` resolves it; `null` when no comment has that id.

## CommentChange

```ts
interface CommentChange {
  type: 'added' | 'edited' | 'deleted' | 'replied' | 'status';
  id: string; // the comment's id, as doc.annotations addresses it
}
```

One change to a comment, as `commentsChanged` reports it. `added` / `deleted`: a comment came or went (with its thread). `edited`: its words, author, color or flags changed, or a reply was edited or removed. `replied`: it got a reply. `status`: a reviewer set a status.

## AnnotationChange

```ts
interface AnnotationChange {
  type: 'added' | 'modified' | 'deleted';
  id: string; // the annotation's id, as doc.annotations addresses it
}
```

One change to a page's annotations, as `annotationsChanged` reports it. `added` / `deleted`: an annotation came or went. `modified`: it was moved, resized, recolored, restyled, reworded or dated. A reply and a review status are annotations of their own, reported `added`.

## TextChange

```ts
interface TextChange {
  pageIndex: number;
  blockId: string; // the id the block had in the session that ended, as listBlocks() listed it then
  kind: 'text' | 'style' | 'box' | 'deleted';
  oldText: string; // the block's text as the session found it, its lines joined by one space
  newText: string; // as the commit left it; the same as oldText for 'style' or 'box', empty for 'deleted'
}
```

One block Edit Text wrote at a commit, as `textChanged` reports it. `kind` says what changed: the words (`'text'`, whatever changed with them), the font, size, weight, slant or color alone (`'style'`), the box alone — a resize or a move (`'box'`) — or the block was removed (`'deleted'`). The blocks are detected afresh after a commit, so `blockId` names the block for a log, not for a later call. Both texts are empty under a license without `extract`.

## DocumentChangeSource

```ts
type DocumentChangeSource = 'tool' | 'pages' | 'outline' | 'attachments' | 'comments' | 'forms' | 'api' | 'undo' | 'redo'
```

What changed the document, as `documentChanged` reports it: `'tool'` a tool writing what the user did with it (the event names the tool); `'pages'` a page turned, moved, added or deleted; `'outline'`, `'attachments'` and `'comments'` a bookmark, attachment or comment edited; `'forms'` a field filled in, signed or set by `doc.forms.setValues()`; `'api'` a change made through the document API (the Security tool's protect and unprotect included); `'undo'` and `'redo'` the history.

## XFDFExportOptions

What `doc.annotations.exportXFDF(options?)` writes: `annotations` (default `true`: text marks, notes, shapes, drawings, polygons, free text, stamps by name and box, replies and review statuses), `fields` (default `true`: the form fields' values as `doc.forms.getValues()` reads them), `links` (default `false`: a link has no name in most files and would be duplicated by a re-import), `pages` (zero-based; omitted, every page), `href` (the `<f href>` file name Acrobat shows; omitted, no `<f>` element).

## XFDFImportOptions

How `doc.annotations.importXFDF(xml, options?)` applies a file: `mode` — `'merge'` (default: an entry whose `name` the document already has replaces that annotation in place, keeping the replies in the document the file does not bring back, and every other entry is added) or `'replace'` (every annotation the file could describe is removed first, so the document ends up with the file's alone; stamps, links and form fields stay); `annotations` and `fields` (default `true`) switch each half off; `invalidateSignatures` from [SignedDocumentOptions](https://kernstra.com/docs/web-sdk/api/types#ty-signeddocumentoptions).

## XFDFImportResult

What `doc.annotations.importXFDF()` resolves to: `imported` (the ids of the annotations added, in the file's order), `replaced` (the ids the file replaced under `mode: 'merge'`), `skipped` (every entry not applied, as [XFDFSkipped](https://kernstra.com/docs/web-sdk/api/types#ty-xfdfskipped)) and `fields` (what `doc.forms.setValues()` reported for the `<fields>`, or `null` when the file has none or `fields` was `false`).

## XFDFSkipped

An entry of an XFDF file that `importXFDF()` did not apply: its `element` (`stamp`, `text`, `caret` …), `page` and `name` (each `null` when the entry has none), a `reason` ([XFDFSkipReason](https://kernstra.com/docs/web-sdk/api/types#ty-xfdfskipreason)) and an English `message` for a log.

## XFDFSkipReason

```ts
type XFDFSkipReason = 'unsupported' | 'no_page' | 'invalid' | 'no_parent'
```

Why an entry of the file was not applied: `unsupported` — a stamp, caret, attachment, sound or redaction, a state that is not a review status, an unknown element; `no_page` — its page is missing or not a page of this document; `invalid` — missing geometry or a refused value, or a name that belongs to a form field, link or pop-up; `no_parent` — a reply to nothing.

## BorderStyle

```ts
type BorderStyle = 'solid' | 'dashed' | 'dotted' | 'cloudy'; // a cloud goes only round a rectangle, ellipse or polygon
```

A shape's outline: what `NewAnnotation.borderStyle` takes and what [`annotations.borderStyles`](https://kernstra.com/docs/web-sdk/config/annotations/borderstyles) offers in the drawing bar's Style picker. `dashed` or `dotted` is a pattern sized to the stroke; `cloudy` goes round a square, circle or polygon only (an open shape asked for it is drawn solid).

## LineEnding

```ts
type LineEnding = 'none' | 'square' | 'circle' | 'diamond' | 'openArrow' | 'closedArrow'
  | 'butt' | 'rOpenArrow' | 'rClosedArrow' | 'slash';
```

A line's cap: what `NewAnnotation.lineEndings` takes (ignored on anything but a line; `lineEndings: { end: 'openArrow' }` is the Arrow tool's arrow) and what [`annotations.lineEndings`](https://kernstra.com/docs/web-sdk/config/annotations/lineendings) offers in the Line and Arrow tools' Ends picker.

## SearchOptions

How `doc.text.search(query, options?)` matches: `matchCase` and `matchWholeWord` (both default to `false`), `pages` (zero-based; restrict the search), `limit` (stop after N matches).

## SearchMatch

```ts
interface SearchMatch { pageIndex: number; text: string; rects: Rect[] }
```

One match from `doc.text.search()`. `rects` are the rectangles it covers, in page space; a match broken across lines has one rectangle per line, which is why it is not a single box.

## DocumentPermissions

```ts
interface DocumentPermissions { // all optional in protect(); all present in permissions
  print?: boolean;
  printHighQuality?: boolean;
  modify?: boolean;
  copy?: boolean;
  annotate?: boolean;
  fillForms?: boolean;
  extractForAccessibility?: boolean;
  assemble?: boolean;
}
```

What a document allows: every entry present in `doc.security.permissions`, every one optional in `ProtectionSettings.permissions`, where permissions you do not mention stay **allowed**. High-quality printing is a degree of printing: `print: false` denies `printHighQuality` too.

## ProtectionSettings

```ts
interface ProtectionSettings { userPassword?: string; ownerPassword?: string; permissions?: DocumentPermissions; invalidateSignatures?: boolean }
```

What `doc.security.protect(settings)` encrypts with (AES-256). `INVALID_ARGUMENT` with no password at all, or when it restricts anything without an `ownerPassword` that differs from `userPassword`; a signed document is refused with `INVALID_STATE` unless `invalidateSignatures`.

## OutlineNode

```ts
interface OutlineNode {
  title: string;
  pageIndex: number | null; // null when the bookmark has no page (it only groups children)
  children: OutlineNode[];
}
```

One bookmark of the tree `doc.outline.get()` resolves to and `set()` takes. A bookmark is addressed by its path — the indices that lead to it in this tree (`[0]` the first top-level bookmark, `[0, 2]` its third child). Without the `extract` feature every title is `''`.

## AddBookmarkOptions

What `doc.outline.add(title, pageIndex, options?)` takes beside the title and the page: `parentPath` (the bookmark to put the new one under, as a path into `get()`; top level when omitted or empty) and `invalidateSignatures` from [SignedDocumentOptions](https://kernstra.com/docs/web-sdk/api/types#ty-signeddocumentoptions).

## AttachmentInfo

```ts
interface AttachmentInfo {
  index: number; // pass to doc.attachments.data / delete
  name: string; // as stored in the file: untrusted input
  size: number; // bytes; 0 when the entry has no file stream
}
```

One embedded file as `doc.attachments.list()` reports it. `index` is its position in the attachment table, kept in name order, so read the list again after an `add` or a `delete`. Without the `extract` feature every name is `''`.

## SignatureInfo

```ts
interface SignatureInfo {
  index: number;
  reason: string; // '' when absent
  signedAt: Date | null; // when it was signed, as the signature says; null when it does not
  subFilter: string; // the signature's format as the file names it ('adbe.pkcs7.detached', …), or ''
  changesAllowed: SignatureChangesAllowed | null; // what the signer allowed afterwards; null when unsaid
  signed: boolean; // whether it holds signature bytes, or is a field still to be signed
}
```

One signature's metadata as `doc.signatures.list()` reports it. **Metadata only**: the SDK does not validate a signature cryptographically — present it as "the document declares a signature", never as "the signature is valid". Without the `extract` feature each `reason` is `''`.

## SignatureChangesAllowed

```ts
type SignatureChangesAllowed = 'none' | 'forms' | 'annotations'
```

What a certification signature allows after signing (its certification level), as `SignatureInfo.changesAllowed`: `'none'`, `'forms'` (filling and signing) or `'annotations'` (those and comments). The SDK enforces it as Acrobat does: a write the level forbids rejects with `INVALID_STATE` unless the call passes `invalidateSignatures: true`. See [Digital signatures](https://kernstra.com/docs/web-sdk/guides/document-features).

## SignedDocumentOptions

```ts
interface SignedDocumentOptions {
  invalidateSignatures?: boolean; // Go ahead although the signature would not survive it
}
```

What a method takes to go ahead on a signed document when the signature would not survive it. Refused by default: a call that writes the file anew (protecting, flattening) would leave every signature no longer verifying, and a change a certification signature forbids would break the certification — Acrobat refuses both. `true` does it anyway: every reader then reports the signatures broken, and once said, nothing is asked again this session. The options of `doc.pages`, `doc.annotations`, `doc.outline` and `doc.attachments` writes extend it.

## PageBoxes

```ts
interface PageBoxes { // every box a Rect in page space, resolved as a reader resolves it
  mediaBox: Rect; // the full sheet; US Letter when the file has none
  cropBox: Rect; // what renders; the MediaBox when the file declares none
  trimBox: Rect; // the CropBox when the file declares none
  bleedBox: Rect; // likewise
  artBox: Rect; // likewise
}
```

A page's boxes, as `doc.pages.boxes(pageIndex)` resolves them without loading the page.

## NewPageSize

The size of a new page for `doc.pages.insert()`, `{ width?, height? }` in PDF points (72 per inch). A4 by default.

## PagePosition

Where `doc.pages.insert()` and `doc.pages.import()` put a page: `{ after }` or `{ before }`, each a zero-based index. Omit both to append at the end.

## PageTurn

```ts
type PageTurn = 90 | 180 | 270 | -90 | -180 | -270
```

How far a page turns in one `doc.pages.rotate(pageIndex, by)`: clockwise degrees from where it stands, negative for counter-clockwise. `INVALID_ARGUMENT` for `0` or anything but a multiple of 90.

## PageOrientation

```ts
type PageOrientation = 0 | 90 | 180 | 270
```

A page's rotation as the file holds it, in clockwise degrees: what `doc.pages.getRotation()` answers and `doc.pages.setRotation()` sets outright.

## InsertPageOptions

What `doc.pages.insert(options?)` takes: `position` (a [PagePosition](https://kernstra.com/docs/web-sdk/api/types#ty-pageposition); omit to append), `size` (a [NewPageSize](https://kernstra.com/docs/web-sdk/api/types#ty-newpagesize); default A4) and `invalidateSignatures` from [SignedDocumentOptions](https://kernstra.com/docs/web-sdk/api/types#ty-signeddocumentoptions).

## ImportPagesOptions

What `doc.pages.import(bytes, options?)` takes beside the bytes: `position` (a [PagePosition](https://kernstra.com/docs/web-sdk/api/types#ty-pageposition); appended when omitted), `password` (the source's password, if it is encrypted) and `invalidateSignatures` from [SignedDocumentOptions](https://kernstra.com/docs/web-sdk/api/types#ty-signeddocumentoptions).

## EditableTextBlock

```ts
interface EditableTextBlock {
  id: string; // stable within one detection pass
  pageIndex: number;
  text: string; // including an uncommitted edit
  bounds: Rect; // in page space — see Coordinates
  fontFamily: string; // as named in the PDF
  fontSize: number; // points
  fontWeight: number; // 100–900
  isItalic: boolean;
  fillColor: string; // '#rrggbb'
  opacity: number; // 0–1
}
```

One editable text block as `viewer.tools.editText.listBlocks(pageIndex)` reports it. Ids are only stable within one detection pass: treat every block id from before a commit as stale. `text` is `''` under a license without `extract`.

## ExportOptions

```ts
interface ExportOptions {
  flatten?: boolean; // Override the configured flatten behavior for this export
  invalidateSignatures?: boolean; // Flatten a signed document anyway; the signature reads as broken afterwards
  pages?: number[]; // Only these pages (zero-based, in this order)
  onProgress?: (done: number, total: number) => void; // Called per page while the export prepares pages
  signal?: AbortSignal; // Aborting cancels the export; it rejects with ABORTED
}
```

The options of `PDFExporter.download()`, `getBlob()`, `getArrayBuffer()` and `getBase64()`. A `flatten` left out comes from [Export](https://kernstra.com/docs/web-sdk/config/export). A page subset is a new document and never carries a signature, so it is not refused; when `onProgress` is supplied the export yields to the event loop between pages so an indicator can paint.

## UploadOptions

```ts
interface UploadOptions extends ExportOptions {
  method?: string; // HTTP method. Default: 'PUT'
  headers?: Record<string, string>; // Content-Type: application/pdf unless these name one (any case)
  credentials?: RequestCredentials; // fetch()'s; 'same-origin' by default, 'include' for a cookie-authenticated endpoint on another origin
}
```

The options of `PDFExporter.uploadTo(url, options?)`: the same options as every export, and the request's `method`, `headers` and `credentials`; the `signal` cancels the upload too (`ABORTED`).

## DownloadResult

```ts
interface DownloadResult { sizeBytes: number; pdfA?: 'kept' | 'dropped' }
```

What `PDFExporter.download()` resolves to. `pdfA`, for a document that claims PDF/A (`doc.pdfA`): whether the file saved still claims it — `'kept'` for a document nobody changed, saved as the bytes it was opened from; `'dropped'` for a changed one, or a page range. Absent for a document that claims none.

## PrintOptions

The options of `viewer.print(options?)`: `pages` (zero-based; every page when omitted) and `annotations` (whether annotations are printed; `true` when omitted). Given, the viewer prints without asking; an empty `pages` list, or a page the document has not, rejects with `INVALID_ARGUMENT`.

## ToolName

```ts
type ToolName =
  | 'pan' // Pan/scroll mode
  | 'selectText' // Text selection mode
  | 'addText' // Click-to-place text
  | 'editText' // Inline edit existing PDF text
  | 'sign' // Electronic signature
  | 'arrow' // Arrow drawing
  | 'draw' // Freehand drawing
  | 'line' // Line drawing
  | 'rectangle' // Rectangle drawing
  | 'ellipse' // Ellipse drawing
  | 'polygon' // Polygon drawing
  | 'polyline' // Polyline drawing
  | 'check' // Check mark
  | 'cross' // Cross mark
  | 'dot' // Dot mark
  | 'erase' // Universal eraser (click to delete any object)
  | 'highlight' // Area highlight annotation
  | 'textHighlight' // Text selection highlight annotation
  | 'image' // Image insertion
  | 'stamp' // Stamp placement (APPROVED, DRAFT, etc.)
  | 'link' // URL or internal page link annotation
  | 'note' // Sticky note annotation
  | 'freeText' // Text box: a free-text comment
  | 'search' // Text search: a panel, not a tool
  | 'managePages' // Page management: a panel, not a tool
  | 'security'; // Password protection and permissions
```

Every name is a tool the SDK ships; the exported `TOOL_NAMES` array lists them all, in the toolbar's order. What `viewer.activateTool()`, `isToolEnabled()` and `toolBlockedReason()` take and `activeTool` and `toolChanged` report. Two of them are panels rather than tools: `activateTool('search')` and `activateTool('managePages')` open their panel and resolve, and `activeTool` stays what it was.

## ToolBlockedReason

```ts
interface ToolBlockedReason {
  reason: 'permission' | 'certified' | 'downloading';
  message: string; // the reason in words, in the viewer's language
}
```

Why the open document forbids a tool, as `viewer.toolBlockedReason(tool)` answers it (`null` when it allows it): `'permission'` (the document's permissions), `'certified'` (its certification) or `'downloading'` (it edits, and the document's bytes are still arriving). A host drawing its own chrome shows `message` and branches on `reason`.

## SidebarTab

```ts
type SidebarTab = 'pages' | 'outline' | 'attachments' | 'signatures' | 'comments'
```

The tabs the sidebar can hold, in rail order: what `viewer.openPanel()` takes and `viewer.activePanel` reports (`null` when the sidebar is collapsed).

## Point

```ts
interface Point { x: number; y: number }
```

A point in page space: PDF points (1/72 inch), the origin at the page's bottom-left corner, `y` growing upwards, unturned by the page's rotation. `viewer.pageToClient()` and `clientToPage()` convert to and from the viewer's CSS pixels.

## Size

```ts
interface Size { width: number; height: number }
```

A width and a height, in the units of what they measure: PDF points in page space, CSS pixels from `viewer.pageToClient()`.

## Rect

```ts
interface Rect extends Point, Size {} // its bottom-left corner and its size; width and height never negative
```

An annotation's `rect`, a form field's, a text block's `bounds`, a search match's `rects` and a page's boxes are all `Rect`s. A rect given to the API is checked: four finite numbers, width and height not negative, within ±14 400 points, or `INVALID_ARGUMENT`. In client space (`viewer.pageToClient()`) a `Rect` has its top-left corner as `x, y`, as the DOM measures.

## RectEdges

```ts
interface RectEdges { left: number; bottom: number; right: number; top: number } // how a PDF file stores a rectangle
```

A rectangle by its edges, for callers that think that way: `rectFromEdges(edges)` (whichever way round the edges are given) and `rectEdges(rect)` convert — see [Helpers](https://kernstra.com/docs/web-sdk/api/helpers).

## Quad

```ts
interface Quad { topLeft: Point; topRight: Point; bottomLeft: Point; bottomRight: Point } // one line a text mark covers
```

One line a text mark covers, its corners named as Acrobat writes them: an `AnnotationInfo.quads` entry, and what `NewAnnotation.quads` takes. `quadToRect(quad)` gives its bounds and `rectToQuad(rect)` the reverse — see [Helpers](https://kernstra.com/docs/web-sdk/api/helpers).

## ColorOption

```ts
interface ColorOption {
  color: string; // '#rgb' or '#rrggbb'; stored and written as '#RRGGBB'
  label: string; // What the color is called: tooltip and screen-reader name. Empty: the hex
}
```

A named color in a palette. The configuration's palettes are stored upper-case (`#RRGGBB`) and the API answers lower-case: compare case-insensitively.

## ColorList

```ts
type ColorList = readonly (string | ColorOption)[]
```

A palette: hex strings, or [ColorOption](https://kernstra.com/docs/web-sdk/api/types#ty-coloroption)s with a label. What [`annotations.palette`](https://kernstra.com/docs/web-sdk/config/annotations/palette), `highlightColors`, `noteColors`, [`tools.sign.inks`](https://kernstra.com/docs/web-sdk/config/tools/sign-inks) and [`tools.stamp.inks`](https://kernstra.com/docs/web-sdk/config/tools/stamp-inks) take.

## SignatureFont

```ts
interface SignatureFont {
  family: string; // A CSS font-family value — load the face yourself (@font-face)
  label: string; // The name shown beside the preview
}
```

A face for the signature dialog's Type tab: what [`tools.sign.fonts`](https://kernstra.com/docs/web-sdk/config/tools/sign-fonts) takes and the exported `SIGNATURE_FONTS` lists.

## SavedSignature

```ts
interface SavedSignature {
  dataUrl: string; // The signature, as a PNG data URL
  initialsDataUrl?: string | null; // The initials, as a PNG data URL, when the user typed them
  name?: string; // The typed name, for labeling the row; empty for a drawn or uploaded one
  method: 'draw' | 'type' | 'upload';
}
```

A signature the user keeps for reuse: plain JSON, what the `savedSignaturesChanged` event gives you and [`tools.sign.savedSignatures`](https://kernstra.com/docs/web-sdk/config/tools/sign-savedsignatures) takes back. See [Keeping saved signatures and stamps](https://kernstra.com/docs/web-sdk/guides/replace).

## SavedStamp

```ts
type SavedStamp =
  | {
      kind: 'text';
      label: string; // The wording
      color: string; // '#RRGGBB'
      dated: boolean; // The placing date under the wording
      border: 'boxed' | 'ribbon' | 'plain';
    }
  | {
      kind: 'image';
      label: string;
      dataUrl: string; // The picture, as a PNG data URL
      widthPt: number; // Its size on the page, in points
      heightPt: number;
    };
```

A stamp the user made with "New stamp": plain JSON, what the `userStampsChanged` event gives you and [`tools.stamp.userStamps`](https://kernstra.com/docs/web-sdk/config/tools/stamp-userstamps) takes back.

## StampPreset

```ts
interface StampPreset {
  label: string; // The wording, written into the PDF as given — e.g. 'PAID', 'BEZAHLT'
  color?: string; // Hex ink. Default: the first of inks
  dated?: boolean; // Add the placing date under the wording. Default: false
  border?: 'boxed' | 'ribbon' | 'plain'; // Default: 'boxed'
}
```

A wording stamp of your own, for [`tools.stamp.presets`](https://kernstra.com/docs/web-sdk/config/tools/stamp-presets): the words are written into the document exactly as you give them.

## CustomFont

```ts
interface CustomFont {
  id: string; // Unique font identifier
  displayName: string; // Name shown in font picker
  ttfUrl?: string; // URL to TTF file (fetched on demand)
  ttfBytes?: Uint8Array; // Pre-loaded TTF bytes (skips fetch)
  category?: 'sans-serif' | 'serif' | 'monospace' | 'display'; // default 'sans-serif'
  cssFallback?: string; // CSS font-family stack for previews; default the display name, then sans-serif
}
```

Your own font: the same bag [`fonts.customFonts`](https://kernstra.com/docs/web-sdk/config/fonts/customfonts) takes and [`FontRegistry.registerCustomFont()`](https://kernstra.com/docs/web-sdk/api/fontregistry/registercustomfont) / `registerCustomFontUrl()` take.

## FontDefinition

```ts
interface FontDefinition {
  id: string;
  displayName: string;
  category: 'sans-serif' | 'serif' | 'monospace' | 'display';
  source: 'standard' | 'bundled' | 'custom';
  cssFallback: string; // CSS font-family stack for previews
  ttfPath?: string; // file name under fonts.fontsBaseUrl (self-hosting)
  ttfUrl?: string; // custom fonts
  ttfBytes?: Uint8Array; // custom fonts
}
```

One font of the catalog: what `BUILTIN_FONTS` lists and [`FontRegistry.getAll()`](https://kernstra.com/docs/web-sdk/api/fontregistry/getall) / `getDefinition(id)` return.

## ConfirmRequest

What [`callbacks.onConfirm`](https://kernstra.com/docs/web-sdk/config/callbacks/onconfirm) is asked: `action` (a [ConfirmableAction](https://kernstra.com/docs/web-sdk/api/types#ty-confirmableaction), the key in [Confirmations](https://kernstra.com/docs/web-sdk/config/confirmations)), and the words the SDK's own dialog would show, in the viewer's language — `title` ("Delete this page?"), `message` (one sentence under it), `confirmLabel` ("Delete", "Discard", "Remove", "Replace") and `cancelLabel` ("Cancel"); `count` (how many things the action takes: pages, a comment's replies, the bookmarks inside one) and `name` (what it is called: a bookmark, an attachment), each present only where the action has one. `name`, and so `message`, carry text from the document: show them as text (a text node, never HTML), as the SDK's dialog does.

## ConfirmableAction

```ts
type ConfirmableAction =
  | 'deleteTextBlock'
  | 'deletePages'
  | 'discardPageEdits'
  | 'deleteComment'
  | 'deleteBookmark'
  | 'deleteAnnotation'
  | 'removeAttachment'
  | 'replaceSignature';
```

An action the viewer asks about before doing it — the `action` of a [ConfirmRequest](https://kernstra.com/docs/web-sdk/api/types#ty-confirmrequest) and a key of [Confirmations](https://kernstra.com/docs/web-sdk/config/confirmations), which says what each one covers and whether it is on by default.

## ToolbarAction

```ts
interface ToolbarAction {
  id: string; // Your own name for the action; the SDK uses it only to name the action in an error report
  label: string; // Button text
  icon?: string; // An IconName, or raw SVG markup starting with <svg
  variant?: 'default' | 'primary'; // 'primary' = accent-colored
  onClick: () => void | Promise<void>;
}
```

Your own toolbar button, for [`toolbar.actions`](https://kernstra.com/docs/web-sdk/config/toolbar/actions). Give every action an icon: on a compact bar labels are hidden on all but `primary` actions, and on a narrow or tiny bar on every action. A rejected promise from `onClick` is logged and reported through the `error` event.

## ToolbarLayout

```ts
type ToolbarLayout = 'bar' | 'ribbon' | 'none' | 'rail'
```

Which toolbar to render, for [`toolbar.layout`](https://kernstra.com/docs/web-sdk/config/toolbar/layout): the bar, the ribbon, the rail, or none — each offering the same tools.

## IconName

```ts
type IconName = keyof typeof ICONS
```

The name of an icon the SDK draws, such as `'zoomIn'` or `'close'` — a key of [`toolbar.icons`](https://kernstra.com/docs/web-sdk/config/toolbar/icons) and of the exported `ICONS`; also what `ToolbarAction.icon` and the `icons` option of `createDropZone`, `createPasswordPrompt` and `createLoadError` take.

## UIStrings

```ts
type UIStrings = { readonly [K in UIStringKey]: string }
```

The string table: every key with its text. The exported `EN_STRINGS` is the English one; a translation for [`locale.strings`](https://kernstra.com/docs/web-sdk/config/locale/strings) or [`locale.translations`](https://kernstra.com/docs/web-sdk/config/locale/translations) is a `Partial<UIStrings>`, so a misspelt key is a compile error.

## UIStringKey

```ts
type UIStringKey = keyof typeof EN_STRINGS; // 'tool.highlight', 'download.title', …
```

One key of the string table.

## LayoutSize

```ts
type LayoutSize = 'comfortable' | 'compact' | 'narrow' | 'tiny'
```

A size class: what [`layout.size`](https://kernstra.com/docs/web-sdk/config/layout/size) pins and what the viewer otherwise assigns from the container width and [`layout.breakpoints`](https://kernstra.com/docs/web-sdk/config/layout/breakpoints).

## LayoutBreakpoints

Container widths (in CSS pixels) at which each size class takes over, for [`layout.breakpoints`](https://kernstra.com/docs/web-sdk/config/layout/breakpoints): `compact` (default 900), `narrow` (default 640), `tiny` (default 480). A container is assigned the smallest class whose threshold it falls at or below. On resolve each threshold is clamped so that `tiny <= narrow <= compact` holds; `ResolvedLayoutBreakpoints` is the filled-in shape.

## BarPosition

```ts
type BarPosition = 'top' | 'bottom'
```

Where a bar sits: [`layout.toolbarPosition`](https://kernstra.com/docs/web-sdk/config/layout/toolbarposition), `toolbarPositionCompact` and `navigationPosition`.

## ToolOverflowMode

```ts
type ToolOverflowMode = 'menu' | 'scroll'
```

What happens to tools that do not fit the bar: [`layout.toolOverflow`](https://kernstra.com/docs/web-sdk/config/layout/tooloverflow).

## PanelDisplayMode

```ts
type PanelDisplayMode = 'auto' | 'push' | 'overlay'
```

How the side panels open beside the document: [`layout.panels`](https://kernstra.com/docs/web-sdk/config/layout/panels).

## PointerKind

```ts
type PointerKind = 'fine' | 'coarse'
```

The pointer the layout assumes — a mouse, or a finger — for [`layout.pointer`](https://kernstra.com/docs/web-sdk/config/layout/pointer).

## PhoneLayout

```ts
type PhoneLayout = 'sheet' | 'dock' | 'split' | 'float' | 'none'
```

The tool chrome on a phone-sized container: [`layout.phone`](https://kernstra.com/docs/web-sdk/config/layout/phone).

## TabletLayout

```ts
type TabletLayout = 'rail' | 'none'
```

The tool chrome on a tablet-sized container: [`layout.tablet`](https://kernstra.com/docs/web-sdk/config/layout/tablet).

## TextEditSurface

```ts
type TextEditSurface = 'auto' | 'inline' | 'sheet'
```

Where text is edited on a small container: [`layout.textEditing`](https://kernstra.com/docs/web-sdk/config/layout/textediting).

## TextBlockDetection

```ts
type TextBlockDetection = 'rows' | 'paragraphs'
```

How the Edit Text tool groups a page's text into editable blocks, for [`tools.editText.blockDetection`](https://kernstra.com/docs/web-sdk/config/tools/edittext-blockdetection): `'paragraphs'` (the default, and recommended) — one block per paragraph: consecutive lines of one column that share leading and face, so a whole paragraph is selected, moved and reflowed as a unit; `'rows'` — one block per visual row, split where a gap reads as a column boundary, so a paragraph's lines are edited one at a time.

## DropZoneOptions

What [`createDropZone(container, options)`](https://kernstra.com/docs/web-sdk/api/helpers/createdropzone) takes: `onFile` (called with the chosen or dropped PDF), `onReject` (called when something other than a PDF was dropped), `title` (the heading; defaults to "Drop a PDF here"), `note` (the line under it; defaults to the privacy line), `action` (the button; defaults to "Choose a file"), `locale` (the viewer's `locale`, so the card speaks its language) and `icons` (the viewer's `toolbar.icons`).

## DropZone

```ts
interface DropZone {
  readonly element: HTMLElement;
  open: () => void; // Opens the file picker — wire it to Ctrl+O
  destroy: () => void;
}
```

The mounted drop zone, as `createDropZone()` returns it.

## PasswordPromptOptions

What [`createPasswordPrompt(container, options)`](https://kernstra.com/docs/web-sdk/api/helpers/createpasswordprompt) takes: `onUnlock` (called with what was typed; resolve `true` to close, `false` for a wrong password — directly or as a promise; a wrong password shakes the field), `onCancel` (offered when there is somewhere else to go), `name` (the file's name, for the heading), `locale` (the viewer's `locale`) and `icons` (the viewer's `toolbar.icons`).

## PasswordPrompt

```ts
interface PasswordPrompt {
  readonly element: HTMLElement;
  destroy: () => void;
}
```

The mounted password prompt, as `createPasswordPrompt()` returns it.

## LoadErrorOptions

What [`createLoadError(container, options)`](https://kernstra.com/docs/web-sdk/api/helpers/createloaderror) takes: `error` (what went wrong: a known `SDKError` gets its own sentence, anything else a general one; the code is shown small under it and the error's own message is that line's tooltip), `onRetry` (offered as "Retry"), `onChooseAnother` (offered as "Try another file"), `locale` (the viewer's `locale`) and `icons` (the viewer's `toolbar.icons`).

## LoadErrorCard

```ts
interface LoadErrorCard {
  readonly element: HTMLElement;
  destroy: () => void;
}
```

The mounted error card, as `createLoadError()` returns it.
