Skip to main content
All notes endpoints require authentication via JWT or API token.
Authorization
string
required
Bearer token (JWT or API token)

Create Note

Create a new note with optional tags.
curl -X POST http://localhost:3001/api/notes \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Meeting Notes",
    "content": "Discuss Q2 objectives and team alignment",
    "isPinned": false,
    "isArchived": false,
    "background": "#FFE5B4",
    "tagIds": ["tag-uuid-1", "tag-uuid-2"]
  }'
title
string
required
Note title (cannot be empty)
content
string
Note content (plain text or markdown)
isPinned
boolean
default:false
Pin note to top of list
isArchived
boolean
default:false
Archive note (hidden from main list)
background
string
Background color (hex code or preset)
tagIds
string[]
Array of tag UUIDs to associate with note
{
  "id": "note-uuid-123",
  "title": "Meeting Notes",
  "content": "Discuss Q2 objectives and team alignment",
  "isPinned": false,
  "isArchived": false,
  "background": "#FFE5B4",
  "state": "active",
  "createdAt": "2026-03-02T10:30:00.000Z",
  "updatedAt": "2026-03-02T10:30:00.000Z",
  "userId": "user-uuid-456",
  "tags": [
    {
      "id": "tag-uuid-1",
      "name": "Work",
      "color": "#3B82F6"
    },
    {
      "id": "tag-uuid-2",
      "name": "Meetings",
      "color": "#10B981"
    }
  ],
  "isOwner": true,
  "permission": null
}

List Notes

Retrieve all active notes (non-archived, non-trashed) with optional filtering.
curl -X GET "http://localhost:3001/api/notes" \
  -H "Authorization: Bearer YOUR_TOKEN"
Search in title and content (case-insensitive)
tagId
string
Filter by tag UUID
limit
number
default:100
Maximum number of notes to return (1-100)
[
  {
    "id": "note-uuid-123",
    "title": "Meeting Notes",
    "content": "Discuss Q2 objectives",
    "isPinned": true,
    "isArchived": false,
    "background": null,
    "state": "active",
    "createdAt": "2026-03-02T10:30:00.000Z",
    "updatedAt": "2026-03-02T10:30:00.000Z",
    "userId": "user-uuid-456",
    "tags": [
      {
        "id": "tag-uuid-1",
        "name": "Work",
        "color": "#3B82F6"
      }
    ],
    "isOwner": true,
    "permission": null,
    "sharedWith": [
      {
        "id": "share-uuid-789",
        "permission": "viewer",
        "sharedWithUser": {
          "id": "user-uuid-999",
          "name": "John Collaborator",
          "email": "[email protected]"
        }
      }
    ]
  },
  {
    "id": "note-uuid-456",
    "title": "Shared Note",
    "content": "Note shared with me",
    "isPinned": false,
    "isArchived": false,
    "background": null,
    "state": "active",
    "createdAt": "2026-03-01T09:00:00.000Z",
    "updatedAt": "2026-03-01T09:00:00.000Z",
    "userId": "user-uuid-999",
    "tags": [],
    "isOwner": false,
    "permission": "editor",
    "sharedWith": []
  }
]
Results are ordered by pinned status (pinned first), then by update date (newest first).

Get Note

Retrieve a single note by ID.
curl -X GET http://localhost:3001/api/notes/note-uuid-123 \
  -H "Authorization: Bearer YOUR_TOKEN"
id
string
required
Note UUID
{
  "id": "note-uuid-123",
  "title": "Meeting Notes",
  "content": "Discuss Q2 objectives and team alignment",
  "isPinned": false,
  "isArchived": false,
  "background": "#FFE5B4",
  "state": "active",
  "createdAt": "2026-03-02T10:30:00.000Z",
  "updatedAt": "2026-03-02T10:30:00.000Z",
  "userId": "user-uuid-456",
  "tags": [
    {
      "id": "tag-uuid-1",
      "name": "Work",
      "color": "#3B82F6"
    }
  ],
  "isOwner": true,
  "permission": null
}

Error Responses

404 Not Found
{
  "statusCode": 404,
  "message": "Note not found or access denied",
  "error": "Not Found"
}

Update Note

Update any field of a note. All fields are optional.
curl -X PATCH http://localhost:3001/api/notes/note-uuid-123 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Updated Meeting Notes",
    "content": "New content here",
    "isPinned": true,
    "tagIds": ["tag-uuid-3"]
  }'
id
string
required
Note UUID
title
string
Updated note title
content
string
Updated note content
isPinned
boolean
Pin/unpin note
isArchived
boolean
Archive/unarchive note
background
string
Updated background color
tagIds
string[]
Updated array of tag UUIDs (replaces existing tags)
{
  "id": "note-uuid-123",
  "title": "Updated Meeting Notes",
  "content": "New content here",
  "isPinned": true,
  "isArchived": false,
  "background": "#FFE5B4",
  "state": "active",
  "createdAt": "2026-03-02T10:30:00.000Z",
  "updatedAt": "2026-03-02T11:00:00.000Z",
  "userId": "user-uuid-456",
  "tags": [
    {
      "id": "tag-uuid-3",
      "name": "Important",
      "color": "#EF4444"
    }
  ],
  "isOwner": true,
  "permission": null
}
Users with editor permission can update shared notes, but only owners can modify sharing settings.

Delete Note (Move to Trash)

Soft-delete a note by moving it to trash.
curl -X DELETE http://localhost:3001/api/notes/note-uuid-123 \
  -H "Authorization: Bearer YOUR_TOKEN"
id
string
required
Note UUID
{
  "id": "note-uuid-123",
  "title": "Meeting Notes",
  "content": "Discuss Q2 objectives",
  "isPinned": false,
  "isArchived": false,
  "background": null,
  "state": "trashed",
  "createdAt": "2026-03-02T10:30:00.000Z",
  "updatedAt": "2026-03-02T12:00:00.000Z",
  "userId": "user-uuid-456",
  "tags": [],
  "isOwner": true,
  "permission": null
}

Restore Note

Restore a trashed note to active state.
curl -X PATCH http://localhost:3001/api/notes/note-uuid-123/restore \
  -H "Authorization: Bearer YOUR_TOKEN"
id
string
required
Note UUID
{
  "id": "note-uuid-123",
  "title": "Meeting Notes",
  "content": "Discuss Q2 objectives",
  "isPinned": false,
  "isArchived": false,
  "background": null,
  "state": "active",
  "createdAt": "2026-03-02T10:30:00.000Z",
  "updatedAt": "2026-03-02T12:30:00.000Z",
  "userId": "user-uuid-456",
  "tags": [],
  "isOwner": true,
  "permission": null
}

Permanent Delete

Permanently delete a note. This action cannot be undone.
curl -X DELETE http://localhost:3001/api/notes/note-uuid-123/permanent \
  -H "Authorization: Bearer YOUR_TOKEN"
id
string
required
Note UUID
{
  "message": "Note permanently deleted"
}
Permanent deletion removes the note and all associated shares. This action is irreversible.

List Trashed Notes

Retrieve all notes in trash.
curl -X GET http://localhost:3001/api/notes/trash \
  -H "Authorization: Bearer YOUR_TOKEN"
[
  {
    "id": "note-uuid-789",
    "title": "Old Note",
    "content": "No longer needed",
    "isPinned": false,
    "isArchived": false,
    "background": null,
    "state": "trashed",
    "createdAt": "2026-02-28T09:00:00.000Z",
    "updatedAt": "2026-03-01T10:00:00.000Z",
    "userId": "user-uuid-456",
    "tags": [],
    "isOwner": true,
    "permission": null
  }
]

List Archived Notes

Retrieve all archived notes.
curl -X GET http://localhost:3001/api/notes/archive \
  -H "Authorization: Bearer YOUR_TOKEN"
[
  {
    "id": "note-uuid-321",
    "title": "Archived Reference",
    "content": "Important but not active",
    "isPinned": false,
    "isArchived": true,
    "background": null,
    "state": "active",
    "createdAt": "2026-01-15T09:00:00.000Z",
    "updatedAt": "2026-02-20T10:00:00.000Z",
    "userId": "user-uuid-456",
    "tags": [
      {
        "id": "tag-uuid-5",
        "name": "Reference",
        "color": "#8B5CF6"
      }
    ],
    "isOwner": true,
    "permission": null
  }
]

Bulk Delete

Move multiple notes to trash at once.
curl -X POST http://localhost:3001/api/notes/bulk/delete \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "noteIds": ["note-uuid-1", "note-uuid-2", "note-uuid-3"]
  }'
noteIds
string[]
required
Array of note UUIDs to delete (cannot be empty)
{
  "count": 3
}
count
number
Number of notes successfully moved to trash

Bulk Archive

Archive multiple notes at once.
curl -X POST http://localhost:3001/api/notes/bulk/archive \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "noteIds": ["note-uuid-4", "note-uuid-5"]
  }'
noteIds
string[]
required
Array of note UUIDs to archive (cannot be empty)
{
  "count": 2
}
count
number
Number of notes successfully archived

Sync Notes

Advanced endpoint for offline-first clients to synchronize local changes with the server.
curl -X POST http://localhost:3001/api/notes/sync \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "lastSyncedAt": "2026-03-02T10:00:00.000Z",
    "changes": [
      {
        "id": "note-uuid-local-1",
        "title": "New Note",
        "content": "Created offline",
        "isPinned": false,
        "state": "active",
        "updatedAt": "2026-03-02T11:00:00.000Z",
        "tagIds": []
      },
      {
        "id": "note-uuid-123",
        "title": "Updated Note",
        "content": "Modified offline",
        "state": "active",
        "updatedAt": "2026-03-02T11:30:00.000Z"
      }
    ]
  }'
lastSyncedAt
string
ISO 8601 timestamp of last sync (optional for initial sync)
changes
array
Array of note changes to sync (optional)
{
  "serverNotes": [
    {
      "id": "note-uuid-123",
      "title": "Server Version",
      "content": "Modified on server",
      "isPinned": false,
      "isArchived": false,
      "background": null,
      "state": "active",
      "createdAt": "2026-03-02T10:30:00.000Z",
      "updatedAt": "2026-03-02T11:45:00.000Z",
      "userId": "user-uuid-456",
      "tags": [],
      "isOwner": true,
      "permission": null
    }
  ],
  "conflicts": [
    {
      "clientNote": {
        "id": "note-uuid-123",
        "title": "Updated Note",
        "updatedAt": "2026-03-02T11:30:00.000Z"
      },
      "serverNote": {
        "id": "note-uuid-123",
        "title": "Server Version",
        "updatedAt": "2026-03-02T11:45:00.000Z"
      }
    }
  ]
}
serverNotes
array
Notes modified on server since lastSyncedAt
conflicts
array
Notes with conflicting changes requiring conflict resolution
The sync endpoint handles three-way merge logic. Client should resolve conflicts by choosing client, server, or merged version.

Build docs developers (and LLMs) love