Instant JSON

Instant JSON is our approach to bringing annotations and bookmarks into a modern format while keeping all important properties to make the Instant JSON spec work with PDF. It’s fully documented and supports long-term storage.

Instant JSON stores PDF changes like annotations and bookmarks in a separate JSON file. This means that a PDF document will only need to be transferred once and all changes will be added as an overlay to the existing PDF. This approach significantly reduces the bandwidth since you only need to transfer the JSON instead of the complete PDF.

Conceptually, Instant JSON defines a list of skippedPdfObjectIds. These point to the PDF’s internal object IDs for annotations. Whenever an object ID is marked as skipped, it’ll no longer be loaded from the original PDF. Instead, it could be defined inside the annotations array with the same pdfObjectId. If this is the case, the PDF viewer will display the new annotation, which signals an update to the original one. If an object ID is marked as skipped but the annotations array doesn’t contain an annotation with the same pdfObjectId, it’ll be interpreted as a deleted annotation. An annotation inside the annotations array without the pdfObjectId property is interpreted as a newly created annotation.

All annotations in the annotations array have a unique id field. For updated annotations that were in the original PDF, this field will be the stringified pdfObjectId. Newly created annotations will get a newly generated ULID.

An “empty” Instant JSON contains neither skippedPdfObjectIds nor annotations, which means the original PDF is untouched. All annotations in the initial PDF are still shown.

Instant JSON also defines a list of skippedPdfBookmarkIds that follow the same principals of skippedPdfObjectIds, but instead they contain a list of bookmarks that no longer need to be loaded from the original document.

The Format

We use Flow type declarations to specify the format of Instant JSON:

declare type InstantJSON = {
  format: "https://pspdfkit.com/instant-json/v1",
  skippedPdfObjectIds?: number[],
  annotations?: Object[],
  bookmarks?: Object[],
  skippedPdfBookmarkIds?: string[],
  formFieldValues?: Object[]
};

format

This is a literal string that includes the version information.

skippedPdfObjectIds

This is an array of PDF object IDs that will be ignored when importing annotations from the original PDF document. If this array is empty, the key shouldn’t be set.

annotations

This is a list of new or updated annotations. Annotations follow the format for Instant JSON for annotations. When an annotation contains a pdfObjectId, it’s considered to be an update to one of the annotations of the original PDF. For newly created annotations, this key won’t be set.

bookmarks

This is a list that contains any new bookmarks added to the PDF. Bookmarks follow the format for Instant JSON for bookmarks.

skippedPdfBookmarkIds

This is an array of bookmark object IDs from the PDF that will be ignored when importing annotations from the original PDF document. If this array is empty, the key shouldn’t be set.

formFieldValues

This is a list of modified form field values. Objects follow the Instant form field value JSON format. This list won’t be preset when no form field values have been modified.

Instant Document JSON API

Exporting Instant JSON

You can export the current annotations of a document as an Instant JSON file via a GET request to /api/documents/:document_id/document.json. To get the current annotation of a layer, send a GET request to /api/documents/:document_id/layers/:layer_name/document.json:

Request

GET /api/documents/:document_id/document.json
Authorization: Token token="<secret token>"
$ curl "http://localhost:5000/api/documents/abc/document.json" \
   -H "Authorization: Token token=<secret token>"

Response

HTTP/1.1 200 OK
Content-Type: application/json

<JSON data>

Importing Instant JSON

PSPDFKit Server supports importing annotations from an Instant JSON file when uploading a document via the /api/documents endpoint. Send a multipart/form-data POST request, including the PDF and the Instant JSON file, to import the annotations in the given PDF file. This will replace all existing annotations in the uploaded PDF with the annotations from the uploaded Instant JSON file. If you want to add annotations to already existing ones instead of replacing them, you can set keep_current_annotations to true:

Request

POST /api/documents
Content-Type: multipart/form-data; boundary=customboundary
Authorization: Token token="<secret token>"

--customboundary
Content-Disposition: form-data; name="file"; filename="Example Document.pdf"
Content-Type: application/pdf

<PDF data>
--customboundary
Content-Disposition: form-data; name="attachment"; filename="attachment.json"
Content-Type: application/json

<annotations data>
--customboundary

Importing Instant JSON on Existing Documents

PSPDFKit Server supports importing annotations from an Instant JSON file on an existing document via two different endpoints:

  • POST /pdf_with_instant_json receives an instant.json file and responds with the resulting PDF of the document/layer and the imported instant.json.

  • POST /copy_with_instant_json can optionally receive an instant.json file and will persist the resulting PDF of the document/layer and the imported instant.json file as a new document. The JSON response will include the document_id of the document.