Instant Layers

Instant layers were introduced as a new concept in PSPDFKit Server and Web 2017.9. They are available in our mobile SDKs starting with PSPDFKit 7.6 for iOS and 4.6 for Android. To use Instant layers in PSPDFKit 7.6 for iOS, you need to run PSPDFKit Server 2018.3 or newer.

A layer provides an editing context for annotations on a document while the PDF file itself remains untouched. This allows you to share the same file across all layers with the same document identifier, thereby saving disk space and transfer time. As such, layers give you a convenient and efficient way to manage multiple versions of a document.


In Instant for iOS, we represent a layer using the InstantDocumentDescriptor protocol. Compared to earlier releases, the responsibilities and general semantics of that API remain untouched. However, the terms “document,” “document descriptor,” and “PDF file” are no longer used interchangeably. Instead:

  • A PDF file corresponds to the file for a certain document identifier.
  • There can be multiple layers for any document identifier, and each layer corresponds to exactly one document descriptor.
  • For display and editing purposes, you can obtain one or more Document instances (or short: documents) from a document descriptor.

ℹ️ Note: To further clarify the distinction between document and document descriptor, the old delegate methods in InstantClientDelegate have been deprecated. Their replacements now all explicitly refer to a document descriptor in their names.

Instant Layers in Practice

When you upload a new PDF file to PSPDFKit Server, the server assigns a document identifier to that file. All annotations in that file are extracted into an immutable base layer. You can create custom layers for a document identifier by issuing JSON Web Tokens (JWTs) that contain the desired name for the layer in the (optional) layer claim, where each layer is uniquely identified by the combination of document identifier and layer name. A new layer mirrors the content of the base layer until the first change is made to its content, which means that layers don’t have to be created manually, but rather they are created on demand once the first changes are synced.

If the layer claim is omitted in the JWT, the “default layer” for that document identifier is used. So if you are already using Instant, all your annotations will be in this default layer, and you can continue to use the default layer without having to change anything on your server or in your client code.

For more technical information about layers, take a look at our Instant Layers Server guide. To learn more about some of the design considerations and our vision for Instant layers, please have a look at the Instant layers blog post.

Try Layers for Yourself

To see layers in action without having to touch your server setup, you can use our example applications:

  1. Follow the steps in our Example Projects guide article for PSPDFKit Server, and log into the example web app in your favorite browser as the user test. A fresh server will be prepopulated with a sample PDF called Document#1, and you can always upload additional PDFs using the Upload PDF button.
  2. Open a document by clicking on its thumbnail and create a new text annotation with the content default layer on the first page — this will make it easy later on for you to see what layer you are dealing with.
  3. Type test in the Create New Layer field (in the right pane) and click the Create Layer button.
  4. Create a new text annotation with the content layer 'test' on the first page — you can now switch back and forth between the default layer and the test layer by clicking on the entries of the Available Layers list in the right pane. If you want, you can create additional layers by typing their names in the text field and adding an annotation to the new layer.

Follow the steps in our Getting Started guide for Instant in order to build and run the iOS example application. This is what allows you to see your existing layers on iOS. When running, the app will display a table view with one section for each PDF file you have uploaded to the example server containing one cell for each layer. After tapping one of the cells, the appropriate PDF file and annotation data will be downloaded as necessary. If you tap another cell in the same section, you will notice how much quicker the second layer for that file is opened; because the file is shared, only the annotation data needed to be fetched.

Using Layers in Your Own App

To use non-default layers, your JWTs need to include the layer claim. To obtain the document descriptor for any layer, call the documentDescriptor(forJWT:) method on your InstantClient, passing in the JWT.

ℹ️ Note: Because you need a JWT in order to obtain a document descriptor for a custom layer that has not yet been loaded, we suggest designing the API endpoint that lists all the layers a user has access to in such a way that the response includes the JWT for each layer. This also greatly reduces the number of server roundtrips needed to, for example, update all downloaded layers.

Related Improvements

To make it quicker and easier to identify integration errors, updating the JWT for a document identifier no longer requires a server roundtrip to reject incompatible tokens. And if your JWT contains the user_id claim, we now also reject those mismatches immediately. This is especially useful in combination with the new localDocumentDescriptors() API.

For the complete list of changes, head on over to our changelog.