JSON Format

Supported Annotations

The following annotation types are supported in PSPDFKit for Web:

  • pspdfkit/image
  • pspdfkit/ink
  • pspdfkit/link
  • pspdfkit/markup/highlight
  • pspdfkit/markup/squiggly
  • pspdfkit/markup/strikeout
  • pspdfkit/markup/underline
  • pspdfkit/note
  • pspdfkit/shape/ellipse
  • pspdfkit/shape/line
  • pspdfkit/shape/polygon
  • pspdfkit/shape/polyline
  • pspdfkit/shape/rectangle
  • pspdfkit/stamp
  • pspdfkit/text

Flow Types

We use Flow type declarations to specify the format of our annotations.

The optional keys are specified as follows:

1
{ optionalKey?: value; }

In order to save traffic, these keys should not be included in the record if the value is undefined.

Basic Properties

Basic Types

We define a number of low-level types that are used throughout all annotation types.

Geometry

Geometry always represents points inside a page. Rects are positioned at the top left point:

Copy
1
2
3
4
5
// [left, top, width, height] as a number in px.
declare type Rect = [number, number, number, number];

// [x, y] in px.
declare type Point = [number, number];

Other

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// "#RRGGBB"
declare type Color = string;

// 0.0 to 1.0.
declare type Opacity = number;

// 0.0 to 1.0; the default is 0.5.
declare type Intensity = number;

// ISO 8601 with full date, time, and time zone information.
// e.g. "2012-04-23T18:25:43.511Z"
// - https://en.wikipedia.org/wiki/ISO_8601
// - https://www.w3.org/TR/NOTE-datetime
declare type Timestamp = string;

declare type Lines = {
  // Intensities are used to weigh the point during natural
  // drawing. They are received by pressure-sensitive drawing
  // or touch devices. The default value should be used if
  // it's not possible to obtain the intensity.
  intensities: Array<Array<Intensity>>,

  // Points are grouped in segments. Points inside a segment
  // are joined to a line. There must be at least one segment
  // with at least one point.
  points: Array<Array<Point>>
};

declare type LineCap =
  | "square"
  | "circle"
  | "diamond"
  | "openArrow"
  | "closedArrow"
  | "butt"
  | "reverseOpenArrow"
  | "reverseClosedArrow"
  | "slash";

declare type LineCaps = {
  start?: LineCap,
  end?: LineCap
};

declare type BlendMode =
  | "normal"
  | "multiply"
  | "screen"
  | "overlay"
  | "darken"
  | "lighten"
  | "colorDodge"
  | "colorBurn"
  | "hardLight"
  | "softLight"
  | "difference"
  | "exclusion";

Action Types

PSPDFKit for Web only supports a subset of all possible annotation actions. Currently, these can be triggered when clicking on a link annotation:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
declare type BaseAction = {
  subAction?: Action
};

declare type GoToAction = BaseAction & {
  type: "goTo",
  // The pageIndex you want to go to.
  pageIndex: number
};

declare type GoToRemoteAction = BaseAction & {
  type: "goToRemote",
  relativePath: string,
  namedDestination: string
};

declare type GoToEmbeddedAction = BaseAction & {
  type: "goToEmbedded",
  newWindow: boolean,
  relativePath: string,
  targetType: "parent" | "child"
};

declare type LaunchAction = BaseAction & {
  type: "launch",
  filePath: string
};

declare type URIAction = BaseAction & {
  type: "uri",
  // URI, e.g.: `https://pspdfkit.com`
  uri: string
};

declare type AnnotationReference = {
  fieldName?: string,
  pdfObjectId?: number
};

declare type HideAction = BaseAction & {
  type: "hide",
  hide: boolean,
  annotationReferences: Array<AnnotationReference>
};

declare type JavaScriptAction = BaseAction & {
  type: "javaScript",
  script: string
};

declare type SubmitFormFlags = Array<
  | "includeExclude"
  | "includeNoValueFields"
  | "exportFormat"
  | "getMethod"
  | "submitCoordinated"
  | "xfdf"
  | "includeAppendSaves"
  | "includeAnnotations"
  | "submitPDF"
  | "canonicalFormat"
  | "excludeNonUserAnnotations"
  | "excludeFKey"
  | "embedForm"
>;

declare type SubmitFormAction = BaseAction & {
  type: "submitForm",
  uri: string,
  flags: SubmitFormFlags,
  fields?: Array<AnnotationReference>
};

declare type ResetFormAction = BaseAction & {
  type: "resetForm",
  flags?: "includeExclude",
  fields?: Array<AnnotationReference>
};

declare type NamedAction = BaseAction & {
  type: "named",
  action:
    | "nextPage"
    | "prevPage"
    | "firstPage"
    | "lastPage"
    | "goBack"
    | "goForward"
    | "goToPage"
    | "find"
    | "print"
    | "outline"
    | "search"
    | "brightness"
    | "zoomIn"
    | "zoomOut"
    | "saveAs"
    | "info"
};

declare type Action =
  | GoToAction
  | GoToRemoteAction
  | GoToEmbeddedAction
  | LaunchAction
  | URIAction
  | HideAction
  | JavaScriptAction
  | SubmitFormAction
  | ResetFormAction
  | NamedAction;

Base Annotation Type

Every annotation shares a set of common values, which are formalized in the BaseAnnotation type. You will later see all annotations extend this type using type intersection.

This means that a specific annotation needs to have all the properties of BaseAnnotation and all the properties of its specific annotation type:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// See the PDF Reference for the below flags. One difference: Instead of a
// `print` flag, like in PDF, we have `noPrint` so that we don't have
// `print` enabled on almost all annotations.
declare type Flags = Array<"noPrint" | "noZoom" | "noRotate" | "noView">

declare type BaseAnnotation = {
  // The spec version that the record is compliant to. Always `1`.
  v: 1,
  // An annotation must always be inside a specific page.
  pageIndex: number,
  // The bounding box of the annotation within the page.
  bbox: Rect,
  // Modifies the transparency of the annotation.
  opacity: Opacity,
  // The object ID from the source PDF.
  pdfObjectId?: number;
  // PDF Flags
  flags?: Flags;
  // Optional PDF Action.
  action?: Action;
  // The name of the creator of the annotation.
  creatorName?: string,
  // The date of the annotation creation.
  createdAt: Timestamp,
  // The date of the last annotation update.
  updatedAt: Timestamp
  // Optional annotation name. This is used to identify the annotation.
  name?: string;
};

declare type Annotation =
  | MarkupAnnotation
  | TextAnnotation
  | NoteAnnotation
  | EllipseAnnotation
  | RectangleAnnotation
  | LineAnnotation
  | PolylineAnnotation
  | InkAnnotation
  | LinkAnnotation
  | ImageAnnotation;

pspdfkit/markup/{highlight, squiggly, strikeout, underline}

Markup annotations include highlight, squiggly, strikeout, and underline. All of these require a list of rects that they are drawn to. The highlight annotation will lay the color on top of the element and apply the multiply blend mode.

Markup annotations
Copy
1
2
3
4
5
6
7
8
9
10
11
12
declare type MarkupAnnotation = BaseAnnotation & {
  type:
    | "pspdfkit/markup/highlight"
    | "pspdfkit/markup/squiggly"
    | "pspdfkit/markup/strikeout"
    | "pspdfkit/markup/underline",
  // List of rects on the page where the markup is drawn.
  rects: Array<Rect>,
  blendMode?: BlendMode,
  color: Color,
  node?: string
};

pspdfkit/stamp

A stamp annotation represents a stamp in a PDF. The image of the stamp depends upon the stampType, which can be one of the following:

  • Accepted
  • Approved
  • AsIs
  • Completed
  • Confidential
  • Departmental
  • Draft
  • Experimental
  • Expired
  • Final
  • ForComment
  • ForPublicRelease
  • InformationOnly
  • InitialHere
  • NotApproved
  • NotForPublicRelease
  • PreliminaryResults
  • Rejected
  • Revised
  • SignHere
  • Sold
  • TopSecret
  • Void
  • Witness
  • Custom

If the stampType is set to Custom, the title, subtitle, and color will define the appearance of the stamp annotation.

Stamp Annotations
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
declare type StampAnnotation = BaseAnnotation & {
  type: "pspdfkit/stamp",
  stampType:
    | "Accepted"
    | "Approved"
    | "AsIs"
    | "Completed"
    | "Confidential"
    | "Departmental"
    | "Draft"
    | "Experimental"
    | "Expired"
    | "Final"
    | "ForComment"
    | "ForPublicRelease"
    | "InformationOnly"
    | "InitialHere"
    | "NotApproved"
    | "NotForPublicRelease"
    | "PreliminaryResults"
    | "Rejected"
    | "Revised"
    | "SignHere"
    | "Sold"
    | "TopSecret"
    | "Void"
    | "Witness"
    // Not a standard stamp. Displays arbitrary text in the title and subtitle.
    | "Custom",
  title?: string,
  subtitle?: string,
  color?: Color,
  note?: string
};

pspdfkit/text

A text annotation can be placed anywhere on the screen. Please keep in mind that fonts are client specific, so you should only use fonts you know are present in the browser where they should be displayed. If a font is not found, PSPDFKit will automatically fall back to a sans-serif font.

Text annotations
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
declare type TextAnnotation = BaseAnnotation & {
  type: "pspdfkit/text",
  // The text contents.
  text: string,
  // A background that will fill the bounding box.
  backgroundColor?: Color,
  // Size of the text in px (this will scale when you zoom in).
  fontSize: number,
  // The font to render the text. A client will fall back to a sans-serif font
  // if it is not supported or if none is defined.
  font?: string,
  // A text can be only italic, only bold, italic and bold, or none of these.
  fontStyle?: Array<"italic" | "bold">,
  // The color of the rendered glyphs.
  fontColor: Color,
  horizontalAlign: "left" | "center" | "right",
  verticalAlign: "top" | "center" | "bottom",
  // Specifies that the text is supposed to fit in the bounding box.
  // This will only be set on new annotations, as we can't easily figure
  // out if an appearance stream contains all the text for existing annotations.
  isFitting?: boolean
};

pspdfkit/ink

Ink annotations are used for freehand drawings on a page. They can contain multiple segments (see the definition of Lines above). Points within a segment are connected to a line.

Ink annotations
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
declare type InkAnnotation = BaseAnnotation & {
  type: "pspdfkit/ink",
  // Refer to the above spec for the `Lines` type.
  lines: Lines,
  // The width of the line in px.
  lineWidth: number,
  // PSPDFKit's natural drawing mode. This value is only used by PSPDFKit
  // for iOS.
  isDrawnNaturally: boolean,
  // True if the annotation is an ink signature.
  isSignature?: boolean,
  // The color of the line.
  strokeColor: Color,
  // The color that fills the bounding box.
  backgroundColor?: Color,
  blendMode?: BlendMode,
  note?: string
};

pspdfkit/link

A link can be used to trigger an action when clicked. The link will be drawn on the bounding box.

Link annotations
Copy
1
2
3
4
5
6
declare type LinkAnnotation = BaseAnnotation & {
  type: "pspdfkit/link",
  // Refer to the above spec for the `Action` type.
  action: Action,
  note?: string
};

pspdfkit/note

Note annotations are “sticky notes” attached to a point in the PDF document. They are represented as markers, and each one has an icon associated with it. Its text content is revealed on selection.

Note annotations
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
declare type NoteAnnotation = BaseAnnotation & {
  type: "pspdfkit/note",
  text: string,
  icon:
    | "comment"
    | "rightPointer"
    | "rightArrow"
    | "check"
    | "circle"
    | "cross"
    | "insert"
    | "newParagraph"
    | "note"
    | "paragraph"
    | "help"
    | "star"
    | "key",
  // Fills the note shape and its icon [canvas].
  color: Color
};

Shape Annotations

Shape annotations are used to draw different shapes — lines, rectangles, ellipses, polylines, and polygons — on a page.

Shape annotations with transparent fill color are only selectable around their visible lines. This means you can create a page full of shape annotations while annotations behind these shape annotations are still selectable:

Copy
1
2
3
4
5
6
declare type ShapeAnnotation = BaseAnnotation & {
  strokeDashArray?: Array<number>,
  strokeWidth: number,
  strokeColor: Color,
  note?: string
};

pspdfkit/shape/ellipse

Ellipse annotations are used to draw ellipses on a page.

Ellipse shape annotations
Copy
1
2
3
4
5
declare type EllipseAnnotation = ShapeAnnotation & {
  type: "pspdfkit/shape/ellipse",
  // Fills the inside of the shape.
  fillColor?: Color
};

pspdfkit/shape/rectangle

Rectangle annotations are used to draw rectangles on a page.

Rectangle shape annotations
Copy
1
2
3
4
5
declare type RectangleAnnotation = ShapeAnnotation & {
  type: "pspdfkit/shape/rectangle",
  // Fills the inside of the shape.
  fillColor?: Color
};

pspdfkit/shape/line

Line annotations are used to draw straight lines on a page.

Line shape annotations
Copy
1
2
3
4
5
6
7
8
declare type LineAnnotation = ShapeAnnotation & {
  type: "pspdfkit/shape/line",
  startPoint: Point,
  endPoint: Point,
  lineCaps?: LineCaps,
  // Fills the inside of the end/start caps.
  fillColor?: Color
};

pspdfkit/shape/polyline

Polyline annotations are used to draw polylines on a page by hand. They can contain any number of sides, which are defined by the polyline vertices.

Polyline shape annotations
Copy
1
2
3
4
5
6
7
declare type PolylineAnnotation = ShapeAnnotation & {
  type: "pspdfkit/shape/polyline",
  // Fills the inside of the line caps.
  fillColor?: Color,
  lineCaps?: LineCaps,
  points: Array<Point>
};

pspdfkit/shape/polygon

Polygon annotations are used to draw polygons on a page by hand. They can contain any number of sides, which are defined by the polygon vertices.

Polygon shape annotations
Copy
1
2
3
4
5
6
declare type PolygonAnnotation = ShapeAnnotation & {
  type: "pspdfkit/shape/polygon",
  // Fills the inside of a closed polygon.
  fillColor?: Color,
  points: Array<Point>
};

pspdfkit/image

Image annotations are used to annotate a PDF with images.

Image annotation
Copy
1
2
3
4
5
6
7
8
9
10
11
declare type ImageAnnotation = BaseAnnotation & {
  type: "pspdfkit/image",
  // A description of the image, e.g. "PSPDFKit Logo."
  description?: string,
  // Only if one can be retrieved.
  fileName?: string,
  contentType?: "image/jpeg" | "image/png" | "application/pdf",
  // Either the SHA256 hash of the attachment or the `pdfObjectId` of the attachment.
  imageAttachmentId?: string,
  note?: string
};

Attachments

Attachments were added to support syncing annotation attachments across different devices. The keys in attachments are the calculated SHA256 hashes of the attachment or the pdfObjectId of the attachment. The binary of the attachment is Base64 encoded.

1
2
3
4
5
declare type Attachments = {
  [string]: {
    binary: string
  }
};

Form Field Values

Form field values were added as new Instant types in order to sync form field values across different devices. The name of a form field value must always be the fully qualified name of a PDF form field:

Copy
1
2
3
4
5
6
7
declare type FormFieldValue = {
  v: 1,
  type: "pspdfkit/form-field-value",
  name: string,
  // Multiple values are allowed for combo boxes, list boxes, and checkboxes.
  value?: string | Array<string>
};

Bookmarks

Bookmarks provide a way to mark actions. Optionally, a bookmark can have a name, in which case clients will show the name of the bookmark in their bookmarks toolbar.

The data is structured in the following way:

  • v — The version of the bookmark specification.
  • pdfBookmarkId — The ID under which the bookmark will be stored in the PDF.
  • type — The type of the entry. For bookmarks, this will always be "pspdfkit/bookmark".
  • name — The optional bookmark name. This is used to identify the bookmark.
  • action — The action that should be triggered when this bookmark is clicked. See action types for more information about this field.
1
2
3
4
5
6
7
declare type Bookmark = {
  v: 1,
  pdfBookmarkId?: string,
  type: "pspdfkit/bookmark",
  name?: string,
  action: Action
};