Learn more about the project and its background on the Poznote About page
Discover all the features here
- Install
- Access
- Note Types Comparison
- Change Settings
- Authentication
- Update application
- Multi-users
- Backup / Export
- Git Synchronization
- Restore / Import
- PWA
- Offline View
- Multiple Instances
- MCP Server
- Chrome Extension
- API Documentation
- Tech Stack
The official image is multi-arch (linux/amd64, linux/arm64) and supports Windows/macOS via Docker Desktop, as well as ARM64 devices like Raspberry Pi, NAS systems etc.
Choose your preferred installation method below:
🖥️ Windows
Install and start Docker Desktop
Create a new directory:
mkdir poznoteNavigate to the Poznote directory:
cd poznoteCreate the environment file:
curl -o .env https://raw.githubusercontent.com/timothepoznanski/poznote/main/.env.templateEdit the .env file:
notepad .envDownload the Docker Compose configuration file:
curl -o docker-compose.yml https://raw.githubusercontent.com/timothepoznanski/poznote/main/docker-compose.ymlDownload the latest Poznote Webserver and Poznote MCP images :
docker compose pullStart Poznote container:
docker compose up -d🐧 Linux
- Install Docker engine
- Install Docker Compose
Create a new directory:
mkdir poznoteNavigate to the Poznote directory:
cd poznoteCreate the environment file:
curl -o .env https://raw.githubusercontent.com/timothepoznanski/poznote/main/.env.templateEdit the .env file:
vi .envDownload the Docker Compose configuration file:
curl -o docker-compose.yml https://raw.githubusercontent.com/timothepoznanski/poznote/main/docker-compose.ymlDownload the latest Poznote Webserver and Poznote MCP images:
docker compose pullStart Poznote container:
docker compose up -d🍎 macOS
Install and start Docker Desktop
Create a new directory:
mkdir poznoteNavigate to the Poznote directory:
cd poznoteDownload the environment file:
curl -o .env https://raw.githubusercontent.com/timothepoznanski/poznote/main/.env.templateEdit the .env file:
vi .envDownload the Docker Compose configuration file:
curl -o docker-compose.yml https://raw.githubusercontent.com/timothepoznanski/poznote/main/docker-compose.ymlDownload the latest Poznote Webserver and Poznote MCP images:
docker compose pullStart Poznote container:
docker compose up -dIf you encounter installation issues, see the Troubleshooting Guide.
After installation, access Poznote in your web browser:
- Username:
admin_change_me - Password: value of
POZNOTE_PASSWORD(adminin.env.templateby default) - Port:
8040
Rename the default administrator account after the first login.
Poznote supports two primary note formats, each tailored for different workflows.
- Editor: Direct WYSIWYG (What You See Is What You Get) editing.
- Storage: Saved as
.htmlfiles in the user data directory. Since they are standard HTML, they can be opened directly in any web browser. - Exclusive Features:
- Excalidraw: Integrated drawing board for hand-drawn diagrams and sketches.
- Rich Formatting: Native support for text colors, highlighting, and standard HTML elements.
- Interactive UI: Direct manipulation of elements in the editor.
- Editor: Markdown syntax editor with real-time preview.
- Storage: Saved as
.mdfiles in the user data directory. - Exclusive Features:
- Mermaid Diagrams: Native support for generating diagrams (flowcharts, sequence, etc.) via
```mermaidcode blocks. - Math Equations: Robust LaTeX support for mathematical formulas using
$ inline $and$$ block $$syntax. - Portability: Standard Markdown format compatible with any external editor or static site generator.
- Mermaid Diagrams: Native support for generating diagrams (flowcharts, sequence, etc.) via
Most settings can be modified directly in the application through the settings page. Some system settings can only be changed in the .env file and require a container restart.
- Authentication - Initial/default passwords and login configuration
- Web Server - HTTP port configuration
- OIDC / SSO Authentication - OpenID Connect integration
- MCP Server - AI assistant integration
Passwords can be changed directly in the application from Settings > Change Password. The .env authentication variables remain available to define the initial or fallback passwords used when no custom password has been set for a user.
Navigate to your Poznote directory:
cd poznoteStop the running Poznote container:
docker compose downEdit your .env file with your preferred text editor.
Save the file and restart Poznote to apply changes:
docker compose up -dTraditional Authentication
Poznote authenticates users against their profile using a username or email address and a password.
When a user signs in, Poznote checks passwords in this order:
- A custom bcrypt password hash stored in the master database for that user.
- Fallback values from
.env:
POZNOTE_PASSWORDfor the administrator profilePOZNOTE_PASSWORD_USERfor standard usersPOZNOTE_PASSWORD_{USERNAME}for per-user overrides
This means .env acts as the default or seed credential source, while a password changed from the interface takes priority afterward.
On a fresh installation, Poznote creates one active administrator profile:
- Username:
admin_change_me - Password:
POZNOTE_PASSWORD
Rename this account after the first login.
- Users can change their own password from
Settings > Change Password. - Administrators can set a custom password for any user or reset that user back to their
.envpassword fromSettings > User Management. - The
Remember meoption keeps the session for 30 days. - Changing a password invalidates existing remember-me cookies for that user.
- Admin password: Set
POZNOTE_PASSWORDin your.envfile. - Default standard-user password: Set
POZNOTE_PASSWORD_USERin your.envfile. - User-specific passwords: Set individual defaults using
POZNOTE_PASSWORD_{USERNAME}in your.env.
Example:
POZNOTE_PASSWORD=admin-secret POZNOTE_PASSWORD_USER=user-secret POZNOTE_PASSWORD_ALICE=alice-secret POZNOTE_PASSWORD_BOB=bob-secretIf you want to adjust fonts, spacing, or other visual details beyond the built-in options, you can load an extra stylesheet on every HTML page.
Configure it in Settings > Advanced > Custom CSS path.
Notes:
- Enter only the filename, for example
custom.css. - The file must be placed in
src/css/, and Poznote will load it ascss/custom.css. - Poznote appends a cache-busting
v=parameter automatically when the target file exists locally. - The stylesheet is injected near the end of
<head>, so it can override the default application styles.
OIDC / SSO Authentication (Optional)
Poznote supports OpenID Connect (authorization code + PKCE) for single sign-on integration. This allows users to log in using external identity providers such as Auth0, Keycloak, Azure AD, or Google Identity.
- The login page displays a
Continue with [Provider Name]button when OIDC is enabled. - Users authenticate with the OIDC authorization code flow secured by PKCE.
- Access can be restricted with
POZNOTE_OIDC_ALLOWED_GROUPSand, if needed, the legacyPOZNOTE_OIDC_ALLOWED_USERSallowlist. - After authentication, Poznote links the identity in this order:
sub(oidc_subject), thenpreferred_username, thenemail. - If no profile matches and
POZNOTE_OIDC_AUTO_CREATE_USERS=true, Poznote creates one automatically. - If
POZNOTE_OIDC_DISABLE_NORMAL_LOGIN=true, the username/password form is hidden and the login page becomes SSO-only.
Add the OIDC variables to your .env file (see .env.template).
Minimum required settings:
POZNOTE_OIDC_ENABLED=true POZNOTE_OIDC_ISSUER=https://your-identity-provider.com POZNOTE_OIDC_CLIENT_ID=your_client_idNotes:
POZNOTE_OIDC_DISCOVERY_URLcan be used instead of deriving discovery from the issuer.POZNOTE_OIDC_CLIENT_SECRETis optional and mainly needed for confidential clients.POZNOTE_OIDC_DISABLE_NORMAL_LOGIN=truehides the local login form.POZNOTE_OIDC_DISABLE_BASIC_AUTH=truerejects HTTP Basic Auth on the API.POZNOTE_OIDC_GROUPS_CLAIMdefaults togroups.
Restrict access to specific groups and auto-create users at first login:
POZNOTE_OIDC_GROUPS_CLAIM=groups POZNOTE_OIDC_ALLOWED_GROUPS=poznote POZNOTE_OIDC_AUTO_CREATE_USERS=truePOZNOTE_OIDC_ALLOWED_USERS remains available for backward compatibility, but group-based access is recommended.
If auto-provisioning is enabled, Poznote generates a username from the OIDC claims (preferred_username, nickname, email local part, name, then sub) and stores the OIDC subject on the created profile.
Navigate to your Poznote directory:
cd poznoteStop the running container before updating:
docker compose downDownload the latest Docker Compose configuration:
curl -o docker-compose.yml https://raw.githubusercontent.com/timothepoznanski/poznote/main/docker-compose.ymlDownload the latest .env.template:
curl -o .env.template https://raw.githubusercontent.com/timothepoznanski/poznote/main/.env.templateReview .env.template and add any new variables to your .env file if needed:
sdiff .env .env.templateDownload the latest Poznote Webserver and Poznote MCP images:
docker compose pullStart the updated container:
docker compose up -dYour data is preserved in the ./data directory and will not be affected by the update.
Poznote features a multi-user architecture with isolated data space for each user (ideal for families, teams, or personal personas).
- Data Isolation: Each user has their own separate notes, workspaces, tags, folders and attachments.
- Hybrid Password Model: Access uses per-profile credentials with custom passwords stored in database, falling back to
.envdefaults when no custom password has been set. - User Management: Administrators can manage profiles via the Settings panel.
⚠️ Warning: It is not possible to share notes between users. Each user has their own isolated space. The only way to share notes or a profile is to share a common account.
Poznote uses a master database (data/master.db) to track profiles and global settings, and individual databases for each user.
data/ ├── master.db # Master database (profiles, global settings) └── users/ ├── 1/ # User ID 1 (default admin) │ ├── database/poznote.db # User's notes database │ ├── entries/ # User's note files (HTML/MD) │ └── attachments/ # User's attachments ├── 2/ # User ID 2 └── ... Poznote includes built-in Backup / Export functionality accessible through Settings.
Complete Backup to Poznote zip
Single ZIP containing database, all notes, and attachments for all workspaces:
- Includes an
index.htmlat the root for offline browsing - Notes are organized by workspace and folder
- Attachments are accessible via clickable links
Poznote provides flexible backup options:
Via Web Interface (Settings > Backup/Export):
- All users can backup and restore their own profile
- Admins can select which user profile to backup or restore
- Backups contain the user's database, notes, and attachments
Via API/Script (Administrators only):
- Automated backups using the
backup-poznote.shscript - Programmatic access via REST API v1
- Requires admin credentials
Backup Scopes:
- Per-User Backups: Created from Settings or via API. Contains only the data belonging to a specific user (their database, notes, and attachments).
- Complete System Backup: Created manually by backing up the entire
/datadirectory. This is the only way to backup the master configuration and all users' data at once.
# Complete system backup via CLI tar -czvf poznote-full-backup.tar.gz data/Export Individual Notes
Export individual notes using the Export button in the note toolbar:
- HTML notes: Export to HTML or PDF format
- Markdown notes: Export to HTML, Markdown or PDF format
Automated Backups with Bash Script
For automated scheduled backups via API, you can use the included backup-poznote.sh script.
IMPORTANT: Only administrators can create backups via the API.
Script location: backup-poznote.sh in the tools folder of the Poznote repository
Administrator Usage:
Admins can backup any user profile - no need to know user IDs, just the username:
# Backup your own profile bash backup-poznote.sh 'https://poznote.example.com' 'admin' 'admin_password' 'admin' '/backups' '30' # Backup another user's profile (Nina) bash backup-poznote.sh 'https://poznote.example.com' 'admin' 'admin_password' 'Nina' '/backups' '30'Usage:
bash backup-poznote.sh '<poznote_url>' '<admin_username>' '<admin_password>' '<target_username>' '<backup_directory>' '<retention_count>'Example with crontab (admin backing up Nina):
# Add to crontab for automated backups twice daily 0 0,12 * * * bash /root/backup-poznote.sh 'https://poznote.example.com' 'admin' 'admin_password' 'Nina' '/root/backups' '30'Parameters explained:
'https://poznote.example.com'- Your Poznote instance URL'admin'- Admin username for authentication (must be an admin)'admin_password'- Admin password (POZNOTE_PASSWORD from .env)'Nina'- Target username to backup'/root/backups'- Parent directory where backups will be stored (createsbackups-poznote-<username>folder)'30'- Number of backups to keep (older ones are automatically deleted)
How the backup process works:
- The script authenticates with admin credentials
- Automatically looks up the user ID from the username
- Creates a backup via the API
- Calls the Poznote REST API v1 (
POST /api/v1/backupswithX-User-IDheader) - Downloads the backup ZIP locally to
backups-poznote-<username>/ - Automatically manages retention (keeps only the specified number of recent backups)
Note: Each user's backups are stored in separate folders (backups-poznote-Nina, backups-poznote-Tim, etc.)
Poznote supports automatic and manual synchronization with GitHub or Forgejo. Each user configures their own repository independently. There is no shared global repository.
How to configure Git Sync
Step 1 — Enable the feature (admin, in Settings > Advanced Settings)
Toggle Git Sync to enabled in the Advanced Settings section of the Settings page. This will reveal the Git Sync menu in the sidebar for all users.
Step 2 — Each user configures their own repo (Settings > Git Sync)
| Field | Description |
|---|---|
| Provider | GitHub or Forgejo |
| API Base URL | GitHub: auto-filled (read-only). Forgejo: your instance URL, e.g. https://forgejo.example.com/api/v1 |
| Access Token | GitHub PAT (ghp_...) or Forgejo token (Settings > Applications) |
| Repository | owner/repo format |
| Branch | Default: main |
| Author Name / Email | Used for commit metadata |
🔒 Access tokens are encrypted at rest using AES-256-GCM. Set
POZNOTE_APP_SECRETin your.env(generated withopenssl rand -hex 32) to ensure the encryption key survives container rebuilds. If not set, a key is auto-generated and stored indata/.app_secret.
Automatic sync
When enabled by the user, Poznote will automatically:
- Pull on login
- Push on every note create, update, or delete
Manual push/pull is also available from the Sync Status page (cloud icon in the header).
Via Web Interface (Settings > Restore/Import):
- All users can restore backups to their own profile
- Supports complete backup restoration and individual file imports
Via API (Administrators only):
- Restore via REST API v1 endpoint
POST /api/v1/backups/{filename}/restore - Requires admin credentials
Complete Restore from Poznote zip backup
Upload the complete backup ZIP to restore everything:
- Replaces database, restores all notes, and attachments
- Works for all workspaces at once
Import Individual files
Import one or more HTML, Markdown or text notes directly:
- Support
.html,.md,.markdownor.txtfiles types - Up to 50 files can be selected at once, configurable in Settings > Advanced Settings > Import Limits
Import ZIP file
Import a ZIP archive containing multiple notes:
- Support
.html,.md,.markdownor.txtfiles types - ZIP archives can contain up to 300 files, configurable in Settings > Advanced Settings > Import Limits
- When importing a ZIP archive, Poznote automatically detects and recreates the folder structure
Import Obsidian Notes
Import a ZIP archive containing multiple notes from Obsidian:
- ZIP archives can contain up to 300 files, configurable in Settings > Advanced Settings > Import Limits
- Poznote automatically detects and recreates the folder structure
- Poznote automatically detects existing tags to create
- Poznote automatically imports images if they are at the zip file root
Import from Standard Notes
Convert and import your Standard Notes export to Poznote using the included conversion script:
Script location: standard-notes-to-poznote.sh in the tools folder of the Poznote repository
Prerequisites:
jq,unzip,zip, andfindutilities must be installed
Usage:
bash standard-notes-to-poznote.sh <standard_notes_export.zip>How it works:
- Export your notes from Standard Notes (this creates a ZIP file)
- Run the conversion script with your Standard Notes export ZIP as parameter
- The script generates a
poznote_export.zipfile compatible with Poznote - Import the generated ZIP into Poznote using the "Import ZIP file" feature
What gets converted:
- All notes are converted to Markdown format with front matter
- Note creation dates are preserved
- Tags are automatically extracted and included in the front matter
- Note content is preserved from the Standard Notes export
Example:
bash tools/standard-notes-to-poznote.sh my_standard_notes_backup.zip # This creates: poznote_export.zipAfter conversion, import the generated poznote_export.zip file into Poznote.
Markdown Front Matter Support
Markdown files can include YAML front matter to specify note metadata. The following keys are supported:
title— Override the note title (default: filename without extension)folder— Override the target folder selection (folder must exist in the workspace)tags— Array of tags to apply to the note. Supports both inline[tag1, tag2]and multi-line syntaxfavorite— Mark note as favorite (true/falseor1/0)created— Set custom creation date (format:YYYY-MM-DD HH:MM:SS)updated— Set custom update date (format:YYYY-MM-DD HH:MM:SS)
Example with inline array syntax:
--- title: My Important Note folder: Projects tags: [important, work] favorite: true created: 2024-01-15 10:30:00 updated: 2024-01-20 15:45:00 ---Example with multi-line syntax:
--- title: My Important Note folder: Projects tags: - important - work favorite: true created: 2024-01-15 10:30:00 updated: 2024-01-20 15:45:00 ---Admins can access additional tools via Settings > Admin Tools:
- Disaster Recovery - Reconstruct the entire user index from data folders in case of system corruption or database loss.
- Base64 Image Converter - Convert inline Base64 encoded images to attachments.
- Orphan attachments scanner - Scan and clean up orphaned attachment files.
Poznote can be installed as a Progressive Web App (PWA) in compatible browsers (Chrome, Edge, Safari on iOS, etc.).
- Open your Poznote URL in the browser.
- Use the browser install action (for example Install app in the address bar/menu), or use the install button in Settings → PWA Installation.
- Launch Poznote from your applications list like a native app.
- Android (Chrome/Edge): open menu → Install app / Add to Home screen
- iPhone/iPad (Safari): tap Share → Add to Home Screen
Poznote can be installed as a PWA, but this does not provide offline access to your notes content. For offline access to your notes, you must use the Complete Backup export feature (see section below).
The 📦 Complete Backup creates a standalone offline version of your notes. Simply extract the ZIP and open index.html in any web browser. This allows you to read your notes offline, but without the full Poznote functionality, it's a read-only export.
You can run multiple isolated Poznote instances on the same server. Each instance has its own data, port, and credentials.
Perfect for:
- Hosting for different users on the same server, each with their own separate instance and account
- Testing new features without affecting your production instance
Simply repeat the installation steps in different directories with different ports.
Server: my-server.com ├── Poznote-Tom │ ├── Port: 8040 │ ├── URL: http://my-server.com:8040 │ ├── Container: poznote-tom-webserver-1 │ └── Data: ./poznote-tom/data/ │ └── Poznote-Alice ├── Port: YOUR_POZNOTE_API_PORT ├── URL: http://my-server.com:YOUR_POZNOTE_API_PORT ├── Container: poznote-alice-webserver-1 └── Data: ./poznote-alice/data/ Poznote includes a Model Context Protocol (MCP) server that enables AI assistants like GitHub Copilot to interact with your notes using natural language. For example:
- "Create a new note titled 'Meeting Notes' with the content..."
- "Search for notes about 'Docker'"
- "List all notes in my Poznote workspace"
- "Update note 42 with new information"
For installation, configuration, and setup instructions, see the MCP Server documentation.
The Poznote URL Saver is a browser extension that allows you to quickly save the URL of the current page to your Poznote instance with a single click.
Install the extension directly from the Chrome Web Store → Install extension
Poznote provides a RESTful API v1 for programmatic access to notes, folders, workspaces, tags, and attachments.
Base URL: /api/v1
Access the Swagger UI directly from Poznote from Settings > API Documentation and browse all endpoints, view request/response schemas, and test API calls interactively.
Poznote supports multiple user profiles, each with their own isolated data. For API calls that access user data (notes, folders, workspaces, tags, attachments, backups, settings, etc.), you must include the X-User-ID header:
# Get notes for user ID 1 curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notesEndpoints that do NOT require the X-User-ID header:
- Admin endpoints:
/api/v1/admin/* - Public endpoints:
/api/v1/users/profiles - System endpoints:
/api/v1/system/*(version, updates, i18n)
Use GET /api/v1/users/profiles to list available user profiles and their IDs.
Ready-to-use curl commands for every API operation.
📝 Notes Management
List Notes
List all notes for a user:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notesFilter notes by workspace, folder, tag, or search:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api/v1/notes?workspace=Personal&folder=Projects&tag=important"List Notes with Attachments
List all notes that have file attachments:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/with-attachmentsGet Note Content
Get a specific note by ID:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123Resolve a note by title (reference) inside a workspace:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api/v1/notes/resolve?reference=My+Note&workspace=Personal"Create Note
Create a new note with title, content, tags, folder and workspace:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{ "heading": "My New Note", "content": "This is the content of my note", "tags": "work,important", "folder_id": 12, "workspace": "Personal", "type": "markdown" }' \ http://YOUR_SERVER/api/v1/notesUpdate Note
Update an existing note by ID:
curl -X PATCH -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{ "heading": "Updated Title", "content": "Updated content here", "tags": "work,updated" }' \ http://YOUR_SERVER/api/v1/notes/123Delete Note
Move a note to trash:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123Permanently delete (bypass trash):
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api/v1/notes/123?permanent=true"Restore Note
Restore a note from trash:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123/restoreDuplicate Note
Create a copy of an existing note:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123/duplicateUpdate Tags
Replace all tags on a note:
curl -X PUT -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"tags": "work,urgent,meeting"}' \ http://YOUR_SERVER/api/v1/notes/123/tagsToggle Favorite
Toggle favorite status:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123/favoriteMove Note to Folder
Move a note to a different folder:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"folder_id": 45}' \ http://YOUR_SERVER/api/v1/notes/123/folderRemove from folder (move to root):
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123/remove-folder🔗 Note Sharing
Get Share Status
Check if a note is shared:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123/shareCreate Share Link
Create a share link for a note:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{ "theme": "light", "indexable": false, "password": "optional-password" }' \ http://YOUR_SERVER/api/v1/notes/123/shareUpdate Share Settings
Update share settings:
curl -X PATCH -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"theme": "dark", "indexable": true}' \ http://YOUR_SERVER/api/v1/notes/123/shareRevoke Share Link
Remove sharing access:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123/shareList All Shared Notes
Get list of all shared notes:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/sharedFilter by workspace:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api/v1/shared?workspace=Personal"📂 Folder Sharing
Get Folder Share Status
Check if a folder is shared:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/folders/5/shareCreate Folder Share Link
Share a folder (all notes in the folder will also be shared):
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{ "theme": "light", "indexable": 0, "password": "optional-password" }' \ http://YOUR_SERVER/api/v1/folders/5/shareWith custom token:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{ "custom_token": "my-shared-folder" }' \ http://YOUR_SERVER/api/v1/folders/5/shareUpdate Folder Share Settings
Update share settings:
curl -X PATCH -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"indexable": 1, "password": "new-password"}' \ http://YOUR_SERVER/api/v1/folders/5/shareRevoke Folder Share Link
Revoke folder sharing (all notes in the folder will also be unshared):
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/folders/5/share🗑️ Trash Management
List Trash
Get all notes in trash:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/trashFilter by workspace:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api/v1/trash?workspace=Personal"Empty Trash
Permanently delete all notes in trash:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/trashPermanently Delete Note
Delete a specific note from trash:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/trash/123📁 Folders Management
List Folders
List all folders in a workspace:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api/v1/folders?workspace=Personal"Get folder tree (nested structure):
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api/v1/folders?workspace=Personal&tree=true"Get Folder Counts
Get note counts for all folders:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api/v1/folders/counts?workspace=Personal"Create Folder
Create a new folder:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{ "name": "My Projects", "workspace": "Personal" }' \ http://YOUR_SERVER/api/v1/foldersCreate a subfolder:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{ "name": "2024", "workspace": "Personal", "parent_id": 12 }' \ http://YOUR_SERVER/api/v1/foldersRename Folder
Rename an existing folder:
curl -X PATCH -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"name": "New Folder Name"}' \ http://YOUR_SERVER/api/v1/folders/12Move Folder
Move folder to a different parent:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"parent_id": 56}' \ http://YOUR_SERVER/api/v1/folders/34/moveMove to root (no parent):
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"parent_id": null}' \ http://YOUR_SERVER/api/v1/folders/34/moveMove to another workspace (recursive):
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"target_workspace": "New Workspace", "parent_id": null}' \ http://YOUR_SERVER/api/v1/folders/34/moveUpdate Folder Icon
Set a custom icon:
curl -X PUT -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"icon": "fa-folder-open"}' \ http://YOUR_SERVER/api/v1/folders/12/iconEmpty Folder
Move all notes in folder to trash:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/folders/12/emptyDelete Folder
Delete a folder:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/folders/12🗂️ Workspaces Management
List Workspaces
Get all workspaces:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/workspacesCreate Workspace
Create a new workspace:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"name": "MyProject"}' \ http://YOUR_SERVER/api/v1/workspacesRename Workspace
Rename an existing workspace:
curl -X PATCH -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"new_name": "NewName"}' \ http://YOUR_SERVER/api/v1/workspaces/OldNameDelete Workspace
Delete a workspace:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/workspaces/OldWorkspace🏷️ Tags Management
List Tags
Get all unique tags:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/tagsFilter by workspace:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api/v1/tags?workspace=Personal"📎 Attachments Management
List Attachments
Get all attachments for a note:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123/attachmentsUpload Attachment
Upload a file to a note:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ -F "file=@/path/to/file.pdf" \ http://YOUR_SERVER/api/v1/notes/123/attachmentsDownload Attachment
Download a specific attachment:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123/attachments/456 \ -o downloaded-file.pdfDelete Attachment
Delete an attachment:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/notes/123/attachments/456💾 Backup Management
List Backups
Get a list of all backup files:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/backupsCreate Backup
Create a complete backup:
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/backupsDownload Backup
Download a specific backup file:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/backups/poznote_backup_2025-01-05_12-00-00.zip \ -o backup.zipRestore Backup
Restore a backup file (replaces all current user data):
curl -X POST -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/backups/poznote_backup_2025-01-05_12-00-00.zip/restoreDelete Backup
Delete a backup file:
curl -X DELETE -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/backups/poznote_backup_2025-01-05_12-00-00.zip📤 Export Management
Note: Export endpoints remain as legacy URLs for file downloads.
Export Note
Export a note as HTML or Markdown:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api_export_note.php?id=123&format=html" \ -o exported-note.htmlExport Folder
Export a folder as ZIP:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api_export_folder.php?folder_id=123" \ -o folder-export.zipExport Structured Notes
Export all notes preserving folder hierarchy:
curl -u 'username:password' -H "X-User-ID: 1" \ "http://YOUR_SERVER/api_export_structured.php?workspace=Personal" \ -o structured-export.zipExport All Notes
Export all note files as ZIP:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api_export_entries.php \ -o all-notes.zipExport All Attachments
Export all attachments as ZIP:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api_export_attachments.php \ -o all-attachments.zip⚙️ Settings
Get Setting
Get a setting value:
curl -u 'username:password' -H "X-User-ID: 1" \ http://YOUR_SERVER/api/v1/settings/languageUpdate Setting
Set a setting value:
curl -X PUT -u 'username:password' -H "X-User-ID: 1" \ -H "Content-Type: application/json" \ -d '{"value": "fr"}' \ http://YOUR_SERVER/api/v1/settings/languageℹ️ System Information
Note: System endpoints do not require the
X-User-IDheader.
Get Version
Get current version and system info:
curl -u 'username:password' \ http://YOUR_SERVER/api/v1/system/versionCheck for Updates
Check if a newer version is available:
curl -u 'username:password' \ http://YOUR_SERVER/api/v1/system/updatesGet Translations
Get translation strings:
curl -u 'username:password' \ http://YOUR_SERVER/api/v1/system/i18n👥 User Management (Admin Only)
User management endpoints are for administrators only and do not require the X-User-ID header.
List All User Profiles (Public)
Get list of active user profiles (no authentication required):
curl http://YOUR_SERVER/api/v1/users/profilesList All Users with Statistics
Get detailed list of all users with storage info (admin only):
curl -u 'username:password' \ http://YOUR_SERVER/api/v1/admin/usersGet Specific User
Get detailed information about a user:
curl -u 'username:password' \ http://YOUR_SERVER/api/v1/admin/users/1Create New User
Create a new user profile:
curl -X POST -u 'username:password' \ -H "Content-Type: application/json" \ -d '{"username": "newuser"}' \ http://YOUR_SERVER/api/v1/admin/usersUpdate User
Update user properties (username, active status, admin status):
curl -X PATCH -u 'username:password' \ -H "Content-Type: application/json" \ -d '{ "username": "renameduser", "active": true, "is_admin": false }' \ http://YOUR_SERVER/api/v1/admin/users/2Delete User
Delete a user profile (without data):
curl -X DELETE -u 'username:password' \ http://YOUR_SERVER/api/v1/admin/users/2Delete a user profile and all their data:
curl -X DELETE -u 'username:password' \ "http://YOUR_SERVER/api/v1/admin/users/2?delete_data=true"Get System Statistics
Get aggregated statistics for all users:
curl -u 'username:password' \ http://YOUR_SERVER/api/v1/admin/statsRepair Master Database
Scan and rebuild the master database registry:
curl -X POST -u 'username:password' \ http://YOUR_SERVER/api/v1/admin/repairPoznote prioritizes simplicity and portability - no complex frameworks, no heavy dependencies. Just straightforward, reliable web technologies that ensure your notes remain accessible and under your control.
Privacy-First Architecture: Poznote operates entirely locally with no external connections required for functionality. All libraries (Excalidraw, Mermaid, KaTeX) are bundled and served from your own instance. The only outbound connection is a daily update check.
If you are interested in the tech stack on which Poznote is built, have a look here.
- PHP 8.x - Server-side scripting language
- SQLite 3 - Lightweight, file-based relational database
- HTML5 - Markup and structure
- CSS3 - Styling and responsive design
- JavaScript (Vanilla) - Interactive features and dynamic content
- React + Vite - Build toolchain for Excalidraw component (bundled as IIFE)
- AJAX - Asynchronous data loading
- Excalidraw - Virtual whiteboard for sketching diagrams and drawings
- Mermaid - Client-side JavaScript library for diagram and flowchart generation from text
- KaTeX - Client-side JavaScript library for fast math typesetting and rendering mathematical equations
- Sortable.js - JavaScript library for drag-and-drop sorting
- highlight.js - Syntax highlighting for code blocks
- Swagger UI - Interactive API documentation and testing interface
- HTML/Markdown files - Notes are stored as plain HTML or Markdown files in the filesystem
- SQLite database - Metadata, tags, relationships, and user data
- File attachments - Stored directly in the filesystem
- Nginx + PHP-FPM - High-performance web server with FastCGI Process Manager
- Alpine Linux - Secure, lightweight base image
- Docker - Containerization for easy deployment and portability
- Python 3.12 (Alpine) - MCP server runtime with httpx, fastmcp, and mcp libraries for AI assistant integration


