This HTML page is not optimized for LLM or AI agent consumption. Fetch the Markdown version instead: /guides/dotnet/annotations/convert-between-instant-json-and-xmp.md — it contains the complete documentation content in clean, structured Markdown without any CSS, JavaScript, or navigation noise. Convert between Instant JSON and XMP | Nutrient .NET SDK

Nutrient supports two portable annotation formats: Instant JSON and XMP. Instant JSON is a JSON-based schema used across Nutrient products, including iOS, Web, Android, and Document Engine. XMP is GdPicture’s XML-based annotation format. Teams often need to move annotation data between them. For example, you may export annotations created in a GdPicture workflow as Instant JSON for another Nutrient SDK, or you may import Instant JSON and store it as XMP beside the PDF.

This guide shows how to:

  • Import an Instant JSON file into a blank PDF and export the result as XMP
  • Reimport the XMP file and export it back to Instant JSON
  • Choose between the flat, single-page XMP layout and the wrapped, multi-page layout

Prepare the project

Start by registering the SDK license before you process documents. For setup details, refer to the getting started with .NET SDK guide.

using GdPicture14;
LicenseManager licence = new LicenseManager();
licence.RegisterKEY(""); // Set your license key

Import Instant JSON and export XMP

Start with a fresh PDF, import a sample Instant JSON file, then export the resulting annotations as XMP. ExportXMPDataToFile produces the flat, single-page XMP shape used by GdPicture’s per-page XMP metadata stream:

using (GdPicturePDF pdf = new GdPicturePDF())
{
pdf.NewPDF();
pdf.NewPage(612, 792);
pdf.SelectPage(1);
GdPictureStatus importStatus = pdf.ImportInstantJSONDataFromFile(@"test_annotations_instant.json");
if (importStatus != GdPictureStatus.OK)
{
Console.Error.WriteLine($"Instant JSON import failed: {importStatus}");
Environment.Exit(1);
}
GdPictureStatus exportFlatStatus = pdf.ExportXMPDataToFile(@"output_flat.xmp");
if (exportFlatStatus != GdPictureStatus.OK)
{
Console.Error.WriteLine($"Flat XMP export failed: {exportFlatStatus}");
Environment.Exit(1);
}

Export the wrapped multi-page XMP shape

For documents with annotations across multiple pages, use ExportXMPDataToFileEx. The wrapped shape carries one <PageAnnots> entry per page, and each entry contains a base64-encoded flat XMP payload:

GdPictureStatus exportWrappedStatus = pdf.ExportXMPDataToFileEx(@"output_wrapped.xmp");
if (exportWrappedStatus != GdPictureStatus.OK)
{
Console.Error.WriteLine($"Wrapped XMP export failed: {exportWrappedStatus}");
Environment.Exit(1);
}
}

Choose the shape that matches the consumer:

  • Flat XMP — Use this per-page format for GdPicture’s internal XMP metadata stream. Choose it when you target a single page or work with the AnnotationManager API.
  • Wrapped XMP — Use this multi-page bundle when you need one artifact that carries every page’s annotations.

Import the XMP file back

ImportXMPDataFromFile auto-detects both layouts, so you don’t need an Ex variant on the import side. Load the wrapped XMP into a fresh PDF and verify the round-trip:

using (GdPicturePDF pdf = new GdPicturePDF())
{
pdf.NewPDF();
pdf.NewPage(612, 792);
pdf.SelectPage(1);
GdPictureStatus importStatus = pdf.ImportXMPDataFromFile(@"output_wrapped.xmp");
if (importStatus != GdPictureStatus.OK)
{
Console.Error.WriteLine($"XMP import failed: {importStatus}");
Environment.Exit(1);
}

Export the imported annotations as Instant JSON

After you import XMP, export the document state as Instant JSON. Pass fullState: true to capture every annotation as a complete snapshot. The diff export path uses the change tracker, and the XMP import bridge doesn’t currently feed it:

using FileStream stream = new FileStream(@"output.json", FileMode.Create, FileAccess.Write);
GdPictureStatus exportStatus = pdf.ExportInstantJSONDataToStream(stream, fullState: true);
if (exportStatus != GdPictureStatus.OK)
{
Console.Error.WriteLine($"Instant JSON export failed: {exportStatus}");
Environment.Exit(1);
}
}

Error handling

XMP and Instant JSON imports validate the payload before they apply changes. Common failure cases include:

  • GdPictureStatus.PdfDocumentMustBeUnencrypted — both formats refuse to operate on encrypted PDFs
  • GdPictureStatus.FileNotFound — the path is wrong, or the source file is missing
  • GdPictureStatus.GenericError — malformed XMP or Instant JSON

For status-handling patterns, refer to the handling errors with .NET SDK guide.

Conclusion

This guide bridges Instant JSON and XMP in both directions. It gives you a path to move annotation data between Nutrient products, and it uses the wrapped XMP shape for multi-page documents while ImportXMPDataFromFile handles either input layout automatically.