> ## Documentation Index
> Fetch the complete documentation index at: https://developer.kodexa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Notes

> Add human-readable annotations and comments to Kodexa documents, data objects, and data attributes using notes that support multiple content formats.

Notes provide a way to attach human-readable annotations, comments, and documentation to documents, data objects, and data attributes. They support multiple content formats and hierarchical organization.

## Overview

Notes support:

* **Multiple Content Types**: TEXT, MARKDOWN, or HTML
* **Attachment to Entities**: Link notes to data objects or data attributes
* **Hierarchical Structure**: Create parent-child note relationships
* **Grouping**: Organize related notes with group keys
* **Custom Properties**: Attach arbitrary metadata to notes

## Creating Notes

<CodeGroup>
  ```python Python theme={null}
  from kodexa_document import Document
  from kodexa_document.accessors import NoteInput, NoteType, DataObjectInput

  with Document() as doc:
      root = doc.create_node("document", "Invoice")
      doc.content_node = root

      # Create a simple text note
      note = doc.notes.create(NoteInput(
          title="Review Comment",
          content="This invoice needs manager approval.",
          note_type=NoteType.text
      ))
      print(f"Created note: {note}")

      # Create a markdown note
      doc.notes.create(NoteInput(
          title="Processing Notes",
          content="## Summary\n- Vendor: Acme Corp\n- Status: **Pending Review**",
          note_type=NoteType.markdown
      ))

      # Create a note attached to a data object
      invoice = doc.data_objects.create(DataObjectInput(path="/invoice"))
      doc.notes.create(NoteInput(
          title="Extraction Note",
          content="Confidence is low for the total amount field.",
          note_type=NoteType.text,
          data_object_id=invoice['id']
      ))
  ```

  ```typescript TypeScript theme={null}
  import { Kodexa } from '@kodexa-ai/document-wasm-ts';

  async function createNotes() {
    await Kodexa.init();
    const doc = await Kodexa.createDocument();

    try {
      // Create a simple text note
      const note = await doc.notes.create({
        title: 'Review Comment',
        content: 'This invoice needs manager approval.',
        noteType: 'TEXT'
      });
      console.log(`Created note: ${note.id}`);

      // Create a markdown note
      await doc.notes.create({
        title: 'Processing Notes',
        content: '## Summary\n- Vendor: Acme Corp\n- Status: **Pending Review**',
        noteType: 'MARKDOWN'
      });

      // Create a note attached to a data object
      const invoice = await doc.dataObjects.create({ path: '/invoice' });
      await doc.notes.create({
        title: 'Extraction Note',
        content: 'Confidence is low for the total amount field.',
        noteType: 'TEXT',
        dataObjectId: invoice.id
      });
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

### Notes with Properties

Attach custom metadata to notes:

<CodeGroup>
  ```python Python theme={null}
  with Document() as doc:
      root = doc.create_node("document", "Content")
      doc.content_node = root

      doc.notes.create(NoteInput(
          title="QA Review",
          content="Reviewed and approved by QA team.",
          note_type=NoteType.text,
          properties={
              "reviewer": "jane.doe@example.com",
              "reviewDate": "2024-01-15",
              "status": "approved",
              "priority": "high"
          }
      ))
  ```

  ```typescript TypeScript theme={null}
  async function noteWithProperties() {
    await Kodexa.init();
    const doc = await Kodexa.createDocument();

    try {
      await doc.notes.create({
        title: 'QA Review',
        content: 'Reviewed and approved by QA team.',
        noteType: 'TEXT',
        properties: {
          reviewer: 'jane.doe@example.com',
          reviewDate: '2024-01-15',
          status: 'approved',
          priority: 'high'
        }
      });
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

### Hierarchical Notes

Create threaded conversations with parent-child notes:

<CodeGroup>
  ```python Python theme={null}
  with Document() as doc:
      root = doc.create_node("document", "Content")
      doc.content_node = root

      # Create a parent note
      parent = doc.notes.create(NoteInput(
          title="Discussion",
          content="Should we flag this for review?",
          note_type=NoteType.text
      ))

      # Create reply notes
      doc.notes.create(NoteInput(
          content="Yes, the confidence scores are below threshold.",
          note_type=NoteType.text,
          parent_note_id=parent['id']
      ))

      doc.notes.create(NoteInput(
          content="Agreed. I've escalated to the review queue.",
          note_type=NoteType.text,
          parent_note_id=parent['id']
      ))

      # Get root-level notes (no parent)
      root_notes = doc.notes.get_root_notes()
      print(f"Top-level notes: {len(root_notes)}")

      # Get replies
      for note in root_notes:
          children = doc.notes.get_child_notes(note['id'])
          print(f"  Replies: {len(children)}")
  ```

  ```typescript TypeScript theme={null}
  async function hierarchicalNotes() {
    await Kodexa.init();
    const doc = await Kodexa.createDocument();

    try {
      // Create a parent note
      const parent = await doc.notes.create({
        title: 'Discussion',
        content: 'Should we flag this for review?',
        noteType: 'TEXT'
      });

      // Create reply notes
      await doc.notes.create({
        content: 'Yes, the confidence scores are below threshold.',
        noteType: 'TEXT',
        parentNoteId: parent.id
      });

      await doc.notes.create({
        content: 'Agreed. I\'ve escalated to the review queue.',
        noteType: 'TEXT',
        parentNoteId: parent.id
      });

      // Get root-level notes
      const rootNotes = await doc.notes.getRootNotes();
      console.log(`Top-level notes: ${rootNotes.length}`);

      // Get replies
      for (const note of rootNotes) {
        const children = await doc.notes.getChildNotes(note.id);
        console.log(`  Replies: ${children.length}`);
      }
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

## Retrieving Notes

<CodeGroup>
  ```python Python theme={null}
  with Document.from_kddb("processed.kddb") as doc:
      # Get all notes
      all_notes = doc.notes.get_all()
      print(f"Total notes: {len(all_notes)}")

      # Get notes for a specific data object
      obj_notes = doc.notes.get_by_data_object_id(data_object_id=1)

      # Get notes for a specific data attribute
      attr_notes = doc.notes.get_by_data_attribute_id(data_attribute_id=1)

      # Get notes by type
      markdown_notes = doc.notes.get_by_type("MARKDOWN")

      # Get by UUID
      note = doc.notes.get_by_uuid("note-uuid")

      # Get by group
      grouped = doc.notes.get_by_group_uuid("group-uuid")
  ```

  ```typescript TypeScript theme={null}
  async function retrieveNotes() {
    await Kodexa.init();
    const doc = await Kodexa.fromBlob(kddbBlob);

    try {
      // Get all notes
      const allNotes = await doc.notes.getAll();
      console.log(`Total notes: ${allNotes.length}`);

      // Get notes for a specific data object
      const objNotes = await doc.notes.getByDataObjectID(1);

      // Get notes for a specific data attribute
      const attrNotes = await doc.notes.getByDataAttributeID(1);

      // Get notes by type
      const markdownNotes = await doc.notes.getByType('MARKDOWN');

      // Get by ID
      const note = await doc.notes.getByID(1);

      // Get by group key
      const grouped = await doc.notes.getByGroupKey('group-key');
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

## Updating and Deleting Notes

<CodeGroup>
  ```python Python theme={null}
  with Document.from_kddb("processed.kddb") as doc:
      # Update a note
      doc.notes.update(note_id=1, input=NoteInput(
          title="Updated Title",
          content="Updated content with corrections.",
          note_type=NoteType.text
      ))

      # Delete a note
      doc.notes.delete(note_id=1)
  ```

  ```typescript TypeScript theme={null}
  async function modifyNotes() {
    await Kodexa.init();
    const doc = await Kodexa.fromBlob(kddbBlob);

    try {
      // Get and update a note
      const note = await doc.notes.getByID(1);
      if (note) {
        note.title = 'Updated Title';
        note.content = 'Updated content with corrections.';
        await doc.notes.update(note);
      }

      // Delete a note
      await doc.notes.delete(1);
    } finally {
      doc.dispose();
    }
  }
  ```
</CodeGroup>

## NoteInput Reference

| Field          | Python              | TypeScript        | Description                   |
| -------------- | ------------------- | ----------------- | ----------------------------- |
| Content        | `content`           | `content`         | The note text (required)      |
| Title          | `title`             | `title`           | Optional note title           |
| Type           | `note_type`         | `noteType`        | `TEXT`, `MARKDOWN`, or `HTML` |
| Data Object    | `data_object_id`    | `dataObjectId`    | Attach to a data object       |
| Data Attribute | `data_attribute_id` | `dataAttributeId` | Attach to a data attribute    |
| Parent Note    | `parent_note_id`    | `parentNoteId`    | Create as a child note        |
| Group          | `group_uuid`        | `groupKey`        | Group related notes           |
| Properties     | `properties`        | `properties`      | Custom metadata dictionary    |

## API Reference

### NoteAccessor Methods

| Method (Python)                | Method (TypeScript)        | Description                |
| ------------------------------ | -------------------------- | -------------------------- |
| `get_all()`                    | `getAll()`                 | Get all notes              |
| `get_by_data_object_id(id)`    | `getByDataObjectID(id)`    | Notes for a data object    |
| `get_by_data_attribute_id(id)` | `getByDataAttributeID(id)` | Notes for a data attribute |
| `create(input)`                | `create(input)`            | Create a new note          |
| `update(id, input)`            | `update(note)`             | Update a note              |
| `delete(id)`                   | `delete(id)`               | Delete a note              |
| `get_by_uuid(uuid)`            | `getByID(id)`              | Get a specific note        |
| `get_by_type(type)`            | `getByType(type)`          | Filter by content type     |
| `get_by_group_uuid(uuid)`      | `getByGroupKey(key)`       | Get grouped notes          |
| `get_root_notes()`             | `getRootNotes()`           | Get top-level notes        |
| `get_child_notes(id)`          | `getChildNotes(id)`        | Get replies/children       |
