v3.2.3

NoteStream AI API

All AI endpoints require an API key passed via the X-API-Key header. API keys can be created from Settings > API Keys in the NoteStream app.

X-API-Key: your-api-key-here

A note and its content are separate entities with a 1:1 mapping. A note holds metadata (ID, author, permissions, timestamps), while note content holds the document body as ProseMirror JSON. Every note has exactly one content record, and they share the same ID. The root node is always { type: "doc", content: [...] }.


Search notes

Search for notes by text content. Returns matching note IDs with a plain text snippet (first 300 characters). Results are paginated with a fixed page size of 100.

GET /ai/search?query=meeting&page=1

Query parameters

NameTypeRequiredDescription
querystringYesThe search text. Case-insensitive substring match.
pagenumberNoPage number (starts at 1). Defaults to 1.

Response

{
  "results": [
    {
      "noteId": "0192d4e5-7a8b-7c6d-9e0f-1a2b3c4d5e6f",
      "snippet": "Meeting notes from the Q2 planning session..."
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 100,
    "totalResults": 250,
    "totalPages": 3,
    "hasNext": true,
    "hasPrevious": false
  }
}

Errors

StatusDescription
401Missing or invalid API key
422Missing or invalid query parameter

Get a note

Retrieve the metadata of a note.

GET /ai/note/:id

Parameters

NameInTypeDescription
idpathstringThe note ID (UUID)

Response

{
  "id": "0192d4e5-7a8b-7c6d-9e0f-1a2b3c4d5e6f",
  "authorId": "user-uuid",
  "isPublished": false,
  "publishedAt": null,
  "accessMode": "EDITABLE",
  "accessEmails": [],
  "pinnedPosition": null,
  "folderId": null,
  "deletedAt": null,
  "createdAt": 1711900800000,
  "updatedAt": 1711900800000
}

Errors

StatusDescription
401Missing or invalid API key
404Note not found or not owned by the API key's user

Update a note

Update the metadata of an existing note. All fields are optional.

PATCH /ai/note/:id

Parameters

NameInTypeDescription
idpathstringThe note ID (UUID)

Request body

{
  "isPublished": true,
  "accessMode": "READONLY",
  "accessEmails": ["collaborator@example.com"]
}
FieldTypeRequiredDescription
isPublishedbooleanNoPublish or unpublish the note.
accessModestringNo"EDITABLE" or "READONLY".
accessEmailsstring[]NoList of email addresses that can access the note.

Response

Returns the updated note object (same shape as GET /ai/note/:id).

Errors

StatusDescription
401Missing or invalid API key
404Note not found or not owned by the API key's user
422Invalid request body

Note: When a note is published (isPublished: true), it becomes accessible via a shareable link. The URL is constructed by removing dashes from the note ID: https://notestream.cloud/shared/note/{noteId without dashes}. For example, note 0192d4e5-7a8b-7c6d-9e0f-1a2b3c4d5e6f becomes https://notestream.cloud/shared/note/0192d4e57a8b7c6d9e0f1a2b3c4d5e6f.


Read note content

Retrieve the content of a note as ProseMirror JSON.

GET /ai/content/:id

Parameters

NameInTypeDescription
idpathstringThe note ID (UUID)

Response

{
  "content": {
    "type": "doc",
    "content": [
      {
        "type": "paragraph",
        "content": [
          { "type": "text", "text": "Hello world" }
        ]
      }
    ]
  }
}

If the note has no content, returns an empty document:

{
  "content": {
    "type": "doc",
    "content": [{ "type": "paragraph" }]
  }
}

Errors

StatusDescription
401Missing or invalid API key
404Note not found or not owned by the API key's user

Replace note content

Replace the entire content of an existing note with new ProseMirror JSON.

PUT /ai/content/:id

Parameters

NameInTypeDescription
idpathstringThe note ID (UUID)

Request body

{
  "content": {
    "type": "doc",
    "content": [
      {
        "type": "paragraph",
        "content": [
          { "type": "text", "text": "Updated content" }
        ]
      }
    ]
  }
}

The content field must be a valid ProseMirror document with type: "doc" and a content array.

Response

{ "success": true }

Errors

StatusDescription
401Missing or invalid API key
404Note not found or not owned by the API key's user
422Invalid ProseMirror JSON structure

Create a note

Create a new note with the given ProseMirror JSON content. The note is assigned to the user who owns the API key.

POST /ai/note

Request body

{
  "content": {
    "type": "doc",
    "content": [
      {
        "type": "paragraph",
        "content": [
          { "type": "text", "text": "A brand new note" }
        ]
      }
    ]
  },
  "isPublished": true
}
FieldTypeRequiredDescription
contentobjectYesProseMirror document with type: "doc"
isPublishedbooleanNoSet to true to publish the note on creation. Defaults to false.
accessModestringNo"EDITABLE" or "READONLY". Defaults to "EDITABLE".
accessEmailsstring[]NoList of email addresses that can access the note. Defaults to [] (no restrictions).

Response

Returns the full note object:

{
  "id": "0192d4e5-7a8b-7c6d-9e0f-1a2b3c4d5e6f",
  "authorId": "user-uuid",
  "isPublished": true,
  "publishedAt": 1711900800000,
  "accessMode": "EDITABLE",
  "accessEmails": [],
  "folderId": null,
  "createdAt": 1711900800000,
  "updatedAt": 1711900800000
}

Errors

StatusDescription
401Missing or invalid API key
422Invalid ProseMirror JSON structure

ProseMirror node types

Notes support the following node types in the content array:

Node typeDescriptionExample
paragraphA block of text{ "type": "paragraph", "content": [{ "type": "text", "text": "..." }] }
headingHeading (attrs: level 1-6){ "type": "heading", "attrs": { "level": 1 }, "content": [...] }
bulletListUnordered list containing listItem nodes
orderedListOrdered list containing listItem nodes
listItemList item wrapping paragraph or nested list
taskListTodo list containing taskItem nodes
taskItemTodo item (attrs: checked boolean){ "type": "taskItem", "attrs": { "checked": false }, "content": [...] }
imageImage (attrs: src){ "type": "image", "attrs": { "src": "https://..." } }
audioAudio recording (attrs: src, audioId)
relationLink to another note (attrs: id, label){ "type": "relation", "attrs": { "id": "note-uuid", "label": "My Note" } }

Text marks

Text nodes can have marks for inline formatting:

Mark typeDescription
boldBold text
italicItalic text
strikeStrikethrough
underlineUnderline
linkHyperlink (attrs: href)
hashtagMarkHashtag (the text content includes the # prefix)

Example: rich note

{
  "content": {
    "type": "doc",
    "content": [
      {
        "type": "heading",
        "attrs": { "level": 1 },
        "content": [{ "type": "text", "text": "Meeting Notes" }]
      },
      {
        "type": "paragraph",
        "content": [
          { "type": "text", "text": "Discussed the " },
          { "type": "text", "text": "roadmap", "marks": [{ "type": "bold" }] },
          { "type": "text", "text": " for Q2." }
        ]
      },
      {
        "type": "taskList",
        "content": [
          {
            "type": "taskItem",
            "attrs": { "checked": false },
            "content": [
              {
                "type": "paragraph",
                "content": [{ "type": "text", "text": "Follow up with design team" }]
              }
            ]
          }
        ]
      }
    ]
  }
}