Convert between Instant JSON and XMP
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 keyImport 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
AnnotationManagerAPI. - 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 PDFsGdPictureStatus.FileNotFound— the path is wrong, or the source file is missingGdPictureStatus.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.