> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/core/get-started/samples/bookmarktest.md).

# PDF Bookmarks and Outlines - Add/Edit/Read

Sample code to use Apryse SDK for programmatically reading and editing existing outline items, and for creating new PDF bookmarks using the high-level API.  Sample code provided in Python, C++, C#, Ja

{% hint style="info" %}
**Requirements**

*These packages are required to use these features in production. Trial keys have unlimited access to all features*

<a href="/core/get-started/get-started.md" class="button primary">Server SDK</a><a href="https://apryse.com/capabilities#PageManipulation" class="button primary">Package: Page Manipulation</a><a href="https://showcase.apryse.com/add-personal-bookmark-pdf" class="button primary">Live demo</a>
{% endhint %}

Sample code to use Apryse SDK for programmatically reading and editing existing outline items, and for creating new PDF bookmarks using the high-level API. Sample code provided in Python, C++, C#, Java, Node.js (JavaScript), PHP, Ruby and VB.

### **Implementation steps**

To manipulate bookmarks and outlines with Apryse Server SDK:

Step 1: Follow [get started with Server SDK in your preferred language or framework](/core/get-started/get-started.md) Step 2: Add the sample code provided in this guide

To use this feature in production, your license key will need the [Page Manipulation Package](https://apryse.com/capabilities#PageManipulation). Trial keys already include all packages.

Learn more about our [Server SDK](/core/get-started/get-started.md) and [PDF Editing & Manipulation Library](/core/page-manipulation/manipulation.md).

{% tabs %}
{% tab title="C#" %}
{% code lineNumbers="true" %}

```csharp
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

using System;
using pdftron;
using pdftron.Common;
using pdftron.Filters;
using pdftron.SDF;
using pdftron.PDF;

namespace BookmarkTestCS
{
	/// <summary>
	//-----------------------------------------------------------------------------------------
	// The sample code illustrates how to read, write, and edit existing outline items 
	// and create new bookmarks using both the high-level and the SDF/Cos API.
	//-----------------------------------------------------------------------------------------
	/// </summary>
	class Class1
	{
		private static pdftron.PDFNetLoader pdfNetLoader = pdftron.PDFNetLoader.Instance();
		static Class1() {}

		static void PrintIndent(Bookmark item)
		{
			int indent = item.GetIndent() - 1;
			for (int i = 0; i < indent; ++i)
				Console.Write("  ");
		}

		// Prints out the outline tree to the standard output
		static void PrintOutlineTree(Bookmark item)
		{
			for (; item.IsValid(); item = item.GetNext())
			{
				PrintIndent(item);
				Console.Write("{0:s}{1:s} ACTION -> ", (item.IsOpen() ? "- " : "+ "), item.GetTitle());

				// Print Action
				pdftron.PDF.Action action = item.GetAction();
				if (action != null && action.IsValid())
				{
					if (action.GetType() == pdftron.PDF.Action.Type.e_GoTo)
					{
						Destination dest = action.GetDest();
						if (dest.IsValid())
						{
							Page page = dest.GetPage();
							Console.WriteLine("GoTo Page #{0:d}", page.GetIndex());
						}
					}
					else
					{
						Console.WriteLine("Not a 'GoTo' action");
					}
				}
				else
				{
					Console.WriteLine("NULL");
				}

				if (item.HasChildren())	 // Recursively print children sub-trees
				{
					PrintOutlineTree(item.GetFirstChild());
				}
			}
		}

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		static void Main(string[] args)
		{
			PDFNet.Initialize(PDFTronLicense.Key);

			// Relative path to the folder containing test files.
			string input_path = "../../../../TestFiles/";
			string output_path = "../../../../TestFiles/Output/";


			// The following example illustrates how to create and edit the outline tree 
			// using high-level Bookmark methods.
			try
			{
				using (PDFDoc doc = new PDFDoc(input_path + "numbered.pdf"))
				{
					doc.InitSecurityHandler();

					// Lets first create the root bookmark items. 
					Bookmark red = Bookmark.Create(doc, "Red");
					Bookmark green = Bookmark.Create(doc, "Green");
					Bookmark blue = Bookmark.Create(doc, "Blue");

					doc.AddRootBookmark(red);
					doc.AddRootBookmark(green);
					doc.AddRootBookmark(blue);

					// You can also add new root bookmarks using Bookmark.AddNext("...")
					blue.AddNext("foo");
					blue.AddNext("bar");

					// We can now associate new bookmarks with page destinations:

					// The following example creates an 'explicit' destination (see 
					// section '8.2.1 Destinations' in PDF Reference for more details)
					Destination red_dest = Destination.CreateFit(doc.GetPage(1));
					red.SetAction(pdftron.PDF.Action.CreateGoto(red_dest));

					// Create an explicit destination to the first green page in the document
					green.SetAction(pdftron.PDF.Action.CreateGoto(
						Destination.CreateFit(doc.GetPage(10))));

					// The following example creates a 'named' destination (see 
					// section '8.2.1 Destinations' in PDF Reference for more details)
					// Named destinations have certain advantages over explicit destinations.
					String key = "blue1";
					pdftron.PDF.Action blue_action = pdftron.PDF.Action.CreateGoto(key,
						Destination.CreateFit(doc.GetPage(19)));

					blue.SetAction(blue_action);

					// We can now add children Bookmarks
					Bookmark sub_red1 = red.AddChild("Red - Page 1");
					sub_red1.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc.GetPage(1))));
					Bookmark sub_red2 = red.AddChild("Red - Page 2");
					sub_red2.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc.GetPage(2))));
					Bookmark sub_red3 = red.AddChild("Red - Page 3");
					sub_red3.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc.GetPage(3))));
					Bookmark sub_red4 = sub_red3.AddChild("Red - Page 4");
					sub_red4.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc.GetPage(4))));
					Bookmark sub_red5 = sub_red3.AddChild("Red - Page 5");
					sub_red5.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc.GetPage(5))));
					Bookmark sub_red6 = sub_red3.AddChild("Red - Page 6");
					sub_red6.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc.GetPage(6))));

					// Example of how to find and delete a bookmark by title text.
					Bookmark foo = doc.GetFirstBookmark().Find("foo");
					if (foo.IsValid())
					{
						foo.Delete();
					}

					Bookmark bar = doc.GetFirstBookmark().Find("bar");
					if (bar.IsValid())
					{
						bar.Delete();
					}

					// Adding color to Bookmarks. Color and other formatting can help readers 
					// get around more easily in large PDF documents.
					red.SetColor(1, 0, 0);
					green.SetColor(0, 1, 0);
					green.SetFlags(2);			// set bold font
					blue.SetColor(0, 0, 1);
					blue.SetFlags(3);			// set bold and italic

					doc.Save(output_path + "bookmark.pdf", 0);
					Console.WriteLine("Done. Result saved in bookmark.pdf");
				}
			}
			catch (PDFNetException e)
			{
				Console.WriteLine(e.Message);
			}


			// The following example illustrates how to traverse the outline tree using 
			// Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(), 
			// Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
			try
			{
				// Open the document that was saved in the previous code sample
				using (PDFDoc doc = new PDFDoc(output_path + "bookmark.pdf"))
				{
					doc.InitSecurityHandler();

					Bookmark root = doc.GetFirstBookmark();
					PrintOutlineTree(root);

					Console.WriteLine("Done.");
				}
			}
			catch (PDFNetException e)
			{
				Console.WriteLine(e.Message);
			}

			// The following example illustrates how to create a Bookmark to a page 
			// in a remote document. A remote go-to action is similar to an ordinary 
			// go-to action, but jumps to a destination in another PDF file instead 
			// of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF 
			// Reference Manual for details.
			try
			{
				using (PDFDoc doc = new PDFDoc(output_path + "bookmark.pdf"))
				{
					doc.InitSecurityHandler();

					// Create file specification (the file referred to by the remote bookmark)
					Obj file_spec = doc.CreateIndirectDict();
					file_spec.PutName("Type", "Filespec");
					file_spec.PutString("F", "bookmark.pdf");

					FileSpec spec = new FileSpec(file_spec);
					pdftron.PDF.Action goto_remote = pdftron.PDF.Action.CreateGotoRemote(spec, 5, true);

					Bookmark remoteBookmark1 = Bookmark.Create(doc, "REMOTE BOOKMARK 1");
					remoteBookmark1.SetAction(goto_remote);
					doc.AddRootBookmark(remoteBookmark1);

					// Create another remote bookmark, but this time using the low-level SDF/Cos API.
					Bookmark remoteBookmark2 = Bookmark.Create(doc, "REMOTE BOOKMARK 2");
					doc.AddRootBookmark(remoteBookmark2);
					Obj gotoR = remoteBookmark2.GetSDFObj().PutDict("A");
					{	// Create the 'Action' dictionary.
						gotoR.PutName("S", "GoToR"); // Set action type
						gotoR.PutBool("NewWindow", true);

						// Set the file specification
						gotoR.Put("F", file_spec);

						// Set the destination.
						Obj dest = gotoR.PutArray("D");
						dest.PushBackNumber(9);  // jump to the tenth page. Note that Acrobat indexes pages from 0.
						dest.PushBackName("Fit"); // Fit the page
					}

					doc.Save(output_path + "bookmark_remote.pdf", SDFDoc.SaveOptions.e_linearized);
					Console.WriteLine("Done. Result saved in bookmark_remote.pdf");
				}
			}
			catch (PDFNetException e)
			{
				Console.WriteLine(e.Message);
			}
			PDFNet.Terminate();
		}
	}
}
```

{% endcode %}
{% endtab %}

{% tab title="C++" %}
{% code lineNumbers="true" %}

```cpp
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

#include <PDF/PDFNet.h>
#include <PDF/PDFDoc.h>
#include <iostream>
#include <assert.h>
#include "../../LicenseKey/CPP/LicenseKey.h"

using namespace std;
using namespace pdftron;
using namespace SDF;
using namespace PDF;

//-----------------------------------------------------------------------------------------
// The sample code illustrates how to read and edit existing outline items and create 
// new bookmarks using the high-level API.
//-----------------------------------------------------------------------------------------

void PrintIndent(Bookmark item) 
{
	int ident = item.GetIndent() - 1;
	for (int i=0; i<ident; ++i) cout << "  ";
}

// Prints out the outline tree to the standard output
void PrintOutlineTree(Bookmark item)
{
	for (; item.IsValid(); item=item.GetNext())
	{
		PrintIndent(item);
		cout << (item.IsOpen() ? "- " : "+ ") << item.GetTitle() << " ACTION -> ";

		// Print Action
		Action action = item.GetAction();
		if (action.IsValid()) {
			if (action.GetType() == Action::e_GoTo) {
				Destination dest = action.GetDest();
				if (dest.IsValid()) {
					Page page = dest.GetPage();
					cout << "GoTo Page #" << page.GetIndex() << endl;
				}
			}
			else {
				cout << "Not a 'GoTo' action" << endl;
			}
		} else {
			cout << "NULL" << endl;
		}

		if (item.HasChildren())	 // Recursively print children sub-trees
		{
			PrintOutlineTree(item.GetFirstChild());
		}
	}
}

int main(int argc, char *argv[])
{
	int ret = 0;
	PDFNet::Initialize(LicenseKey);

	// Relative path to the folder containing test files.
	string input_path =  "../../TestFiles/";
	string output_path = "../../TestFiles/Output/";

	// The following example illustrates how to create and edit the outline tree 
	// using high-level Bookmark methods.
	try  
	{
		PDFDoc doc((input_path + "numbered.pdf").c_str());
		doc.InitSecurityHandler();
		
		// Lets first create the root bookmark items. 
		Bookmark red = Bookmark::Create(doc, "Red");
		Bookmark green = Bookmark::Create(doc, "Green");
		Bookmark blue = Bookmark::Create(doc, "Blue");

		doc.AddRootBookmark(red);
		doc.AddRootBookmark(green);
		doc.AddRootBookmark(blue);

		// You can also add new root bookmarks using Bookmark.AddNext("...")
		blue.AddNext("foo");
		blue.AddNext("bar");

		// We can now associate new bookmarks with page destinations:

		// The following example creates an 'explicit' destination (see 
		// section '8.2.1 Destinations' in PDF Reference for more details)
		Destination red_dest = Destination::CreateFit(doc.GetPageIterator().Current());
		red.SetAction(Action::CreateGoto(red_dest));

		// Create an explicit destination to the first green page in the document
		green.SetAction(Action::CreateGoto( 
			Destination::CreateFit(doc.GetPage(10)) ));

		// The following example creates a 'named' destination (see 
		// section '8.2.1 Destinations' in PDF Reference for more details)
		// Named destinations have certain advantages over explicit destinations.
		const char* key = "blue1";
		Action blue_action = Action::CreateGoto((UChar*) key, UInt32(strlen(key)),
			Destination::CreateFit(doc.GetPage(19)) );
		
		blue.SetAction(blue_action);

		// We can now add children Bookmarks
		Bookmark sub_red1 = red.AddChild("Red - Page 1");
		sub_red1.SetAction(Action::CreateGoto(Destination::CreateFit(doc.GetPage(1))));
		Bookmark sub_red2 = red.AddChild("Red - Page 2");
		sub_red2.SetAction(Action::CreateGoto(Destination::CreateFit(doc.GetPage(2))));
		Bookmark sub_red3 = red.AddChild("Red - Page 3");
		sub_red3.SetAction(Action::CreateGoto(Destination::CreateFit(doc.GetPage(3))));
		Bookmark sub_red4 = sub_red3.AddChild("Red - Page 4");
		sub_red4.SetAction(Action::CreateGoto(Destination::CreateFit(doc.GetPage(4))));
		Bookmark sub_red5 = sub_red3.AddChild("Red - Page 5");
		sub_red5.SetAction(Action::CreateGoto(Destination::CreateFit(doc.GetPage(5))));
		Bookmark sub_red6 = sub_red3.AddChild("Red - Page 6");
		sub_red6.SetAction(Action::CreateGoto(Destination::CreateFit(doc.GetPage(6))));
		
		// Example of how to find and delete a bookmark by title text.
		Bookmark foo = doc.GetFirstBookmark().Find("foo");
		if (foo.IsValid()) 
		{
			foo.Delete();
		}
		else 
		{
			assert(false);
		}

		Bookmark bar = doc.GetFirstBookmark().Find("bar");
		if (bar.IsValid()) 
		{
			bar.Delete();
		}
		else 
		{
			assert(false);
		}

		// Adding color to Bookmarks. Color and other formatting can help readers 
		// get around more easily in large PDF documents.
		red.SetColor(1, 0, 0);
		green.SetColor(0, 1, 0);
		green.SetFlags(2);			// set bold font
		blue.SetColor(0, 0, 1);
		blue.SetFlags(3);			// set bold and italic

		doc.Save((output_path + "bookmark.pdf").c_str(), 0, 0);
		cout << "Done. Result saved in bookmark.pdf" << endl;
	}
	catch(Common::Exception& e)
	{
		cout << e << endl;
		ret = 1;
	}
	catch(...)
	{
		cout << "Unknown Exception" << endl;
		ret = 1;
	}

	
	// The following example illustrates how to traverse the outline tree using 
	// Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(), 
	// Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
	try  
	{
		// Open the document that was saved in the previous code sample
		PDFDoc doc((output_path + "bookmark.pdf").c_str());
		doc.InitSecurityHandler();
		
		Bookmark root = doc.GetFirstBookmark();
		PrintOutlineTree(root);

		cout << "Done." << endl;
	}
	catch(Common::Exception& e)
	{
		cout << e << endl;
		ret = 1;
	}
	catch(...)
	{
		cout << "Unknown Exception" << endl;
		ret = 1;
	}

	// The following example illustrates how to create a Bookmark to a page 
	// in a remote document. A remote go-to action is similar to an ordinary 
	// go-to action, but jumps to a destination in another PDF file instead 
	// of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF 
	// Reference Manual for details.
	try  
	{
		// Open the document that was saved in the previous code sample
		PDFDoc doc((output_path + "bookmark.pdf").c_str());
		doc.InitSecurityHandler();

		// Create file specification (the file referred to by the remote bookmark)
		Obj file_spec = doc.CreateIndirectDict(); 
		file_spec.PutName("Type", "Filespec");
		file_spec.PutString("F", "bookmark.pdf");
		FileSpec spec(file_spec);
		Action goto_remote = Action::CreateGotoRemote(spec, 5, true);

		Bookmark remoteBookmark1 = Bookmark::Create(doc, "REMOTE BOOKMARK 1");
		remoteBookmark1.SetAction(goto_remote);
		doc.AddRootBookmark(remoteBookmark1);

		// Create another remote bookmark, but this time using the low-level SDF/Cos API.
		// Create a remote action
		Bookmark remoteBookmark2 = Bookmark::Create(doc, "REMOTE BOOKMARK 2");
		doc.AddRootBookmark(remoteBookmark2);
		
		Obj gotoR = remoteBookmark2.GetSDFObj().PutDict("A");
		{
			gotoR.PutName("S","GoToR"); // Set action type
			gotoR.PutBool("NewWindow", true);

			// Set the file specification
			gotoR.Put("F", file_spec);

			// jump to the first page. Note that pages are indexed from 0.
			Obj dest = gotoR.PutArray("D");  // Set the destination
			dest.PushBackNumber(9); 
			dest.PushBackName("Fit");
		}

		doc.Save((output_path + "bookmark_remote.pdf").c_str(), SDFDoc::e_linearized, 0);

		cout << "Done. Result saved in bookmark_remote.pdf" << endl;
	}
	catch(Common::Exception& e)
	{
		cout << e << endl;
		ret = 1;
	}
	catch(...)
	{
		cout << "Unknown Exception" << endl;
		ret = 1;
	}

	PDFNet::Terminate();
	return ret;
}
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code lineNumbers="true" %}

```go
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2021 by PDFTron Systems Inc. All Rights Reserved.
// Consult LICENSE.txt regarding license information.
//---------------------------------------------------------------------------------------

package main
import (
    "fmt"
    "strconv"
    "os"
    . "pdftron"
)

import  "pdftron/Samples/LicenseKey/GO"

//-----------------------------------------------------------------------------------------
// The sample code illustrates how to read and edit existing outline items and create 
// new bookmarks using the high-level API.
//-----------------------------------------------------------------------------------------

// Relattive path to the folder containing the test files.
var inputPath = "../../TestFiles/"
var outputPath = "../../TestFiles/Output/"

func PrintIndent(item Bookmark){
    indent := item.GetIndent() - 1
    i := 0
    for i < indent{
        os.Stdout.Write([]byte("  "))
        i = i + 1
    }
}

// Prints out the outline tree to the standard output
func PrintOutlineTree (item Bookmark){
    for item.IsValid(){
        PrintIndent(item)

        if item.IsOpen(){
            os.Stdout.Write([]byte("- " + item.GetTitle() + " ACTION -> "))
        }else{
            os.Stdout.Write([]byte("+ " + item.GetTitle() + " ACTION -> "))
        }

        // Print Action
        action := item.GetAction()
        if action.IsValid(){
            if action.GetType() == ActionE_GoTo{
                dest := action.GetDest()
                if dest.IsValid(){
                    page := dest.GetPage()
                    fmt.Println("GoTo Page //" + strconv.Itoa(page.GetIndex()))
                }
            }else{
                fmt.Println("Not a 'GoTo' action")
            }
        }else{
            fmt.Println("NULL")
        }
        // Recursively print children sub-trees   
        if item.HasChildren(){        
            PrintOutlineTree(item.GetFirstChild())
        }
        item = item.GetNext()
    }
}            

func main(){
    PDFNetInitialize(PDFTronLicense.Key)

    // The following example illustrates how to create and edit the outline tree
    // using high-level Bookmark methods.
    
    doc := NewPDFDoc(inputPath + "numbered.pdf")
    doc.InitSecurityHandler()
    
    // Lets first create the root bookmark items. 
    red := BookmarkCreate(doc, "Red")
    green := BookmarkCreate(doc, "Green")
    blue := BookmarkCreate(doc, "Blue")
    
    doc.AddRootBookmark(red)
    doc.AddRootBookmark(green)
    doc.AddRootBookmark(blue)
    
    // You can also add new root bookmarks using Bookmark.AddNext("...")
    blue.AddNext("foo")
    blue.AddNext("bar")

    // We can now associate new bookmarks with page destinations:
    
    // The following example creates an 'explicit' destination (see 
    // section '8.2.1 Destinations' in PDF Reference for more details)
    itr := doc.GetPageIterator()
    redDest := DestinationCreateFit(itr.Current())
    red.SetAction(ActionCreateGoto(redDest))

    // Create an explicit destination to the first green page in the document
    green.SetAction(ActionCreateGoto(DestinationCreateFit(doc.GetPage(10))))

    // The following example creates a 'named' destination (see 
    // section '8.2.1 Destinations' in PDF Reference for more details)
    // Named destinations have certain advantages over explicit destinations.
    key := []byte("blue1")
    blueAction := ActionCreateGoto(&key[0], 2, DestinationCreateFit(doc.GetPage(19)))
    
    blue.SetAction(blueAction)
    
    // We can now add children Bookmarks
    subRed1 := red.AddChild("Red - Page 1")
    subRed1.SetAction(ActionCreateGoto(DestinationCreateFit(doc.GetPage(1))))
    subRed2 := red.AddChild("Red - Page 2")
    subRed2.SetAction(ActionCreateGoto(DestinationCreateFit(doc.GetPage(2))))
    subRed3 := red.AddChild("Red - Page 3")
    subRed3.SetAction(ActionCreateGoto(DestinationCreateFit(doc.GetPage(3))))
    subRed4 := subRed3.AddChild("Red - Page 4")
    subRed4.SetAction(ActionCreateGoto(DestinationCreateFit(doc.GetPage(4))))
    subRed5 := subRed3.AddChild("Red - Page 5")
    subRed5.SetAction(ActionCreateGoto(DestinationCreateFit(doc.GetPage(5))))
    subRed6 := subRed3.AddChild("Red - Page 6")
    subRed6.SetAction(ActionCreateGoto(DestinationCreateFit(doc.GetPage(6))))
    
    // Example of how to find and delete a bookmark by title text.
    foo := doc.GetFirstBookmark().Find("foo")
    if foo.IsValid(){
        foo.Delete()
    }else{
        panic("Foo is not Valid")
    }
    bar := doc.GetFirstBookmark().Find("bar")
    if bar.IsValid(){
        bar.Delete()
    }else{
        panic("Bar is not Valid")
    }
    // Adding color to Bookmarks. Color and other formatting can help readers 
    // get around more easily in large PDF documents.
    red.SetColor(1.0, 0.0, 0.0);
    green.SetColor(0.0, 1.0, 0.0);
    green.SetFlags(2);            // set bold font
    blue.SetColor(0.0, 0.0, 1.0);
    blue.SetFlags(3);             // set bold and itallic
    
    doc.Save(outputPath + "bookmark.pdf", uint(0))
    doc.Close()
    fmt.Println("Done. Result saved in bookmark.pdf")

    // The following example illustrates how to traverse the outline tree using 
    // Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(), 
    // Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
    
    // Open the document that was saved in the previous code sample
    doc = NewPDFDoc(outputPath + "bookmark.pdf")
    doc.InitSecurityHandler()
    
    root := doc.GetFirstBookmark()
    PrintOutlineTree(root)
    
    doc.Close()
    fmt.Println("Done.")
    
    // The following example illustrates how to create a Bookmark to a page 
    // in a remote document. A remote go-to action is similar to an ordinary 
    // go-to action, but jumps to a destination in another PDF file instead 
    // of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF 
    // Reference Manual for details.
    
    doc = NewPDFDoc(outputPath + "bookmark.pdf")
    doc.InitSecurityHandler()
    
    // Create file specification (the file reffered to by the remote bookmark)
    fileSpec := doc.CreateIndirectDict()
    fileSpec.PutName("Type", "Filespec")
    fileSpec.PutString("F", "bookmark.pdf")
    spec := NewFileSpec(fileSpec)
    gotoRemote := ActionCreateGotoRemote(spec, 5, true)
    
    remoteBookmark1 := BookmarkCreate(doc, "REMOTE BOOKMARK 1")
    remoteBookmark1.SetAction(gotoRemote)
    doc.AddRootBookmark(remoteBookmark1)
    
    // Create another remote bookmark, but this time using the low-level SDF/Cos API.
    // Create a remote action
    remoteBookmark2 := BookmarkCreate(doc, "REMOTE BOOKMARK 2")
    doc.AddRootBookmark(remoteBookmark2)
    
    gotoR := remoteBookmark2.GetSDFObj().PutDict("A")
    gotoR.PutName("S","GoToR")  // Set action type
    gotoR.PutBool("NewWindow", true)
    
    // Set the file specification
    gotoR.Put("F", fileSpec)
    
    // jump to the first page. Note that pages are indexed from 0.
    dest := gotoR.PutArray("D")  // Set the destination
    dest.PushBackNumber(9); 
    dest.PushBackName("Fit");
    
    doc.Save(outputPath + "bookmark_remote.pdf", uint(SDFDocE_linearized))
    doc.Close()
    PDFNetTerminate()
    fmt.Println("Done. Result saved in bookmark_remote.pdf")
}
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code lineNumbers="true" %}

```java
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

import com.pdftron.common.PDFNetException;
import com.pdftron.pdf.*;
import com.pdftron.sdf.Obj;
import com.pdftron.sdf.SDFDoc;


public class BookmarkTest {

    public static void main(String[] args) {
        PDFNet.initialize(PDFTronLicense.Key());

        // Relative path to the folder containing test files.
        String input_path = "../../TestFiles/";
        String output_path = "../../TestFiles/Output/";

        // The following example illustrates how to create and edit the outline tree
        // using high-level Bookmark methods.
        try (PDFDoc doc = new PDFDoc((input_path + "numbered.pdf"))) {
            doc.initSecurityHandler();

            // Lets first create the root bookmark items.
            Bookmark red = Bookmark.create(doc, "Red");
            Bookmark green = Bookmark.create(doc, "Green");
            Bookmark blue = Bookmark.create(doc, "Blue");

            doc.addRootBookmark(red);
            doc.addRootBookmark(green);
            doc.addRootBookmark(blue);

            // You can also add new root bookmarks using Bookmark.AddNext("...")
            blue.addNext("foo");
            blue.addNext("bar");

            // We can now associate new bookmarks with page destinations:

            // The following example creates an 'explicit' destination (see
            // section '8.2.1 Destinations' in PDF Reference for more details)
            Destination red_dest = Destination.createFit(doc.getPageIterator().next());
            red.setAction(Action.createGoto(red_dest));

            // Create an explicit destination to the first green page in the document
            green.setAction(Action.createGoto(
                    Destination.createFit(doc.getPage(10))));

            // The following example creates a 'named' destination (see
            // section '8.2.1 Destinations' in PDF Reference for more details)
            // Named destinations have certain advantages over explicit destinations.
            byte[] key = {'b', 'l', 'u', 'e', '1'};
            Action blue_action = Action.createGoto(key,
                    Destination.createFit(doc.getPage(19)));

            blue.setAction(blue_action);

            // We can now add children Bookmarks
            Bookmark sub_red1 = red.addChild("Red - Page 1");
            sub_red1.setAction(Action.createGoto(Destination.createFit(doc.getPage(1))));
            Bookmark sub_red2 = red.addChild("Red - Page 2");
            sub_red2.setAction(Action.createGoto(Destination.createFit(doc.getPage(2))));
            Bookmark sub_red3 = red.addChild("Red - Page 3");
            sub_red3.setAction(Action.createGoto(Destination.createFit(doc.getPage(3))));
            Bookmark sub_red4 = sub_red3.addChild("Red - Page 4");
            sub_red4.setAction(Action.createGoto(Destination.createFit(doc.getPage(4))));
            Bookmark sub_red5 = sub_red3.addChild("Red - Page 5");
            sub_red5.setAction(Action.createGoto(Destination.createFit(doc.getPage(5))));
            Bookmark sub_red6 = sub_red3.addChild("Red - Page 6");
            sub_red6.setAction(Action.createGoto(Destination.createFit(doc.getPage(6))));

            // Example of how to find and delete a bookmark by title text.
            Bookmark foo = doc.getFirstBookmark().find("foo");
            if (foo.isValid()) {
                foo.delete();
            } else {
                throw new Exception("Foo is not Valid");
            }

            Bookmark bar = doc.getFirstBookmark().find("bar");
            if (bar.isValid()) {
                bar.delete();
            } else {
                throw new Exception("Bar is not Valid");
            }

            // Adding color to Bookmarks. Color and other formatting can help readers
            // get around more easily in large PDF documents.
            red.setColor(1, 0, 0);
            green.setColor(0, 1, 0);
            green.setFlags(2);            // set bold font
            blue.setColor(0, 0, 1);
            blue.setFlags(3);            // set bold and itallic

            doc.save((output_path + "bookmark.pdf"), SDFDoc.SaveMode.NO_FLAGS, null);
            System.out.println("Done. Result saved in bookmark.pdf");
        } catch (Exception e) {
            System.out.println(e);
        }

        // The following example illustrates how to traverse the outline tree using
        // Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(),
        // Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
        // Open the document that was saved in the previous code sample
        try (PDFDoc doc = new PDFDoc((output_path + "bookmark.pdf"))) {
            doc.initSecurityHandler();

            Bookmark root = doc.getFirstBookmark();
            PrintOutlineTree(root);
            System.out.println("Done.");
        } catch (Exception e) {
            System.out.println(e);
        }

        // The following example illustrates how to create a Bookmark to a page
        // in a remote document. A remote go-to action is similar to an ordinary
        // go-to action, but jumps to a destination in another PDF file instead
        // of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF
        // Reference Manual for details.
        // Open the document that was saved in the previous code sample
        try (PDFDoc doc = new PDFDoc((output_path + "bookmark.pdf"))) {
            doc.initSecurityHandler();

            // Create file specification (the file reffered to by the remote bookmark)
            Obj file_spec = doc.createIndirectDict();
            file_spec.putName("Type", "Filespec");
            file_spec.putString("F", "bookmark.pdf");
            FileSpec spec = new FileSpec(file_spec);
            Action goto_remote = Action.createGotoRemote(spec, 5, true);

            Bookmark remoteBookmark1 = Bookmark.create(doc, "REMOTE BOOKMARK 1");
            remoteBookmark1.setAction(goto_remote);
            doc.addRootBookmark(remoteBookmark1);

            // Create another remote bootmark, but this time using the low-level SDF/Cos API.
            // Create a remote action
            Bookmark remoteBookmark2 = Bookmark.create(doc, "REMOTE BOOKMARK 2");
            doc.addRootBookmark(remoteBookmark2);

            Obj gotoR = remoteBookmark2.getSDFObj().putDict("A");
            {
                gotoR.putName("S", "GoToR"); // Set action type
                gotoR.putBool("NewWindow", true);

                // Set the file specification
                gotoR.put("F", file_spec);

                // jump to the first page. Note that pages are indexed from 0.
                Obj dest = gotoR.putArray("D"); // Set the destination
                dest.pushBackNumber(9);
                dest.pushBackName("Fit");
            }

            doc.save((output_path + "bookmark_remote.pdf"), SDFDoc.SaveMode.LINEARIZED, null);
            System.out.println("Done. Result saved in bookmark_remote.pdf");
        } catch (Exception e) {
            System.out.println(e);
        }

        PDFNet.terminate();
    }

    static void PrintIndent(Bookmark item) throws PDFNetException {
        int ident = item.getIndent() - 1;
        for (int i = 0; i < ident; ++i) System.out.print("  ");
    }

    // Prints out the outline tree to the standard output
    static void PrintOutlineTree(Bookmark item) throws PDFNetException {
        for (; item.isValid(); item = item.getNext()) {
            PrintIndent(item);
            System.out.print((item.isOpen() ? "- " : "+ ") + item.getTitle() + " ACTION -> ");

            // Print Action
            Action action = item.getAction();
            if (action.isValid()) {
                if (action.getType() == Action.e_GoTo) {
                    Destination dest = action.getDest();
                    if (dest.isValid()) {
                        Page page = dest.getPage();
                        System.out.println("GoTo Page #" + page.getIndex());
                    }
                } else {
                    System.out.println("Not a 'GoTo' action");
                }
            } else {
                System.out.println("NULL");
            }

            if (item.hasChildren())     // Recursively print children sub-trees
            {
                PrintOutlineTree(item.getFirstChild());
            }
        }
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.
//---------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------------------
// The sample code illustrates how to read and edit existing outline items and create 
// new bookmarks using the high-level API.
//-----------------------------------------------------------------------------------------

const { PDFNet } = require('@pdftron/pdfnet-node');
const PDFTronLicense = require('../LicenseKey/LicenseKey');

((exports) => {

  exports.runBookmarkTest = () => {

    const getIndent = async (item) => {
      const ident = (await item.getIndent()) - 1;
      let str = '';
      for (let i = 0; i < ident; ++i) {
        str += '  ';
      }
      return str;
    };

    // Prints out the outline tree to the standard output
    const printOutlineTree = async (item) => {
      for (; item != null; item = await item.getNext()) {
        const indentString = await getIndent(item);
        const titleString = await item.getTitle();

        const actionString = indentString + (await item.isOpen() ? '- ' : '+ ') + titleString + ' ACTION -> ';

        // Print Action
        const action = await item.getAction();
        if (await action.isValid()) {
          const actionType = await action.getType();
          if (actionType === PDFNet.Action.Type.e_GoTo) {
            const dest = await action.getDest();
            if (await dest.isValid()) {
              const page = await dest.getPage();
              console.log(actionString + 'GoTo Page #' + (await page.getIndex()));
            }
          } else {
            console.log(actionString + 'Not a "GoTo" action');
          }
        } else {
          console.log(actionString + 'NULL');
        }

        if (await item.hasChildren()) {
          await printOutlineTree(await item.getFirstChild());
        }
      }
    };

    const main = async () => {
      // Relative path to the folder containing test files.
      const inputPath = '../TestFiles/';
      const outputPath = inputPath + 'Output/';
      
      // The following example illustrates how to create and edit the outline tree
      // using high-level Bookmark methods.
      try {
        let doc = await PDFNet.PDFDoc.createFromFilePath(inputPath + 'numbered.pdf');
        doc.initSecurityHandler();

        // Lets first create the root bookmark items.
        const red = await PDFNet.Bookmark.create(doc, 'Red');
        const green = await PDFNet.Bookmark.create(doc, 'Green');
        const blue = await PDFNet.Bookmark.create(doc, 'Blue');

        doc.addRootBookmark(red);
        doc.addRootBookmark(green);
        doc.addRootBookmark(blue);

        // You can also add new root bookmarks using Bookmark.addNext("...")
        blue.addNewNext('foo');
        blue.addNewNext('bar');

        // We can now associate new bookmarks with page destinations:

        // The following example creates an 'explicit' destination (see
        // section '8.2.1 Destinations' in PDF Reference for more details)
        const redIter = await doc.getPageIterator(1);
        const redCurrpage = await redIter.current();
        const redDest = await PDFNet.Destination.createFit(redCurrpage);
        red.setAction(await PDFNet.Action.createGoto(redDest));

        // Create an explicit destination to the first green page in the document
        const tenthPage = await doc.getPage(10);
        const greenDest = await PDFNet.Destination.createFit(tenthPage);
        green.setAction(await PDFNet.Action.createGoto(greenDest));

        // The following example creates a 'named' destination (see
        // section '8.2.1 Destinations' in PDF Reference for more details)
        // Named destinations have certain advantages over explicit destinations.
        const key = 'blue1';
        const nineteenthPage = await doc.getPage(19);
        const blueDest = await PDFNet.Destination.createFit(nineteenthPage);
        const blueAction = await PDFNet.Action.createGotoWithKey(key, blueDest); // TODO FIND FIX

        blue.setAction(blueAction);

        // We can now add children Bookmarks subRed1 instanceof Promise
        const subRed1 = await red.addNewChild('Red - Page 1');
        subRed1.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(1))));
        const subRed2 = await red.addNewChild('Red - Page 2');
        subRed2.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(2))));
        const subRed3 = await red.addNewChild('Red - Page 3');
        subRed3.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(3))));
        const subRed4 = await subRed3.addNewChild('Red - Page 4');
        subRed4.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(4))));
        const subRed5 = await subRed3.addNewChild('Red - Page 5');
        subRed5.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(5))));
        const subRed6 = await subRed3.addNewChild('Red - Page 6');
        subRed6.setAction(await PDFNet.Action.createGoto(await PDFNet.Destination.createFit(await doc.getPage(6))));

        // Example of how to find and delete a bookmark by title text.
        const firstbookmark = await doc.getFirstBookmark();
        const foo = await firstbookmark.find('foo');
        if (await foo.isValid()) {
          foo.delete();
        } else {
          console.log('Bookmark foo is invalid');
        }
        const bar = await firstbookmark.find('bar');
        if (await bar.isValid()) {
          bar.delete();
        } else {
          console.log('Bookmark bar is invalid');
        }

        // Adding color to Bookmarks. Color and other formatting can help readers
        // get around more easily in large PDF documents.
        red.setColor(1, 0, 0);
        green.setColor(0, 1, 0);
        green.setFlags(2); // set bold font
        blue.setColor(0, 0, 1);
        blue.setFlags(3); // set bold and italic

        await doc.save(outputPath + 'bookmark.pdf', 0);
        console.log('Done. Result saved in bookmark.pdf');
      } catch (err) {
        console.log(err);
      }

        // The following example illustrates how to traverse the outline tree using
        // Bookmark navigation methods: Bookmark.getNext(), Bookmark.getPrev(),
        // Bookmark.getFirstChild () and Bookmark.getLastChild ().
      try {
        // Open the document that was saved in the previous code sample
        const doc = await PDFNet.PDFDoc.createFromFilePath(outputPath + 'bookmark.pdf');
        doc.initSecurityHandler();

        const root = await doc.getFirstBookmark();
        await printOutlineTree(root);

        console.log('Done.');
      } catch (err) {
        console.log(err);
      }

        // The following example illustrates how to create a Bookmark to a page
        // in a remote document. A remote go-to action is similar to an ordinary
        // go-to action, but jumps to a destination in another PDF file instead
        // of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF
        // Reference Manual for details.

        try {
          // Open the document that was saved in the previous code sample
        const doc = await PDFNet.PDFDoc.createFromFilePath(outputPath + 'bookmark.pdf');
        doc.initSecurityHandler();

        // Create file specification (the file referred to by the remote bookmark)
        const fileSpec = await doc.createIndirectDict();
        fileSpec.putName('Type', 'Filespec');
        fileSpec.putString('F', 'bookmark.pdf');
        const spec = await PDFNet.FileSpec.createFromObj(fileSpec);
        const gotoRemote = await PDFNet.Action.createGotoRemoteSetNewWindow(spec, 5, true);

        const remoteBookmark1 = await PDFNet.Bookmark.create(doc, 'REMOTE BOOKMARK 1');
        remoteBookmark1.setAction(gotoRemote);
        doc.addRootBookmark(remoteBookmark1);

        // Create another remote bookmark, but this time using the low-level SDF/Cos API.
        // Create a remote action
        const remoteBookmark2 = await PDFNet.Bookmark.create(doc, 'REMOTE BOOKMARK 2');
        doc.addRootBookmark(remoteBookmark2);

        const gotoR = await (await remoteBookmark2.getSDFObj()).putDict('A');
        {
          gotoR.putName('S', 'GoToR'); // Set action type
          gotoR.putBool('NewWindow', true);

          // Set the file specification
          gotoR.put('F', fileSpec);

          // jump to the first page. Note that pages are indexed from 0.
          const dest = await gotoR.putArray('D');
          dest.pushBackNumber(9);
          dest.pushBackName('Fit');
        }

        await doc.save(inputPath + 'Output/bookmark_remote.pdf', PDFNet.SDFDoc.SaveOptions.e_linearized);

        console.log('Done. Result saved in bookmark_remote.pdf');
      } catch (err) {
        console.log(err);
      }
    };
    PDFNet.runWithCleanup(main, PDFTronLicense.Key).catch(function (error) {
      console.log('Error: ' + JSON.stringify(error));
    }).then(function () { return PDFNet.shutdown(); });
  };
  exports.runBookmarkTest();
})(exports);
// eslint-disable-next-line spaced-comment
//# sourceURL=BookmarkTest.js
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code lineNumbers="true" %}

```python
#---------------------------------------------------------------------------------------
# Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
# Consult LICENSE.txt regarding license information.
#---------------------------------------------------------------------------------------

import site
site.addsitedir("../../../PDFNetC/Lib")
import sys
from PDFNetPython import *

sys.path.append("../../LicenseKey/PYTHON")
from LicenseKey import *

#-----------------------------------------------------------------------------------------
# The sample code illustrates how to read and edit existing outline items and create 
# new bookmarks using the high-level API.
#-----------------------------------------------------------------------------------------

# Relattive path to the folder containing the test files.
input_path = "../../TestFiles/"
output_path = "../../TestFiles/Output/"

def PrintIndent(item):
    indent = item.GetIndent() - 1
    i = 0
    while i < indent:
        sys.stdout.write("  ")
        i = i + 1

# Prints out the outline tree to the standard output
def PrintOutlineTree (item):
    while item.IsValid():
        PrintIndent(item)
        if item.IsOpen():
            sys.stdout.write("- " + item.GetTitle() + " ACTION -> ")
        else:
            sys.stdout.write("+ " + item.GetTitle() + " ACTION -> ")
    
        # Print Action
        action = item.GetAction()
        if action.IsValid():
            if action.GetType() == Action.e_GoTo:
                dest = action.GetDest()
                if dest.IsValid():
                    page = dest.GetPage()
                    print("GoTo Page #" + str(page.GetIndex()))
            else:
                print("Not a 'GoTo' action")
        else:
            print("NULL")
    
        # Recursively print children sub-trees   
        if item.HasChildren():        
            PrintOutlineTree(item.GetFirstChild())
        item = item.GetNext()
            

def main():
    PDFNet.Initialize(LicenseKey)

    # The following example illustrates how to create and edit the outline tree
    # using high-level Bookmark methods.
    
    doc = PDFDoc(input_path + "numbered.pdf")
    doc.InitSecurityHandler()
    
    # Lets first create the root bookmark items. 
    red = Bookmark.Create(doc, "Red")
    green = Bookmark.Create(doc, "Green")
    blue = Bookmark.Create(doc, "Blue")
    
    doc.AddRootBookmark(red)
    doc.AddRootBookmark(green)
    doc.AddRootBookmark(blue)
    
    # You can also add new root bookmarks using Bookmark.AddNext("...")
    blue.AddNext("foo")
    blue.AddNext("bar")

    # We can now associate new bookmarks with page destinations:
    
    # The following example creates an 'explicit' destination (see 
    # section '8.2.1 Destinations' in PDF Reference for more details)
    itr = doc.GetPageIterator()
    red_dest = Destination.CreateFit(itr.Current())
    red.SetAction(Action.CreateGoto(red_dest))

    # Create an explicit destination to the first green page in the document
    green.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(10))))

    # The following example creates a 'named' destination (see 
    # section '8.2.1 Destinations' in PDF Reference for more details)
    # Named destinations have certain advantages over explicit destinations.
    key = bytearray(b"blue1")    
    blue_action = Action.CreateGoto(key, len(key), Destination.CreateFit(doc.GetPage(19)))
    
    blue.SetAction(blue_action)
    
    # We can now add children Bookmarks
    sub_red1 = red.AddChild("Red - Page 1")
    sub_red1.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(1))))
    sub_red2 = red.AddChild("Red - Page 2")
    sub_red2.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(2))))
    sub_red3 = red.AddChild("Red - Page 3")
    sub_red3.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(3))))
    sub_red4 = sub_red3.AddChild("Red - Page 4")
    sub_red4.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(4))))
    sub_red5 = sub_red3.AddChild("Red - Page 5")
    sub_red5.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(5))))
    sub_red6 = sub_red3.AddChild("Red - Page 6")
    sub_red6.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(6))))
    
    # Example of how to find and delete a bookmark by title text.
    foo = doc.GetFirstBookmark().Find("foo")
    if foo.IsValid():
        foo.Delete()
    else:
        raise Exception("Foo is not Valid")
    
    bar = doc.GetFirstBookmark().Find("bar")
    if bar.IsValid():
        bar.Delete()
    else:
        raise Exception("Bar is not Valid")
    
    # Adding color to Bookmarks. Color and other formatting can help readers 
    # get around more easily in large PDF documents.
    red.SetColor(1, 0, 0);
    green.SetColor(0, 1, 0);
    green.SetFlags(2);            # set bold font
    blue.SetColor(0, 0, 1);
    blue.SetFlags(3);             # set bold and itallic
    
    doc.Save(output_path + "bookmark.pdf", 0)
    doc.Close()
    print("Done. Result saved in bookmark.pdf")

    # The following example illustrates how to traverse the outline tree using 
    # Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(), 
    # Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
    
    # Open the document that was saved in the previous code sample
    doc = PDFDoc(output_path + "bookmark.pdf")
    doc.InitSecurityHandler()
    
    root = doc.GetFirstBookmark()
    PrintOutlineTree(root)
    
    doc.Close()
    print("Done.")
    
    # The following example illustrates how to create a Bookmark to a page 
    # in a remote document. A remote go-to action is similar to an ordinary 
    # go-to action, but jumps to a destination in another PDF file instead 
    # of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF 
    # Reference Manual for details.
    
    doc = PDFDoc(output_path + "bookmark.pdf")
    doc.InitSecurityHandler()
    
    # Create file specification (the file reffered to by the remote bookmark)
    file_spec = doc.CreateIndirectDict()
    file_spec.PutName("Type", "Filespec")
    file_spec.PutString("F", "bookmark.pdf")
    spec = FileSpec(file_spec)
    goto_remote = Action.CreateGotoRemote(spec, 5, True)
    
    remoteBookmark1 = Bookmark.Create(doc, "REMOTE BOOKMARK 1")
    remoteBookmark1.SetAction(goto_remote)
    doc.AddRootBookmark(remoteBookmark1)
    
    # Create another remote bookmark, but this time using the low-level SDF/Cos API.
    # Create a remote action
    remoteBookmark2 = Bookmark.Create(doc, "REMOTE BOOKMARK 2")
    doc.AddRootBookmark(remoteBookmark2)
    
    gotoR = remoteBookmark2.GetSDFObj().PutDict("A")
    gotoR.PutName("S","GoToR")  # Set action type
    gotoR.PutBool("NewWindow", True)
    
    # Set the file specification
    gotoR.Put("F", file_spec)
    
    # jump to the first page. Note that pages are indexed from 0.
    dest = gotoR.PutArray("D")  # Set the destination
    dest.PushBackNumber(9); 
    dest.PushBackName("Fit");
    
    doc.Save(output_path + "bookmark_remote.pdf", SDFDoc.e_linearized)
    doc.Close()
    PDFNet.Terminate()
    print("Done. Result saved in bookmark_remote.pdf")
    
if __name__ == '__main__':
    main()
```

{% endcode %}
{% endtab %}

{% tab title="PHP" %}
{% code lineNumbers="true" %}

```php
<?php
//---------------------------------------------------------------------------------------
// Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
// Consult LICENSE.txt regarding license information.
//---------------------------------------------------------------------------------------
if(file_exists("../../../PDFNetC/Lib/PDFNetPHP.php"))

include("../../../PDFNetC/Lib/PDFNetPHP.php");
include("../../LicenseKey/PHP/LicenseKey.php");

//---------------------------------------------------------------------------------------
// The sample code illustrates how to read and edit existing outline items and create 
// new bookmarks using the high-level API.
//---------------------------------------------------------------------------------------	

function PrintIndent ($item) {
	$ident = $item->GetIndent() - 1;
	for ($i=0; $i<$ident; ++$i) {
		echo "    ";
	}
}

// Prints out the outline tree to the standard output
function PrintOutlineTree($item) {
	for (; $item->IsValid(); $item=$item->GetNext())
	{
		PrintIndent($item);
		echo ($item->IsOpen() ? "- " : "+ ").$item->GetTitle()." ACTION -> ";

		// Print Action
		$action = $item->GetAction();
		if ($action->IsValid()) {
			if ($action->GetType() == Action::e_GoTo) {
				$dest = $action->GetDest();
				if ($dest->IsValid()) {
					$page = $dest->GetPage();
					echo nl2br("GoTo Page #".$page->GetIndex()."\n");
				}
			}
			else {
				echo nl2br("Not a 'GoTo' action\n");
			}
		} else {
			echo nl2br("NULL\n");
		}

		if ($item->HasChildren())	 // Recursively print children sub-trees
		{
			PrintOutlineTree($item->GetFirstChild());
		}
	}
}
	PDFNet::Initialize($LicenseKey);
	PDFNet::GetSystemFontList();    // Wait for fonts to be loaded if they haven't already. This is done because PHP can run into errors when shutting down if font loading is still in progress.

	// Relative path to the folder containing the test files.
	$input_path = getcwd()."/../../TestFiles/";
	$output_path = $input_path."Output/";

	// The following example illustrates how to create and edit the outline tree 
	// using high-level Bookmark methods.
	$doc = new PDFDoc($input_path."numbered.pdf");
	$doc->InitSecurityHandler();

	// Lets first create the root bookmark items. 
	$red = Bookmark::Create($doc, "Red");
	$green = Bookmark::Create($doc, "Green");
	$blue = Bookmark::Create($doc, "Blue");

	$doc->AddRootBookmark($red);
	$doc->AddRootBookmark($green);
	$doc->AddRootBookmark($blue);

	// You can also add new root bookmarks using $bookmark->AddNext("...")
	$blue->AddNext("foo");
	$blue->AddNext("bar");

	// We can now associate new bookmarks with page destinations:

	// The following example creates an 'explicit' destination (see 
	// section '8.2.1 Destinations' in PDF Reference for more details)
	$ir= $doc->GetPageIterator();
	$red_dest = Destination::CreateFit($ir->Current());
	$red->SetAction(Action::CreateGoto($red_dest));

	// Create an explicit destination to the first green page in the document
	$green->SetAction(Action::CreateGoto(Destination::CreateFit($doc->GetPage(10)) ));

	// The following example creates a 'named' destination (see 
	// section '8.2.1 Destinations' in PDF Reference for more details)
	// Named destinations have certain advantages over explicit destinations.
	$key = "blue1";
	$blue_action = Action::CreateGoto($key, strlen($key), Destination::CreateFit($doc->GetPage(19)));

	$blue->SetAction($blue_action);

	// We can now add children Bookmarks
	$sub_red1 = $red->AddChild("Red - Page 1");
	$sub_red1->SetAction(Action::CreateGoto(Destination::CreateFit($doc->GetPage(1))));
	$sub_red2 = $red->AddChild("Red - Page 2");
	$sub_red2->SetAction(Action::CreateGoto(Destination::CreateFit($doc->GetPage(2))));
	$sub_red3 = $red->AddChild("Red - Page 3");
	$sub_red3->SetAction(Action::CreateGoto(Destination::CreateFit($doc->GetPage(3))));
	$sub_red4 = $sub_red3->AddChild("Red - Page 4");
	$sub_red4->SetAction(Action::CreateGoto(Destination::CreateFit($doc->GetPage(4))));
	$sub_red5 = $sub_red3->AddChild("Red - Page 5");
	$sub_red5->SetAction(Action::CreateGoto(Destination::CreateFit($doc->GetPage(5))));
	$sub_red6 = $sub_red3->AddChild("Red - Page 6");
	$sub_red6->SetAction(Action::CreateGoto(Destination::CreateFit($doc->GetPage(6))));
	
	// Example of how to find and delete a bookmark by title text.
	$foo = $doc->GetFirstBookmark()->Find("foo");
	if ($foo->IsValid()) 
	{
		$foo->Delete();
	}
	else 
	{
		assert(false);
	}

	$bar = $doc->GetFirstBookmark()->Find("bar");
	if ($bar->IsValid()) 
	{
		$bar->Delete();
	}
	else 
	{
		assert(false);
	}

	// Adding color to Bookmarks. Color and other formatting can help readers 
	// get around more easily in large PDF documents.
	$red->SetColor(1.0, 0.0, 0.0);
	$green->SetColor(0.0, 1.0, 0.0);
	$green->SetFlags(2);			// set bold font
	$blue->SetColor(0.0, 0.0, 1.0);
	$blue->SetFlags(3);			// set bold and italic

	$doc->Save($output_path."bookmark.pdf", 0);
	echo nl2br("Done. Result saved in bookmark.pdf\n");

	// The following example illustrates how to traverse the outline tree using 
	// Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(), 
	// Bookmark.GetFirstChild () and Bookmark.GetLastChild ().

	// Open the document that was saved in the previous code sample
	$doc = new PDFDoc($output_path."bookmark.pdf");
	$doc->InitSecurityHandler();

	$root = $doc->GetFirstBookmark();
	PrintOutlineTree($root);
	echo nl2br("Done.\n");

	// The following example illustrates how to create a Bookmark to a page 
	// in a remote document. A remote go-to action is similar to an ordinary 
	// go-to action, but jumps to a destination in another PDF file instead 
	// of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF 
	// Reference Manual for details.

	// Open the document that was saved in the previous code sample
	$doc = new PDFDoc($output_path."bookmark.pdf");
	$doc->InitSecurityHandler();

	// Create file specification (the file referred to by the remote bookmark)
	$file_spec = $doc->CreateIndirectDict(); 
	$file_spec->PutName("Type", "Filespec");
	$file_spec->PutString("F", "bookmark.pdf");
	$spec = new FileSpec($file_spec);
	$goto_remote = Action::CreateGotoRemote($spec, 5, true);

	$remoteBookmark1 = Bookmark::Create($doc, "REMOTE BOOKMARK 1");
	$remoteBookmark1->SetAction($goto_remote);
	$doc->AddRootBookmark($remoteBookmark1);

	// Create another remote bookmark, but this time using the low-level SDF/Cos API.
	// Create a remote action
	$remoteBookmark2 = Bookmark::Create($doc, "REMOTE BOOKMARK 2");
	$doc->AddRootBookmark($remoteBookmark2);

	$gotoR = $remoteBookmark2->GetSDFObj()->PutDict("A");
	
	$gotoR->PutName("S","GoToR"); // Set action type
	$gotoR->PutBool("NewWindow", true);

	// Set the file specification
	$gotoR->Put("F", $file_spec);

	// jump to the first page. Note that pages are indexed from 0.
	$dest = $gotoR->PutArray("D");  // Set the destination
	$dest->PushBackNumber(9); 
	$dest->PushBackName("Fit");

	$doc->Save($output_path."bookmark_remote.pdf", SDFDoc::e_linearized);
	PDFNet::Terminate();
	echo nl2br("Done. Result saved in bookmark_remote.pdf\n");
?>
```

{% endcode %}
{% endtab %}

{% tab title="Ruby" %}
{% code lineNumbers="true" %}

```ruby
#---------------------------------------------------------------------------------------
# Copyright (c) 2001-2023 by Apryse Software Inc. All Rights Reserved.
# Consult LICENSE.txt regarding license information.
#---------------------------------------------------------------------------------------

require '../../../PDFNetC/Lib/PDFNetRuby'
include PDFNetRuby
require '../../LicenseKey/RUBY/LicenseKey'

$stdout.sync = true

#-----------------------------------------------------------------------------------------
# The sample code illustrates how to read and edit existing outline items and create 
# new bookmarks using the high-level API.
#-----------------------------------------------------------------------------------------

# Relattive path to the folder containing the test files.
input_path = "../../TestFiles/"
output_path = "../../TestFiles/Output/"

def PrintIndent(item)
	indent = item.GetIndent() - 1
	i = 0
	while i < indent do
		print "  "
		i = i + 1
	end
end

# Prints out the outline tree to the standard output
def PrintOutlineTree (item)
	while item.IsValid() do
		PrintIndent(item)
		if item.IsOpen()
			print( "- " + item.GetTitle() + " ACTION -> ")
		else
			print("+ " + item.GetTitle() + " ACTION -> ")
		end
	
		# Print Action
		action = item.GetAction()
		if action.IsValid()
			if action.GetType() == Action::E_GoTo
				dest = action.GetDest()
				if dest.IsValid()
					page = dest.GetPage()
					puts "GoTo Page #" + page.GetIndex().to_s()
				end
			else
				puts "Not a 'GoTo' action"
			end
		else
			puts "NIL"
		end
	
		# Recursively print children sub-trees   
		if item.HasChildren() 
			PrintOutlineTree(item.GetFirstChild())
		end
		item = item.GetNext()
	end
end

	PDFNet.Initialize(PDFTronLicense.Key)


	# The following example illustrates how to create and edit the outline tree
	# using high-level Bookmark methods.
	
	doc = PDFDoc.new(input_path + "numbered.pdf")
	doc.InitSecurityHandler()
	
	# Lets first create the root bookmark items. 
	red = Bookmark.Create(doc, "Red")
	green = Bookmark.Create(doc, "Green")
	blue = Bookmark.Create(doc, "Blue")
	
	doc.AddRootBookmark(red)
	doc.AddRootBookmark(green)
	doc.AddRootBookmark(blue)
	
	# You can also add new root bookmarks using Bookmark.AddNext("...")
	blue.AddNext("foo")
	blue.AddNext("bar")

	# We can now associate new bookmarks with page destinations:
	
	# The following example creates an 'explicit' destination (see 
	# section '8.2.1 Destinations' in PDF Reference for more details)
	itr = doc.GetPageIterator()
	red_dest = Destination.CreateFit(itr.Current())
	red.SetAction(Action.CreateGoto(red_dest))

	# Create an explicit destination to the first green page in the document
	green.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(10))))

	# The following example creates a 'named' destination (see 
	# section '8.2.1 Destinations' in PDF Reference for more details)
	# Named destinations have certain advantages over explicit destinations.
	key = "blue1"
	blue_action = Action.CreateGoto(key, key.length, Destination.CreateFit(doc.GetPage(19)))
	
	blue.SetAction(blue_action)
	
	# We can now add children Bookmarks
	sub_red1 = red.AddChild("Red - Page 1")
	sub_red1.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(1))))
	sub_red2 = red.AddChild("Red - Page 2")
	sub_red2.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(2))))
	sub_red3 = red.AddChild("Red - Page 3")
	sub_red3.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(3))))
	sub_red4 = sub_red3.AddChild("Red - Page 4")
	sub_red4.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(4))))
	sub_red5 = sub_red3.AddChild("Red - Page 5")
	sub_red5.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(5))))
	sub_red6 = sub_red3.AddChild("Red - Page 6")
	sub_red6.SetAction(Action.CreateGoto(Destination.CreateFit(doc.GetPage(6))))
	
	# Example of how to find and delete a bookmark by title text.
	foo = doc.GetFirstBookmark().Find("foo")
	if foo.IsValid()
		foo.Delete()
	else
		raise "Foo is not Valid"
	end
	
	bar = doc.GetFirstBookmark().Find("bar")
	if bar.IsValid()
		bar.Delete()
	else
		raise "Bar is not Valid"
	end
	
	# Adding color to Bookmarks. Color and other formatting can help readers 
	# get around more easily in large PDF documents.
	red.SetColor(1, 0, 0);
	green.SetColor(0, 1, 0);
	green.SetFlags(2);	# set bold font
	blue.SetColor(0, 0, 1);
	blue.SetFlags(3);	# set bold and itallic
	
	doc.Save(output_path + "bookmark.pdf", 0)
	doc.Close()
	puts "Done. Result saved in bookmark.pdf"

	# The following example illustrates how to traverse the outline tree using 
	# Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(), 
	# Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
	
	# Open the document that was saved in the previous code sample
	doc = PDFDoc.new(output_path + "bookmark.pdf")
	doc.InitSecurityHandler()
	
	root = doc.GetFirstBookmark()
	PrintOutlineTree(root)
	
	doc.Close()
	puts "Done."
	
	# The following example illustrates how to create a Bookmark to a page 
	# in a remote document. A remote go-to action is similar to an ordinary 
	# go-to action, but jumps to a destination in another PDF file instead 
	# of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF 
	# Reference Manual for details.
	
	doc = PDFDoc.new(output_path + "bookmark.pdf")
	doc.InitSecurityHandler()
	
	# Create file specification (the file reffered to by the remote bookmark)
	file_spec = doc.CreateIndirectDict()
	file_spec.PutName("Type", "Filespec")
	file_spec.PutString("F", "bookmark.pdf")
	spec = FileSpec.new(file_spec)
	goto_remote = Action.CreateGotoRemote(spec, 5, true)
	
	remoteBookmark1 = Bookmark.Create(doc, "REMOTE BOOKMARK 1")
	remoteBookmark1.SetAction(goto_remote)
	doc.AddRootBookmark(remoteBookmark1)
	
	# Create another remote bookmark, but this time using the low-level SDF/Cos API.
	# Create a remote action
	remoteBookmark2 = Bookmark.Create(doc, "REMOTE BOOKMARK 2")
	doc.AddRootBookmark(remoteBookmark2)
	
	gotoR = remoteBookmark2.GetSDFObj().PutDict("A")
	gotoR.PutName("S","GoToR")  # Set action type
	gotoR.PutBool("NewWindow", true)
	
	# Set the file specification
	gotoR.Put("F", file_spec)
	
	# jump to the first page. Note that pages are indexed from 0.
	dest = gotoR.PutArray("D")  # Set the destination
	dest.PushBackNumber(9); 
	dest.PushBackName("Fit");
	
	doc.Save(output_path + "bookmark_remote.pdf", SDFDoc::E_linearized)
	doc.Close()
	PDFNet.Terminate
	puts "Done. Result saved in bookmark_remote.pdf"
```

{% endcode %}
{% endtab %}

{% tab title="VB" %}
{% code lineNumbers="true" %}

```vb
'
' Copyright (c) 2001-2024 by Apryse Software Inc. All Rights Reserved.
'

Imports System

Imports pdftron
Imports pdftron.Common
Imports pdftron.Filters
Imports pdftron.SDF
Imports pdftron.PDF

Module BookmarkTestVB2003
    Dim pdfNetLoader As PDFNetLoader
    Sub New()
        pdfNetLoader = pdftron.PDFNetLoader.Instance()
    End Sub
    '-----------------------------------------------------------------------------------------
    ' The sample code illustrates how to read, write, and edit existing outline items 
    ' and create new bookmarks using both the high-level and the SDF/Cos API.
    '-----------------------------------------------------------------------------------------
    Sub Main()
        BookmarkTest.RunTest()
    End Sub


    Class BookmarkTest

        Public Shared Sub PrintIndent(ByVal item As Bookmark)
            Dim indent As Integer = item.GetIndent() - 1
            Dim i As Integer
            For i = 1 To indent
                Console.Write("  ")
            Next
        End Sub

        Public Shared Sub PrintOutlineTree(ByVal item As Bookmark)

            Do While item.IsValid()

                PrintIndent(item)
                If item.IsOpen Then
                    Console.Write("- {0:s} ACTION -> ", item.GetTitle())
                Else
                    Console.Write("+ {0:s} ACTION -> ", item.GetTitle())
                End If


                ' Print Action
                Dim action As pdftron.PDF.Action = item.GetAction()
                If action.IsValid() Then
                    If action.GetType() = pdftron.PDF.Action.Type.e_GoTo Then
                        Dim dest As Destination = action.GetDest()
                        If (dest.IsValid()) Then
                            Dim page As Page = dest.GetPage()
                            Console.WriteLine("GoTo Page #{0:d}", page.GetIndex())
                        End If
                    Else
                        Console.WriteLine("Not a 'GoTo' action")
                    End If
                Else
                    Console.WriteLine("NULL")
                End If

                If item.HasChildren() Then   ' Recursively print children sub-trees
                    PrintOutlineTree(item.GetFirstChild())
                End If
                item = item.GetNext()
            Loop
        End Sub


        Shared Sub RunTest()

            PDFNet.Initialize(PDFTronLicense.Key)

            ' Relative path to the folder containing test files.
            Dim input_path As String = "../../../../TestFiles/"
            Dim output_path As String = "../../../../TestFiles/Output/"


            ' The following example illustrates how to create and edit the outline tree 
            ' using high-level Bookmark methods.
            Try
                Using doc1 As PDFDoc = New PDFDoc(input_path + "numbered.pdf")
                    doc1.InitSecurityHandler()


                    ' Lets first create the root bookmark items. 
                    Dim red As Bookmark = Bookmark.Create(doc1, "Red")
                    Dim green As Bookmark = Bookmark.Create(doc1, "Green")
                    Dim blue As Bookmark = Bookmark.Create(doc1, "Blue")

                    doc1.AddRootBookmark(red)
                    doc1.AddRootBookmark(green)
                    doc1.AddRootBookmark(blue)

                    ' You can also add new root bookmarks using Bookmark.AddNext("...")
                    blue.AddNext("foo")
                    blue.AddNext("bar")

                    ' We can now associate new bookmarks with page destinations:

                    ' The following example creates an 'explicit' destination (see 
                    ' section '8.2.1 Destinations' in PDF Reference for more details)
                    Dim red_dest As Destination = Destination.CreateFit(doc1.GetPage(1))
                    red.SetAction(pdftron.PDF.Action.CreateGoto(red_dest))

                    ' Create an explicit destination to the first green page in the document
                    green.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc1.GetPage(10))))

                    ' The following example creates a 'named' destination (see 
                    ' section '8.2.1 Destinations' in PDF Reference for more details)
                    ' Named destinations have certain advantages over explicit destinations.
                    Dim key As String = "blue1"
                    Dim blue_action As pdftron.PDF.Action = pdftron.PDF.Action.CreateGoto(key, Destination.CreateFit(doc1.GetPage(19)))

                    blue.SetAction(blue_action)

                    ' We can now add children Bookmarks
                    Dim sub_red1 As Bookmark = red.AddChild("Red - Page 1")
                    sub_red1.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc1.GetPage(1))))
                    Dim sub_red2 As Bookmark = red.AddChild("Red - Page 2")
                    sub_red2.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc1.GetPage(2))))
                    Dim sub_red3 As Bookmark = red.AddChild("Red - Page 3")
                    sub_red3.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc1.GetPage(3))))
                    Dim sub_red4 As Bookmark = sub_red3.AddChild("Red - Page 4")
                    sub_red4.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc1.GetPage(4))))
                    Dim sub_red5 As Bookmark = sub_red3.AddChild("Red - Page 5")
                    sub_red5.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc1.GetPage(5))))
                    Dim sub_red6 As Bookmark = sub_red3.AddChild("Red - Page 6")
                    sub_red6.SetAction(pdftron.PDF.Action.CreateGoto(Destination.CreateFit(doc1.GetPage(6))))

                    ' Example of how to find and delete a bookmark by title text.
                    Dim foo As Bookmark = doc1.GetFirstBookmark().Find("foo")
                    If foo.IsValid() Then
                        foo.Delete()
                    End If
                    Dim bar As Bookmark = doc1.GetFirstBookmark().Find("bar")
                    If bar.IsValid() Then
                        bar.Delete()
                    End If

                    ' Adding color to Bookmarks. Color and other formatting can help readers 
                    ' get around more easily in large PDF documents.
                    red.SetColor(1, 0, 0)
                    green.SetColor(0, 1, 0)
                    green.SetFlags(2)     ' set bold font
                    blue.SetColor(0, 0, 1)
                    blue.SetFlags(3)   ' set bold and italic

                    doc1.Save(output_path + "bookmark.pdf", 0)
                End Using
                Console.WriteLine("Done. Result saved in bookmark.pdf")
            Catch e As PDFNetException
                Console.WriteLine(e.Message)
            End Try


            ' The following example illustrates how to traverse the outline tree using 
            ' Bookmark navigation methods: Bookmark.GetNext(), Bookmark.GetPrev(), 
            ' Bookmark.GetFirstChild () and Bookmark.GetLastChild ().
            Try
                ' Open the document that was saved in the previous code sample
                Using doc1 As PDFDoc = New PDFDoc(output_path + "bookmark.pdf")
                    doc1.InitSecurityHandler()

                    Dim root As Bookmark = doc1.GetFirstBookmark()
                    PrintOutlineTree(root)
                    Console.WriteLine("Done.")
                End Using
            Catch e As PDFNetException
                Console.WriteLine(e.Message)
            End Try

            ' The following example illustrates how to create a Bookmark to a page 
            ' in a remote document. A remote go-to action is similar to an ordinary 
            ' go-to action, but jumps to a destination in another PDF file instead 
            ' of the current file. See Section 8.5.3 'Remote Go-To Actions' in PDF 
            ' Reference Manual for details.
            Try
                Using doc1 As PDFDoc = New PDFDoc(output_path + "bookmark.pdf")
                    doc1.InitSecurityHandler()

                    ' Create file specification (the file referred to by the remote bookmark)
                    Dim file_spec As Obj = doc1.CreateIndirectDict()
                    file_spec.PutName("Type", "Filespec")
                    file_spec.PutString("F", "bookmark.pdf")

                    Dim spec As FileSpec = New FileSpec(file_spec)
                    Dim goto_remote As pdftron.PDF.Action = pdftron.PDF.Action.CreateGotoRemote(spec, 5, True)

                    Dim remoteBookmark1 As Bookmark = Bookmark.Create(doc1, "REMOTE BOOKMARK 1")
                    remoteBookmark1.SetAction(goto_remote)
                    doc1.AddRootBookmark(remoteBookmark1)

                    ' Create another remote bookmark, but this time using the low-level SDF/Cos API.
                    Dim remoteBookmark2 As Bookmark = Bookmark.Create(doc1, "REMOTE BOOKMARK 2")
                    doc1.AddRootBookmark(remoteBookmark2)
                    Dim gotoR As Obj = remoteBookmark2.GetSDFObj().PutDict("A")

                    gotoR.PutName("S", "GoToR")  ' Set action type
                    gotoR.PutBool("NewWindow", True)

                    ' Set the file specification
                    gotoR.Put("F", file_spec)

                    ' Set the destination
                    Dim dest As Obj = gotoR.PutArray("D")
                    dest.PushBackNumber(9) ' Jump to the tenth page. Note that Acrobat indexes pages from 0.
                    dest.PushBackName("Fit") ' Fit the page

                    doc1.Save(output_path + "bookmark_remote.pdf", SDFDoc.SaveOptions.e_linearized)
                End Using
                Console.WriteLine("Done. Result saved in bookmark_remote.pdf")
            Catch e As PDFNetException
                Console.WriteLine(e.Message)
            End Try
            PDFNet.Terminate()
        End Sub

    End Class

End Module
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/core/get-started/samples/bookmarktest.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
