What is an Instant layer?

An Instant layer represents a set of document changes, such as annotations, bookmarks, form fields, and digital signatures. Users with write access can edit the layer, while those with read access can only view it.

What it’s best for

Layers are ideal for independent review workflows where multiple parties need to annotate or modify the same document separately. Common use cases include:

  • Student-teacher workflows — Students annotate the same PDF independently, while teachers provide private feedback on each student’s layer
  • Multi-reviewer processes — Different reviewers provide feedback without seeing each other’s comments

Benefits

  • Low storage cost — Layers on the same document identifier share access to the same source file, eliminating the need to reupload, while keeping each layer’s content isolated
  • Minimal bandwidth — Adding layers doesn’t require transferring the document again
  • Scalable — It’s inexpensive to add multiple layers on clients and servers

Terminology

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 (i.e. documents) from a document descriptor.

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 Document Engine, 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 layers don’t have to be created manually, rather they’re 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’re already using Instant, all your annotations will be in this default layer, and you can continue using 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 guide for Document Engine. To learn more about some of the design considerations and our vision for Instant layers, read 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. Set up and run the Document Engine example project(opens in a new tab), which starts a local Document Engine instance with a Node.js web application. Once running, open the web app at http://localhost:3000 in your browser and log in 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. Note that the Instant iOS Example(opens in a new tab) app can also connect to this same Document Engine instance, enabling you to view and annotate the same documents and layers from both web and iOS.
  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 which layer you’re 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 get started guide for Instant 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’ve 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’ll notice how much more quickly 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.

Because you need a JWT to obtain a document descriptor for a custom layer that hasn’t 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.

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 over to our changelog.