All notes endpoints require authentication via JWT or API token.
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"]
}'
Note title (cannot be empty)
Note content (plain text or markdown)
Archive note (hidden from main list)
Background color (hex code or preset)
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)
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": []
}
]
True if current user owns the note
Current user’s permission: viewer, editor, or null if owner
Only present if user is note owner. Lists all shares.
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": "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
{
"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"]
}'
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": "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": "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"
{
"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"]
}'
Array of note UUIDs to delete (cannot be empty)
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"]
}'
Array of note UUIDs to archive (cannot be empty)
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"
}
]
}'
ISO 8601 timestamp of last sync (optional for initial sync)
Array of note changes to sync (optional)
Show Change Object Fields
Note UUID (can be client-generated)
Note state: active, trashed, or deleted
ISO 8601 timestamp of change
{
"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"
}
}
]
}
Notes modified on server since lastSyncedAt
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.