---
title: "Import and export annotations with Instant JSON | Nutrient Web SDK"
canonical_url: "https://www.nutrient.io/guides/web/importing-exporting/instant-json/"
md_url: "https://www.nutrient.io/guides/web/importing-exporting/instant-json.md"
last_updated: "2026-06-09T10:26:34.648Z"
description: "Implement Instant JSON as your default format for annotation sync, storage, and selective export. Learn import/export best practices, data-scoping patterns, and how it compares to XFDF and server-backed sync."
---

# Importing and exporting annotations with Instant JSON

Importing and exporting annotations enables you to persist user interactions — such as highlights, comments, or drawings — and reload them later. This is especially useful when working with custom-rendered annotations, where you control how annotations appear in the viewer. Exporting annotations in a portable format such as Instant JSON makes it possible to store, share, or sync them across users, devices, or sessions without needing to save the entire PDF file.

Recommendation summary:

- **Instant JSON** — Default format for internal persistence and syncing annotation data.

- **XFDF** — Use when you need interoperability with external PDF tools like Adobe Acrobat.

- **Server-backed (Document Engine with Instant synchronization)** — Use for collaborative, multiuser workflows across sessions and devices.

If you’re deciding between these approaches, start with [how to choose Instant JSON vs. XFDF vs. server-backed sync](https://www.nutrient.io/guides/web/annotations/import-and-export/choose-persistence-strategy.md).

If your workflow requires real-time team review or multiuser continuity, use [Web SDK with Document Engine](https://www.nutrient.io/guides/web/annotations/import-and-export/server-backed.md) and [Instant synchronization](https://www.nutrient.io/guides/web/instant-synchronization.md). If you need data exchange with external tools, use the [XML Forms Data Format (XFDF)](https://www.nutrient.io/guides/web/importing-exporting/xfdf-support.md) guide.

If you need to export only the currently selected annotations without including unrelated review data, refer to the [export only selected annotations](https://www.nutrient.io/guides/web/annotations/import-and-export/export-only-selected-annotations.md) guide.

## Annotation serialization

Serialization converts an annotation’s properties — such as type, position, color, and custom metadata — into a text-based format called Instant JSON. Think of it as capturing a complete snapshot of the annotation’s state that can be saved or transmitted.

## Annotation deserialization

Deserialization is the reverse process. It takes saved Instant JSON data and uses it to recreate the annotation inside the viewer. This ensures annotations maintain their appearance and behavior, even across sessions or platforms.

## How to serialize and deserialize annotations

You can export (serialize) a single annotation to Instant JSON by passing the annotation’s immutable record to the [`NutrientViewer.Annotations.toSerializableObject()`](https://www.nutrient.io/api/web/functions/NutrientViewer.Annotations.toSerializableObject.html) method of our [public API](https://www.nutrient.io/api/web/). This method converts the given annotation into a JSON object that captures all supported properties:

### JAVASCRIPT

```js

// Create an annotation and convert a rectangle annotation to Instant JSON.
const annotation = new NutrientViewer.Annotation.RectangleAnnotation({
  pageIndex: 0,
  boundingBox: new NutrientViewer.Geometry.Rect({
    left: 100,
    top: 150,
    width: 200,
    height: 75
  })
});
const annotationJSON = NutrientViewer.Annotations.toSerializableObject(
  annotation
);

```

### JSON

```json

// Annotation Instant JSON.
{
  v: 1,
  pageIndex: 0,
  bbox: [100, 150, 200, 75],
  opacity: 1,
  createdAt: "1970-01-01T00:00:00.000Z",
  updatedAt: "1970-01-01T00:00:00.000Z",
  isCommentThreadRoot: false,
  strokeWidth: 5,
  strokeColor: "#2293fb",

  type: "pspdfkit/shape/rectangle",
};

```

To import (deserialize) the annotation later, use the counterpart, [`NutrientViewer.Annotations.fromSerializableObject()`](https://www.nutrient.io/api/web/functions/NutrientViewer.Annotations.fromSerializableObject.html). This method takes the exported JSON and reconstructs the annotation in the viewer:

```js

const annotation = NutrientViewer.Annotations.fromSerializableObject(
  annotationJSON
);

```

Refer to the [Instant JSON](https://www.nutrient.io/guides/web/json/schema/annotations.md) guide for details on format structure and supported properties.

## Importing annotations in Instant JSON

You can import annotations in Instant JSON format in both [operational modes](https://www.nutrient.io/guides/web/about/operational-modes.md) of Nutrient Web SDK:

- When using Web SDK only (client-side processing)

- When using Web SDK with Document Engine (server-side processing)

This guide covers Instant JSON importing and exporting when using Web SDK. For Web SDK with Document Engine, refer to the [importing and exporting with Document Engine](https://www.nutrient.io/guides/web/annotations/import-and-export/server-backed.md) guide.

### Importing annotations in Instant JSON with document editing

If [document editing](https://www.nutrient.io/sdk/features-list/) is included in your license, you can use the `applyInstantJson` [document operation](https://www.nutrient.io/api/web/modules/DocumentOperations.html) to import Instant JSON through [`instance.applyOperations()`](https://www.nutrient.io/api/web/classes/NutrientViewer.Instance.html#applyoperations), as demonstrated in the code snippet below:

```js

instance.applyOperations([
  {
    type: "applyInstantJson",
    instantJson: {
      annotations: [
        {
          bbox: [100, 150, 200, 75],
          blendMode: "normal",
          createdAt: "1970-01-01T00:00:00Z",
          id: "01F73GJ4RPENTCMFSCJ5CSFT5G",
          name: "01F73GJ4RPENTCMFSCJ5CSFT5G",
          opacity: 1,
          pageIndex: 0,
          strokeColor: "#2293FB",

          strokeWidth: 5,
          type: "pspdfkit/shape/rectangle",
          updatedAt: "1970-01-01T00:00:00Z",
          v: 1
        }
      ],
      format: "https://pspdfkit.com/instant-json/v1"
    }
  }
]);

```

### Importing annotations in Instant JSON without document editing

If [document editing](https://www.nutrient.io/sdk/features-list/) isn’t included in your license, you can use the [`NutrientViewer.Configuration#instantJSON`](https://www.nutrient.io/api/web/interfaces/Configuration.html#instantjson) setting, as demonstrated in the code snippet below:

```js

NutrientViewer.load({...otherOptions,
  instantJSON: {
    annotations: [
      {
        bbox: [100, 150, 200, 75],
        blendMode: "normal",
        createdAt: "1970-01-01T00:00:00Z",
        id: "01F73GJ4RPENTCMFSCJ5CSFT5G",
        name: "01F73GJ4RPENTCMFSCJ5CSFT5G",
        opacity: 1,
        pageIndex: 0,
        strokeColor: "#2293FB",

        strokeWidth: 5,
        type: "pspdfkit/shape/rectangle",
        updatedAt: "1970-01-01T00:00:00Z",
        v: 1
      }
    ],
    format: "https://pspdfkit.com/instant-json/v1"
  }
});

```

## Exporting annotations in Instant JSON

To export an annotation in Instant JSON for storage or further processing, use the [`instance.exportInstantJSON()`](https://www.nutrient.io/api/web/classes/NutrientViewer.Instance.html#exportinstantjson) API method. You can export any saved annotations in the Instant JSON format:

```js

instance.exportInstantJSON();

```

**Avoid PDF ID mismatch errors**

If you’re storing Instant JSON for later use (in a database, local storage, or on a server), you’ll want to remove the `pdfId` property before saving it. The reason is that `pdfId` becomes outdated whenever the document changes, which can lead to errors when you try to load the JSON back later.

**Remove pdfId when exporting:**

```js

// Destructure to exclude `pdfId`.
const {pdfId,...instantJSON} = await instance.exportInstantJSON()
await saveToDatabase(instantJSON) // Save without `pdfId`.

```

**Why remove pdfId?**

The `pdfId` changes when you perform [document operations](https://www.nutrient.io/guides/web/editor.md) like rotating, adding, or removing pages. If you keep the `pdfId` in your stored JSON and then try to load it after making changes to the PDF, you’ll encounter a “PDF ID mismatch” error because the stored `pdfId` no longer matches the current document.

**When importing stored JSON:**

```js

// Remove `pdfId` if you didn't exclude it during export.
if (instantJSON.pdfId) {
  delete instantJSON.pdfId;
}

await NutrientViewer.load({
  container: '#container',

  document: documentUrl,
  instantJSON: instantJSON
});

```

[Learn more about `pdfId` and when to keep it](https://www.nutrient.io/guides/web/json/how-it-works/#understanding-pdfid).
---

## Related pages

- [Importing and exporting annotations in a database](/guides/web/annotations/import-and-export/database.md)
- [How to choose Instant JSON vs. XFDF vs. server-backed sync](/guides/web/annotations/import-and-export/choose-persistence-strategy.md)
- [Importing and exporting annotations with Document Engine](/guides/web/annotations/import-and-export/server-backed.md)
- [Importing and exporting annotations in XFDF](/guides/web/importing-exporting/xfdf-support.md)
- [Export only selected annotations](/guides/web/annotations/import-and-export/export-only-selected-annotations.md)

